# Setup

Three layers: the **core** (skill + agent + hook — required), the **second
model** (stages 4/6 — recommended), and **image generation** (stage 3 —
recommended). The pipeline runs without the optional layers and says so in
the receipt; it never silently pretends they ran.

## 1 · Core (required)

Clone the repository, inspect a dry run, install, and diagnose:

```bash
git clone <this repo> && cd web-studio
./install.sh --dry-run
./install.sh
npm run doctor
```

The dependency-free installer refuses unmanaged or modified collisions,
non-regular and symlink destinations, preserves unrelated settings and hooks,
records exact SHA-256 ownership, backs up managed reinstalls, and rolls back a
failed write. Tests use `--claude-home <disposable-path>` and never touch the
operator's home. Open a new Claude Code session after a successful install.

### Manual fallback

If you deliberately install manually, copy the skill, agent, and hook, then
register the following entry. Manual files are not installer-owned and a later
installer run will refuse to overwrite them unless they exactly match the
packaged files.

```bash
cp -r skills/web-studio ~/.claude/skills/
cp agents/the-designer.md ~/.claude/agents/
cp hooks/direction-gate.js ~/.claude/hooks/
```

Use an **absolute path** in settings — `~` is not reliably expanded in hook
commands:

```json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "node /Users/YOU/.claude/hooks/direction-gate.js",
            "timeout": 5
          }
        ]
      }
    ]
  }
}
```

Verify the hook works without waiting for a real run — it's a plain script
you can exercise directly:

```bash
mkdir -p /tmp/gate-test
node ~/.claude/hooks/direction-gate.js --init /tmp/gate-test
echo '{"tool_name":"Write","tool_input":{"file_path":"/tmp/gate-test/x.html"}}' \
  | node ~/.claude/hooks/direction-gate.js
# → prints a BLOCK message. Then:
node ~/.claude/hooks/direction-gate.js --sign /tmp/gate-test "test direction"
echo '{"tool_name":"Write","tool_input":{"file_path":"/tmp/gate-test/x.html"}}' \
  | node ~/.claude/hooks/direction-gate.js
# → prints nothing (pass). Clean up: rm -r /tmp/gate-test
```

The repository also exercises unsigned, signed, empty-declaration, malformed-
gate, unrelated-file, and re-initialization behavior with `npm test`. Those are
logic tests; they do not replace the live Claude Code witness below.

At stage 9 (or any time), remove a project's gate with
`node ~/.claude/hooks/direction-gate.js --clear <project_dir>` — and add
`.direction-gate.json` to the project's `.gitignore` so the gate file never
ships with the site.

> **Witnessed on Claude Code 2.1.217:** sanitized live client streams preserve
> a denied unsigned `Write` and a successful signed retry. The direct hook replay
> records exit 2 for deny and exit 0 for allow. Future client versions should
> repeat the protocol in `EVIDENCE.md`; they do not inherit compatibility.

**Then open a new Claude Code session** — agents and skills register at
session start, not mid-session. Verify: ask Claude to "invoke the-designer
for a connectivity check." If it reports the agent isn't found, the session
predates the install.

## 2 · Second model (stages 4/6 — recommended)

Default wiring is the OpenAI Codex CLI, because it's synchronous and
subscription-billed:

```bash
npm install -g @openai/codex@latest
codex login   # browser OAuth — ChatGPT subscription covers usage
# verify:
codex exec --skip-git-repo-check "reply with exactly: OK" < /dev/null
```

Troubleshooting: a `spawn … ENOENT` error naming a `codex-<platform>` path
means the platform binary didn't install — re-run the npm install.

**Swapping it out:** any CLI that takes a prompt and returns text
synchronously works (llm, ollama, gemini). The pipeline's only contract is
the reply format it asks for: `FLAGS: … | BUDGET_OK: … | NOTE: …`.

**Why a second model at all:** a different model catches a different class
of error than the builder catches in itself — and it's cheaper. It gets zero
design authority; mechanical checks only.

## 3 · Image generation (stage 3 — recommended)

Default wiring is the Higgsfield CLI (aggregates most current image/video
models; has cost estimation):

```bash
npm install -g @higgsfield/cli   # the CLI package (verified name)
higgsfield auth login            # browser OAuth
# verify (free, creates no job):
higgsfield account status
higgsfield generate cost <model> --prompt "test"
```

The pipeline's usage pattern: `generate cost` first (free estimate), then
`generate create <model> --prompt "…" --aspect-ratio 16:9 --wait`.

**Swapping it out:** any image CLI/MCP works. If it has no cost-estimate
command, set an explicit budget cap in `DESIGN.md` §3 and track spend
manually in the run log.

**No image tool?** The Designer art-directs with CSS/SVG instead — gradients
it commits to, not defaults it falls into. The receipt notes media was
not generated.

## 4 · Visual checks (stage 6)

No install — `scripts/visual-checks.js` is a self-contained browser-console
script. Serve the built site over HTTP (`python3 -m http.server` in the site
dir), open it, resize to 375px, paste the script into the console, read the
JSON report; repeat at 1280px. Your agent can run it through its page-JS
tool instead of a human console. Collect console *errors* separately via
your tool's console reader — a page script can't see errors thrown before
it was injected.

## 5 · Fonts

See [FONTS.md](FONTS.md). Short version: download from Fontshare/Google
Fonts directly (this repo ships no font files — most quality free fonts
prohibit redistribution), self-host the woff2s, and always record the
license in `DESIGN.md`'s type section.
