Claude Mastery
#19 · Tuesday Edition
⌨️ CLI POWER MOVE
🔥 New🔧 Try It
v2.1.116 — /resume 67% Faster, Main-Thread Agent Hooks, and a gh Rate-Limit Hint

Claude Code v2.1.116 shipped Apr 20 — a focused release where three of the fixes are each worth knowing on their own.

  • /resume is up to 67% faster on 40MB+ sessions and now handles dead-fork entries without degrading. If you live in long-running conversations, this is the first time the resume step feels like a cheap operation again. Paired with this: /resume no longer silently loads an empty conversation when a session file fails — it reports the load error, which means you can stop staring at a blank transcript wondering if you lost work.
  • Agent hooks: frontmatter now fires when running as --agent on the main thread. Before 2.1.116, custom hooks configured in an agent definition only fired when that agent was invoked as a subagent. Running the same agent on the main thread silently dropped them. If you've been wiring PreToolUse/PostToolUse hooks into agents and wondering why they only fired sometimes, this was the reason.
  • Bash tool hints when gh hits GitHub's API rate limit. That's the one headless agents used to burn entire loops on — retry, get 403, retry, get 403. Now the model sees the rate-limit signal and can back off or switch strategy.

Other quiet wins: MCP startup is faster when you have several stdio servers (template listing is deferred to your first @-mention), the Usage tab in Settings shows 5-hour/weekly numbers immediately instead of blocking on the usage endpoint, and the sandbox auto-allow rule that was letting some rm/rmdir calls into /, $HOME, and other critical paths now gets caught by the dangerous-path check.

Update path for npm users: claude update or npm i -g @anthropic-ai/claude-code. Native binary users: claude update picks up the new manifest from storage.googleapis.com.

🏗️ AGENT ARCHITECTURE
🔧 Try It🔬 Deep Dive
Ralph — The While-Loop Coding Agent, Now Containerized and Auditable

Ralph is Geoffrey Huntley's July 2025 pattern for autonomous coding: while :; do cat PROMPT.md | claude-code ; done. One prompt, one loop, one task per iteration, a shared @fix_plan.md and @progress.txt that the agent reads and updates each pass. Huntley reports shipping a $50k contract for $297 in API costs, and six repos during a YC hackathon weekend, using exactly this.

The pattern's three non-obvious disciplines, all from Huntley's original post:

  1. One item per loop. Each iteration tackles exactly one item on the backlog. Break that and context-window pressure kills you by iteration three.
  2. Deterministic prompt stack. Every loop allocates the context the same way — the same @specs/*, the same @AGENT.md, the same plan file. The model re-hydrates from files, not from conversation history.
  3. Greenfield only. Huntley is explicit: "There's no way in heck would I use Ralph in an existing code base." The pattern is for bootstrapping, not refactoring.

The new ergonomics layer is Rickvian's ralph-scaffold (dev.to, Apr 21). npx ralph-scaffold drops a scripts/ralph/ directory into your repo (ralph.sh loop, prompt.md, prd.json backlog, progress.txt log) that runs inside a .devcontainer with credential forwarding explicitly disabled — the container talks to GitHub via a fine-grained PAT scoped to the single target repo. The agent can commit, push, and branch; it can't touch your SSH keys or cloud tokens because it can't see them.

Operator note: Ralph doesn't replace interactive coding; it replaces *a specific class of Sunday-evening greenfield work* — the projects where you already know the shape of the thing but don't want to hand-type the 40 files it takes to scaffold it. Treat the backlog (prd.json) as the actual engineering artifact. That's the part that lives or dies on your precision.

🧭 OPERATOR THINKING
🔬 Deep Dive🌿 Evergreen
Your Plugin Marketplace Is a Governance Layer, Not a Git Repo

Michael Tuszynski's Apr 20 dev.to post reframes a mistake most teams are about to make: the Claude Code plugin marketplace isn't a distribution channel — it's a governance layer. Treating it like npm-for-plugins misses the whole point.

The three-layer model he proposes:

  • Skills/Plugins execute code inside developer sessions.
  • Marketplace (your marketplace.json) lists the approved set.
  • Managed Settings (strictKnownMarketplaces in settings.json) controls which marketplaces employees are even allowed to add.

The specific operator moves, worth copying wholesale:

  1. Pin to commit hashes, not tags. Tags move. Commits don't. A marketplace entry with "version": "v1.2.0" can silently ship new behavior; a marketplace entry with "ref": "a3f9c12..." can't. This matters most for plugins that run PreToolUse hooks — a version bump that adds a new "convenience" feature is a permissions change in disguise.
  2. Split the repos. Keep the marketplace manifest in a separate repo from plugin source. Approval policy lives on the manifest repo (PR review, signed commits, branch protection); development lives on the source repo. Same plugin, two different review surfaces.
  3. Layer PreToolUse hooks on top. Marketplace approval is compile-time; hooks are runtime. Block curl | sh patterns, credential-file reads, and anything that writes outside the project root regardless of which plugin invoked it.

What's still missing in 2026: plugin binary signing, real sandboxing of plugin execution, and a seed-directory pathway for air-gapped environments (there's no CLAUDE_CODE_PLUGIN_SEED_DIR yet). If you're in a regulated org, that's the gap you still have to close yourself — probably with wrapper scripts that verify SHA-256 of downloaded plugins against a manifest before /plugin install runs.

🌐 ECOSYSTEM INTEL
🔥 New🔧 Try It
ctx — Workstream-Bound /resume That Works Across Claude Code and Codex

ctx (dchu917/ctx, MIT, 3 stars) is a Show-HN from Apr 20 that solves a small but sharp problem: /resume only resumes *this tool's* sessions. If you run Claude Code for one part of a task and Codex for another, you can't hop between them without re-pasting context.

ctx introduces workstreams — named, local contexts backed by SQLite that bind to a specific transcript and can be resumed from either agent:

/ctx start feature-audit --pull # create workstream, pull current transcript
/ctx resume feature-audit # continue later from same or different agent
/ctx branch feature-audit feature-audit-v2 # safe branch — new stream, shared history

In Claude Code it runs as a slash command. In Codex (no custom slash commands yet), it runs as a plain CLI (ctx resume feature-audit) — both paths read and write the same local database, which is where the cross-tool trick lives.

Install paths include ./setup.sh --global, a curl | bash bootstrap, or npx skills add https://github.com/dchu917/ctx --skill ctx -y -g. Local-first, no API keys, no cloud.

Caveats: 3 stars, 1 contributor, 2 releases — this is conceptually interesting, not production-ready. The pattern (workstream-as-branchable-context) is the thing to take away. Even if ctx doesn't stick, expect the idea to land elsewhere: "/resume should be a graph, not a stack" is a reasonable direction for the ecosystem once you've felt the pain of branching a long session.

If you already bounce between Claude Code and Codex on the same problem, 10 minutes of trying ctx on a throwaway workstream tells you whether the branching model fits your head. If it doesn't, you've lost 10 minutes. If it does, you've found the primitive that's been missing from /resume since day one.

🔬 PRACTICE LAB
🔧 Try It🔬 Deep Dive
Boot Ralph In a Dev Container Tonight and Let It Grind a Toy Backlog

Spin up Ralph on an isolated, disposable container and watch an autonomous agent close out a five-story backlog overnight — without ever seeing your SSH keys.

Prerequisites: Node 18+, Docker Desktop or Engine running, VS Code with the Dev Containers extension, a fine-grained GitHub PAT scoped to *one* throwaway repo (Settings → Developer settings → Personal access tokens → Fine-grained), and claude logged in (Max subscription fine — Ralph calls claude-code inside the container, inheriting your auth through an env var).

What you'll do: Scaffold a Ralph workflow, draft a five-item backlog, let the loop run for 2–3 hours, and inspect progress.txt + git history in the morning.

Steps:

  1. Create an empty throwaway GitHub repo (private), clone it, cd in.
  2. Scaffold the workflow and the dev container:
npx ralph-scaffold
code .

When VS Code prompts, pick Reopen in Container. First build takes a few minutes — it's installing Node, Claude Code, gh, and jq in the container.

  1. Open scripts/ralph/prd.json. Replace the stub with five tiny, concrete stories. Example for a toy CLI:
json
[
{"id": "001", "title": "init npm package with TS + vitest",
"acceptanceCriteria": ["tsc passes", "vitest shows 0 tests"], "priority": 1, "passes": false},
{"id": "002", "title": "add argv parser (yargs) with --help",
"acceptanceCriteria": ["--help prints", "unit test for parser"], "priority": 2, "passes": false},
{"id": "003", "title": "implement `hello <name>` command",
"acceptanceCriteria": ["prints 'hello <name>'", "unit test covers empty name"], "priority": 3, "passes": false},
{"id": "004", "title": "add GitHub Action running vitest on PR",
"acceptanceCriteria": [".github/workflows/ci.yml exists", "runs on push + PR"], "priority": 4, "passes": false},
{"id": "005", "title": "write README with install + usage",
"acceptanceCriteria": ["README mentions both commands", "renders in GitHub"], "priority": 5, "passes": false}
]
  1. Paste your fine-grained PAT into the container shell (not your shell):
gh auth login --with-token <<< "ghp_your_fine_grained_pat_here"

This is the *only* credential Ralph gets. Nothing else is forwarded.

  1. Kick the loop. From the container terminal:
bash scripts/ralph/ralph.sh

Leave it. Close the laptop lid, walk away, come back in 2–3 hours.

Expected outcome: Each prd.json entry flips to "passes": true. The container has pushed 5+ commits to a claude/ branch (or opened a PR, depending on your scaffold config). progress.txt reads like a diary — "learned that vitest config needs globals: true for the async helpers," "reverted yargs import after ESM error." When the last story passes, the script prints COMPLETE and exits.

Verify: Run three checks before trusting anything the container produced:

  • jq '.[] | select(.passes==false)' scripts/ralph/prd.json — should return nothing. If any story is still false, the agent couldn't finish; open progress.txt and see why.
  • git log --oneline origin/claude/* — should show one commit per story, each with a message referencing the story id.
  • gh run list — the CI workflow Ralph wrote for story 004 should be green on its own PR. If red, the agent shipped a workflow it didn't verify.

If any check fails, don't patch manually — sharpen the acceptance criteria in prd.json, wipe the branch, and run again. Ralph's job is to learn from the failure; yours is to tighten the spec.