docs(v2): runtime-split guide, CLAUDE.md gotchas, setup CJK autodetect
- docs/v2-build-and-runtime.md: new — runtime split rationale (Node host, Bun container), lockfile topology, supply-chain trade-offs, image build surface, two session-wake paths, CI shape, key invariants. Indexed from CLAUDE.md v2 Docs Index. - CLAUDE.md: Container Runtime (Bun) section with trigger/action gotchas a contributor editing the container must know (named-param prefix rule, bun:test vs vitest, bun.lock regeneration, no minimumReleaseAge for the Bun tree, no tsc build step, DELETE pragma invariant). CJK font support section for Claude sessions outside of /setup to proactively offer when they detect CJK signals. Development section updated with Bun commands. - .claude/skills/setup/SKILL.md: step 3b — auto-enable CJK fonts without asking if the user is already writing in CJK; otherwise ask only on clear signals (CJK timezone from step 2a). 3c renumbered from old 3b.
This commit is contained in:
40
CLAUDE.md
40
CLAUDE.md
@@ -102,13 +102,18 @@ Before creating a PR, adding a skill, or preparing any contribution, you MUST re
|
||||
Run commands directly — don't tell the user to run them.
|
||||
|
||||
```bash
|
||||
# Host (Node + pnpm)
|
||||
pnpm run dev # Host with hot reload
|
||||
pnpm run build # Compile host TypeScript (src/)
|
||||
./container/build.sh # Rebuild agent container image (nanoclaw-agent:latest)
|
||||
pnpm test # Host tests
|
||||
pnpm test # Host tests (vitest)
|
||||
|
||||
# Agent-runner (Bun — separate package tree under container/agent-runner/)
|
||||
cd container/agent-runner && bun install # After editing agent-runner deps
|
||||
cd container/agent-runner && bun test # Container tests (bun:test)
|
||||
```
|
||||
|
||||
Container typecheck is a separate tsconfig — if you edit `container/agent-runner/src/`, run `pnpm exec tsc -p container/agent-runner/tsconfig.json --noEmit` to check it.
|
||||
Container typecheck is a separate tsconfig — if you edit `container/agent-runner/src/`, run `pnpm exec tsc -p container/agent-runner/tsconfig.json --noEmit` from root (or `bun run typecheck` from `container/agent-runner/`).
|
||||
|
||||
Service management:
|
||||
```bash
|
||||
@@ -146,7 +151,38 @@ This project uses pnpm with `minimumReleaseAge: 4320` (3 days) in `pnpm-workspac
|
||||
| [docs/v2-setup-wiring.md](docs/v2-setup-wiring.md) | What's wired, what's open in the setup flow |
|
||||
| [docs/v2-checklist.md](docs/v2-checklist.md) | Rolling status checklist across all subsystems |
|
||||
| [docs/v2-architecture-diagram.md](docs/v2-architecture-diagram.md) | Diagram version of the architecture |
|
||||
| [docs/v2-build-and-runtime.md](docs/v2-build-and-runtime.md) | Runtime split (Node host + Bun container), lockfiles, image build surface, CI, key invariants |
|
||||
|
||||
## Container Build Cache
|
||||
|
||||
The container buildkit caches the build context aggressively. `--no-cache` alone does NOT invalidate COPY steps — the builder's volume retains stale files. To force a truly clean rebuild, prune the builder then re-run `./container/build.sh`.
|
||||
|
||||
## Container Runtime (Bun)
|
||||
|
||||
The agent container runs on **Bun**; the host runs on **Node** (pnpm). They communicate only via session DBs — no shared modules. Details and rationale: [docs/v2-build-and-runtime.md](docs/v2-build-and-runtime.md).
|
||||
|
||||
**Gotchas — trigger + action:**
|
||||
|
||||
- **Adding or bumping a runtime dep in `container/agent-runner/`** → edit `package.json`, then `cd container/agent-runner && bun install` and commit the updated `bun.lock`. Do not run `pnpm install` there — agent-runner is not a pnpm workspace.
|
||||
- **Bumping `@anthropic-ai/claude-agent-sdk`, `@modelcontextprotocol/sdk`, or any agent-runner runtime dep** → no `minimumReleaseAge` policy applies to this tree. Check the release date on npm, pin deliberately, never `bun update` blindly.
|
||||
- **Writing a new named-param SQL insert/update in the container** → use `$name` in both SQL and JS keys: `.run({ $id: msg.id })`. `bun:sqlite` does not auto-strip the prefix the way `better-sqlite3` does on the host. Positional `?` params work normally.
|
||||
- **Adding a test in `container/agent-runner/src/`** → import from `bun:test`, not `vitest`. Vitest runs on Node and can't load `bun:sqlite`. `vitest.config.ts` excludes this tree.
|
||||
- **Adding a Node CLI the agent invokes at runtime** (like `agent-browser`, `claude-code`, `vercel`) → put it in the Dockerfile's pnpm global-install block, pinned to an exact version via a new `ARG`. Don't use `bun install -g` — that bypasses the pnpm supply-chain policy.
|
||||
- **Changing the Dockerfile entrypoint or the dynamic-spawn command** (`src/container-runner.ts` line ~301) → keep `exec bun ...` so signals forward cleanly. The image has no `/app/dist`; don't reintroduce a tsc build step.
|
||||
- **Changing session-DB pragmas** (`container/agent-runner/src/db/connection.ts`) → `journal_mode=DELETE` is load-bearing for cross-mount visibility. Read the comment block at the top of the file first.
|
||||
|
||||
## CJK font support
|
||||
|
||||
Agent containers ship without CJK fonts by default (~200MB saved). If you notice signals the user works with Chinese/Japanese/Korean content — conversing in CJK, CJK timezone (e.g., `Asia/Tokyo`, `Asia/Shanghai`, `Asia/Seoul`, `Asia/Taipei`, `Asia/Hong_Kong`), system locale hint, or mentions of needing to render CJK in screenshots/PDFs/scraped pages — offer to enable it:
|
||||
|
||||
```bash
|
||||
# Ensure .env has INSTALL_CJK_FONTS=true (overwrite or append)
|
||||
grep -q '^INSTALL_CJK_FONTS=' .env && sed -i.bak 's/^INSTALL_CJK_FONTS=.*/INSTALL_CJK_FONTS=true/' .env && rm -f .env.bak || echo 'INSTALL_CJK_FONTS=true' >> .env
|
||||
|
||||
# Rebuild and restart so new sessions pick up the new image
|
||||
./container/build.sh
|
||||
launchctl kickstart -k gui/$(id -u)/com.nanoclaw # macOS
|
||||
# systemctl --user restart nanoclaw # Linux
|
||||
```
|
||||
|
||||
`container/build.sh` reads `INSTALL_CJK_FONTS` from `.env` and passes it through as a Docker build-arg. Without CJK fonts, Chromium-rendered screenshots and PDFs containing CJK text show tofu (empty rectangles) instead of characters.
|
||||
|
||||
Reference in New Issue
Block a user