Skip to content
pySilverPublic

About

claude code workflow tools

Resources

Stars

4 stars

Watchers

0 watching

Forks

Latest commit

 

History

53 Commits

Folders and files

Repository files navigation

cc-tools

CI

A personal collection of Claude Code agents and skills, packaged as a marketplace of small, single-purpose plugins.

This is an opinionated set — it's the toolbox I actually use, grouped by what each tool is for rather than what it is. A few of these are honestly tuned to my own projects (Python/Django, an ADR + plan + exec workflow, a Context7 MCP), so they won't all drop cleanly into a different setup. I've flagged that per plugin below. Even where a tool doesn't fit you as-is, it might give you ideas for building your own.

Install

Add the marketplace, then install the plugins you want:

/plugin marketplace add pySilver/cc-tools

/plugin install decide@silver-cc-tools
/plugin install git@silver-cc-tools
/plugin install research@silver-cc-tools
/plugin install basedpyright-lsp@silver-cc-tools
/plugin install pyrefly-lsp@silver-cc-tools
/plugin install tracking@silver-cc-tools
/plugin install huddle@silver-cc-tools
/plugin install output-styles@silver-cc-tools

Test a plugin locally before installing:

claude --plugin-dir plugins/decide

Validate the marketplace and a plugin:

claude plugin validate .
claude plugin validate ./plugins/decide

After install, components are namespaced by plugin: skills are invoked as /decide:interview-me, /git:finalize-feature-branch, /research:web-research. basedpyright-lsp and pyrefly-lsp have no command to invoke — each registers a language server that activates automatically when you open a .py/.pyi file. They claim the same extensions, so enable only one: with both on, the first server registered wins and the other never starts. output-styles has no command either — it adds Direct to the /config → Output style picker, where you select it.

Manual install (alternative)

Copy the files you want straight into your Claude Code config directory. Agents go under ~/.claude/agents/, skills under ~/.claude/skills/. Restart Claude Code afterward.

decide — interview-me + brief skills:

cp -r plugins/decide/skills/interview-me ~/.claude/skills/
cp -r plugins/decide/skills/brief ~/.claude/skills/

git — finalize-feature-branch skill:

cp -r plugins/git/skills/finalize-feature-branch ~/.claude/skills/

research — web-research skill:

cp -r plugins/research/skills/web-research ~/.claude/skills/

huddle — there's nothing useful to copy: the skill calls bin/huddle, which only a plugin puts on PATH. Load it as a plugin directory instead (claude --plugin-dir plugins/huddle).

output-styles — the Direct output style:

cp plugins/output-styles/output-styles/direct.md ~/.claude/output-styles/

basedpyright-lsp / pyrefly-lsp — there's nothing to copy: a language server isn't a skill or agent, so it can't be dropped into ~/.claude. Load one as a plugin directory instead:

claude --plugin-dir plugins/basedpyright-lsp
# or
claude --plugin-dir plugins/pyrefly-lsp

Note: installed manually, skills lose the plugin: namespace — invoke them by bare name (/interview-me, /web-research, etc.).

Updating

Plugin versions are intentionally omitted from the manifests, so every commit to this repo is a new version. The /plugin menu has two update paths:

  • /plugin → Marketplaces → Update marketplace — pulls the latest catalog from the repo immediately. The reliable way to get updates.
  • /plugin → Installed → Update now — uses a local cache that can lag. Use it as a fallback after updating the marketplace.

Enable /plugin → Marketplaces → Enable auto-update to refresh the catalog on each session start.

Plugins

Plugin Description
decide Pre-code design gates — intent interviews, risk triage, decision briefs
git Finalize a feature branch — rebase, squash to one commit, verify, push
research Grounded web research with source-quality discipline and inline citations
basedpyright-lsp Python LSP (basedpyright) for Claude — navigation + diagnostics, from the project's pinned venv
pyrefly-lsp Same, backed by pyrefly instead — pick whichever your type-check gate runs
tracking Deferred-work backlog (docs/backlog/) — one slug-named file per item, git rm'd when fixed
huddle Questions as a page in an agterm overlay — diagrams, trade-offs side by side, real code, sliders
agrev Review a plan or other markdown document in plannotator, in an agterm session, round by round
peer-planning Coarse-task plans, executed task by task with Codex reviewing each diff from the adjacent agterm pane
output-styles Direct — peer-to-peer tone, plain English, choice-first, diagrams-first

decide

Two tools for the stretch before any code is written: one to find out what you actually want, and one to make the resulting fork readable.

Component Trigger Description
skill /decide:interview-me Extracts what you actually want — one question at a time, each carrying the agent's own guess, until it can predict your answers
skill /decide:brief Rebuilds your context before you pick — one concrete failing run, why it became possible, the forks replayed against it, pointers last

interview-me — the gate before anything gets drafted. What people ask for and what they want are different things: "build me a dashboard" is the conventional phrasing, not the problem, and the gap between the two is free to close now and expensive to close after code exists. The mechanism is one question at a time with the agent's own guess attached — you react to a wrong hypothesis far faster than you compose an answer from scratch, and attaching the guess is what forces the agent to commit to an assumption it can be visibly wrong about instead of quietly building on it. It opens with a one-sentence read of what you want and an honest confidence number, and every number under ~70% has to say what is still missing, so the score is a request for specific help rather than a mood. It listens for want vs. should want — "scalable", "clean architecture", "the standard approach" are answers that sound like a thoughtful answer instead of being one, and they get one probe: if you didn't have to justify this to anyone, what would you actually want? It closes with a six-line restate (Outcome / User / Why now / Success / Constraint / Out of scope) and an explicit yes — "whatever you think is best" is delegation, "sounds good" is ambiguous, and silence is not confirmation, so each of those re-asks instead of terminating. The stop condition is checkable rather than a vibe: can I predict your reaction to the next three questions I would ask? — with a floor, so several rounds of flat confidence ends the interview and reports that something foundational is missing rather than grinding on.

Produces intent, not a document. The deliverable is a confirmed statement of intent that an ADR, a brainstorm, or a planner then consumes; it deliberately writes no file by default and defers to the host project's documentation conventions if you want it persisted, rather than inventing a directory to hold it. Needs a live user — it declines to run in CI, /loop, or an unattended plan executor and flags the underspecified ask as a blocker instead of guessing. Adapted from addyosmani/agent-skills (MIT); see NOTICE for what was kept and what changed.

brief — the format an agent should use when it hands a fork back to you. You wrote the design while fully focused; by the time an agent hits a judgement call three days later, the plan and the ADR are gone from your head, and a verdict built out of section names and internal terms asks you to reload a whole design from a pointer before you can read the question. This fixes the shape. First settle the problem — name the guard you reached for and what it leaves in place, run a root-cause or likelihood tool if one is available, and say plainly when the verdict is judgement rather than a checked result. Then five parts, in order: the story (one concrete run in time order, real values not variable names, ending badly, with one clause saying whether it was reproduced or derived — the two read identically and only one is evidence); the step back (2–5 lines: why this became possible, asking why until the answer is a decision someone made rather than a line of code, plus how far the same cause reaches — then landing on local, design, or unknown); the forks (two to four, cheapest first, each with its cost now and its cost if added later, each replaying the same story to its new ending, each labelled removes the cause or guards only); the recommendation (one option, one question, answerable in one word, plus an offer to expand any fork — offering to re-explain costs you nothing, a pointer asks you to go read); and the pointers last, one line, never inside the story.

The step back is what makes the menu safe to answer. A readable fork is still the wrong question when the fork itself is the artifact of an earlier bad split, and from inside a list of options you cannot tell which kind you are looking at — so the brief has to say it. When it lands on design, revising that decision is one of the forks, costed and replayed like the rest, and if it is genuinely off the table (shipped, needs a migration, the release is Friday) that line goes where the fork would have been rather than being omitted, which would let the menu imply it was never available. The "how far does it reach" clause is the other half: two options look equally reasonable until you know the same choice has four other exits nobody has hit yet. Both directions are errors — a step back that relabels the defect line as the cause tells you nothing, and one that manufactures a design flaw so the section has something to say is worse, so local ("the plan was right, this build diverged from it") is a one-line answer the format expects most of the time.

It deliberately does not fire for a failure the agent can fix itself, a yes/no on a step just described, work done in this session, or anything small and reversible — a five-part brief on a two-minute fork spends the attention the format exists to protect. Two send checks: could you pick an option without opening the plan, the ADR, or the code — and can you tell whether picking from this menu is patching over something? In Claude Code, the story, the step back, and the forks go in the message and the choice goes to AskUserQuestion, where each option description carries what we do + cost + removes or guards — an option description that is itself a pointer defeats the whole thing.

Pairs with the Direct output style (the output-styles plugin below). The style already says lead with the answer and skip trailing summaries; this skill is the documented exception — the story leads, and the closing question is the next action rather than a recap. Repo-agnostic; a root-cause or likelihood tool is used when one is present and skipped when not. It has eval coverage under plugins/decide/evals/ — one case that it fires with the right shape, and two that it stays quiet, because the failure mode of this format is over-firing.

git

Component Trigger Description
skill /git:finalize-feature-branch [default-branch] Rebase onto the default branch, collapse to one commit, verify, merge into the default branch and push

finalize-feature-branch — takes an approved feature branch to exactly one commit ahead of the default branch. It detects the default branch (or asks), previews what will change, fetches and rebases (resolving clean conflicts, aborting on unclear ones), collapses multiple commits via git reset --soft + commit (never interactive rebase), proposes a commit message derived from the branch name, verifies, then lands the branch. Each step confirms before acting. Repo-agnostic — plain git.

Two things it is opinionated about:

  • Landing defaults to merge, not publish. The first offer is fast-forward the branch into the default branch locally and git push origin <default>; publishing the feature branch with --force-with-lease is the second option, for when a PR is wanted. The default branch is never force-pushed, and a rejected push stops the run rather than escalating.
  • From a worktree it lands on the remote instead. If another worktree holds the default branch, the local merge is impossible — git checkout and git fetch . HEAD:<default> both refuse — so the first offer becomes git push origin HEAD:<default>, the same fast-forward one hop earlier. It never rewrites the ref behind the other checkout's back, and afterwards it reports that worktree as behind, offering to fast-forward it only when it is clean.
  • The full test suite is skipped when the rebase pulled in nothing but documentation — and only then. reset --soft rewrites history, not the tree, so the only thing that can break a verified branch is incoming upstream work; the skill diffs the pre-fetch merge-base against the new default-branch tip to see exactly what that was. A resolved conflict, no passing suite earlier in the session, or a single unclassifiable file all force a full run. .md is not automatically documentation: files under tests/, requirements*.txt, doctested .rst, and repos that ship markdown as source are named as never-docs. Anything left unclassified prompts a question instead of a guess, and a skip is always reported with its reason.

research

Component Trigger Description
skill /research:web-research <question> Grounded web research with source-quality heuristics and inline citations

web-research — answers questions from current, citable sources. It scopes the question, searches with precise terms (parallel queries for distinct angles), fetches primary sources with focused extraction, cross-checks claims that matter (versions, advisories, prices, breaking changes — one source is a lead, two is a fact), and cites sources inline. It prefers official docs, RFCs, and release notes over SEO aggregators and undated tutorials, and reports the answer rather than narrating the search.

Note: prefers a Context7 MCP for library/framework docs and gh for GitHub URLs when available, falling back to plain web search otherwise.

basedpyright-lsp

Component Trigger Description
lsp opening a .py/.pyi file Registers a basedpyright language server for Python

basedpyright-lsp — gives Claude a Python language server (go-to-definition, find-references, hover, document/workspace symbols, call hierarchy, plus diagnostics) backed by basedpyright, the pyright fork. There's no command to run; the server starts when a Python file is opened.

Why this exists. Diagnostics are already covered twice over — by the editor's own LSP while a file is open, and by the git hook that runs basedpyright as the type-check gate at commit. What's missing is navigation for Claude in terminal-only sessions (no editor attached): jumping to a definition, finding references, walking a call hierarchy. That's this plugin's unique value. The catch is that diagnostics must not disagree with the gate, so the server is sourced from the same pinned basedpyright the gate uses rather than a global install that can drift to a different version.

It resolves the server binary in priority order, anchored to the project root (${CLAUDE_PROJECT_DIR}, falling back to cwd):

  1. <root>/.venv/bin/basedpyright-langserver — the project's pinned basedpyright (matches the gate). Preferred.
  2. uv run --project <root> --no-sync basedpyright-langserver — when a pyproject.toml exists and uv is on PATH; resolves the project env without activating it and without an implicit sync.
  3. a global basedpyright-langserver on PATH — last resort (its version may differ from the project pin).
  4. none found → exits non-zero with an install hint. It never auto-installs — adding basedpyright to the project's dev deps is your call, not the plugin's.

Replaces pyright-lsp@claude-plugins-official (which hardcodes pyright-langserver and looks it up on PATH only — it never finds a basedpyright that lives in a project venv). Disable any pyright/basedpyright LSP from another marketplace before enabling this one.

Tuned for my setup. Assumes a project venv at .venv/ and/or a uv-managed pyproject.toml, and a basedpyright type-check gate to agree with. On a non-uv project with no .venv, only the global fallback applies — adjust bin/langserver.sh for other layouts (Poetry, conda, a differently-named venv).

pyrefly-lsp

Component Trigger Description
lsp opening a .py/.pyi file Registers a pyrefly language server for Python

pyrefly-lsp — the same idea as basedpyright-lsp, backed by pyrefly (Meta's Rust-based Python type checker and language server) instead. Same discovery order, anchored to the project root (${CLAUDE_PROJECT_DIR}, falling back to cwd):

  1. <root>/.venv/bin/pyrefly — the project's pinned pyrefly (matches the gate). Preferred.
  2. uv run --project <root> --no-sync pyrefly — when a pyproject.toml exists and uv is on PATH.
  3. a global pyrefly on PATH — last resort (its version may differ from the project pin).
  4. none found → exits non-zero with an install hint. It never auto-installs.

Started as pyrefly lsp (pyrefly speaks stdio by default — no --stdio flag). Unlike the basedpyright wrapper, this one cds to the project root first: pyrefly discovers both its config (pyrefly.toml / [tool.pyrefly]) and a project-root venv by walking up from the cwd, and the LSP subprocess cwd isn't documented.

Which one? Match whatever runs as your type-check gate — the point of both plugins is that Claude's diagnostics don't disagree with the thing that blocks your commit. Pyrefly is much faster and still moving quickly; basedpyright has the deeper rule set and the pyright-compatible config. Don't run both: they declare the same .py/.pyi extensions, so the first registered wins, the other silently never starts, and /plugin shows a warning naming the winner.

Tuned for my setup. Same assumptions as basedpyright-lsp: a .venv/ and/or a uv-managed pyproject.toml. Adjust bin/langserver.sh for Poetry, conda, or a differently-named venv.

tracking

Where side-quest findings live, so they neither derail the current task nor evaporate — a register for the items that are real but not today's job.

Component Trigger Description
skill /tracking:backlog [slug] Read, work, and append deferred-work items in docs/backlog/ — one slug-named file per item, worth: yes/later/no, no index, git rm in the fixing commit

backlog — a defect, open decision, or follow-up surfaces mid-conversation; this writes it into docs/backlog/ instead of letting it derail the work or vanish, and reads it back later. One file per item, named by a slug that names the defect (reopen-fallback-ignores-frontmost.md) so it can be cited from a commit and dedupe is a filename check; no index file — the directory listing is the index. Three frontmatter fields: worth: yes | later | no (the triage call the list is ordered by — later must name the unknown that would settle it, no is kept deliberately so the next review that touches the file does not rediscover and re-argue it), where: path or path:symbol (never a line number — those rot), and added (never updated, so it reads as age). Items pass a three-part admission gate (real and re-derivable from code; not being done now; not owned by a dated review) and the body is written for a reader without the conversation: the concrete run with real values, the misreading to prevent, options with costs plus a recommendation for a later, and provenance. Reading the list verifies every where against the tree and reports stale anchors as stale rather than as work, then offers fix-a-named-item / drop / leave via AskUserQuestion; /tracking:backlog <slug> jumps to one item. Appending dedupes on where then slug, refuses to write onto a non-default branch without asking (a note on a feature branch gets swept into that PR or dies with it), checks the index for pre-existing staged work before offering to commit, and offers commit and push together. No checkbox, no resolved state: the item is git rm'd in the commit that lands its fix. Adapted from umputun/cc-thingz (MIT); see NOTICE for what was kept and what changed.

Tuned for my setup. Assumes the docs/ layout (docs/backlog/, dated reviews under docs/reviews/<date>/). The item shape is project-agnostic otherwise. backlog is Git-only by design.

huddle

Component Trigger Description
skill /huddle:huddle, or any question that asks you to choose or approve Asks the question as a page in an agterm HTML overlay over the agent's own session and hands the answer back as JSON
command huddle (on the Bash tool's PATH) The launcher the skill runs: huddle q … for one line, huddle - for a JSON spec, huddle wait, huddle render, huddle demo

huddle — a text prompt is the wrong shape for many of the questions an agent asks a developer. "Which of these three architectures?" wants the three diagrams. "Is this the right fix?" wants the code. "How round should the cards be?" wants a slider and a preview, not a list of pixel values. huddle gives the agent a page for those: options that carry a picture (mermaid diagrams, wireframes, color, radius and type samples, charts), up to nine choices with a gray subtitle, a reasoned Recommended badge and pros and cons, alternatives side by side, sliders with a live preview and the starting look beside it, several related questions on one page with a review of every answer before anything is sent, and a free-text box on every question, so a note travels with the choice or replaces it. The keys are 1–9, arrows, Tab for the note, ⏎ to send, and ⌥⏎ for "let's talk in the terminal instead". The page takes the terminal theme's colors, and while it waits the session's sidebar row shows the same amber "asking" glyph a built-in question gets. The agent writes a small JSON spec, or one line: huddle q "Which store?" "*Redis|already runs|no new service" "Postgres|one table".

What I changed from the upstream skill, mostly to make it hold up as a daily tool:

  • It is a command, not a path. The launcher lives in the plugin's bin/, which Claude Code puts on the Bash tool's PATH, so the agent can type huddle wait <id> turns later without carrying a path around, and the skill's allowed-tools: Bash(huddle *) pre-authorizes it in the turn that loads the skill. Upstream set H=…/huddle.py once and used $H afterwards, which is empty in every later Bash call because shell state does not persist between them.
  • Real code, from disk. {"code": {"file": "src/x.py", "lines": "40-62"}} reads the lines when the page is built and shows them numbered under their path; diff, md and mermaid take a file the same way. Escaping source into JSON by hand is where a spec breaks or the snippet you decide on quietly stops matching the file. A whole file over 300 lines is refused: name the lines the question is about.
  • It refuses to ask nobody. A claude -p run started from an agterm shell inherits AGTERM_ENABLED=1, so upstream would open a page inside ralphex or a plan executor and stall it for 570 s. Claude Code sets CLAUDE_CODE_SESSION_ATTENDED=0 there; huddle reads it and exits 3 without opening anything. The skill also tells subagents to hand their question to whoever started them.
  • Failures say what they are. An overlay slot already taken is exit 5 busy instead of a bare error, and when the overlay in the way is a huddle page, the reply carries its id — usually the agent's own question, left pending by a timeout, whose id was lost with the call that opened it; huddle wait on an invalid page id or a stopped agterm fails at once instead of spinning out its 570 s and reporting pending; a malformed spec gets the JSON error, never a traceback.
  • The one remote script is verified. Diagrams need mermaid, which is fetched once from jsDelivr and inlined into a page that runs with agterm's bridge — and that bridge can type into terminals. The bundle is now checked against a pinned sha256 on every use; on a mismatch the diagrams show as source and stderr says why.
  • The agent doesn't check for agterm; huddle does. Upstream's description names AGTERM_ENABLED=1 as the condition for using it. In eval runs of my first rewrite, which kept that condition, the agent spent a Bash call checking the variable, and where that call was not allowed it never asked with a page at all (0 of 6 runs). The description now says to run huddle without checking; it tried in 6 of 6. For that to be safe, the browser fallback outside agterm is now opt-in: a plain terminal gets exit 3 and nothing opens.
  • The "asking" glyph tells the truth. Status hooks that repaint the sidebar after every tool call and at turn end (mine do) covered a question waiting in the background, so the sidebar said "working" while a page sat unanswered. The plugin installs a Stop hook (hooks/hooks.json): when a turn ends with a huddle page still open, it re-posts the asking glyph, and because hooks run in parallel and in no fixed order, it keeps re-posting over any slower hook for 6 s (a hook slower than that wins), then exits. It runs async, so the turn's end never waits on it, and its shell guard skips Python entirely outside agterm or without python3. It does nothing mid-turn, so a long test run keeps its working glyph, and the glyph it posts clears when you visit the session, so a question you close with nobody waiting does not strand an amber triangle. One case it misses: Stop does not run when you interrupt a turn with Escape, so the glyph stays as the last hook left it until the next turn ends — but then you are at that session, where the page is.
  • A page carries more context than a list, never less. A plan-approval page once showed three bare options, "Story 3", "Story 4", "Story 5", and none of the evidence. The agent had written each question's evidence under context, which the upstream page shows only at the top level, so it dropped all of it silently. A question's context now renders like its body; any key the page does not read is an error that names the key it probably meant; and an option labeled only by its position ("Story 3", "Option B") with nothing else on it is refused, so the agent has to put the story's text on the option. The skill's new "Carry the context" section says the same to the agent: what is being decided lives on the option, labeled by what it says, with its full text open on the page.
  • q options take a third field for the recommendation's reason (*Label|subtitle|why), api.select on a single-choice question replaces the choice instead of adding a second one, and the "when to ask with a page" rules defer to whatever your own CLAUDE.md says about asking.

It asks every choice with a page, and your own rules decide whether it gets to. A list of short labels is where the difference between options gets lost, so huddle takes every question that asks you to choose or approve — a design fork, a sequencing call, a plan or its parts, even a choice between two options — and leaves only typed answers (a name, a path, a number) and a bare "go ahead?" on a step just described to the terminal. If your instructions say how questions are asked, they need to hand those questions over. Mine route 2–4-option choices to the question widget, and with only a narrow exception for "structural" choices, my sessions sent 89 questions to the widget and 3 to huddle in the first two days (counted from the session transcripts). This rule, as a Claude-only rules file (~/.claude/rules/huddle.md, not a rules file Codex also reads), turned that around:

Inside agterm, every question that asks me to choose or approve goes through the
huddle skill: a design fork, a sequencing call, a plan or its parts, a choice
between two options. It replaces the question widget there, overriding the
shared rule on how questions are asked. Only a question I answer by typing (a
name, a path, a number) or a bare "go ahead?" on a step you just described stays
in the terminal.

Measured in claude -p runs with my real configuration and the real launcher, three runs each: an architecture choice, a code judgement and a two-option "full suite or unit tests?" all went to huddle 3 of 3; a rename confirmation and a "which Jira ticket?" question stayed in the terminal 3 of 3; the question widget was used 0 times in 15. The narrower exception it replaces got the architecture and code questions but left the two-option choice in the terminal, and a looser first wording of that one missed the architecture question too ("the user asked for one plain question"): naming what the agent is about to do is what makes these lines work.

Permissions. allowed-tools only covers the turn that loads the skill; the grant clears at your next message. If you don't run in auto mode, add "Bash(huddle *)" to permissions.allow so a huddle wait in a later turn doesn't prompt. Plugin bin/ directories come after your own PATH entries, so a huddle of your own would shadow this one.

Needs agterm 0.34+ and Python 3 (standard library only). Outside agterm it opens nothing and exits 3, so the agent asks in the terminal; "browser": true in ~/.config/huddle/defaults.json serves the page on 127.0.0.1 in your browser instead. Personal defaults — style, panel size, the status glyph, a sound when a question arrives — live in ~/.config/huddle/defaults.json. tests/test-huddle.sh renders every template and demo and loads each page in headless Chrome when one is installed. Five eval cases under plugins/huddle/evals/ check that the agent reaches for a page on an architecture choice, a code judgement and a two-option choice, with a spec worth showing, and stays in the terminal for a go-ahead and a typed answer. Screenshots are in the upstream README. Adapted from skkap/claude-skills (MIT); see NOTICE for what was kept and what changed.

agrev

Component Trigger Description
skill /agrev:agrev [file], or "review this plan" Opens the document in plannotator in an agterm session right after the agent's, waits for your decision, and answers your annotations in the next round

agrev — reading a plan as raw markdown in a terminal, or as a diff, is the wrong place to mark it up. agrev opens the document rendered in plannotator, in an agterm session of its own right after the agent's, so the chat stays one click away. You comment on phrases, mark text for deletion, attach images, and press Send Feedback or Approve. The agent gets every annotation at once, edits the document itself, and opens the next round with its replies pinned to the phrases they answer; plannotator shows what changed since the last round. scripts/review.py does everything that touches plannotator and agterm: it records plannotator's URL instead of opening a browser, shows the page in agterm, and puts a small proxy in front of plannotator that keeps its cookies between reviews, because an agterm overlay starts with empty storage and every review would otherwise open on the onboarding dialogs. It also strips the agent's own pinned comments from the feedback plannotator exports, so they are not read back as yours.

Needs agterm, plannotator and Python 3 (standard library only). review.py open names the plannotator install command when it is missing. Each round's log, result and comments stay in ~/.cache/agrev/runs/.

peer-planning

Component Trigger Description
skill /peer-planning:make Writes a plan in docs/plans/ whose tasks state the outcome, the constraints and the proof of done, not the steps, for an executor that finds the details itself
skill /peer-planning:exec <plan> Runs the plan as a two-agent loop in an agterm split: a subagent implements each task, Codex reviews the diff before the commit, then Codex is cleared for the next task

peer-planning — one agent working alone accepts its own reasoning. Here a second one, Codex in the other pane of the split, reads every task's diff before it is committed, and for a task the plan marks for discussion it argues the approach before any code is written. This session orchestrates: it hands each task to an implementation subagent (Opus at medium by default), carries messages between Codex and the subagent, and clears Codex between tasks so each review starts fresh. Every step lands in an events.jsonl log, and a monitor page in an agterm overlay shows who holds the wait. After the last task it reviews the whole branch in revmux rounds, a full pass and then re-checks of the fixes, with a fresh subagent fixing each round's findings, then runs the project's /polish step, and stops before finalize, which you run. The plans make writes are coarse, because the executor is capable and the planner's job is to settle the decisions, not to script the edits. Both skills read the project's .claude/planning-rules.md.

Needs the rest of the setup. agterm with its two-agent-chat recipe installed (peer-chat.py on PATH, the peer-chat skill for Claude and for Codex), Codex running in the right pane of the split, and revmux for the branch review. A project changes that review by overriding revmux's comprehensive and final profiles in .revmux/prompts/profiles/, or replaces the playbook with its own .claude/peer-planning/review.md. A project without a /polish command skips that step. The monitor's test panel is fed by a separate peer_planning_pytest module loaded through PYTHONPATH, which this repo does not ship; without it the panel stays empty.

output-styles

Component Trigger Description
output style /config → Output style → Direct Peer-to-peer tone, plain English, choice-first, diagrams-first

Ships direct.md as a Claude Code output style — a system-prompt modification, not a skill, so there's nothing to invoke. Install the plugin, then pick Direct under /config → Output style (or set "outputStyle": "Direct" in a settings file). It takes effect on the next /clear or session, since the system prompt is read once at session start. keep-coding-instructions: true is set, so Claude's built-in software-engineering instructions stay in place and this layers on top.

force-for-plugin is deliberately not set: enabling the plugin offers the style, it doesn't impose it. If you want it applied automatically everywhere, add force-for-plugin: true to the frontmatter of your own copy — it overrides the user's outputStyle setting, which is why it isn't the shipped default.

Direct sets the working relationship first: Claude and I are both senior engineers, so it is told to hold its own opinion, disagree openly, challenge a wrong premise, and never soften a real problem — the point is to stop the model from treating me as an authority it can't argue with. On top of that: plain English and short replies, concrete A:/B: choices instead of guessing intent or pre-deciding, and a lead-with-a-diagram rule for anything structural (ASCII in chat, Mermaid in files and Artifacts, since chat clients don't render Mermaid).

An AI tells section bans the wording tics of model-generated prose — AI vocabulary ("delve", "pivotal", "leverage"), "not just X, but Y", forced groups of three, synonym cycling, hedge stacks, filler, inline-header bullets that restate their own line, abstract metaphor nouns, and feeling-words where the mechanism should be. Cherry-picked from Cursor's unslop skill; the "add soul" half and the blanket em-dash ban were deliberately left behind.

A Scope section bounds all of it: these rules shape text written for me to read, and nothing else. Subagent prompts, plans, ADRs, commit messages, and anything under docs/ keep full detail — exact errors, file:line, provenance, stated uncertainty. Brevity applied to text another agent consumes is information loss that never reaches a human to be noticed. Same axis as the diagram rule: the destination decides, not the topic.

Editing it. Unlike a SKILL.md, an output style is part of the system prompt: edits need /reload-plugins (or a restart) and a /clear before they show up. To iterate on a fork of it without installing, run claude --plugin-dir plugins/output-styles.

Development

This repo is markdown apart from the two language-server launcher scripts and huddle's launcher and page runtime. GitHub Actions checks frontmatter, shellcheck, and the manifests on every push and PR (see .github/workflows/ci.yml); its shell-test step runs whatever matches tests/test-*.sh, so a test only needs a file dropped in tests/. The one there now, tests/test-huddle.sh, covers huddle.

Behavior that only shows up when a model reads a skill is covered by eval cases instead, in the native claude plugin eval format under a plugin's own evals/ directory (plugins/decide/evals/ and plugins/huddle/evals/ so far):

claude plugin eval decide@silver-cc-tools        # + no-plugin baseline arm
claude plugin eval ./plugins/decide --ablation with-without

These are not in CI — they cost money and need a live agent. Targeting a plugin by name adds the baseline arm automatically; a path target needs --ablation with-without, and without a baseline a score says nothing about whether the skill changed anything.

License

MIT — see LICENSE.

About

claude code workflow tools

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages