Guidance for agents working in Xerxes. Read this before changing the repository.
Xerxes (xerxes-agents v0.3.0) is a Bun-native TypeScript multi-agent runtime. It provides a
terminal UI, JSON-RPC daemon, OpenAI-compatible API, provider routing, tool execution, MCP,
subagents, channels, persistent sessions, and tiered memory.
- Runtime: Bun 1.3+
- Language: TypeScript (strict)
- Runtime source:
xerxes/src/ - Runtime tests:
xerxes/test/ - TUI source:
xerxes/src/ui/ - TUI tests:
xerxes/src/ui/__tests__/ - Bundled skill content:
xerxes/skills/
The repository is Bun-native. Do not add a Python runtime, Python test, Python packaging metadata, or a Python subprocess fallback. User-requested tools may operate on Python files in a user's workspace; that is different from making Xerxes depend on Python.
Run these from the repository root unless a command says otherwise.
# Install locked workspace dependencies
bun install --frozen-lockfile
# Start Xerxes
bun run xerxes
bun run xerxes "explain this function"
bun run xerxes --resume <session_id>
bun run xerxes daemon --project-dir .
bun run xerxes acp --project-dir .
# Runtime validation
bun run --cwd xerxes check
bun test xerxes/test/<file>.test.ts
bun run --cwd xerxes test:runtime
# TUI validation
bun run --cwd xerxes check:ui
bun run --cwd xerxes test:ui
# Full repository gate
bun run check && bun run test && bun run build
git diff --check
# Documentation and maintenance
bun run docs:build
bun run --cwd xerxes fix-license-headersDo not validate repository changes with python, python3, uv, pytest, ruff, or mypy.
Do not add Node/npm lifecycle wrappers when Bun can run the command directly.
xerxes/
├── src/
│ ├── cli.ts # CLI entry point
│ ├── xerxes.ts # Embedded facade
│ ├── daemon/ # v35 JSON-RPC daemon and session bridge
│ ├── streaming/ # Async turn loop and stream events
│ ├── llms/ # Provider routing and transports
│ ├── executors/ # Tool registry and dispatch
│ ├── tools/ # Built-in and Claude-compatible tools
│ ├── agents/, cortex/ # Agent specs and orchestration
│ ├── session/, memory/ # Durable state, FTS, replay, retrieval
│ ├── security/ # Policies, scanning, sandbox routing
│ ├── mcp/, acp/ # MCP and Agent Client Protocol surfaces
│ ├── channels/ # Messaging adapters and gateways
│ ├── api-server/ # OpenAI-compatible HTTP service
│ ├── extensions/ # Skills, hooks, plugins, authoring
│ └── ui/ # React + OpenTUI terminal client
├── test/ # Bun contract and integration tests
└── skills/ # Bundled SKILL.md content and safe assets
docs/ # Markdown documentation and Bun docs output
examples/ # Bun/TypeScript examples
scripts/install.sh # Bun installer and launcher setup
xerxes/src/cli.tsselects interactive TUI, one-shot, daemon, ACP, or an explicit command such asdoctor,export, orskill.- The TUI communicates with the Bun daemon through the v35 newline-delimited JSON-RPC protocol.
streaming/loop.tsnormalizes provider deltas into serializable stream events, routes tool calls through permissions and the tool registry, and guarantees a terminal turn event.runtime/enforces turn, budget, and compaction limits whilesession/persists data.- The TUI renders the same event vocabulary the daemon, API, MCP, and channels consume.
Preserve public wire formats and persisted-session behavior unless the user explicitly authorizes a protocol migration. Do not invent a successful fallback for an unsupported external integration: return a typed, actionable error or require an explicit injected host port.
- Use strict TypeScript and explicit public types. Prefer discriminated unions over boolean state
flags and
unknownplus narrowing over uncheckedany. - Use native async iterators and
AbortSignalfor stream cancellation. Do not block the event loop. - Prefer top-level functions and small concrete helpers over class hierarchies without a real lifecycle or shared mutable state.
- Keep imports at the top. Use lazy imports only for genuine startup cost or cycle isolation.
- Validate external input at the boundary: CLI arguments, JSON-RPC frames, provider responses, persisted records, YAML agent specs, and webhook payloads.
- Use
Bun.file,Bun.write,Bun.spawn,Bun.serve, andBun.sqlitewhere the implementation is runtime-specific. Keep a narrow interface around privileged or host-owned capabilities. - Let errors propagate unless a catch adds context or intentionally changes control flow. Never swallow provider, filesystem, or tool failures.
- Keep security decisions explicit. Tool-policy and sandbox denials must remain observable.
- Every TypeScript source file begins with the repository Apache-2.0 header used by adjacent files.
- Do not extend obsolete compatibility shims just to preserve retired internals.
Add or update focused Bun tests beside the subsystem you change. A test should exercise observable behavior, not merely an exported symbol. At minimum cover error and cancellation behavior at boundaries that stream, persist, call a provider, or execute a tool.
Run the narrowest relevant test while iterating, then run the full root gate before handing over a
cross-cutting change. Inspect git diff --check after generated or bulk asset work. Do not edit
generated dist/ output manually; use the owning Bun build command.
For live-provider, browser, channel, email, or cloud tests, keep credentials outside the repository and make the external call opt-in. Offline tests must use a deterministic injected port or fixture.
xerxes/skills/ is recursively copied into the runtime distribution by
xerxes/scripts/copyBundledSkills.ts. Preserve safe references, templates, and assets when
moving a bundled skill. Do not leave a duplicate name frontmatter entry that can shadow the native
skill. Executable or privileged integrations belong in native TypeScript with an explicit host port;
do not revive unsafe legacy scripts.
Keep the UI protocol-independent: xerxes/src/ui talks only to the documented daemon RPC
surface.
When changing a slash command, update all three layers together:
- daemon command/handler and its contract test;
- TUI command registry, completion, and state restoration behavior; and
- user-facing help or docs.
Never make a slash picker erase a transcript permanently. Overlay state must restore the prior screen after cancel, completion, or a provider error. Preserve keyboard access and narrow-terminal fallbacks when changing layout.
Native browser automation uses Chromium DevTools Protocol (CDP). It only attaches to an explicitly
supplied, already-running Chromium-compatible browser endpoint (for example through /browser connect <endpoint>); Xerxes does not launch or own a browser process on the user's behalf.
Documentation is Markdown and native Bun-generated API content. Keep README commands, install
instructions, CLI help, examples, CI workflows, Docker files, and AGENTS.md aligned with the
actual Bun executable. Before a release or cross-cutting handoff, run the full Bun gate and report
only the results that completed in the current worktree.
Commit messages use Conventional Commit/Commitizen form:
type(scope): concise description
Do not stage, commit, push, create a PR, alter external accounts, or publish artifacts unless the user explicitly asks.