Imported from sourabh1007/ai-project-studio (
AGENTS.md). Install upstream withnpx skills add sourabh1007/ai-project-studio. Copyright stays with the author.
AGENTS.md — working agreement for this repo
This file orients AI agents (and new humans) working on AI Project Studio. Read it fully before making changes. For deeper detail, follow the links into docs/.
What this project is
An Electron desktop app that wraps AI coding CLIs (GitHub Copilot, Agency) in an IDE-style workspace organized by Feature → Session, with live usage/cost analytics and AI-native features (skills, task plans, summaries). Monorepo with three npm workspaces:
backend/— Express API + domain modules (TypeScript, ports & adapters).ui/— React + Vite front-end.desktop/— Electron shell that spawns the backend and loads the UI.
Golden rules (do not violate)
- Backend has a 100% coverage gate. Every backend line/branch/function/statement must be covered or CI fails. Add tests for every change. Run
npm run test:coverage --workspace backend. - Keep IO at the edges. Domain logic is pure and testable against ports (interfaces). Native/IO adapters (node-pty, node:sqlite, HTTP, fs, process spawning) are thin and excluded from coverage. Don't put logic in adapters.
- Dependencies are injected via explicit
depsobjects, wired only inbackend/src/main.ts(the composition root). Don't reach for singletons/globals; add a dependency to the relevant*Depsinterface and wire it inmain.ts. - Every backend module owns its config as a
{ NAMESPACE, zodSchema, defaults }trio in<module>/config.ts, registered inmain.ts. Add config there, never scatterprocess.envreads through the code. - Don't couple the core to a specific CLI. Copilot/Agency are
provideradapters behindIAIProvider. New tools and user-facing behaviors must go through generic provider/registry hooks — see docs/adding-a-provider.md. - Prefer editing existing files over adding new ones; match the surrounding style. Comment only where intent is non-obvious.
- Commit trailers: include the co-author/session trailers already used in this repo's history when committing.
Architecture in one screen
Electron (desktop/) ── spawns ──▶ Express API (backend/src/api)
│ loads UI │ routes → domain modules
▼ ▼
React UI (ui/) ◀── HTTP · SSE · WS ── api/usage-stream, controllers
│
provider registry ─▶ Copilot / Agency CLIs ─▶ CLI session-store.db
│ │ tailed by
terminal (node-pty) runs the CLI TUI ▼ ▼
usage ─▶ credit ─▶ aggregation ─▶ API ─▶ UI
persistence (node:sqlite) ⇦ modules
Key primitives live in backend/src/kernel/ (event bus, clock, ids, logger, typed errors). Live updates flow over an event bus (usage.recorded, session.*) forwarded to the UI via SSE in api/usage-stream.ts.
Full detail: docs/architecture.md · module reference: docs/backend-modules.md · UI: docs/ui-guide.md.
Where things live
| Area | Path |
|---|---|
| Composition root (all wiring) | backend/src/main.ts |
| HTTP routes & controllers | backend/src/api/ |
| Provider abstraction & adapters | backend/src/provider/ (provider-contract.ts, copilot-adapter/, agency-adapter/) |
| Persistence (repos + schema) | backend/src/persistence/ |
| Shared kernel | backend/src/kernel/ |
| UI shell (what's actually mounted) | ui/src/App.tsx → workspace, skills, settings views |
| UI styles/tokens | ui/src/styles/ |
Dead code warning:
ui/src/features/feature-board,.../feature-detail, and.../session-panelare not mounted byApp.tsx. The live app renders the workspace, skills, and settings views. Don't assume those unmounted components reflect current behavior.
Common tasks
- Add an API endpoint → add a controller in
api/, register it inapi/routes.ts(ApiRoutesDeps+createApiRoutes), wire deps inmain.ts, test the controller. - Add a domain module → create
<module>/with a*-contract.ts(ports/types), a pure service, aconfig.tstrio, and a repo port if it persists. Wire inmain.ts. Mirror an existing module likeskills/orfeature-tasks/. - Add a new CLI tool/provider → implement
IAIProviderunderprovider/<tool>-adapter/, register inmain.ts. See docs/adding-a-provider.md. - Add a feature agent (an attachable analysis surface like the Review Board) → create
agents/<id>/(manifest + config trio + service +routes(ctx)) andui/src/agents/<id>/, register in the two agent arrays. See docs/agents.md. - Change persisted shape → update
persistence/db/schema.ts+ the relevant*-repo.tsand its tests.
Build / test / run
npm install # once
npm run build # backend tsc + ui tsc/vite
npm run test:coverage --workspace backend # 100% gate — must pass
npm run test:coverage --workspace ui # UI gate
npm run lint # backend typecheck
npm run desktop # build + launch Electron
Use the smallest targeted test while iterating (npx vitest run <path> inside backend/), then run the full gate before committing. More: docs/development.md.
Environment quirks (important on Windows)
- Backend uses the experimental
node:sqlitemodule → requires Node ≥ 22.5; run backend coverage from insidebackend/(vitesthas a sqlite shim there). - On Windows, ConPTY doesn't search PATH/PATHEXT — executables are resolved by
terminal/executable-resolver.ts. The Copilot CLI is a.EXEshim and requires a valid UUID--session-id. - PowerShell: use
;(not&&) before PS keywords; multi-line commit messages via here-strings.
Definition of done
- Behavior implemented and matches the request.
-
npm run buildpasses (backend + UI typecheck). -
npm run test:coverage --workspace backendpasses at 100%. - UI tests pass if UI changed.
- New config/deps wired in
main.ts; no stray globals. - Docs updated if architecture/behavior changed.