Improve Claude Code
Work through the claude-code Things backlog: fetch todos, triage with the user, then plan and implement each in parallel as separate PRs.
The backlog has two sources. The user files todos tagged claude-code by hand (and agent-ideas files external-harvest ideas in the same shape). Discover mode adds a second source: it mines this machine's session history for config-change candidates, grounds them against the live config, and files the keepers as claude-code todos. Both sources feed the one implement loop below. Discover is upstream of triage, not a replacement.
Watch mode is the downstream follow-on. Once PRs exist, it tracks them under /loop, implements review feedback as it lands, and closes each backing todo on merge. See Watch.
Sweep mode is the destructive counterpart to Discover: it proposes stale or graduated memories for retirement and deletes only what you approve. It is interactive-only and never runs unattended. See Sweep.
In every mode, the loop itself is in scope: this skill's own SKILL.md, the claude-code:session skill's queries and views, and the Things scripts the loop depends on. Findings in that class may be dispatched to background worktree agents immediately, even when everything else routes to planning or triage discussion.
All Things interaction goes through the things:jxa and things:url skills (never inline JXA). PRs go through pull-request:create (never gh pr create).
Arguments
$0 (optional mode) routes to a workflow. With no mode, run the default backlog loop: Fetch and Triage the claude-code todos, then plan and implement the selection as PRs.
discover: mine session history for grounded improvement candidates, write a digest, and file the keepers. See Discover. Interactive runs never auto-file. Pass--scheduledfor the unattended weekly variant that auto-filesnew, grounded, high-confidence candidates and never prompts. See Scheduled.watch: track the open PRs this skill opened, implement review feedback, and close each backing todo on merge. Run it under/loop /improve-claude-code watch. See Watch.sweep: propose stale or graduated memories for retirement and delete only what you approve. Interactive only, never unattended. See Sweep.
Discover
Mine session history for improvement candidates, ground them against the live config, write a digest, and file the keepers. Interactive Discover never auto-files: filing is an explicit user choice. The one exception is Scheduled, the unattended variant, which auto-files high-confidence grounded candidates. Implementing is a separate run of the loop below, unless the user opts into Direct Implementation for the run. The engine is the claude-code:session skill's fan-out, whose references/discovery.md carries the recipe (dimension cheat sheet, grounding mandate, host safety, Tier-2 catalog). Load that skill to read it.
Refresh
Run the session skill's scripts/refresh.ts --refresh once, alone (a refresh with work to do needs exclusive access to the database file), and note the DB path it prints. Never let a fanned-out agent refresh.
Fan-Out
Launch one Agent call per dimension (hook latency, hook blocks, permissions and sandbox, context tax, tokens, turns and compaction, skill economy), the same mining fan-out agent-ideas uses. The DB path is stable (the session skill states it), so agent prompts reference it directly; point each agent at references/discovery.md. Each agent runs its dimension's named queries (by name, read-only) plus any inline rollups, and returns structured candidate findings plus the exact SQL it ran. Read-only opens share the lock, so agents never contend with each other.
Grounding
Mandatory. Launch one or more grounding agents that re-check every candidate against the live files under /Users/ben/src/bendrucker/claude. Drop anything the config already addresses. Downgrade anything thin or host-skewed. Apply the harmony test from the repo's CLAUDE.md: a candidate that would fight a native Claude Code behavior gets reframed as an accommodation or a light-touch experiment with forward evaluation and removal criteria, since the harness's defaults encode aggregate usage and eval knowledge the finding lacks (Claude Code v2.1.198 moving Explore off Haiku onto the conversation model is the canonical case). Carry grounded (boolean) and confidence (high/medium/low) per candidate. Raw query findings go stale within a week against a config that changes weekly: a prior run overturned four of its own headline findings. See the grounding rules in references/discovery.md (hooks run in parallel, so never sum durations as wall-clock, and split friction into what a setting can fix and what it cannot).
Dedup
Fingerprint each candidate (see Fingerprint), then check two ledgers for that fingerprint: Things todos and the config repo's PR bodies. Direct-Implementation PRs carry the marker only in the PR body, so the Things scan alone misses them.
For Things, query via things:jxa for every claude-code-tagged todo and recently-completed (logbook) todo, and scan their notes for Discovery: <fp>.
For PR bodies, scan every PR on the config repo:
gh api --paginate '/repos/bendrucker/claude/pulls?state=all&per_page=100' \
--jq '.[] | (if .merged_at then "MERGED" elif .state == "closed" then "CLOSED" else "OPEN" end) as $s
| (.body // "") | scan("Discovery: [0-9a-f]{12}") | "\($s) \(.)"'
Paginate rather than passing gh pr list --limit <n>, which silently drops every PR past the limit once the repo outgrows it.
Each line is <STATE> Discovery: <fp>, where STATE is OPEN, MERGED, or CLOSED. Build a fingerprint-to-state map, strongest state wins (MERGED over OPEN). Then mark each candidate:
already-shipped: fingerprint in aMERGEDPR body, or in a completed todo (the annotate phase removes theclaude-codetag on a shipped todo, so the marker persists in notes or the logbook).already-filed: fingerprint in anOPENPR body, or in an openclaude-codetodo.new: fingerprint not found. ACLOSEDunmerged PR does not count, so a finding abandoned that way resurfaces asnew.
When one fingerprint lands in more than one place, already-shipped wins over already-filed. Suppress both from the actionable set. Still count them in the digest tail. Things and the PR history are the ledgers: no separate dedup store.
Digest
The only guaranteed output. Write tmp/claude-discovery-digest-<YYYY-Www>.md, ranked and grouped high to low confidence. Each entry shows the finding, its grounding note, the SQL that produced it, and its dedup status. Default host=local for config-change candidates; cite imported hosts as corroborating counts only, never pasting raw content/command/stdout from an egress-blocked host (see host safety in references/discovery.md). Never auto-file from this step in an interactive run. Only the Scheduled path files without asking, and it files after the digest lands.
File the Keepers
Present the actionable (new, grounded) candidates and ask the user which to file (numbers, ranges like 1-3, or all), mirroring the triage UX below. For each selected candidate, create one Things todo via things:url, tagged claude-code:
- Title:
[discovery] <finding title> - Notes: the pitch, then the SQL/evidence, then
Discovery: <fingerprint>on its own line.
One todo per candidate, not one blob. Filing lands findings in the same backlog the implement loop drains.
Hand Off
Report how many todos landed. The existing triage, plan, implement, PR, CI, and annotate phases run on them later, unchanged. Filing is the default terminal action of Discover mode. Implementing is a separate, explicit choi