Architecture
System architecture, monorepo layout, language choices, build and release pipeline, and the package boundaries a subagent fleet builds against.
What ships today (2026-11). Two surfaces: the CLI/TUI (@picassohq/cli, not yet on npm) and Picasso for Mac 1.0.54 (Apple silicon, macOS 14+). Both run the agent loop in the pinned engine (0.2.2-rc.1, kept current by a gated background updater) with Picasso's plugins (packages/picasso-*); the CLI talks to it over stdio (tui-architecture.md) and the Mac app through the local relay inapps/desktop-helper(mac-relay.md). The engine's home is~/.picasso/dsh-home. The stack choices below are the original plan; where they differ,tui-architecture.mdandmac-relay.mddescribe the shipped system.
Stack decisions
- CLI core: TypeScript on Node.js 22+. The ecosystem gravity for AI coding tools (Claude Code, Codex, Gemini CLI, OpenCode, Crush) is TypeScript, and matching it minimizes distribution and contribution friction. Bun is supported but not required.
- Performance-critical paths: Rust binaries for repo indexing, tree-sitter parsing, and the memory layer's vector store. Invoked from TS via N-API bindings or stdio.
- TUI: Ink (React for terminals) for the interactive surface. The component primitives in
packages/tuimirrordesign/tui-primitives.jsxone-to-one — same names, same prop shapes. The design tokens indesign/styles.cssare the source of truth for color, type, spacing, and motion. Bubbletea (Go) was evaluated; Ink wins on TS-shared types with the rest of the stack and on cross-rendering with the dashboard. - Web dashboard: Next.js 15 (App Router), React 19, TanStack Query, Tailwind v4 configured against
design/styles.csstokens. Hosted on Vercel. - Database: Postgres (Supabase) for user accounts, sessions, ad telemetry. Object storage (S3 or R2) for session artifacts and replays. Qdrant or Lance for the memory layer's vector index.
- Auth: WorkOS for SSO and SAML; Clerk for consumer auth; both behind a single auth abstraction.
- Models: Provider-abstracted via a
Providerinterface (see07-providers.md). No model logic in the core.
Monorepo layout
Single repo, pnpm workspaces, Turborepo for the build graph.
picasso/
├── apps/
│ ├── cli/ The npm-published CLI binary. Entrypoint.
│ ├── mac/ Native macOS desktop app (SwiftUI) + local helper.
│ ├── marketing/ Next.js marketing/waitlist site.
│ ├── dashboard/ Next.js companion web app.
│ ├── api/ Backend service (Fastify) for sessions, ads, telemetry.
│ ├── admin/ Next.js master-backend admin console.
│ └── docs/ Docs site source.
├── packages/
│ ├── core/ Agent loop, plan/act/observe/reflect.
│ ├── tools/ Built-in tool catalog.
│ ├── subagents/ Subagent orchestration.
│ ├── plan-mode/ Plan generation and approval flow.
│ ├── mcp/ MCP client + server + registry.
│ ├── sessions/ Persist, resume, fork, replay.
│ ├── providers/ Provider abstraction. Per-provider adapters.
│ ├── sandbox/ OS-level sandboxing wrappers.
│ ├── hooks/ Hook runtime.
│ ├── commands/ Slash + user-defined commands.
│ ├── tui/ Ink components, status line, diff renderer.
│ ├── auth/ Auth abstraction.
│ ├── telemetry/ Opt-in event collection.
│ ├── ads-sdk/ Ad surface SDK. ZeroClick + TryGravity adapters.
│ ├── memory/ Persistent memory layer. Vector + graph store.
│ ├── goals/ /goal long-horizon mode.
│ ├── cache-harness/ V2 cache-aware prompt/context harness.
│ ├── secrets/ Secret detection and redaction.
│ ├── admin/ Master-backend admin domain logic.
│ ├── admin-client/ Typed client for the admin/control-plane API.
│ ├── control-plane/ Control-plane service logic (orgs, budgets, flags).
│ ├── desktop-agent/ Mac local-helper agent runtime bridge.
│ ├── desktop-browser/ In-app browser preview engine.
│ ├── desktop-git/ Git operations for the desktop app.
│ ├── desktop-ipc/ Desktop <-> local-helper IPC.
│ ├── desktop-projects/ Workspace/project management for the desktop app.
│ ├── desktop-schedules/ Scheduled/automation runs for the desktop app.
│ ├── desktop-sponsors/ Sponsored-surface logic for the desktop app.
│ ├── desktop-voice/ Voice/dictation for the desktop app.
│ └── shared/ Shared types, errors, logging.
├── crates/
│ ├── indexer/ Rust repo indexer (tree-sitter).
│ ├── memdb/ Rust vector + graph store for memory layer.
│ └── sandbox-native/ Rust shims for seatbelt / Landlock / Job Objects.
├── scripts/ Release, signing, codegen scripts.
└── infra/ Terraform for Postgres, Qdrant, S3, Vercel.Thedesktop-*packages and theapps/macSwiftUI app make up the native macOS surface; the CLI/TUI and the desktop app sharecore,providers,memory,goals,sessions, and the rest of the engine.
Package boundaries
Each package has one job and a single owner role. Cross-package imports go through public entry points (index.ts) only — no deep imports. Dependency direction is strict and one-way:
cli, mac, marketing, dashboard, api, admin, docs (apps)
│
▼
memory, goals ◄── highest-level packages
│
▼
core, subagents, plan-mode, sessions
│
▼
tools, mcp, providers, sandbox, hooks, commands, ads-sdk
│
▼
tui, auth, telemetry
│
▼
sharedViolations of the direction are caught by eslint-plugin-boundaries on CI.
Build and release pipeline
- CI: GitHub Actions. Every PR runs
pnpm lint,pnpm typecheck,pnpm test,pnpm build. Turborepo caches across runs. - Versioning: Changesets. Every PR with a public-facing change requires a changeset.
- Release: Tag-triggered release workflow that publishes
@picassohq/cliand sub-packages to npm, builds notarized macOS binaries (Apple Developer signing), signed Windows binaries (EV cert), and Linux.tar.gz+.deb+.rpm. Homebrew formula updated by a separate job that PRs into our tap. - Telemetry pipeline: Events ship to ClickHouse for analytics, Tinybird for dashboards. PII scrubbing happens at the SDK before the event leaves the user's machine.
- Ad pipeline: Ad SDK fetches from ad network adapters (ZeroClick, TryGravity) on the dashboard side. Ad impression logs go to our analytics for revenue attribution.
Runtime topology
When a user runs picasso:
- CLI binary starts in their terminal.
- CLI authenticates via cached device-code token, or prompts for login.
- CLI loads project context:
picasso.yamlconfig,.picasso/commands/, project memory profile (see15-memory.md). - User issues a command (interactive turn,
picasso run "...",picasso goal "..."). - The CLI starts (or reuses) the pinned engine; the engine builds the prompt envelope: system prompt + injected memory + project rules + tool catalog (
lean-context-architecture.md). - The engine calls the provider route the person chose (
picasso provider,picasso models; see07-providers.md). - Tool calls execute locally in the sandbox; results stream back to the model.
- Session events stream to the API for persistence; telemetry events ship if opted in.
- On
/goalmode, the loop continues autonomously until the completion contract is met. - The web dashboard reads from the API and renders sessions, replays, ads, and account settings.
Local dev environment
pnpm i && pnpm dev brings up:
- CLI in watch mode (
packages/corerebuilds on save). - Dashboard at
localhost:3000. - API at
localhost:3001. - Postgres + Qdrant in Docker.
- Stub ad-network server returning fake ads.
Distribution
See 14-distribution.md for the full surface. Channels at launch: npm (npm i -g @picassohq/cli, publish pending) and the notarized Mac DMG with Sparkle updates. Homebrew, a curl installer and Windows or Linux binaries are not shipped.
Security posture
- Code execution sandboxed by default. Detail in
08-sandbox.md. - Telemetry opt-in, never required. Detail in
12-telemetry.md. - Memory layer is per-account isolated. No cross-account memory access, no training on user code unless explicitly opted in. Detail in
15-memory.md. - Ads served from dashboard, never injected into model output. Detail in
13-ads-monetization.md.
What we are not building in v1
Listed so the surface is honest:
- IDE plug-ins. Web dashboard and CLI are the surfaces. JetBrains and VS Code plug-ins are v2.
- Mobile app. The companion dashboard is responsive; a native mobile app is v2.
- Custom model training. Memory is retrieval, not fine-tuning.
- Enterprise on-prem deployment. Cloud only in v1; on-prem is v2.