Canonical guidance for coding agents working in this repository. Tool-specific adapters may add
integration details, but must not duplicate or override the shared project contract here. If
AGENTS.local.md exists, read it before work because it contains host-only setup.
Vision is a self-hosted financial transaction manager. It supports transaction CRUD, categorization, multi-bank CSV imports, portfolios, Belgian tax, planned and recurring transactions, and English/Dutch localization. License: AGPL-3.0-only.
The Bun-workspaces monorepo uses React 19, TypeScript, Vite, Tailwind and Radix on the frontend; Node/Bun, Express and PostgreSQL on the backend; Vitest for backend tests; and Electron for the desktop app.
| Workspace | Path |
|---|---|
vision-frontend |
apps/frontend/ |
financial-transaction-manager-node |
apps/node-backend/ |
Use bun run --filter '<workspace>' <script> for filtered commands.
Before changing code, search docs/ for the relevant architecture decision, contract, feature,
and convention. Treat docs as intent and code as current behavior; resolve conflicts explicitly.
- Architectural change: read
docs/adr/. ADRs are append-only; supersede with a new ADR. - Route change: read
docs/reference/api-endpoint-matrix.md.openapi.yamldefines the operation set. - Entry points:
docs/index.md,docs/common-tasks.md,docs/architecture/index.md,docs/reference/code-patterns.md, anddocs/reference/scripts.md.
bun install
bun run dev
bun run build
bun run lint
bun run lint:backend
bun run typecheck
bun run test
bun run test:frontend
bun run check
# from apps/node-backend:
bun vitest run src/path/to/x.test.js
bun vitest run --test-name-pattern="name"Use the repository skills in .agents/skills/ for database migrations, localization, releases,
documentation synchronization, and TODO backlog batches.
For TODO backlog implementation, read .agents/skills/implement-todo-batch/SKILL.md for the
canonical selection, recovery, delegation, validation, and publication workflow. Use
.agents/prompts/implement-todo-batch.md as the cloud kickoff when its goal and explicit
publication authorization match the user's request. Deliver one batch, then stop; the skill itself
does not authorize publication or merge.
These obligations are tracked here because Codex does not auto-load AGENTS.local.md when this
root file exists. AGENTS.local.md may add machine-specific convenience, but it cannot weaken or
replace these rules.
- In the devcontainer, Codex uses isolated container state. Codex authentication and configuration
do not synchronize with the host. Never copy
~/.codex/auth.jsoninto the container. Treat changes under container~/.codex/as ephemeral and report them before the session ends; tracked repository files under.agents/and.codex/persist through the workspace mount. - On the EraPartner macOS host, browser-driven visual review uses the native Vision Demo app and
synthetic data, never the real financial stack. Launch it with
open "/Applications/Vision Demo.app"and rebuild it with./install-demo.shafter relevant code changes. Discover its persisted random backend port fromappPortin the Demo settings, then check/health. Its PostgreSQL cluster is isolated below~/Library/Application Support/Vision Demo/native/vision_demo; it uses only the bundled native runtime. - Do not wipe or mutate the Demo database merely to make it boot. Inspect the native Demo logs and
seed activation state first. When a canonical synthetic reset is intended, use
bun run demo:reset-nativeand reopen the Demo app. Never apply that workflow to real Vision. - Charts render lazily. Scroll a chart into view before capturing an in-viewport screenshot and
store browser artifacts under
.playwright-mcp/. - Codex browser tooling is the supported replacement for Claude's Playwright plugin. There is no
Codex TypeScript-LSP plugin in this project;
bun run typecheckand the relevant build/test commands are the authoritative diagnostics and must not be skipped because editor diagnostics appear clean.
- Backend: ES2022+ ESM and
async/await. Useundefined, notnull, for optional values. Prefer functions over classes. Add comments only when they explain non-obvious intent. - Frontend: strict TypeScript; interfaces for props and state; Zod input validation;
@/*maps toapps/frontend/src/*; functional components and hooks; React Query for server state; Tailwind andclass-variance-authorityfor variants. Prefix intentionally unused values with_. - Never commit or print secrets or personal financial information. Use
.env.localonly. - Validate inputs with Zod on the frontend and server-side validation on the backend. Use least-privilege database users, rate-limit public endpoints, and audit new dependencies.
- Keep changes focused. Do not mix unrelated cleanup into a task.
Use this documentation sequence:
- Before implementation, find the relevant intent, contract, and architecture docs.
- After the implementation diff is stable, but before final verification and commit, evaluate its
documentation impact. Use the
update-vision-docsskill whenever a documented surface may have changed. Readdocs/AGENTS.mdbefore editing anything underdocs/. - Update affected docs in the same change. If no update is required, state why in the completion report instead of creating a placeholder note.
Documentation is required when a change alters user-visible behavior, an API or schema contract, configuration or environment behavior, architecture or ownership, an integration, a security property, packaging or operations, or a documented public interface or code location. It is usually not required for tests-only changes, formatting, comments, generated-output refreshes, or internal refactors that preserve behavior, contracts, architecture, and documented paths.
- API change: update
openapi.yaml, the route documentation, and the endpoint matrix; regenerate derived types and state whether the change is breaking. - Localization change: use the
i18nskill and finish withbun run validate-locales. - Schema change: use the
db-migrationsskill; create a migration and rollback plan, but do not apply it to user data without approval. - Packaging, Electron, or compose change: follow the nested
packaging/AGENTS.mdrules and verify the packaged compose copy.
Scale checks to risk:
- Isolated edit: targeted test and lint.
- Cross-module change: targeted tests, workspace lint, and typecheck.
- Security, persistence, migration, or destructive change: tests, lint, typecheck, build, and focused safety checks.
- Destructive or irreversible command: explain the exact effect and get confirmation first.
Finish with changed files, checks run, skipped checks, residual risk, and follow-ups.
| Path | Purpose |
|---|---|
apps/frontend/src/ |
React frontend |
apps/node-backend/src/main.js |
Backend entry point |
alembic/versions/ |
Database migrations |
config/ |
Shared tool configuration |
i18n/source/ |
Locale source files |
apps/frontend/src/locales/ |
Generated locales |
packaging/electron/ |
Desktop shell |
docs/ |
Obsidian knowledge base |
.devcontainer/ |
Hardened development sandbox |
.agents/skills/implement-todo-batch/ |
Cloud-first bounded TODO batch orchestration |
.agents/prompts/implement-todo-batch.md |
Short kickoff for one TODO batch pull request |
When an authorized local publication workflow uses direct commits, commit to main unless the user
asks for a branch. Cloud TODO batches instead use the platform-managed task branch and pull-request
flow described above; do not update main directly.
Create a session note only when a substantial session produces durable context not already captured in an ADR, feature, reference, or guide. Examples include a multi-stage investigation, a cross-module delivery, or operational findings needed for later work. Do not create session notes for review-only work, routine fixes or refactors, formatting, generated-output refreshes, or documentation-only maintenance unless the user asks for one.
Run bash .codex/cloud/setup.sh as the Codex cloud environment setup command. Use only disposable,
non-production database credentials in cloud environment variables. Cloud sessions cannot validate
the macOS Electron package, host Demo app, Apple Container isolation, or hardware-backed signing;
report those checks as skipped and leave them for a local session. In cloud sessions, do not
publish with shell Git commands, configure Git credentials, or create a pull request with gh.
The platform-managed Open pull request action may create a pull request, and the connected
GitHub integration may update the same branch for pull-request-linked follow-ups. When the user
explicitly requests it, that integration may enable native squash auto-merge for the exact pull
request. Confirm the auto-merge request by reading back the pull-request state; do not infer it from
green local checks or a submitted request. If native auto-merge is unavailable, the integration may
merge after all required checks and approvals pass and no blocking review, code-quality, or
code-scanning condition remains. Do not use an admin bypass or directly update a default or
protected branch outside that approved merge.
The Open pull request action is a post-task platform control and does not need to appear as a
terminal command, MCP resource, or agent-visible make_pr tool. A missing shell remote or absent
in-task publication tool is not an implementation blocker. Finish the reviewed diff and report the
publication handoff separately from known CI or ruleset failures.