A personal fork of obra/superpowers. It loads as agent behavior across seven AI coding harnesses, and it captures the rationale behind each decision so the next session can read it back.
Note
Personal fork, maintained for my own use. Upstream is obra/superpowers: the canonical project, its marketplace, and its community live there.
Important
Not accepting contributions. Issues and pull requests on this repository will not be reviewed.
An agent makes a hundred small decisions while it builds something. Three weeks later, nobody remembers why. Snowball records those decisions as they happen and feeds them back to the next session, so the reasoning behind the code is still there when you need it.
Upstream superpowers gives a coding agent a development methodology: brainstorm before coding, plan before editing, verify before claiming done. Snowball keeps all of that and adds a second layer. A passive decision trail records what was decided and why. The result is a skills library with a memory.
Snowball is two interlocking processes.
The forward spine is a chain of gates that carries work from idea to merged code. Each gate refuses to advance until its precondition is met, so the agent cannot run ahead of its own justification.
The decision spine runs underneath, passively. Hooks watch the events the skills already emit and record each decision, with no skill modified and nobody having to remember to log. At completion the records are committed onto the same branch as the code, distilled into a local project ADR at .snowball/adr.md, and recalled at cycle start via a session-start excerpt and recalling-project-context.
flowchart TD
subgraph FWD["Forward spine: idea to merged"]
A["using-snowball<br/>skill check first"] --> B["brainstorming<br/>design gate"]
B --> C["writing-plans"]
C --> D["using-git-worktrees"]
D --> E["execute + TDD<br/>+ systematic-debugging"]
E --> F["verification-before-completion"]
F --> G["code review"]
G --> H["finishing-a-development-branch"]
end
subgraph DEC["Decision spine: passive capture"]
H1["hooks capture<br/>MADRs + observations"] --> H2["commit onto the branch"]
H2 --> H3["distill into .snowball/adr.md"]
H3 --> H4["recall via recalling-project-context"]
end
B -.->|emits decisions| H1
G -.->|emits decisions| H1
H -->|"commit records, then offer ADR sync"| H2
H4 -.->|cycle start| A
The full write-up of the two spines lives in docs/design/snowball-process.md.
Snowball captured the decision trail behind its own development. You can read the evidence instead of taking the claim on faith:
docs/snowball/decisions/: operator decisions as MADR markdown, plusobservations.jsonlfor lower-confidence agent observations. EveryAskUserQuestionanswer and approval phrase in a snowball session lands here.docs/design/snowball-process.md: the two-spine model written out, with the diagram above.docs/design/snowball-process-steelman.argdown: a steelman of the process as an argdown graph, checked with the Dung grounded-extension tool. Six arguments survive, five objections are defeated, zero remain undecided.
The decision trail behind Snowball was captured by Snowball.
The fork is at v5.4.0. It began as a near-mirror of superpowers v5.1.0 and has since diverged along one axis: decision intelligence. These additions are fork-original and are not in upstream.
| Version | Fork-original addition |
|---|---|
| v5.2.0 | structured-argumentation: argdown as an intermediate representation, with a bundled parser-validator |
| v5.3.0 | M2 brain-jam companion: an optional second-model (MiniMax) brainstorming partner |
| v5.4.0 | decision-logging (hook-driven capture) and syncing-decisions-to-memory (ADR distillation) |
| v6.1.0 | recalling-project-context — cycle-start recall loop (tier-0 hook + tier-1 skill, staleness in prepare, sync disk cache); completion-flow decision trail in finishing-a-development-branch |
| v6.2.0 | chorus companion: brainstorming delegates to chorus:chorus for multi-model debate (replacing M2 brain-jam) |
| v6.3.0 | Junie (JetBrains IDE plugin) support: forward spine via skills + AGENTS.md; decision spine via snowball-capture MCP server (partial — Junie has no hook rail). Junie CLI discoverability: .junie-extension/marketplace.json lets Junie CLI users /extensions marketplace add https://github.com/kellenff/snowball and install via /extensions install snowball. Runtime path resolution: run.cjs wrapper around snowball-capture resolves the server's path at start time, replacing the <absolute-path-to-snowball> placeholder; install-path-fix.cjs is an optional cross-platform rewriter for adapters that don't resolve relative paths. |
| v6.6.0 | VTCode harness adapter: forward spine via .vtcode/AGENTS.md bootstrap mirror + skills/using-snowball/references/vtcode-tools.md tool mapping; skills are symlinked into VTCode's .agents/skills/ discovery path. Decision spine via .vtcode/hooks.toml (UserPromptSubmit, PostToolUse on request_user_input, SessionStart, Stop, PreCompact) — same hook rail Claude Code, Cursor, and OpenCode use. |
Everything else tracks upstream closely. Skill content, the bootstrap design, and the multi-harness adapter pattern all originate there.
- A markdown skills library that loads as agent behavior via session-start context injection.
- A multi-harness plugin: one
skills/directory, six per-harness manifests, one shared bootstrap script that adapts its output to each harness. - Zero
npm installfor consumers. Skills are plain markdown and the bootstrap is one bash file. Five skills ship local Node scripts with their dependencies pre-bundled into the committed.cjsfiles:brainstorming(a stdlib-only visual-companion server),decision-logging(hook bridges),structured-argumentation(an argdown validator),syncing-decisions-to-memory(ADR prepare and render), andrecalling-project-context(recall prepare and session-start excerpt). Node runs those five;npm installis still not required.
- Not an MCP server, not a runtime tool, not a library you import.
- Not on any plugin marketplace for Claude Code, Cursor, OpenCode, Codex, Gemini CLI, GitLab Duo, Aider, and VTCode. Pi users install via
pi install git:github.com/kellenff/snowball— a pi package, not a Claude-Code-style marketplace. - Not accepting issues, PRs, or feature requests.
These are real artifacts that have not been reconciled with the fork's posture. They are tracked here so a future debug session does not waste time:
- Install instructions inherited from upstream do not work. The bulk rename pointed old documentation text at
kellenff/snowball-marketplace, which does not exist. The Setup section below is the real install path. scripts/sync-to-codex-plugin.shtargets the wrong destination. ItsFORK=constant still points at upstream's Codex distribution repo, so the script will fail or push to a repo I do not own. Codex support stays; only the sync path is broken.CLAUDE.mdis absent. This fork has no Claude-Code-specific context file yet.AGENTS.mdcovers the other harnesses and is freshly written for the fork; a Claude-Code file may follow..github/ISSUE_TEMPLATE/carries upstream's open-issues assumption, which does not fit a fork that takes no issues.
18 skills in five groups. Each links to its SKILL.md.
using-snowball: the entry-point skill, injected into every session by the bootstrap hook. It sets the "check skills before responding" discipline and the instruction priority (user > project skills > snowball skills > default system prompt).
brainstorming: gated design exploration that refuses implementation until a design is presented and approved. Ships a visual companion server for diagram-driven review.writing-plans: produces an implementation plan before code is written.executing-plans: runs an existing plan with review checkpoints.test-driven-development: red/green/refactor enforcement.systematic-debugging: root-cause-first debugging.verification-before-completion: run the verification commands and show the output before claiming success.finishing-a-development-branch: structured merge, PR, or cleanup at the end of work; commits the decision trail on preserve paths.
requesting-code-review: produces review-ready output.receiving-code-review: responds to feedback with technical rigor, not performative agreement.subagent-driven-development: orchestrates implementation across subagents.dispatching-parallel-agents: splits independent tasks across parallel agents.
decision-logging: reference documentation for the hook-driven capture system. Four Claude Code hooks emit operator MADRs and agent observations; the agent does not invoke this skill, the hooks do the work.syncing-decisions-to-memory: distills the decision logs into the local project ADR at.snowball/adr.md. It owns the TRADEOFFS and PHILOSOPHY sections and is idempotent.recalling-project-context: cycle-start recall — tier-0 session hook excerpt plus tier-1 active gate before non-trivial work (disk ADR, scoped MADRs, staleness, optional yactt graph). Closes the capture → commit → distill → recall loop.structured-argumentation: argdown as an intermediate representation for the structure of an argument (option comparison, hypothesis elimination, claim decomposition). Ships a parser-only validator bundled from@argdown/core.
using-git-worktrees: sets up an isolated workspace for feature work.writing-skills: the meta-skill for creating and adversarially testing new skills.
Capture is passive. No skill is modified, and the operator never has to remember to log. The brainstorming, planning, and review skills generate the events; the hooks observe them.
| Hook | Trigger | Produces |
|---|---|---|
PostToolUse on AskUserQuestion |
Operator picks an option | One MADR per question-answer pair |
| UserPromptSubmit (pattern match) | Operator submits an approval phrase | One MADR, deduped against recent captures |
| Stop, detached worker | Session ends | Headless claude -p extracts observations from the transcript tail into observations.jsonl |
| PreCompact, detached worker | Auto-compaction is imminent | The same worker, run before the context window is summarized |
All hooks no-op silently outside a git repo. Stop and PreCompact coordinate through a per-session cursor and a non-blocking flock, so each transcript region is fed to claude -p exactly once. Even a long session abandoned after compacting still emits its pre-compaction observations.
Capture hooks are registered for Claude Code and Cursor. Claude uses AskUserQuestion; Cursor uses AskQuestion. Other harnesses run the forward spine without the decision trail.
At completion, finishing-a-development-branch commits the records under docs/snowball/decisions/ onto the same branch as the work, then offers to run syncing-decisions-to-memory to refresh .snowball/adr.md.
At the next session, the bootstrap hook injects a capped ADR excerpt from .snowball/adr.md when present (written by syncing-decisions-to-memory). For full recall and scoped decision logs at cycle start, invoke recalling-project-context before non-trivial design work — it falls back to on-disk MADRs when the ADR is absent.
| Harness | Manifest | Bootstrap loader | Context file |
|---|---|---|---|
| Claude Code | .claude-plugin/plugin.json |
hooks/hooks.json to hooks/run-hook.cmd session-start |
none yet (bootstrap injects via hook) |
| Cursor | .cursor-plugin/plugin.json |
hooks/hooks-cursor.json to the same script |
AGENTS.md |
| GitHub Copilot CLI | .claude-plugin/plugin.json (shared) |
same script; detects COPILOT_CLI=1 and emits SDK-standard JSON |
AGENTS.md |
| OpenCode | .opencode/plugins/snowball.js |
JS plugin, experimental.chat.messages.transform hook |
AGENTS.md |
| Codex CLI / Codex App | .codex-plugin/plugin.json |
distributed via scripts/sync-to-codex-plugin.sh (currently stale) |
AGENTS.md |
| Gemini CLI | gemini-extension.json |
extension-managed; skills activate via activate_skill |
GEMINI.md |
| GitLab Duo | .gitlab/duo/hooks.json (CLI only) |
hooks.json to run-hook.cmd session-start; detects DUO_SESSION_ID |
AGENTS.md |
| Aider | .aider.conf.yml |
read entry in config |
AGENTS.md |
| Junie (JetBrains IDE + CLI) | extensions/snowball/extension.json + .junie-extension/marketplace.json (CLI only) |
bundled snowball-capture MCP server + .junie/AGENTS.md for context; CLI users register the repo as a custom Junie marketplace |
AGENTS.md |
| VTCode | .vtcode/AGENTS.md (bootstrap mirror) |
project guidelines via AGENTS.md; skills symlinked into .agents/skills/; unified_search auto-approved via prefix cache; apply_patch observation+blast-radius hooks |
AGENTS.md |
| Pi | root package.json (pi key) |
extensions/pi/snowball.ts (resources_discover, before_agent_start, input, session_shutdown, session_compact) |
skills/using-snowball/references/pi-tools.md |
The whole plugin hinges on skills/using-snowball/SKILL.md being injected into the agent's context at session start, not just present on disk. Without injection, the agent never invokes the Skill tool and the rest of the library is dead weight.
For shell-driven harnesses, hooks/session-start reads using-snowball/SKILL.md, JSON-escapes it with bash parameter substitution (no jq dependency), wraps it in <EXTREMELY_IMPORTANT> framing, and branches on environment variables:
CURSOR_PLUGIN_ROOTset:additional_context(snake_case).CLAUDE_PLUGIN_ROOTset withoutCOPILOT_CLI:hookSpecificOutput.additionalContext.DUO_SESSION_IDset:hookSpecificOutput.additionalContext(GitLab Duo CLI, same shape as Claude Code).- Otherwise:
additionalContext(Copilot CLI and SDK standard).
hooks/run-hook.cmd is a polyglot file. Line 1 (: << 'CMDBLOCK') is a no-op heredoc in bash, which lets Windows batch syntax live in the same file. On Windows, cmd.exe ignores the bash framing and locates bash.exe; on Unix, bash skips the batch block and execs the named script.
OpenCode cannot shell out reliably, so .opencode/plugins/snowball.js does the same job in JS: it reads the SKILL.md, strips frontmatter inline, caches the result, and injects the bootstrap as the first text part of the first user message. A guard prevents double-injection when OpenCode re-runs the transform per agent step.
This repo installs by clone-and-link, not marketplace distribution.
If you'd rather skip the clone step, the bootstrap installer can be piped straight from the repo's raw branch:
curl -fsSL https://raw.githubusercontent.com/kellenff/snowball/main/scripts/install.sh | bash -s -- vtcode --target /path/to/your/projectRead it first if you're cautious about piping curl to bash:
curl -fsSL https://raw.githubusercontent.com/kellenff/snowball/main/scripts/install.sh | lessPass arguments after --:
# Pick a provider and a target project in one shot
curl -fsSL https://raw.githubusercontent.com/kellenff/snowball/main/scripts/install.sh \
| bash -s -- --provider vtcode --target /path/to/your/project
# Pull the latest Snowball and refresh a project
curl -fsSL https://raw.githubusercontent.com/kellenff/snowball/main/scripts/install.sh \
| bash -s -- --provider vtcode --target /path/to/your/project --update--provider accepts any of the names listed at the top of scripts/install.sh --help (claude-code, vtcode, duo, aider, opencode, cursor, codex, gemini, copilot, junie, junie-cli). The default provider when piped from curl is vtcode, since it's the only one whose install is fully shell-scriptable end-to-end; the others print the exact commands and stop.
git clone https://github.com/kellenff/snowball.git ~/Projects/snowballThen install into each harness:
- Claude Code: register the repo as a local marketplace with
/plugin marketplace add /path/to/snowball, install with/plugin install snowball@snowball-dev(the marketplace name is set in.claude-plugin/marketplace.json), then run/reload-plugins. The hook inhooks/hooks.jsonfires at everySessionStart,/clear, and/compact. - OpenCode: see
docs/README.opencode.md. The plugin auto-registers its skills path; no manual symlink is needed. - Cursor, Codex, Gemini CLI, Copilot CLI: follow each harness's plugin documentation, pointing at this repo's matching manifest.
- GitLab Duo: see
docs/README.gitlab-duo.md. Short version: from inside a target project, runscripts/install-into-project.shfrom this clone. It writes per-skill files underskills/<name>/, symlinksAGENTS.md, and generates.gitlab/duo/hooks.jsonwith the absolute Snowball path patched in. Duo CLI users launch with--enable-project-hooksso the SessionStart hook fires. - Aider: from inside a target project, run
scripts/install-into-project.shfrom this clone. It copies skills intoskills/and ensures.aider.conf.ymlincludesread: [AGENTS.md]. - Junie (JetBrains IDE plugin): in the IDE, install the local extension pointing at
extensions/snowball/in this clone. Themcp/mcp.jsonpoints at../snowball-capture/run.cjswhich resolves the server's path at start time, so no manual edit is needed forsnowball-capture. Theargdownentry is an external user-installed MCP server and still needs its<absolute-path-to-*>placeholder replaced with a real absolute path. Configure yactt separately as Streamable HTTP MCP for blast-radius graph intel. Restart the IDE so Junie picks up the wiring. The.junie/AGENTS.mdis read automatically as project guidelines. - Junie CLI: in any project, in a Junie CLI session, run
/extensions marketplace add https://github.com/kellenff/snowballand then/extensions install snowball. The extension content is cached under~/.junie/extensions/; no project files are modified. After install, thesnowball-captureandargdownMCP servers should appear asActivein/mcp. Configure yactt separately for graph tools. The bundledmcp/mcp.jsonuses a relative path torun.cjswhich resolves the server's path at start time; for adapters that don't resolve relative paths, runnode extensions/snowball/scripts/install-path-fix.cjsonce after install. - VTCode: run
bash scripts/install.sh vtcode --target <your-project>from inside the Snowball clone (the curl-pipe form is in the Quick install block above). The install script symlinks the skills into~/.agents/skills/, links the bootstrap mirror as<your-project>/AGENTS.md, and writes bothhooks.tomlandcron-madr-digest.jsoninto<your-project>/.vtcode/with the absolute path to your Snowball clone already substituted — no manual edit required. Re-run with--forceto refresh after a pull. Manual fallback if you can't run the script: clone the repo to~/Projects/snowball, symlink each skill into~/.agents/skills/, symlink.vtcode/AGENTS.mdas<your-project>/AGENTS.md, thencpboth.vtcode/hooks.tomlandscripts/cron-madr-digest.jsoninto<your-project>/.vtcode/andsed 's|/absolute/path/to/snowball|~/Projects/snowball|g'each — but the install script is the supported path. Verify withvtcode skills list(all 18 skills should appear) and by answering arequest_user_inputprompt — a MADR should appear underdocs/snowball/decisions/. The committed.vtcode/tool-policy.jsonis a user-environment artifact, not a Snowball-managed file. - Pi: from inside any project, run
pi install git:github.com/kellenff/snowball. Pi clones the repo into~/.pi/agent/git/snowball/and auto-discovers the extension + skills. Verify withpi list. Detailed instructions:docs/README.pi.md. - Windows: see
docs/windows/. The polyglothooks/run-hook.cmdhandles Windows as long as bash is reachable (Git for Windows, MSYS2, Cygwin, or PATH).
Update after a pull:
cd ~/Projects/snowball
git pull
# In Claude Code: /reload-pluginsVersion bumps across the six manifests are driven by scripts/bump-version.sh reading .version-bump.json.
Snowball uses pre-commit hooks for formatting, linting, and the decision-logging build. Consumers do not need any of this; the shipped .cjs bundles already inline their dependencies.
# Required tools (one-time)
brew install pre-commit shellcheck shfmt markdownlint-cli2 oxlint oxfmt bun
# Local devDeps (typescript, @types, js-yaml, @argdown/core for the bun build)
npm install
# Test deps for decision-logging
(cd tests/decision-logging && npm install)
# Activate hooks, then verify the toolchain
pre-commit install
pre-commit run --all-filesThe bundles under skills/*/scripts/*.cjs are built outputs. Edit the TypeScript in skills/*/src/, and the pre-commit hook regenerates and stages the bundles. Bun (bun build --target=node --format=cjs) is a maintainer dependency only.
| Path | What lives here |
|---|---|
skills/ |
The 20 skills (see the Skills index). Each is a directory with a SKILL.md plus optional references/, scripts/, and src/. |
hooks/ |
session-start (the bash bootstrap), run-hook.cmd (polyglot bash/batch wrapper), hooks.json (Claude Code registration), hooks-cursor.json (Cursor registration). |
.claude-plugin/ |
Claude Code plugin manifest plus the dev marketplace manifest. |
.codex-plugin/, .cursor-plugin/, .opencode/, gemini-extension.json, .gitlab/duo/ |
Per-harness manifests and plugins. |
docs/design/ |
The two-spine process write-up and its argdown rationale and steelman maps. |
docs/snowball/decisions/ |
Captured decision trail: MADR markdown plus observations.jsonl. |
docs/snowball/specs/, docs/snowball/plans/ |
Design specs and implementation plans. |
docs/ |
Setup notes (README.opencode.md, README.gitlab-duo.md, windows/) and testing notes (testing.md). |
tests/ |
11 test groupings: per-harness bootstrap tests, Codex-sync verification, skill-triggering evals, decision-logging and decision-sync tests, SDD end-to-end runs. |
scripts/ |
bump-version.sh, install-into-project.sh, and sync-to-codex-plugin.sh (currently stale). |
AGENTS.md, GEMINI.md |
Per-harness context files. No CLAUDE.md in this fork yet. |
RELEASE-NOTES.md |
Snowball's own release history from v5.2.0 onward. |
docs/design/snowball-process.md: the two-spine methodology.docs/testing.md: what eachtests/grouping covers and how to run it.docs/README.opencode.md,docs/README.gitlab-duo.md,docs/windows/: harness-specific setup.AGENTS.md,GEMINI.md: per-harness context files..claude/grfp/: the staging reports (deep-dive, crystal-ball, brain-jam, think-tank) behind this README.
MIT, inherited from upstream. See LICENSE.
Snowball is a fork of obra/superpowers by Jesse Vincent and the team at Prime Radiant. All skill content, the bootstrap design, and the multi-harness adapter pattern originate there. This fork exists for personal maintenance; substantive credit belongs upstream.