Thanks for your interest in contributing. Sunam is a browser-native AI coding assistant
built on the pi agent engine and the Succinix container environment. Please read
AGENTS.md first — it is the unified AI-engineering entry for this repository,
and the real project specs live under .trellis/spec/.
Requirements: Node.js 22 (the CI version), npm, and a modern Chromium browser (Chrome/Edge) for anything that touches the container or the UI.
npm ci # install exact dependencies from the lockfile
npm run dev # start the dev server on http://localhost:7891The dev server is preconfigured with the Cross-Origin-Opener-Policy /
Cross-Origin-Embedder-Policy headers that WebContainer requires. Do not change the port
or remove these headers. npm run dev also syncs the Succinix host runtime assets
(predev → scripts/sync-succinix-assets.mjs) and frees port 7891 if it is occupied.
Open http://localhost:7891, configure a provider in Settings → Providers, and you can start a conversation.
src/
main.tsx # React entry
app/ # root providers, global styles, startup
pages/ # host page shells (MainPage / ConfiguredPage)
contracts/ # ctx.* services, plugin/agent/capability/UI contracts
entities/ # domain types + v3 persistence (IndexedDB)
shared/ # contracts, i18n, config stores, browser utilities, base UI
host/ # Cordis startup, ui slots, system prompt, sunam extension API
plugins/ # every business capability as a Cordis plugin
manifest.generated.ts # build-generated plugin manifest (host-owned)
config|settings|storage|i18n|persistence|workspace|updates
runtime|terminal|files|resources|capability|tools|llm|agent
plugin-manager|telemetry|notes
ui-chat|ui-sidebar|ui-workspace|ui-settings|ui-capability|ui-terminal|ui-file-manager
tests/
unit/ # Vitest unit & component tests
component/ # rendered behavior and interaction tests
e2e/ # Playwright end-to-end flows
visual/ # Playwright visual regression
runtime/ # real Succinix/WebContainer acceptance
scripts/ # sync, architecture/bundle/check gates
.trellis/ # Trellis workflow (spec / tasks / workspace)
- TypeScript strict is required, with
noUncheckedIndexedAccess,exactOptionalPropertyTypesandnoImplicitReturns. Runnpm run typecheck(0 errors). - Trellis workflow: the project is managed by Trellis. Read
.trellis/workflow.mdand the relevant spec leaf under.trellis/spec/before writing code in a layer. Follow the task lifecycle (python3 .trellis/scripts/task.py …) — do not bypass it.AGENTS.mdis the entry; do not create a secondAGENTS.mdunder.agents/. - Architecture boundaries:
src/sharedis the base layer;src/entitiesandsrc/contractsmay depend on it. Every business capability lives insrc/plugins/*and communicates throughctx.*services, Cordis events and publicindex.tsentries — never through another plugin's internal files.src/hostassembles plugins;src/pagesandsrc/appare host shells.scripts/check-architecture.mjsplusscripts/check-plugin-boundaries.mjsenforce this insidenpm run check. AgentWorkspaceRuntimeis the sole boundary between the agent core and the container. The agent never reaches into the Succinix runtime directly; process ownership is(sessionId, runId, containerId).- Every agent tool must carry a
capabilitydeclaration throughdefineTool(module / defaultEnabled / warnOnDisable / dependencies) — missing it fails compilation. New tools first define schema, permissions, concurrency, timeout, result and persistence boundaries. - UI language is English for all user-facing text; the app is localized via
shared/i18n(中文 / English / 日本語). Add locale keys for every new string. - No emoji in UI text, output, or comments that render to the user.
- Dark, restrained theme — follow the existing design tokens (motion, radius, colors) and the "professional, not toy-like" production feel. No new runtime dependencies without a spec.
- Comments: Chinese is fine for developer-facing comments; identifiers are English.
Run at least npm run check before opening a PR. The full gate is npm run check:all.
| Command | Covers |
|---|---|
npm run typecheck |
strict TypeScript (0 errors) |
npm run lint |
Oxlint (0 errors) |
npm run test |
Vitest unit & component tests |
npm run test:coverage |
full core coverage gate (statements/functions/lines ≥85%, branches ≥80%) |
npm run check:architecture |
architecture + capability-registry audit |
npm run build + npm run check:bundle |
production build + initial/total JS and dist size gates |
npm run test:e2e |
Playwright end-to-end flows |
npm run test:visual |
desktop / mobile visual regression (diff ≤ 0.2%) |
npm run test:runtime |
real Succinix/WebContainer acceptance |
npm run check:audit |
production dependency high/critical = 0 |
- Excerpts: when a change is narrow (a pure-logic module, a single tool), running the
relevant Vitest file or a focused Playwright spec is a reasonable local excerpt — but the
PR must still state that
npm run check(orcheck:allfor UI/container changes) has been run on the final state. - New visual baselines: regenerate baselines with the matching Chromium version, review
them by hand, then run one verification pass without
--update. - Runtime / network / browser limits: if a check cannot run (no Chromium, no port
permission, no network for
check:audit), record it as not executed / externally blocked in the PR description — never mark it as passed. - Freeze gates: core coverage and bundle thresholds are hard; the pi lazy-load channel is excluded from initial JS but still counted in total JS gzip.
This project follows the Trellis task lifecycle. The canonical flow is:
- TASK spec — a task describes the change, its Trellis spec leaves, the physical boundaries (what must not change), and its acceptance gates. Small fixes may reference an existing task instead.
- Implementation — implement with tests where applicable; keep commits focused and
atomic, using Conventional Commits:
feat: …,fix(agent): …,docs: …,refactor(tests): …,chore: …. - Audit — an independent read-only review (a separate agent or a maintainer) compares the implementation against the task spec. Address findings; re-run the gates on the final state. Do not skip the audit for large changes.
- Acceptance — the gates pass (
npm run check, pluscheck:allfor UI/container changes), the audit is clean, and the task is archived under.trellis/tasks/archive/.
Practical steps for a pull request:
git checkout -b feat/your-change
# implement + tests
npm run check
git push -u origin feat/your-change
# open a PR describing the change, why it matters, and how you verified itKeep the diff reviewable — split large changes into multiple PRs. A maintainer will review; address feedback and re-run the gates.
- When architecture, persistence, public behavior, verification gates or dependency policy
change, update the affected Markdown in
README.md/docs/(English + 中文 where a bilingual document exists) and any affected.trellis/spec/leaf. - Contributors must ensure their commits can be released under AGPL-3.0-only, and must preserve third-party copyright and license notices.
- Never add a runtime dependency without a spec leaf; dependency updates are evaluated separately per the dependency advisory policy.
Open an issue for bugs and feature requests. For design questions, refer to AGENTS.md, the architecture and agent runtime design docs, and the README.