# Claude Code workbench

Twelve standalone browser assets, a linked inspector, and an optional local Claude Code adapter.
Independent Forever collection; not affiliated with Anthropic.

## Try the browser assets

Open any `infinite/claude-code/*.html` directly. Each starts with explicitly labeled illustrative
Demo records, supports keyboard controls and light/dark themes, and pauses its idle cycle when
hidden or reduced motion is enabled. No framework, external library or model API call.

## Connect your project

Requires Node.js 18+ and Git. From the unzipped kit directory:

```sh
node tools/claude-workbench/server.mjs --project /absolute/path/to/project
```

Open the printed localhost URL. Git diffs, worktrees and root instruction files come from that
explicit project. Context, usage, agents, hook events and test receipts remain unknown until
Claude supplies them. No automatic scan of personal transcripts or Claude settings.

Print a mergeable configuration snippet, then review and merge it into your chosen Claude
settings file. Preserve existing hooks and statusLine commands:

```sh
node tools/claude-workbench/server.mjs --project /absolute/path/to/project --print-config
```

To opt into browser permission decisions, add `--permission-relay` to both commands. Read
the [adapter setup notes](./adapter.md) before enabling it.
The adapter must be running while hooks use it. It binds to `127.0.0.1`, uses a per-run token and
private state directory, and accepts only allowlisted operations. Browser actions never run shell
commands or apply patches. Git refresh is read-only; review decisions and handoff drafts persist
in the adapter's private ledger. Permission waits expire with a deny result.

## Use in your own UI

Embed one asset in an iframe. Send version 1 `forever:workbench:state` messages from its parent:

```js
frame.contentWindow.postMessage({
  type: 'forever:workbench:state', version: 1, asset: 'permissions',
  mode: 'local', connection: 'connected', updatedAt: new Date().toISOString(),
  data: {items: [{id: 'opaque-request-id', tool: 'Bash', command: 'npm test',
    scope: '/your/project', state: 'pending'}]}
}, location.origin);
```

Listen for `forever:workbench:action`, verify the exact iframe's `contentWindow`, validate the
asset/action/payload, then return confirmed state. Tiles also dispatch `workbench-action`
CustomEvents for same-document hosts. See `model.mjs` for all twelve asset IDs, selected data,
action validation and the full snapshot. `permission-decision` answers one pending relay;
`hunk-decision` updates a review ledger; `handoff-save` saves text; `refresh` reads observations.
Other controls only inspect or export supplied data.

Mutating tile messages include a unique `requestId`. Return an `ack` object on the confirmed
state message: `{requestId, ok: true, message: 'Saved'}` or `{requestId, ok: false, message: 'Retry'}`.
Only the matching receipt finishes that action, including a save whose values stayed the same.
Failed saves keep the draft so the user can retry. Hosted handoff exports carry current draft
fields to the parent; canonical export records mode, project, branch and check receipts.

## Data limits

Demo is illustrative. Local values are observations, not guarantees: a hook event alone does not
prove a test passed; a reported exit code and commit make a receipt. Instruction files found on
disk are not proof Claude loaded them. MCP observations do not prove a server remains healthy.
Cost is Claude's reported session estimate, not a billing invoice. Input/cache values describe
the current context usage; missing fields stay unknown. Review status never means a patch was
applied. Exported handoffs include their source mode and reported check evidence.

Official integration references: [status line](https://code.claude.com/docs/en/statusline),
[hooks](https://code.claude.com/docs/en/hooks). Verified against documentation on 2026-10-17.
