# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Commands ```sh bun install # install dependencies bun run check # Biome lint + format (run before committing) bun test # run all tests bun test # run a single test file bun run bundle # bundle all *-entry.ts files → dist/*.esm.js uncaged-workflow add # register a workflow bundle uncaged-workflow run # run a registered workflow ``` ### One-time setup for docx-diff binary ```sh cd /Users/yanjiayi/workspace/docx-diff && npm install && npm run build && npm link ``` The `@uncaged` scoped packages resolve from a private registry configured in `bunfig.toml` (`https://git.shazhou.work/api/packages/shazhou/npm/`). ## Architecture This is a Bun monorepo (`workspaces: ["templates/*", "workflows"]`) for developing `@uncaged/workflow-runtime` workflows. **Two layers:** - `templates//` — pure data packages: `WorkflowDefinition` (roles + `ModeratorTable`), no agent binding. Exported from `src/index.ts`. - `workflows/` — binds a template's `WorkflowDefinition` to an `AdapterFn` and `ExtractFn`; each workflow instance is a `*-entry.ts` file that the bundle script turns into a single `dist/*.esm.js`. **Bundle script** (`scripts/bundle.ts`): scans `workflows/` for `*-entry.ts` files, bundles each with Bun into `dist/.esm.js` (ESM, Node target, no splitting). All `@uncaged/workflow-*` packages are kept external. Also emits a `.d.ts` shim per bundle. **Engine loop**: `ModeratorTable` routes from `START` → role → … → `END`. Each step: Adapter produces typed meta via the role's Zod schema; engine appends the step and selects the next role. **Core types** (from `@uncaged/workflow-runtime`): - `RoleMeta` — `Record>`: role name → meta shape - `RoleDefinition` — `description`, `systemPrompt`, `schema` (Zod v4) - `WorkflowDefinition` — `description` + `roles` + `ModeratorTable` - `ModeratorTable` — declarative, serializable routing table; maps `START`/role names to ordered transition lists (`check` + next role or `END`) - `AdapterFn` — receives system prompt + Zod schema, returns a `RoleFn` - `ExtractFn` — resolves structured data from a CAS content hash ## Coding Conventions - **`type` not `interface`** — use type aliases everywhere. - **`T | null` not `?:`** — write nullable fields as `field: T | null`, not `field?: T`. - **`function` not `class`** — no classes except third-party requirements or `Error` subclasses. - **Named exports only** — no default exports. Workflow bundles must export `run` and `descriptor` by name. - **No `console.log`** — use structured logger in library code. - **No dynamic `import()`** — bundles must be statically analyzable; dynamic imports break hash and loading constraints. - **No `import()` in business code** — the only exception is the engine's own bundle loader.