This file is for coding agents working in this repository. It summarizes the commands, workflows, and code conventions that are visible in the current codebase.
This repository uses the Shared Context Engineering (SCE) approach for AI-assisted software delivery with explicit, versioned context: https://sce.crocoder.dev/
- Root repo contains four main working areas:
cli/- Rust CLI (sce)evals/- Bun + TypeScript eval harnessconfig/- generated agent config, skills, and Pkl sourcescontext/- shared context docs, plans, decisions, and handovers
- No root
AGENTS.mdexisted before this file. - No
.cursor/rules/directory was found. - No
.cursorrulesfile was found. - No
.github/copilot-instructions.mdfile was found. - If any of those files are added later, update this document to fold their instructions in.
- Nix is the primary reproducible entrypoint at repo root.
- Root
flake.nixprovides Bun, TypeScript, Pkl, jq, and the Rust toolchain. - Root
flake.nixdefines Crane-based Rust packaging and check derivations for the CLI. - Run Cargo via Nix, not directly from the host shell. Prefer
nix develop -c sh -c 'cd cli && <cargo command>'. - For validation, prefer
nix flake checkand avoid runningcargo testdirectly unless a user explicitly requests it. - Optional local Nix tuning can live in user-level
~/.config/nix/nix.conf; recommended values aremax-jobs = autoandcores = 0. auto-optimise-store = trueis intentionally treated as a system-level/etc/nix/nix.confsetting, not a repo-managed user setting.- Bun is used for the eval harness, not npm or pnpm scripts.
- Rust edition is
2021. - TypeScript runs in strict mode in
evals/tsconfig.json.
- Enter dev shell:
nix develop - Run all flake checks visible at root:
nix flake check - Run generated-output parity check:
nix run .#pkl-check-generated - Regenerate and sync
.opencodeconfig:nix run .#sync-opencode-config
Run these through Nix from repo root unless noted otherwise.
- Build CLI:
nix develop -c sh -c 'cd cli && cargo build' - Run CLI:
nix develop -c sh -c 'cd cli && cargo run -- --help' - Build packaged CLI output:
nix build .#default - Run packaged CLI app:
nix run .#sce -- --help - Run all CLI tests:
nix develop -c sh -c 'cd cli && cargo test' - Run a single test by exact name:
nix develop -c sh -c 'cd cli && cargo test parser_routes_mcp -- --exact' - Run tests in one module/file pattern:
nix develop -c sh -c 'cd cli && cargo test setup' - Run ignored? none were found; do not assume ignored-test flows exist.
- Format check:
nix develop -c sh -c 'cd cli && cargo fmt --check' - Auto-format:
nix develop -c sh -c 'cd cli && cargo fmt' - Lint:
nix develop -c sh -c 'cd cli && cargo clippy --all-targets --all-features'
Run these from evals/.
- Run eval test suite:
bun test ./evals.test.ts - Run a single Bun test by name:
bun test ./evals.test.ts -t "runs context bootstrap flow with Shared Context"
- Preferred repo validation from repo root:
nix flake check - Evals validation from repo root:
nix develop -c sh -c 'cd evals && bun test ./evals.test.ts' - Generated-config validation from repo root:
nix run .#pkl-check-generated
- Rust tests live inline in source files and in module test files such as
cli/src/services/setup/tests.rs. - Rust/Cargo commands should be executed through
nix develop, even for one-off builds, tests, fmt, and clippy runs. - Prefer
nix flake checkfor routine verification and avoidcargo testunless the user explicitly asks for it. - Rust single-test selection uses standard Cargo substring matching; add
-- --exactfor deterministic one-test runs. - Bun tests use
bun:testand support-tname filtering. - Evals create runtime artifacts under
evals/.resultsand model-run directories; do not treat those as source files. - Some eval tests depend on an OpenCode SDK server and model configuration; they are heavier than unit tests.
- GitHub Actions publish Tessl tiles from
config/.opencode/skills/**andconfig/.claude/skills/**. - Release workflow packages agent files from
config/.opencode/agent/Shared Context.mdandconfig/.claude/agents/shared-context.md. - Root
flake.nixpackagesscethrough Crane'sbuildDepsOnly+buildPackagepipeline and runscli-tests,cli-clippy, andcli-fmtthrough Crane-backed checks. - Changes under generated config trees may need a Pkl regeneration or parity check.
- Follow existing local patterns before introducing new abstractions.
- Keep changes scoped and incremental.
- Prefer deterministic behavior and stable output text; this matters in CLI tests.
- Use explicit constants for repeated strings, timeouts, intervals, exit codes, and numeric formatting.
- Prefer small helper functions when they improve readability of branching or setup code.
- Avoid introducing framework-heavy patterns; this repo is mostly plain Rust, Bun, shell, and config assets.
- Group imports in this order: standard library, third-party crates, then
crate::...imports. - Use grouped
stdimports such asuse std::path::{Path, PathBuf};. - Prefer explicit imported items over wildcard imports.
- Keep import lists stable and reasonably compact.
- Use ESM
importsyntax only. - Keep imports grouped: Node builtins, external packages, then local files.
- Use
typeimports inline where appropriate, for exampleimport { foo, type Bar } from "pkg";. - Use explicit relative file paths like
./test-setup.
- Rust formatting is delegated to
rustfmt; do not hand-format against it. - Rust uses 4-space indentation.
- TypeScript in
evals/uses 2-space indentation, semicolons, trailing commas where multiline, and double-quoted strings. - Shell scripts use
#!/usr/bin/env bashandset -euo pipefail. - Quote shell expansions unless you intentionally need word splitting.
- Prefer readable multi-line expressions over dense one-liners.
- In Rust, prefer strong enums and structs for command requests, runtime state, and result payloads.
- Derive common traits explicitly; common order in this repo is
Clone, Copy, Debug, Eq, PartialEqwhen applicable. - In TypeScript, prefer named
typealiases for payloads and test result structures. - Keep strict-mode friendliness: handle
undefined, use narrow unions, and avoid implicit any. - Prefer explicit return types on exported TypeScript helpers.
- Keep data structures serialization-friendly when they are written to JSON or surfaced by CLI output.
- Rust types and enums:
UpperCamelCase. - Rust functions, modules, and variables:
snake_case. - Rust constants:
SCREAMING_SNAKE_CASE. - TypeScript types:
PascalCase. - TypeScript variables and functions:
camelCase. - Test names are descriptive, behavior-oriented, and usually sentence-like with underscores in Rust.
- Prefer names that encode intent, not implementation trivia.
- Rust uses
anyhow::Resultbroadly for service-layer operations. - Add context to I/O and process failures with
Context/with_context. - Use
bail!andanyhow!for concise early exits when appropriate. - Preserve user-facing diagnostics as stable strings when tests assert on them.
- Separate machine classification from rendered messages when the CLI contract cares about exit codes.
- In TypeScript, throw
Errorwith direct, actionable messages. - Convert unknown thrown values with helper functions like
getErrorMessagebefore logging or persisting.
- Keep stdout reserved for intended command payloads.
- Keep errors on stderr and preserve stable prefixes/codes when existing code does so.
- Do not casually rewrite help text, error phrasing, or JSON field names; tests may depend on exact wording.
- Prefer deterministic ordering in rendered collections, embedded asset lists, and discovered file paths.
- Add unit tests close to the code they exercise.
- Match the repo's current pattern of focused behavioral test names.
- Assert on exact output when the CLI contract is supposed to be stable.
- For filesystem or manifest checks, sort collected paths before asserting.
- Keep tests isolated; clean up temporary state and abort long-running resources in teardown.
- Shell scripts should fail fast, validate prerequisites early, and print concrete remediation steps.
- Prefer staging-and-swap workflows for generated config updates instead of in-place mutation.
- Treat
config/.opencode,config/.claude, and repository-root.opencode/as sensitive generated trees. - If you edit generated outputs manually, verify whether the corresponding Pkl source should be updated instead.
- Check for unrelated worktree changes before broad edits.
- Avoid destructive git commands unless the user explicitly asks for them.
- When touching both
config/and.opencode/, verify whether sync/regeneration is expected. - When verifying changes, prefer
nix flake checkinstead of runningcargo testdirectly. - When changing eval harness code, run the narrowest Bun test or script that covers the change.
- Default verification for code changes:
nix flake check - TypeScript eval change:
cd evals && bun test ./evals.test.ts -t "<test name>" - Generated config or Pkl change:
nix run .#pkl-check-generated - Cross-cutting repo change:
nix flake check
README.mdflake.nixcontext/context-map.mdcontext/overview.mdcli/Cargo.tomlcli/src/app.rscli/src/services/setup/tests.rsevals/package.jsonevals/tsconfig.jsonevals/evals.test.tsevals/test-setup.tsscripts/sync-opencode-config.sh