Onboarding · For Mark · Apr 29

Claude Code — Pro Setup

The CLI does the work. The settings, hooks, skills, and habits make it 10× faster than the same model on the web. This doc is what we'd hand a new pro joining the team — a tight install, the exact settings.json we use, and the workflow rules that turn Claude Code into an editor that ships code instead of a chatbot that suggests it.

Mark — this is how we work. Read top-to-bottom once, then come back to the section you need. Setup steps land you in 30 minutes; the workflow section is where the leverage is.

Apr 29, 2026 · Robert · For new Orbiter collaborators
← Back to Status Reports
What "Pro" Means Here
HabitWhat it looks like
Plan before you build.Decide → align → execute. Never code before the plan is named.
Verify your own work.A green build is not evidence; a passing test against the actual user flow is. Same-session toasts don't count.
Multiple choice over open-ended.Force decisions with a 2–4 option picker, not "what do you want?". Faster turns.
Cheap models for grunt work.Dispatch greps, lints, JSON parsing, retries to Haiku/Llama. Keep the expensive brain for judgment.
No auto-publish.Robert reviews before anything posts. Same applies to Mark. The agent never pushes to main, never sends a Slack DM, never deletes branches without a checkpoint.
Terse responses.One sentence per update. Skip the recap — Mark can read the diff.

If you find yourself writing a 6-paragraph "here's what I did" message, stop. We've coded that out. Read the diff, send a one-liner.


Setup — 30 Minutes Total

1. Terminal first

Don't skip this. Powerlevel10k, iTerm2, modern CLI tools, fzf, zoxide. Full instructions in the dev-terminal skill — Robert sent it separately. Do that before anything else. A 1990s terminal is a tax on every command.

2. Install Claude Code

# Install
npm install -g @anthropic-ai/claude-code

# Verify
claude --version

# First run — authenticates via browser
claude

The CLI lives at claude. Run it in any project root. The first run pops a browser to OAuth into Anthropic. Copy the API key into your shell rc file as a fallback:

# ~/.zshrc
export ANTHROPIC_API_KEY="sk-ant-..."

Default model: claude-opus-4-7 for everything that matters. Switch to claude-sonnet-4-6 for higher-throughput work, claude-haiku-4-5 for cheap grunt work. Toggle model at runtime with /model.

3. The settings.json we use

Two files. Both live in ~/.claude/.

~/.claude/settings.json — global defaults, machine-wide. Checked into your dotfiles if you have them.

{
  "model": "claude-opus-4-7",
  "permissions": {
    "allow": [
      "Bash(git status:*)",
      "Bash(git diff:*)",
      "Bash(git log:*)",
      "Bash(git add:*)",
      "Bash(git commit:*)",
      "Bash(git push:*)",
      "Bash(pnpm install:*)",
      "Bash(pnpm dev:*)",
      "Bash(pnpm build:*)",
      "Bash(pnpm test:*)",
      "Bash(pnpm lint:*)",
      "Bash(pnpm typecheck:*)",
      "Bash(ls:*)",
      "Bash(cat:*)",
      "Bash(rg:*)",
      "Bash(fd:*)",
      "Bash(gh pr view:*)",
      "Bash(gh pr list:*)",
      "Bash(gh repo view:*)"
    ],
    "deny": [
      "Bash(rm -rf:*)",
      "Bash(git push --force:*)",
      "Bash(git reset --hard:*)"
    ]
  },
  "env": {
    "EDITOR": "code --wait",
    "PAGER": "delta"
  }
}

Why these defaults?

~/.claude/settings.local.json — per-project overrides (or the same shape, just narrower). You can also put a settings.json at the repo root in .claude/settings.json so the project ships its own permissions. Useful for "in this repo, allow X".

4. Statusline (the always-on context bar)

The line at the bottom of your terminal showing current model, branch, project, time. Two routes:

Quick: /statusline slash command — Claude writes one for you based on what you ask for.

Curated: drop this into ~/.claude/statusline.sh, mark it executable, and reference it in settings.json:

#!/usr/bin/env bash
# ~/.claude/statusline.sh
input=$(cat)
model=$(echo "$input" | jq -r '.model.display_name // "unknown"')
cwd=$(echo "$input" | jq -r '.workspace.current_dir' | sed "s|$HOME|~|")
branch=$(cd "$(echo "$input" | jq -r '.workspace.current_dir')" 2>/dev/null && git branch --show-current 2>/dev/null)
printf "\033[2m%s\033[0m  \033[1m%s\033[0m  %s%s" \
  "$model" "$cwd" \
  "$([ -n "$branch" ] && echo "$branch")" \
  ""

Then in settings.json:

{
  "statusLine": {
    "type": "command",
    "command": "~/.claude/statusline.sh"
  }
}

Now every prompt shows: opus-4-7 ~/Projects/orbiter-sandbox feat/interview-flow.

5. agent-browser (the verification primitive)

This is non-negotiable for frontend work. The agent cannot trust its own toasts. It needs a real browser.

# Install
npm install -g @anthropic-ai/agent-browser

# Verify
agent-browser --version

# Headed Chrome (Google OAuth requires headed)
agent-browser --headed open http://localhost:3001
agent-browser set viewport 1440 810

The pattern Mark — when you ask Claude to verify a UI change:

Open the running dev server, click the thing, screenshot the result, OCR the relevant area, confirm the text matches what you expected. Only then is it done.

This is what "verify your own work" means in practice. Without agent-browser, the agent ships UI changes that look right in a code review and break the moment a human clicks them.

6. Skills (the leverage layer)

Skills are markdown files at ~/.claude/skills/<skill-name>/SKILL.md. The agent reads them when relevant. They're how you encode "always do X this way" without retraining a model.

ls ~/.claude/skills/  # Robert ships ~200 of these

To use a skill in a session, name it: "use the dev-terminal skill" or in a slash command: /dev-terminal. The agent loads it.

To create one:

~/.claude/skills/my-skill/
├── SKILL.md      # the actual instructions, with YAML frontmatter
└── (any other reference files the skill points to)

Frontmatter shape:

---
name: my-skill
description: One-line summary the agent uses to decide if this skill applies.
---

# My Skill

Body...

The trigger pattern: the description field is what the agent matches against your request. Be specific — "Use this skill when the user asks for X, Y, or Z". The looser the description, the more often it loads when irrelevant.

We'll bundle a starter set in your ~/.claude/skills/ once you're set up — mark-onboarding, dev-terminal, crayon-sdk, xano-mcp-workflow, xanoscript-builder, and a couple Orbiter-specific ones.

7. CLAUDE.md (per-repo context)

Every repo gets a CLAUDE.md at the root. The CLI auto-loads it on startup.

# CLAUDE.md

## Build & Development Commands
```bash
pnpm install
pnpm dev       # port 3001
pnpm test
pnpm typecheck
```

## Architecture Overview
- Next.js 14 App Router
- Xano backend (workspace 3, API group 1270)
- AlloyDB ScaNN for vector search
- Crayon SDK for UI components

## Code Patterns

### API calls
Always use `/api/<route>/route.ts` BFFs. Never call Xano directly from a component.

### When in doubt
Check `docs/architecture.md` and `docs/anything-engine.md` first.

## Git Workflow
- Always create PRs targeting `main` (M-Pederson/orbiter-sandbox is single-branch)
- Pre-commit runs Biome + typecheck

Two purposes: telling the agent the conventions, and telling future-you what you decided. Treat it as the canonical handbook.

The orbiter-sandbox already has one. Read it. Add to it as patterns crystallize.

8. MCP servers (the data plumbing)

Model Context Protocol servers expose your data to the CLI as tools. We use three:

MCPWhat it gives youAuth
orbiter-docsmcp__orbiter-docs__search_orbiter_io_docs to grep Mark's Mintlify corpus from inside Claude CodeAlready configured in Robert's setup
xano-mcpmcp__xano-mcp__execute / info / list_all_tools — full Xano admin surface (read endpoints, edit XanoScript, deploy)XANO_META_TOKEN env var
charlotte-mcpEmail + calendar + tasks — Mark probably won't need this one yetOAuth, optional

To add an MCP, edit ~/.claude/mcp.json. Robert will hand you a templated config when you're ready — that's its own skill (xano-mcp-workflow).

9. Keybindings (chord shortcuts)

A ~/.claude/keybindings.json file lets you bind multi-key chords. The pros use them. Two we recommend:

{
  "keybindings": [
    {
      "key": "cmd+shift+v",
      "action": "toggle-verbose",
      "description": "Toggle verbose mode (show all tool calls)"
    },
    {
      "key": "cmd+shift+m",
      "action": "next-model",
      "description": "Cycle through opus → sonnet → haiku"
    }
  ]
}

Run /keybindings-help if you want to see the full list of bindable actions.

10. Hooks (the auto-correct layer)

Hooks are shell commands that run on lifecycle events: PostToolUse, Stop, UserPromptSubmit, etc. Use them to enforce invariants you don't want the agent to forget.

Examples we run:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "cd $CLAUDE_PROJECT_DIR && pnpm typecheck 2>&1 | tail -5"
          }
        ]
      }
    ],
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "echo 'session ending — verify build before claiming done'"
          }
        ]
      }
    ]
  }
}

The PostToolUse hook above means: every time the agent edits a file, run typecheck and feed the last 5 lines back to the agent. If TypeScript breaks, the agent sees it immediately and fixes before continuing. No more "I shipped it!" → "wait, it doesn't compile."

Don't go overboard. Each hook adds latency to every tool call. The two above are the highest-ROI starting set.


How We Work — The Workflow That Makes the Tools Matter

This section is more important than any of the setup. Tools are commodity. Workflow is leverage.

Plan → align → build

  1. Robert (or Mark) describes the task. Two-three sentences max.
  2. Agent restates the plan. What it will change, what it won't, what the open questions are.
  3. Decision picker. If there's a fork, the agent uses AskUserQuestion with 2–4 concrete named options. Never "what do you want?".
  4. Build. Only after alignment.
  5. Verify. Self-test against the actual user flow.
  6. Report. One sentence: what changed, what's next.

Skipping step 2 is the #1 reason work goes sideways. The agent commits to an interpretation that's 80% right and you lose 20 minutes redirecting.

Use multiple choice to drive forward

Robert's hard rule: always give multiple choice / interview-style options to push decisions forward fast.

# bad
What direction do you want me to take this in?

# good
[picker — Header: "Direction"]
  - Use the existing classifier endpoint (less work, but less control)
  - Add a new dispatcher (more flexible, ~30 min)
  - Punt for now and unblock the demo

The picker is faster than typing a reply. It also forces the agent to commit to real options instead of vague gestures.

Dispatch grunt work to cheap models

Don't waste the expensive brain on file listings, JSON parsing, retry loops, "is this URL 200?", "extract failing tests from this log."

If you have access to snappy-dispatch (Robert will share if/when relevant): one-line call, cheap model executes, you get the result back. Sub-penny per dispatch, 2–4 second latency.

For Mark today: just call out when a task is grunt work. The agent will switch to Haiku for that step automatically if you tell it to.

Verify, don't trust toasts

This rule is the difference between shipping and thinking you shipped.

Same-session toasts are not evidence. When the agent reports "done", check the diff yourself, run the actual flow yourself (or via agent-browser), and only then mark it done.

Background tasks for long ops

Two patterns:

run_in_background: true on Bash — for builds, dev servers, long-running watchers. The CLI gives you a task ID; you read output later. The agent doesn't sit and wait.

Sub-agents via the Task tool — spawn a fresh-context worker for a self-contained job (refactor, write a doc, run a multi-step search). The sub-agent has its own context window, returns one summary at the end.

Use sub-agents when:

Don't use sub-agents for tasks that need your taste, judgment, or knowledge of the conversation history. Those stay with the main agent.

Fallback runner (when you're rate-limited or curious)

Two options when Claude Code itself is unavailable:

snappy-shell — boots pi (a different agent runtime) with the full skill kernel loaded. Same skills, different brain. Cascade: OpenAI → Gemini Pro → Gemini Flash → Anthropic Sonnet, falling through on quota errors. Useful for "I want a second opinion" or "Anthropic is down."

claude-private — a zero-telemetry fork of Claude Code that talks to OpenRouter. Same UX, different auth. Useful when you want to route through OpenRouter for cost or compliance reasons.

Both come with skills. Robert will share the install path when you're ready.

The certificate rule

This is Robert's house style: no agent reports "done" without a verification certificate. Same-session toasts don't count. The actor cannot be the auditor.

In practice: when the agent says "committed and pushed", the next thing it does is git log -1 and gh pr view <id> to prove it. If the proof step fails, the original claim was wrong.

You'll absorb this rhythm by example. The first few sessions you'll catch yourself trusting a toast. Stop, verify, and the muscle memory builds.

Avoid backwards-compat hacks

Robert's rule: if you remove code, remove it cleanly. No // removed for X reason, no rename-to-_var-because-unused, no shimmed re-exports. If it's gone, it's gone — the diff is the record.


Day 1 Walkthrough — Your First 30 Minutes
# 0. Open a fresh terminal window
cd ~/Desktop/projects/orbiter-sandbox  # or wherever you cloned it

# 1. Boot the dev server in background
pnpm install
claude   # opens the CLI inside this repo

# 2. First prompt — let the agent read the lay of the land
> Read CLAUDE.md and docs/architecture.md, then tell me in 5 bullets what
> this repo does and where I'd start to add a new outcome class.

# 3. Watch what it does
# It should: read the two files, summarize, propose a starting point.
# Notice: it doesn't just answer, it cites file paths and line numbers.

# 4. Ask for a small change
> Edit prompts/find_investors/interview.md so the deck-or-describe
> opener says "Show me your deck OR describe the round in 2 sentences"
> instead of the current wording. Run pnpm sync-prompts and confirm.

# 5. Verify
> Open localhost:3001/chat, type "I want investors", screenshot the first
> assistant message, confirm the new wording is showing.

If you got through that without major friction, you're set up. If not, the troubleshooting section below covers the usual suspects.


60-Minute Walkthrough — Your First End-to-End Change

Build a new prompt. Sync it. Test it. Commit it.

> Add a new prompt file at prompts/find_investors/synthesize-v2.md.
> It should be the same as synthesize.md but enforce a 90-word max on the
> WHY paragraph. Add a registry entry mapping it to a new var slot
> $synthesize_v2 in endpoint 8401. Sync. Test in /chat by running a real
> investor query and confirming the WHY paragraph fits the new limit.
> Commit on a new branch, push, open a PR.

The agent should:

  1. Read synthesize.md, registry.json, the relevant Xano endpoint
  2. Plan the change, ask if you want a new branch or a commit on main (AskUserQuestion)
  3. Write the new file, update registry, run sync
  4. Open agent-browser, run a query, screenshot, OCR, count words
  5. If under 90, commit; if not, iterate the prompt
  6. git push, gh pr create, paste the URL

That's the pro flow. Tooling does the manual labor. You stay in the judgment seat.


90-Minute Walkthrough — Using Sub-Agents

When a task gets big, spawn sub-agents. Try this:

> I want to add interview prompts for find_journalists, find_event_attendees,
> and find_warm_intros. They should follow the same shape as
> find_investors/interview.md (deck-or-describe → ready-flag → JSON contract).
>
> Spawn three Task sub-agents in parallel — one per class. Each writes its
> interview.md, adds it to the registry, runs sync, and reports back with
> a verification screenshot from /chat.

Three sub-agents work in parallel. You get three "done" reports back, each with a screenshot. Total wall time: ~the time of the slowest one, not 3× one.

If something's off, you redirect just that sub-agent — the others stay clean.


Troubleshooting

claude doesn't recognize my changes to ~/.claude/settings.json.
Restart the CLI. Settings are read at session start. There's no live-reload.

Permissions prompt for a command I thought I allowed.
Pattern matching is exact. Bash(git push:*) allows git push, git push origin, etc. — but not Bash(git push). Always use :* suffix.

Agent claims it ran a command but the output is empty.
Usually a long-running shell that timed out at 2 minutes. Re-run with run_in_background: true. The agent should know this — if it doesn't, point it at this section.

agent-browser saved-state expired (Google OAuth re-prompt).
Re-run the full login flow, save state again:

agent-browser --headed open http://localhost:3001
# log in manually
agent-browser state save ~/.claude/workos-auth-state.json

The agent is going off on a tangent.
Interrupt. Two ways:

  1. Esc once — stops the current generation, lets you redirect
  2. Esc Esc (double) — clears the current turn entirely

Use the picker to push it back on track: "Pick one of: A, B, C."

The agent is being verbose.
You can correct it inline ("just give me the answer, no recap"). Or save it to memory: /remember the user wants terse responses, no trailing summaries.

TypeScript compiles but the build broke.
The PostToolUse hook is too narrow. Add pnpm build to the matcher list, or add a separate hook for Edit|Write that runs full pnpm check.

Hook is adding 30 seconds to every edit.
Hooks run synchronously. If the typecheck takes 30s, that's 30s per edit. Either narrow the matcher (e.g., only .ts/.tsx paths) or move the heavy check to a Stop hook that runs once at session end.


What's Next

Once you're set up:

  1. Run the day-1 walkthrough. Just to feel the rhythm.
  2. Pick a real task. Probably the mark-onboarding skill we ship next to this doc — read it, edit it, sync it.
  3. Tell Robert what's friction-free vs friction-heavy. This doc evolves.
  4. Add to your ~/.claude/skills/. When you find yourself explaining the same context twice, that's a skill waiting to be written.

We'll layer on the more advanced stuff (cross-machine ops, autonomous loops, ralph experiments, dispatch swarms) as you ask for it. Day 1 is just: install, settings, terminal, browser, skills, MCP. The rest compounds.


Where to Look for Code

Each of those files is plain text. Edit, save, restart the CLI, you're live.