Avesd is the kiosk that grows with you: a local-first, extensible desktop workspace that gains capabilities through replaceable plugins. The first product is an Electron application; optional account and cloud capabilities can be added later without becoming a dependency of the local workflow.
- Node.js 24 (see
.nvmrc) - Corepack
- pnpm 11.23.0 (pinned in
package.json)
pnpm install
pnpm devUse the root pnpm scripts for repository tasks:
pnpm lint
pnpm compile
pnpm test
pnpm build
pnpm validateEquivalent Make targets provide short, stable entry points such as make dev,
make validate, and make update-all; running plain make performs no work.
See Development for test selection, validation boundaries,
browser test setup, and dependency maintenance.
apps/desktop— Electron main, preload, and React renderer processes.packages/acp-client— provider-neutral ACP v1 client boundary.packages/configuration— shared TypeScript, ESLint, and Vitest defaults.packages/kernel— Cordis-backed plugin lifecycle adapter and contribution registries.packages/plugin-api— stable contracts implemented by plugins.packages/plugin-data— runtime-neutral local data-source contributions.packages/plugin-ui— framework-neutral renderer widget contracts and contribution points.packages/ui— internal React components and design tokens for trusted Avesd product surfaces.packages/workspace-model— runtime-neutral workspace, dashboard, widget, and data-source ownership contracts..agents/common-skills-policy.mdand.agents/audit-policy.md— local repository policy for globally installed shared skills.working— non-authoritative audits, plans, notes, and archived project memory.
Desktop code preserves process boundaries and groups related files by feature:
apps/desktop/
src/
main/
main.ts # Process startup entry
desktop-application.ts # Application composition, IPC, and lifecycle
agent/ # Agent transport, tools, permissions, MCP entry
browser/ # Native web surfaces and browser bindings
plugins/ # Local authoring, installation, sandboxed views
storage/ # Config, workspace files, scoped storage, resources
workspace/ # Workbench orchestration and widget service bridge
preload/
preload.ts # Context bridge startup entry
desktop-api.ts # Narrow privileged bridge implementation
shared/
browser/ # Browser IPC contracts
plugins/ # Local plugin IPC contracts
storage/ # File, SQLite, and resource contracts/facades
workspace/ # Widget workspace contracts/facades
desktop-api.ts # Aggregate preload API
widget-appearance.ts # DOM/native geometry
renderer/src/
components/ # Dashboard shell and widget hosting
workbench/ # Renderer orchestration
plugins/ # One directory per built-in plugin/adapter
test/
unit/ # Mirrors src/, including renderer browser tests
integration/ # Real listeners, processes, and multi-owner storage
e2e/
support/ # Shared isolated desktop lifecycle and helpers
*.test.mjs # Independently runnable native scenarios
run.mjs # Explicit scenario selection
Keep tests in each workspace's test/ directory, not beside production code.
Unit and component tests mirror src/ under test/unit/ and import the covered
implementation directly. Integration tests mirror the owning source path under
test/integration/; native Electron scenarios live under test/e2e/.
Configuration rule tests mirror eslint/ under test/unit/eslint/.
Path correspondence does not require a test for every source file. TypeScript
tests remain included in compile and type-aware lint checks.
Add a feature folder when several related files need a home; avoid generic
utils folders, internal barrel files, or new packages solely to shorten paths.
Package-level src/index.ts files define the public export surface and contain
only re-exports. Put declarations, factories, and behavior in files named for
their responsibilities. Configuration factories use explicit filenames such as
create-vitest-config.ts; package export specifiers remain stable. Executable
entry points use names such as main.ts and preload.ts and keep startup wiring
small. Build outputs remain out/main/index.js and out/preload/index.cjs.
Shared ESLint rules apply to workspace source, configuration, tests, and root
scripts. pnpm lint checks scripts/ and the root ESLint configuration before
running workspace checks. Nonempty function and enum bodies start with one blank
line after {; a return preceded by another statement in its block also has a
blank line before it. Empty bodies do not need padding. These conventions are
autofixable, including the requirement to use braces around conditional bodies.
Avesd keeps a small trusted Electron host and moves product capabilities into
replaceable plugins. Renderer code reaches privileged behavior only through
narrow typed preload APIs and explicit IPC contracts. The internal runtime uses
Cordis behind @avesd/plugin-api, so public plugins do not depend on the runtime
framework.
Workspaces own dashboards and shared data sources. Dashboards own widget instances, private data sources, and view state. Plugin identity is a separate security namespace injected by the kernel. Layout, navigation, persistence, and permission changes pass through host-owned transactional services.
The local workflow requires no account or cloud service. Workspace snapshots, plugin data, browser grants, and application settings remain on the user's machine. Sandboxed local widgets and embedded web pages receive only explicitly declared, host-mediated capabilities.
See Runtime architecture for the complete model.
- Development — validation, tests, and dependency tasks.
- Runtime architecture — process boundaries, workspace ownership, navigation, persistence, and Agent integration.
- Application configuration — local data directory configuration and migration.
- Local widgets — Agent-authored widgets, private storage, shared resources, testing, and activation.
- Agent sessions — tier routing, widget tasks, and unified session management.
- Browser widgets — embedded pages, script tools, and browser control bindings.