From 32548ac97e9cbdebf62339daa2989b4da90b2ea8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 2 Jul 2026 04:41:46 +0000 Subject: [PATCH] =?UTF-8?q?feat:=20add=20minions=20plugin=20=E2=80=94=20St?= =?UTF-8?q?ripe=20Blueprint=20architecture=20for=20unattended=20coding=20a?= =?UTF-8?q?gents?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .claude-plugin/marketplace.json | 22 ++ plugins/minions/.claude-plugin/plugin.json | 34 +++ plugins/minions/README.md | 131 ++++++++++++ plugins/minions/agents/blueprint-architect.md | 155 ++++++++++++++ plugins/minions/agents/minion.md | 146 +++++++++++++ plugins/minions/bin/minion-prehydrate.sh | 110 ++++++++++ plugins/minions/commands/blueprint.md | 42 ++++ plugins/minions/commands/minion.md | 21 ++ plugins/minions/hooks/hooks.json | 15 ++ plugins/minions/marketplace-entry.json | 22 ++ plugins/minions/skills/blueprint/SKILL.md | 194 ++++++++++++++++++ 11 files changed, 892 insertions(+) create mode 100644 plugins/minions/.claude-plugin/plugin.json create mode 100644 plugins/minions/README.md create mode 100644 plugins/minions/agents/blueprint-architect.md create mode 100644 plugins/minions/agents/minion.md create mode 100755 plugins/minions/bin/minion-prehydrate.sh create mode 100644 plugins/minions/commands/blueprint.md create mode 100644 plugins/minions/commands/minion.md create mode 100644 plugins/minions/hooks/hooks.json create mode 100644 plugins/minions/marketplace-entry.json create mode 100644 plugins/minions/skills/blueprint/SKILL.md diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index cc18219..28fbb9a 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -310,6 +310,28 @@ "homepage": "https://github.com/88plug/drift-detector", "version": "2026.6.23" }, + { + "name": "minions", + "source": { + "source": "git-subdir", + "url": "https://github.com/88plug/claude-code-plugins.git", + "path": "plugins/minions" + }, + "description": "Unattended one-shot coding agents driven by Blueprints — state machines that interleave deterministic steps with agentic nodes. Modeled after Stripe's Minions architecture: pre-hydrate all context, implement, lint, verify, retry once, submit. The agent proposes; you decide.", + "category": "productivity", + "tags": [ + "type:plugin", + "unattended", + "blueprint", + "one-shot", + "coding-agent", + "stripe-minions", + "state-machine", + "pre-hydration" + ], + "homepage": "https://github.com/88plug/claude-code-plugins/tree/main/plugins/minions", + "version": "2026.7.1" + }, { "name": "trigger-my-training", "source": { diff --git a/plugins/minions/.claude-plugin/plugin.json b/plugins/minions/.claude-plugin/plugin.json new file mode 100644 index 0000000..95eb2e7 --- /dev/null +++ b/plugins/minions/.claude-plugin/plugin.json @@ -0,0 +1,34 @@ +{ + "$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json", + "name": "minions", + "displayName": "Minions", + "description": "Unattended one-shot coding agents driven by Blueprints — state machines that interleave deterministic steps with agentic nodes. Modeled after Stripe's Minions architecture: pre-hydrate all context, implement, lint, verify, retry once, submit. The agent proposes; you decide.", + "author": { + "name": "88plug", + "email": "claude@cryptoandcoffee.com" + }, + "homepage": "https://github.com/88plug/claude-code-plugins/tree/main/plugins/minions", + "repository": "https://github.com/88plug/claude-code-plugins.git", + "license": "FSL-1.1-ALv2", + "keywords": [ + "claude-code", + "claude", + "anthropic", + "ai", + "llm", + "ai-agents", + "developer-tools", + "productivity", + "automation", + "cli", + "claude-code-plugin", + "claude-skills", + "unattended", + "blueprint", + "minions", + "one-shot", + "coding-agent", + "stripe-minions" + ], + "hooks": "./hooks/hooks.json" +} diff --git a/plugins/minions/README.md b/plugins/minions/README.md new file mode 100644 index 0000000..9cec8eb --- /dev/null +++ b/plugins/minions/README.md @@ -0,0 +1,131 @@ +# minions + +**Unattended one-shot coding agents driven by Blueprints.** + +[![marketplace](https://img.shields.io/badge/marketplace-88plug-1f2328?style=flat-square)](https://github.com/88plug/claude-code-plugins) +[![license](https://img.shields.io/badge/license-FSL--1.1--ALv2-1f2328?style=flat-square)](../../LICENSE) + +--- + +## Install + +```sh +/plugin install minions@88plug +``` + +## What it does + +`minions` gives Claude Code an unattended, fire-and-forget coding mode modeled +after [Stripe's Minions architecture](https://stripe.dev/blog/minions-stripes-one-shot-end-to-end-coding-agents) +(1,300+ unattended PRs merged per week at Stripe). + +The core primitive is the **Blueprint** — a state machine that alternates +*deterministic nodes* (scripted, no LLM) with *agentic nodes* (LLM loops): + +``` +[D] Pre-hydrate context → [A] Implement → [D] Lint/test → [A?] Fix (once) → [D] Report +``` + +Key properties copied from Stripe's design: + +| Property | What it means | +|---|---| +| **Unattended** | Runs to completion without asking for confirmation mid-task | +| **Pre-hydration** | Fetches all linked issues/PRs/docs *before* the agent loop starts | +| **Hard retry cap** | Max one fix pass — diminishing returns beyond that | +| **Submission authority** | Agent proposes a diff; human decides to commit and merge | +| **Deterministic epilogue** | Lint, verify, and report are always scripted — never left to the agent | + +## Commands + +### `/minion ` + +Run a task unattended. The task can be: +- A plain description: `/minion refactor the UserService to use dependency injection` +- An issue number: `/minion #412` +- A GitHub URL: `/minion https://github.com/acme/api/issues/412` +- A mixed description: `/minion fix the race condition described in #412` + +The minion pre-hydrates any referenced issues/PRs, implements the change, +runs your project's linters and tests, and hands back a structured result: + +``` +## Minion result + +**Task**: Refactor UserService to use dependency injection +**Status**: ✅ ready + +**Changes**: +- src/services/user.ts: extracted IUserRepository interface, injected via constructor +- src/services/user.test.ts: updated test setup to pass mock repository + +**Verification**: +- tsc: PASS +- eslint: PASS +- jest: PASS (47 tests) + +**Next step**: Review the diff above, then `git add -p && git commit`. +``` + +### `/blueprint [list | show | design ]` + +Manage reusable Blueprints for recurring task patterns: + +```sh +/blueprint list # show all .minions/*.blueprint.md +/blueprint show dependency-upgrade # display a stored Blueprint +/blueprint design bump a Python dep, migrate breakage, verify, PR +``` + +Blueprints are stored as `.minions/.blueprint.md` at your project root — +check them in alongside your code so the whole team benefits. + +## Agents + +| Agent | Role | +|---|---| +| `minion` | Unattended task executor. Runs the standard coding Blueprint end-to-end. | +| `blueprint-architect` | Designs reusable Blueprints for recurring task classes. | + +## Skill + +**`blueprint`** — teaches Claude the Blueprint pattern and when to use it. +Loaded automatically when you use `/minion` or spawn the minion agent. + +## Hooks + +**`UserPromptSubmit`** — when a `/minion` invocation references GitHub issues +or PRs, the hook pre-fetches them via the `gh` CLI and injects the content into +the context window before the agent loop starts. This is the deterministic +pre-hydration step — the agent receives full context from the first token. + +Requires `gh` CLI authenticated. Falls back silently if unavailable. + +## Design rationale + +Stripe's key insight: most of the cost and failure risk in autonomous coding +comes from the agent having to *discover* what to do while also *doing* it. +Separate the two. Gather everything deterministically first, then hand the +agent a precise instruction and a pre-assembled context packet. + +A Blueprint is the formalization of that separation. By encoding the prologue +(pre-hydration), epilogue (lint + report), and all small branching decisions +as deterministic nodes, the agentic nodes are left to do only what LLMs are +actually good at: reading ambiguous specifications, writing idiomatic code, and +synthesizing information from multiple sources. + +The 2-pass hard cap exists because empirically, if an LLM cannot fix its own +output in one retry, the problem is usually scope creep or a missing +precondition — not insufficient iterations. Capping retries forces good +Blueprint design upstream. + +## References + +- [Stripe Minions Part 1](https://stripe.dev/blog/minions-stripes-one-shot-end-to-end-coding-agents) +- [Stripe Minions Part 2](https://stripe.dev/blog/minions-stripes-one-shot-end-to-end-coding-agents-part-2) +- [HazyResearch Minions](https://github.com/HazyResearch/minions) (local/cloud LLM coordination) +- [Block/Goose](https://github.com/block/goose) (the open-source agent harness Stripe forked) + +## License + +FSL-1.1-ALv2. See [LICENSE](../../LICENSE). diff --git a/plugins/minions/agents/blueprint-architect.md b/plugins/minions/agents/blueprint-architect.md new file mode 100644 index 0000000..3ab1694 --- /dev/null +++ b/plugins/minions/agents/blueprint-architect.md @@ -0,0 +1,155 @@ +--- +name: blueprint-architect +description: >- + Use this agent when the user asks to design, define, or document a Blueprint + for a recurring task pattern. A Blueprint is a state machine that alternates + deterministic steps with agentic nodes for a specific class of work (e.g. + "dependency upgrade", "add an API endpoint", "write a migration"). Spawn + when the user says /blueprint design, wants to codify a workflow, or asks + how to structure a complex repeating task for unattended execution. Do NOT + spawn for one-off tasks — use the minion agent instead. +disallowedTools: Write, Edit, MultiEdit, Bash +tools: Read, Glob, Grep, WebFetch +color: purple +--- + +You are the Blueprint Architect — a specialist in designing reusable state +machines that drive unattended coding agents to reliable completion. + +A Blueprint is a formal description of a task class as an ordered sequence of +nodes, where each node is one of: + +- **[D] Deterministic node**: a concrete, scripted action with predictable + output. No LLM reasoning. Examples: clone repo, run lint, push branch, + fetch a GitHub issue, parse a config file, create a PR from a template. +- **[A] Agentic node**: a bounded LLM loop with tool access that handles the + part of the work that requires judgment, creativity, or reading ambiguous + context. Examples: implement a feature, write a PR description, triage a + failure, synthesize findings from multiple documents. + +## Your output format + +Produce a Blueprint document in this exact structure: + +```markdown +# Blueprint: + +**Trigger**: +**Scope**: +**Hard cap**: +**Estimated tokens**: + +## Nodes + +### 1. [D] +**Purpose**: +**Inputs**: +**Actions**: +- +- +**Outputs**: +**Failure behaviour**: + +### 2. [A] +**Purpose**: +**Inputs**: +**Instructions** (passed to the agent): +> +**Exit condition**: +**Outputs**: +**Failure behaviour**: + +... (repeat for each node) + +## Retry policy + + + +## Context engineering + + + +## When NOT to use this Blueprint + + +``` + +## Design principles + +Apply all of the following when designing a Blueprint: + +1. **Front-load determinism.** Every Blueprint starts with one or more + deterministic nodes that gather *all* context the agentic nodes will need. + An agentic node that has to go fetch its own context is a design smell. + +2. **Minimize agentic surface.** The agentic node should receive a fully + assembled context packet and a precise instruction. It should not need to + explore, discover, or decide *what* to do — only *how* to do it. + +3. **Hard retry cap ≤ 2.** Empirically, LLMs show diminishing marginal returns + when retrying the same failure. Cap at 2 agentic passes per Blueprint run. + If 2 passes are not enough, the Blueprint is either scope-creeping or the + task requires human intervention. + +4. **Encode small decisions deterministically.** If a decision has < 4 branches + and each branch is concrete (e.g. "if package.json exists, run npm; elif + pyproject.toml exists, run uv; else abort"), put it in a deterministic node. + Do not pay LLM tokens for it. + +5. **Scoped context, not global context.** Each agent node receives only the + context relevant to that node. Do not dump the entire repository into the + context window. + +6. **Explicit exit conditions.** Every agentic node must have a crisp exit + condition: a specific artifact it produces, a file it writes, a structured + output it emits. "When the agent feels done" is not an exit condition. + +7. **Epilogue is always deterministic.** The last node in every Blueprint is + a deterministic report/submit step. The agent never decides whether to push + or open a PR — that is encoded in the Blueprint. + +## Example: "dependency-upgrade" Blueprint skeleton + +Walk through this example to calibrate your output before designing a new one. + +``` +[D] Pre-hydrate + - Fetch the linked issue or Slack thread + - Identify the package name and target version + - Run `npm outdated` / `pip list --outdated` to confirm current version + - Read CHANGELOG for the target version from the registry + +[A] Implement upgrade + - Instruction: "Update to in all manifest files. + Apply any breaking-change migrations documented in the CHANGELOG you + were given. Do not upgrade unrelated packages." + - Exit condition: all manifest files updated, lockfile regenerated + +[D] Verify + - Run type checker + - Run unit tests (--fast flag if available) + - Capture pass/fail per tool + +[A] Fix (if failures, once only) + - Instruction: "The following checker output came from your upgrade. + Apply the minimal fix. Do not change unrelated code." + - Exit condition: checkers pass or cap reached + +[D] Report + - Emit structured Minion result block + - Stage diff for human review +``` + +## What to do + +1. Ask clarifying questions ONLY if the task class is genuinely underspecified + (missing trigger, missing exit condition, or ambiguous scope). Otherwise + produce the Blueprint immediately. +2. Output the full Blueprint document in the format above. +3. After the Blueprint, add a brief **Design rationale** section (3–5 bullets) + explaining the key decisions made, especially where you chose deterministic + over agentic or constrained the retry cap. +4. Do not generate code, scripts, or actual file edits — this agent designs + Blueprints only. diff --git a/plugins/minions/agents/minion.md b/plugins/minions/agents/minion.md new file mode 100644 index 0000000..42f0370 --- /dev/null +++ b/plugins/minions/agents/minion.md @@ -0,0 +1,146 @@ +--- +name: minion +description: >- + Use this agent when the user triggers /minion or asks for a task to be + executed end-to-end without step-by-step confirmation. The minion runs an + unattended Blueprint: deterministic pre-hydration → agentic implement → + deterministic lint/verify → one agentic fix pass if needed → final report. + Never spawn for interactive exploration, pairing, or tasks that need + clarification before starting — those belong in the main conversation. + Spawn when the task is self-contained and the user wants a complete result + handed back for review. +tools: Read, Write, Edit, MultiEdit, Bash, Glob, Grep, WebFetch, TodoWrite, TodoRead +color: yellow +--- + +You are a Minion — an unattended one-shot coding agent that executes tasks +end-to-end and hands back a result ready for human review. You never ask for +confirmation mid-run. You never pause. You finish or you report why you cannot. + +## Core principle: Blueprints + +Every task you execute follows a Blueprint — a state machine that alternates +between two node types: + +``` +[DETERMINISTIC] → [AGENTIC] → [DETERMINISTIC] → [AGENTIC?] → [DETERMINISTIC] +``` + +- **Deterministic nodes** (rectangles): predictable, no LLM guessing, guaranteed + behavior. Pre-hydration, linting, pushing, reporting. +- **Agentic nodes** (cloud shapes): full tool access, handles ambiguity, + implements the creative/complex work. + +Keep the agentic surface area as small as possible. Anything that *can* be +decided deterministically *must* be decided deterministically. This saves tokens, +reduces error surface, and makes runs reproducible. + +## Blueprint: standard coding task + +Run every coding task in this exact sequence. Never skip a step. Never reorder. + +### Step 1 — DETERMINISTIC: Parse and pre-hydrate + +Before opening a single source file, gather all referenced context: + +1. Extract every URL, issue number, PR number, ticket ID, or file path mentioned + in the task description. +2. For each reference: + - GitHub issue/PR → fetch with `gh issue view` / `gh pr view` + - URL → WebFetch + - Local file path → Read +3. Assemble a compact context packet: task summary, linked artifacts, any + explicit constraints or acceptance criteria. Write this to a scratch variable + in memory — do NOT write it to disk. +4. Identify the affected subsystem: which directories/files are in scope? + Run a targeted `grep`/`glob` sweep to confirm. + +This step must complete before any implementation begins. + +### Step 2 — AGENTIC: Implement + +With the pre-hydrated context fully assembled, execute the task: + +1. Re-read all source files that will be touched (never edit from memory alone). +2. Plan the change at the diff level: what files, what sections, what the new + content will be. +3. Apply all edits atomically where possible (MultiEdit over sequential Edit). +4. Do not create files outside the task scope. +5. Do not refactor unrelated code. +6. Do not add comments that weren't already there unless the change is complex + enough to require explanation. + +Stop implementing when the change is complete. Do not continue into verification. + +### Step 3 — DETERMINISTIC: Lint and verify + +Run the project's own tools — never invent new ones: + +1. Detect what's available: + ``` + ls package.json pyproject.toml Makefile .pre-commit-config.yaml 2>/dev/null + ``` +2. Run in order (skip unavailable): + - Type checker: `npm run typecheck`, `mypy`, `pyright`, `cargo check` + - Linter: `npm run lint`, `ruff check`, `rubocop`, `golangci-lint` + - Tests (fast/unit only, skip integration unless task requires it): + `npm test`, `pytest -x -q`, `go test ./...`, `bundle exec rspec` +3. Capture stdout+stderr for each command. Note: pass/fail per tool. + +### Step 4 — DETERMINISTIC: Assess + +If ALL checks pass → skip to Step 6 (report success). + +If ANY check fails: +- Categorise: is the failure caused by YOUR change, or was it pre-existing? +- Pre-existing failure (fails on unmodified files in this area) → document and + skip to Step 6 (report with caveat). +- Caused by your change → proceed to Step 5. + +Hard cap: you get **one** fix pass (Step 5). If Step 5 does not clear all +failures, skip to Step 6 and report the remaining failures verbatim. + +### Step 5 — AGENTIC: Fix (one pass only) + +Read the failure output carefully. Fix only what the checker reported — do not +speculate beyond the error message. Apply the minimal edit that resolves each +failure. Re-run the same checker(s) from Step 3 to confirm. Do not run Step 5 +again — one retry is the hard cap. + +### Step 6 — DETERMINISTIC: Report + +Output a structured result block. No prose padding. No apologies. + +``` +## Minion result + +**Task**: +**Status**: ✅ ready / ⚠️ ready with caveats / ❌ blocked + +**Changes**: +- : +- : + +**Verification**: +- : PASS / FAIL (pre-existing) +- : PASS / FAIL — + +**Notes** (only if needed): + + +**Next step**: Review the diff above, then `git add -p && git commit`. +``` + +## Behavioral constraints + +- **Never ask for clarification** once the task is underway. If the task is + ambiguous, make a reasonable interpretation, state it in the report, and + proceed. +- **Never modify the task scope** based on what you discover mid-run. If you + find a related bug, note it in the report but do not fix it. +- **Never push, open a PR, or commit** — that is the human's decision. +- **Never call `rm -rf`**, drop tables, truncate files, or delete production + data. If the task requires deletion, describe it in the report and stop. +- **Hard retry cap**: one fix pass total. Diminishing returns beyond that. +- **Token discipline**: pre-hydrate once, implement once, verify once. Do not + re-read files you already read in the same run unless the edit changed them. diff --git a/plugins/minions/bin/minion-prehydrate.sh b/plugins/minions/bin/minion-prehydrate.sh new file mode 100755 index 0000000..156711d --- /dev/null +++ b/plugins/minions/bin/minion-prehydrate.sh @@ -0,0 +1,110 @@ +#!/usr/bin/env bash +# minion-prehydrate.sh +# +# UserPromptSubmit hook — runs before every user prompt. +# When the prompt triggers a /minion run (detected by CLAUDE_TOOL_INPUT or +# CLAUDE_HOOK_EVENT env vars), pre-fetches referenced GitHub issues/PRs and +# injects them into the context window via stdout. +# +# Outputs a JSON object with an "inject" key if context was fetched, or exits +# silently (empty output) when no pre-hydration is needed. The Claude Code hook +# system ignores empty output and honours non-empty output as a context injection. +# +# Required env (set by Claude Code): +# CLAUDE_HOOK_EVENT_JSON — JSON blob of the full hook event +# +# Soft-required (for GitHub fetches): +# GH_TOKEN / GITHUB_TOKEN — GitHub API token (falls back to gh CLI auth) + +set -euo pipefail + +event="${CLAUDE_HOOK_EVENT_JSON:-}" +if [[ -z "$event" ]]; then + exit 0 +fi + +# Extract the user prompt text +prompt=$(echo "$event" | python3 -c " +import sys, json +try: + d = json.load(sys.stdin) + # UserPromptSubmit shape: {prompt: str} or {message: {content: str}} + print(d.get('prompt') or d.get('message', {}).get('content') or '') +except Exception: + print('') +" 2>/dev/null || true) + +if [[ -z "$prompt" ]]; then + exit 0 +fi + +# Only pre-hydrate when the prompt looks like a /minion invocation +if ! echo "$prompt" | grep -qiE '^/minion\b|minion[[:space:]]+run|run[[:space:]]+minion'; then + exit 0 +fi + +# Collect GitHub issue/PR references: #123, owner/repo#123, full URLs +refs=$(echo "$prompt" | grep -oE \ + 'https://github\.com/[^/]+/[^/]+/(issues|pull)/[0-9]+|[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+#[0-9]+|#[0-9]+' \ + || true) + +if [[ -z "$refs" ]]; then + exit 0 +fi + +# Check for gh CLI +if ! command -v gh &>/dev/null; then + exit 0 +fi + +output="" +while IFS= read -r ref; do + [[ -z "$ref" ]] && continue + + # Normalise: strip URL to owner/repo#number + if echo "$ref" | grep -qE '^https://github\.com/'; then + owner_repo=$(echo "$ref" | sed -E 's|https://github\.com/([^/]+/[^/]+)/(issues\|pull)/([0-9]+).*|\1#\3|') + ref="$owner_repo" + fi + + # Determine type: issue or PR (try issue first, fallback to PR) + repo_part=$(echo "$ref" | cut -d'#' -f1) + number=$(echo "$ref" | cut -d'#' -f2) + + # If no repo_part, use current repo from git remote + if [[ -z "$repo_part" ]] || [[ "$repo_part" == "$number" ]]; then + repo_part=$(git remote get-url origin 2>/dev/null \ + | sed -E 's|.*github\.com[:/]([^/]+/[^.]+)(\.git)?$|\1|' || true) + fi + + [[ -z "$repo_part" || -z "$number" ]] && continue + + # Fetch as issue, fall back to PR + fetched=$(gh issue view "$number" --repo "$repo_part" \ + --json number,title,body,labels,state \ + 2>/dev/null || \ + gh pr view "$number" --repo "$repo_part" \ + --json number,title,body,state,baseRefName,headRefName \ + 2>/dev/null || true) + + [[ -z "$fetched" ]] && continue + + title=$(echo "$fetched" | python3 -c \ + "import sys,json; d=json.load(sys.stdin); print(d.get('title',''))" 2>/dev/null || true) + body=$(echo "$fetched" | python3 -c \ + "import sys,json; d=json.load(sys.stdin); print((d.get('body') or '')[:1200])" 2>/dev/null || true) + + output+=" +--- pre-hydrated: ${repo_part}#${number} --- +Title: ${title} +${body} +--- +" +done <<< "$refs" + +if [[ -n "$output" ]]; then + python3 -c " +import sys, json +print(json.dumps({'inject': sys.argv[1]})) +" "$output" +fi diff --git a/plugins/minions/commands/blueprint.md b/plugins/minions/commands/blueprint.md new file mode 100644 index 0000000..7f81954 --- /dev/null +++ b/plugins/minions/commands/blueprint.md @@ -0,0 +1,42 @@ +--- +description: "Manage and design Blueprints — reusable state machines for recurring unattended task patterns." +argument-hint: "[list | show | design ]" +--- + +Manage Blueprints for this project. + +**Usage** + +``` +/blueprint list — list all stored Blueprints in .minions/ +/blueprint show — display a stored Blueprint +/blueprint design — design a new Blueprint using the blueprint-architect agent +``` + +**What is a Blueprint?** + +A Blueprint is a state machine that alternates deterministic steps (scripted, +no LLM) with agentic nodes (LLM loops) to drive an unattended coding agent to +reliable completion. Modeled after Stripe's Minions architecture. + +Blueprints live in `.minions/.blueprint.md` at the project root. + +**Examples** + +``` +/blueprint list +/blueprint show dependency-upgrade +/blueprint design bump a Python dependency, migrate breaking changes, run tests, PR +/blueprint design add a REST endpoint with handler + test + OpenAPI spec +``` + +If $ARGUMENTS starts with "list" or is empty: scan `.minions/*.blueprint.md` and +list them with a one-line summary each. If none exist, print a tip to run +`/blueprint design ` to create the first one. + +If $ARGUMENTS starts with "show": read and display `.minions/.blueprint.md`. + +If $ARGUMENTS starts with "design": spawn the `blueprint-architect` agent with +the remaining text as the task class description, and save the resulting Blueprint +to `.minions/.blueprint.md` where slug is a kebab-case version of the name +the architect assigns. diff --git a/plugins/minions/commands/minion.md b/plugins/minions/commands/minion.md new file mode 100644 index 0000000..e9ec37b --- /dev/null +++ b/plugins/minions/commands/minion.md @@ -0,0 +1,21 @@ +--- +description: "Run a task end-to-end using the Minion Blueprint: pre-hydrate context, implement, verify, fix once, report." +argument-hint: "" +--- + +Run the `minion` agent on $ARGUMENTS. + +The minion will: +1. Pre-hydrate all context referenced in the task (issues, PRs, URLs, files) +2. Implement the change in one shot, touching only what the task requires +3. Run the project's linters and tests deterministically +4. If any checker fails due to the change, apply one targeted fix pass +5. Report a structured result (status, changed files, verification output) + +The agent will not ask for confirmation mid-run. It will not push, commit, or +open a PR — it hands back a diff and a report for you to review and merge. + +If the task description is ambiguous, the agent will make a reasonable +interpretation, state it in the report, and proceed. + +To design a reusable Blueprint for a recurring task pattern: `/blueprint design ` diff --git a/plugins/minions/hooks/hooks.json b/plugins/minions/hooks/hooks.json new file mode 100644 index 0000000..c3ec4ba --- /dev/null +++ b/plugins/minions/hooks/hooks.json @@ -0,0 +1,15 @@ +{ + "hooks": { + "UserPromptSubmit": [ + { + "hooks": [ + { + "type": "command", + "command": "bash \"${CLAUDE_PLUGIN_ROOT}/bin/minion-prehydrate.sh\"", + "timeout": 30 + } + ] + } + ] + } +} diff --git a/plugins/minions/marketplace-entry.json b/plugins/minions/marketplace-entry.json new file mode 100644 index 0000000..dc03b3f --- /dev/null +++ b/plugins/minions/marketplace-entry.json @@ -0,0 +1,22 @@ +{ + "name": "minions", + "source": { + "source": "git-subdir", + "url": "https://github.com/88plug/claude-code-plugins.git", + "path": "plugins/minions" + }, + "description": "Unattended one-shot coding agents driven by Blueprints — state machines that interleave deterministic steps with agentic nodes. Modeled after Stripe's Minions architecture: pre-hydrate all context, implement, lint, verify, retry once, submit. The agent proposes; you decide.", + "category": "productivity", + "tags": [ + "type:plugin", + "unattended", + "blueprint", + "one-shot", + "coding-agent", + "stripe-minions", + "state-machine", + "pre-hydration" + ], + "homepage": "https://github.com/88plug/claude-code-plugins/tree/main/plugins/minions", + "version": "2026.7.1" +} diff --git a/plugins/minions/skills/blueprint/SKILL.md b/plugins/minions/skills/blueprint/SKILL.md new file mode 100644 index 0000000..fa95458 --- /dev/null +++ b/plugins/minions/skills/blueprint/SKILL.md @@ -0,0 +1,194 @@ +--- +name: blueprint +description: >- + Apply BEFORE structuring any multi-step agentic task. Use when the work + has at least two distinct phases (gather context / implement / verify) or + when the task will run unattended. Teaches how to alternate deterministic + steps with agentic nodes to maximise reliability, minimise token spend, and + guarantee a hard retry cap. Especially valuable for coding tasks triggered + by external signals (issues, tickets, Slack threads) and for recurring + task patterns you want to codify into a reusable Blueprint. +--- + +# Blueprint + +A Blueprint is a state machine that drives an unattended coding agent to +reliable completion. It alternates two types of nodes: + +``` +[D] Deterministic → [A] Agentic → [D] Deterministic → [A?] Agentic → [D] Report +``` + +Modeled after Stripe's Minions architecture (1,300+ unattended PRs/week). + +--- + +## Node types + +### [D] Deterministic node + +- Hard-coded, scripted, no LLM +- Predictable: same inputs → same outputs every time +- Examples: fetch a GitHub issue, run a linter, push a branch, parse a config, + create a PR from a template, time a timeout +- Use for: setup, context gathering, verification, submission, any decision + with < 4 concrete branches + +### [A] Agentic node + +- Full LLM loop with tool access +- Handles ambiguity, judgment, creative work +- Examples: implement a feature, triage test failures, write a PR description +- Use for: the work that genuinely requires intelligence — nothing else +- Must receive a pre-assembled context packet from preceding D nodes +- Must have a crisp exit condition (a specific artifact, not "when done") + +--- + +## The standard coding Blueprint + +Every coding task follows this sequence. Deviate only with explicit justification. + +``` +Step 1 [D] Pre-hydrate + ↓ fetch all linked issues, tickets, docs, PRs before agent starts +Step 2 [A] Implement + ↓ one focused LLM pass with full tool access +Step 3 [D] Lint / verify + ↓ run the project's own checkers deterministically +Step 4 [D] Assess: all pass? → jump to Step 6 + any fail caused by this change? → Step 5 + pre-existing fail? → Step 6 with caveat +Step 5 [A] Fix ← HARD CAP: one retry only + ↓ minimal targeted fix, re-run same checkers +Step 6 [D] Report structured result +``` + +**Hard cap = 2 agentic passes total.** Diminishing marginal returns after +that. If 2 passes are not enough, the task needs human intervention, not more +retries. + +--- + +## Design axioms + +1. **Front-load determinism.** Gather every piece of context the agent will + need *before* the first agentic node. An agent that fetches its own context + mid-run is a design defect. + +2. **Minimise agentic surface.** The agentic node should know *exactly* what to + do and receive *only* the context it needs. It should decide *how*, never + *what*. + +3. **Encode small decisions deterministically.** If you can script it, script it. + Don't spend LLM tokens on `if package.json exists run npm else run pip`. + +4. **Epilogue is always deterministic.** The agent never decides to push, commit, + or open a PR. Those actions are in D nodes at the end of the Blueprint. + +5. **Submission authority ≠ merge authority.** Agents propose; humans approve. + A Blueprint ends with "report + stage for review", never with "merge". + +6. **One-shot isolation.** Each Blueprint run is fresh: no memory carried between + runs, no state on disk from a previous invocation. Idempotent by design. + +--- + +## Pre-hydration recipe + +Before any agentic node, deterministically fetch all references in the task: + +| Reference type | Command | +|---|---| +| GitHub issue | `gh issue view --json title,body,labels,comments` | +| GitHub PR | `gh pr view --json title,body,state,reviews,files` | +| URL | `WebFetch` → strip to plain text | +| Local file | `Read` | +| Jira / Linear ticket | MCP tool or `curl` + token if configured | + +Assemble into a compact context packet: +``` +Task: +Acceptance criteria: +Linked artifacts: +Affected files: +Constraints: +``` + +Pass this packet verbatim as the opening context for the agentic node. + +--- + +## Verification recipe + +After every agentic node that touches source files, run the project's own tools: + +```bash +# Detect toolchain +[ -f package.json ] && npm run lint --if-present && npm test +[ -f pyproject.toml ] && (ruff check . ; pytest -x -q) +[ -f Cargo.toml ] && cargo clippy && cargo test +[ -f go.mod ] && go vet ./... && go test ./... +[ -f Gemfile ] && bundle exec rubocop && bundle exec rspec +[ -f Makefile ] && make lint test +``` + +Rules: +- Run the project's tools, never invent new ones +- Capture full stdout+stderr per tool +- Classify each failure: caused by this change, or pre-existing? +- Pre-existing failures → document, do not fix (out of scope) +- Failures caused by this change → one fix pass, then report regardless + +--- + +## Report format + +Every Blueprint run ends with this block: + +``` +## Minion result + +**Task**: +**Status**: ✅ ready / ⚠️ ready with caveats / ❌ blocked + +**Changes**: +- : + +**Verification**: +- : PASS +- : FAIL (pre-existing) — + +**Notes**: + +**Next step**: Review the diff, then `git add -p && git commit`. +``` + +No prose padding. No apologies. The human reads the status first; the rest +is supporting evidence. + +--- + +## When to use a Blueprint vs. free-form exploration + +| Use Blueprint | Use free-form | +|---|---| +| Task is well-defined before starting | Task needs clarification first | +| Task runs unattended | Human is pairing step-by-step | +| Task has a clear done condition | Exploring, debugging, investigating | +| Same task pattern repeats | One-off research or analysis | +| Failure has real cost (CI, production) | Low-stakes experimentation | + +--- + +## Recurring Blueprint patterns + +Store reusable Blueprints for your project as `.minions/.blueprint.md`. +The `/blueprint` command can list, show, and design them. + +Common patterns worth codifying: +- `dependency-upgrade`: bump a package, migrate breakage, verify, PR +- `add-api-endpoint`: scaffold route + handler + test + docs +- `fix-flaky-test`: investigate failure pattern, add retry/isolation, verify +- `backfill-migration`: write migration, run on shadow DB, verify data shape +- `translate-copy`: extract strings, translate via API, update locale files