Architecture Overview
Jawcode (jwc) is a full coding-agent harness forked from
gajae-code.
The internal @gajae-code/* package namespace originates from
that upstream repository. Everything from provider streaming to TUI rendering
is implemented in-house — no wrapper around another agent.
Identity
The public CLI is jwc. The npm package is
jawcode, exposing both the CLI binary and a programmatic SDK
surface at jawcode/sdk. The runtime is built on
Bun 1.3.14 (workspaces + catalog), with Biome for
lint/format and Rust N-API crates for native performance-critical paths.
Monorepo Structure
The repository is a Bun monorepo containing 8 TypeScript packages, 1 Rust
workspace with 6 crates, and 2 Python packages. The primary product surface
is packages/coding-agent/.
jawcode/
packages/
jwc/ jawcode npm package, jwc bin, jawcode/sdk
coding-agent/ CLI runtime: tools, session, skills, prompts, modes
agent/ Provider-agnostic agent loop and state
ai/ 46+ provider streaming, auth broker/gateway
tui/ Differential-rendering terminal UI
natives/ Rust N-API bindings (grep, AST, PTY, shell)
utils/ Shared utilities, logging, config
stats/ Local observability dashboard
crates/
pi-natives/ N-API root (AST, grep, clipboard, PTY, shell, ...)
pi-ast/ tree-sitter / ast-grep parsing
pi-iso/ OS isolation helpers
pi-shell/ brush-based shell execution
brush-*-vendored/ Vendored POSIX/bash shell primitives
python/
jwc-rpc/ Typed Python client for jwc --mode rpc
robogjc/ Self-hosted GitHub triage/fix bot
Entry Point Flow
A normal CLI session follows this path from terminal to agent loop:
CLI bootstrap packages/coding-agent/src/cli.ts
|
v
main.ts Converts CLI options to CreateAgentSessionOptions
|
v
sdk.ts createAgentSession() — assembles everything:
| model registry, auth, settings, workspace tree,
| context files, skills, tools, system prompt
v
agent-loop.ts @gajae-code/agent-core turn loop:
| user message -> model stream -> tool dispatch -> yield
v
Mode dispatch interactive (TUI), print, RPC, RPC-UI, or ACP
Execution Modes
| Mode | File | Description |
|---|---|---|
| Interactive | modes/interactive-mode.ts |
Default TUI session with composer, live tool preview, chat history, and viewport scroll |
modes/print-mode.ts |
Single-shot execution, outputs to stdout, exits | |
| RPC | modes/rpc/ |
JSONL RPC over stdio — used by jwc-rpc Python client and robogjc bot |
| RPC-UI | modes/rpc/ |
RPC with attached TUI for debugging |
| ACP | modes/acp/ |
Agent Client Protocol for structured external integration |
| Bridge | modes/bridge/ |
Remote bridge connection to a backend server |
Key Design Decisions
Bun-native runtime
The entire stack runs on Bun — file I/O via Bun.file() /
Bun.write(), subprocess spawning via Bun Shell, SQLite via
bun:sqlite. A Node.js compatibility shim layer exists at
packages/jwc/dist-node/ for the SDK embedding surface, but the
CLI itself requires Bun.
Rust N-API for hot paths
Performance-critical operations — grep, AST search/edit, syntax highlighting, clipboard, PTY management, shell execution, token counting, and text measurement — are implemented in Rust and exposed through N-API bindings. The native layer is compiled per-platform and loaded at runtime with version validation.
Fixed workflow surface
Exactly four workflow skills are bundled: jaw-interview,
plan (jwc orchestrate), goal
(jwc goal), and team. Five callable task role
agents complement them: executor, executor_ext,
architect, planner, and critic.
This surface is intentionally fixed — improvement comes from making this
small set better, not from adding more.
Prompt-cache-aware subagent design
Subagent spawn/resume cycles are designed around LLM prompt caching. Static prompt segments (system prompt, role definitions) form a cacheable prefix shared across fork/resume cycles. Dynamic content (assignment, conversation snapshot) is appended after the static boundary. This means each spawn/resume reuses cached tokens, reducing latency and cost.
Append-only context with compaction
The agent context is append-only during a session. When the context window fills, a compaction pass summarizes older turns while preserving tool results and key decisions. This avoids lossy sliding-window truncation while keeping token usage bounded.
Source-bundled defaults
Default skills, prompts, and role agent definitions are embedded from source
files at build time using Bun's import with { type: "text" }.
The runtime can still discover project/user overrides from .jwc/
directories, but a missing project .jwc directory never removes
the default workflow surface.
Dependency Direction
jwc CLI/package (packages/jwc)
-> @gajae-code/coding-agent
-> @gajae-code/agent-core
-> @gajae-code/ai
-> @gajae-code/tui
-> @gajae-code/natives
-> @gajae-code/utils
-> @gajae-code/stats
@gajae-code/natives
-> crates/pi-natives
-> crates/pi-ast
-> crates/pi-iso
-> crates/pi-shell
-> crates/brush-*-vendored
Verification Gates
The repository uses focused verification rather than monolithic CI:
# TypeScript type checking
bun run check:ts
# Workflow definition integrity
bun scripts/check-visible-definitions.ts
bun scripts/verify-g002-gates.ts
# Rebrand/naming consistency
bun scripts/rebrand-inventory.ts --strict
# Default surface tests
bun test packages/coding-agent/test/default-jwc-definitions.test.ts