Project instructions for AI agents and maintainers working in the Stave repository.
- Keep repository guidance public, self-contained, and English-only.
- Prefer repo-local instructions over user-home-specific conventions.
- Use Bun for install, test, and build commands. Use
bunx --buninstead ofnpx.
Stave is an installable product. Do not bake author-specific machine state into code, docs, tests, or examples.
- Do not add personal absolute paths such as
/Users/<name>/.... - Do not assume private dotfile layouts such as
~/.claude/localas product defaults. - Prefer placeholders such as
<workspace>,<user-home>, and/tmp/...in docs and test fixtures. - If runtime behavior depends on a user-home lookup, keep it configurable and describe it generically.
- Use Conventional Commits for every commit.
- Keep PR titles in Conventional Commits form and keep the subject lowercase.
- For explicit PR requests, use
skills/stave-worktree-pr-flow/SKILL.mdwhen the runtime supports repo-local skills. - For explicit release requests, use
skills/stave-release/SKILL.mdwhen the runtime supports repo-local skills. - Ordinary commit or push requests must not change
package.json,CHANGELOG.md, or semver tags unless the user explicitly asks for release work. - Release tags use
vX.Y.Z. - Refresh
CHANGELOG.mdwithbunx --bun conventional-changelog-cli -p conventionalcommits -i CHANGELOG.md -sunless the work is intentionally establishing a brand-new baseline release.
src/: renderer app, Zustand store, editor, chat surfaces, and client-side helperselectron/: Electron main process, preload bridge, provider runtimes, IPC handlers, persistenceserver/: browser-only dev bridge serverdocs/: end-user, developer, architecture, and provider documentationtests/: unit and integration coverage
High-signal files:
src/store/app.store.ts: central Zustand storeelectron/providers/claude-sdk-runtime.ts: Claude runtime adapterelectron/providers/codex-sdk-runtime.ts: Codex runtime adaptersrc/types/window-api.d.ts: renderer-to-main IPC contractelectron/preload.ts: exposed renderer bridge
Use shadcn-ui when the task adds or changes shadcn/ui components and the runtime supports that skill.
Any UI, layout, or visual change must verify the theme system. Required check files:
src/globals.csssrc/lib/themes/types.tssrc/lib/themes/presets.tssrc/lib/themes/builtin-themes.tssrc/lib/themes/apply.tssrc/lib/themes/validate.tssrc/lib/themes/index.tssrc/store/theme.utils.tstests/custom-theme.test.ts
Rules:
- Keep
src/globals.cssbase tokens andsrc/lib/themes/presets.tsin sync. - If you add or rename a theme token, update built-in themes and any Tailwind
@theme inlinemapping in the same change. - If a UI change introduces a new semantic surface color, define it for light mode, dark mode, and every built-in theme.
- Do not treat UI work as complete until theme behavior has been checked explicitly.
Treat provider runtime options, IPC payloads, and normalized provider events as multi-file contracts.
Required check files:
electron/providers/types.tssrc/lib/providers/provider.types.tssrc/lib/providers/schemas.tssrc/types/window-api.d.tselectron/preload.tselectron/main/ipc/schemas.ts- call sites such as
src/store/app.store.ts
Rules:
- Keep
NormalizedProviderEventandNormalizedProviderEventSchemain sync. - When a provider payload changes, verify the full renderer -> preload -> IPC schema -> main -> runtime path.
- If a change is provider-specific, say so explicitly. Otherwise, check the sibling provider adapter for symmetry.
- For Codex runtime upgrades, review
docs/providers/codex-upgrade-checklist.md.
Terminal work includes docked terminals, CLI session panels, PTY lifecycle, restore behavior, and terminal shell layout.
Required check files:
src/components/layout/useTerminalSessionManager.tssrc/components/layout/useTerminalTabManager.tssrc/components/layout/useTerminalInstance.tssrc/components/layout/TerminalTabSurface.tsxsrc/components/layout/pty-session-surface.utils.tssrc/components/layout/terminal-surface-styles.tssrc/components/layout/TerminalDock.tsxsrc/components/layout/CliSessionPanel.tsxsrc/components/layout/app-shell.shortcuts.tssrc/lib/terminal/types.tssrc/store/workspace-session-state.tssrc/store/app.store.tselectron/main/ipc/terminal.tselectron/host-service/terminal-runtime.tssrc/types/window-api.d.tstests/pty-session-surface.utils.test.tstests/terminal-dock.utils.test.tstests/terminal-session-slot-registry.test.ts
Rules:
- Renderer unmount detaches a session; closing a tab closes it.
- Keep terminal DOM workarounds inside terminal-specific hooks, not shell components.
- Keep shell chrome separate from PTY lifecycle logic.
- Use shared slot-key helpers instead of hardcoded formats.
Hot surfaces in this repository are sensitive to unstable selectors and long-lived effect mistakes.
- Do not return fresh objects, arrays, maps, sets, or fallback containers from Zustand selectors.
- Derive filtered or presentation-only collections outside the selector.
- Prefer row-local subscriptions over broad parent subscriptions on lists and tab surfaces.
- Treat
useEffect, observers, timers, IPC listeners, and keep-alive callbacks as stale-closure risks by default.
Relevant docs:
docs/developer/zustand-selector-stability.mddocs/developer/terminal-regression-prevention.mddocs/developer/provider-session-stability.md
When handing follow-up work to a newly created Stave workspace:
- Write the handoff plan to
.stave/context/plans/<taskIdPrefix>_<timestamp>.md. Perform this Write only after exiting plan mode (viaExitPlanMode) — plan mode is read-only except for that handoff path, so finish planning first. - Leave only a short pointer such as
See plan: .stave/context/plans/<filename>.mdin workspace notes. - Keep todos terse and point them back at the plan file.
- Do not copy the source workspace's notes, todos, or plan body verbatim into the target workspace.
Use the smallest relevant check set for the change, then escalate when the scope is broad.
Common commands:
bun run typecheckbun testbun run buildbun run build:desktopbun run build:pagesbun run test:ci