A desktop portal that runs Claude Agent SDK subagents across a whole portfolio of projects — intent routing, an autonomous PR worker fenced by hard budgets, and five custom MCP servers feeding it live business data.
71-second guided tour · narrated · tap Sound on to hear it
The fence
The PR worker picks up a governance task, opens a git worktree, and hands it to a subagent — but the subagent works inside a fence: a diff ceiling, a spend ceiling, a wall-clock ceiling, a turn ceiling, and a denylist that keeps .env files and private keys out of reach. A pre-check refuses to start when the tooling is wrong; a post-check re-measures the diff before a PR is ever opened.
scope-fence.ts
export const DEFAULT_FENCE: Fence = { maxLines: 500, maxFiles: 15, maxCostCents: 50, maxWallClockMs: 600_000, maxTurns: 15, deniedPathGlobs: [ '.env', '.env.*', '**/secrets/**', '*.pem', '*.key', ], }; // preCheck refuses to start without gh and a configured // remote. postCheck re-measures the diff before the PR opens. const ok = await preCheck(projectPath);
Inside the app
The Command Center: five projects, with build, deploy, PR, and issue state on every card.
The morning briefing assembles overnight changes and ranks what needs attention.
Repeated fixes distill into knowledge drafts the next run starts from.
A QA orchestrator mid-run — $0.85 of a $2.00 spend ceiling used, three subagents reporting.
What's Inside
Voice or text goes to an orchestrator that parses intent, picks the target project, loads the relevant skills and memory, and routes to a subagent running in that project’s own directory against its own CLAUDE.md.
orchestratorThe orchestrator parses intent, identifies which project a request is about, assembles skill and memory context, then delegates. The subagent runs in the project’s cwd and reads that project’s own instructions — so one portal drives many codebases without blurring them together.
pr-workerA 30-second poll picks up governance tasks, creates a git worktree, runs a subagent inside the scope fence, pushes the branch, and opens the PR through a short-lived repo-scoped token. Isolation is a worktree, so a failed run leaves the working copy untouched.
scope-fence500 lines, 15 files, 50 cents, ten minutes, fifteen turns — plus glob denials for .env, secrets, and key material. Ten Vitest files cover the fence, retry, budget, and token-broker paths specifically.
governanceA scheduled agent assembles portfolio context from SQLite, decides what needs attention, and delegates to registered agents. Every action lands in an audit log, so an autonomous decision is reviewable after the fact.
memoryCommand outcomes are recorded as signals and surfaced as context on later runs. Confidence decays over time, so a lesson learned from a codebase that has since changed stops steering the agent.
skillsRecurring fix patterns live as markdown auto-injected into agent prompts. A distillation loop promotes repeated fixes into new skills and clusters of failures into knowledge drafts — the system writes its own next prompt.
Design Principles
Autonomy is only safe when the blast radius is bounded in advance. Diff size, spend, wall clock, and turn count all have hard ceilings, and the paths that matter most are denied by glob rather than by instruction — because an instruction is a request and a denylist is not.
Every autonomous change happens in its own git worktree, so a run that goes wrong is discarded rather than untangled. The human sees the result as a PR — the same review surface as any other contributor.
A system that solves the same problem twice has learned nothing. Distillation promotes repeated fixes to skills and failure clusters to knowledge drafts, so the next attempt starts where the last one finished — and decaying confidence keeps stale lessons from outliving their codebase.
The whole surface runs without API keys or agent spend. Developing the orchestration layer should not cost tokens every time the window reloads, and a demo should never depend on live credentials.
More Work