From pipeline
Use this skill whenever the user wants to advance a GitHub issue or PR through a label-driven dev pipeline toward `pipeline:ready-to-deploy`. Triggers include phrases like "pipeline issue 419", "push #360 forward", "advance this PR through review", "run the pipeline on <issue>", or the `/pipeline` slash command. Do NOT use this skill for: general PR review (use /review), backlog triage/cleanup (use /sweep), or deploying a finished item (deployment is out of scope — the pipeline stops at ready-to-deploy).
How this skill is triggered — by the user, by Claude, or both
Slash command
/pipeline:pipelineThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Self-contained TypeScript skill that advances a GitHub issue (or PR's linked
core/package-lock.jsoncore/package.jsoncore/profiles/claude.jsoncore/profiles/codex.jsoncore/profiles/openclaw.jsoncore/scripts/config.tscore/scripts/gh.tscore/scripts/harness.tscore/scripts/last30days.tscore/scripts/lock.tscore/scripts/openspec.tscore/scripts/pipeline.tscore/scripts/profile.tscore/scripts/prompts/docs_update.mdcore/scripts/prompts/fix.mdcore/scripts/prompts/implementing.mdcore/scripts/prompts/index.tscore/scripts/prompts/plan_review.mdcore/scripts/prompts/plan_revision.mdcore/scripts/prompts/planning.mdSelf-contained TypeScript skill that advances a GitHub issue (or PR's linked
issue) through a 10-stage label-driven state machine, ending at
pipeline:ready-to-deploy. The pipeline does NOT auto-merge — the user owns
the merge button.
backlog → ready → planning → implementing
→ review-1 → fix-1 → review-2 → fix-2
→ pre-merge → ready-to-deploy
Each item carries one pipeline:<stage> label and at most one blocked
label. Stage transitions are driven by structured outcomes from the stage
handlers in scripts/stages/. The skill owns the labels — it sets,
removes, and transitions them as side-effects of running the underlying
stage logic. There is no separate orchestrator process.
backlog is a triage marker (e.g. set by /sweep). /pipeline starts work
at ready and only acts on items that already carry a pipeline:* label.
/pipeline N advance loop (default; up to 12 transitions)
/pipeline N --status read-only — print stage, blocker, PR, last review
/pipeline N --unblock "<answer>" post answer + clear blocked label
/pipeline N --once advance one stage and stop
/pipeline N --dry-run log what would happen; no harness calls, no GitHub writes
/pipeline N --domain <d> override domain name in lock/log paths
/pipeline N --base <branch> override base branch
/pipeline N --repo-path <path> target a different repo working tree
The number is auto-detected as an issue or PR via the GitHub API. PRs are
resolved to their linked closing issue (the pipeline is issue-centric). PRs
without a Closes #N reference are refused with an explanation.
The skill is a Node 24+ TypeScript codebase under
${CLAUDE_PLUGIN_ROOT}/skills/pipeline/core/scripts/, run via native type-stripping (no
build step). First-ever invocation runs npm install automatically.
Required:
gh CLI authenticated against the target repoclaude CLI on PATH (for the implementer/reviewer harness when configured to claude)codex CLI on PATH (for the harness when configured to codex)ANTHROPIC_API_KEYA repo can opt-in to overrides by committing .github/pipeline.yml:
base_branch: main # default 'main'
worktree_root: .worktrees # relative to repo root
max_concurrent_worktrees: 5
auto_merge: false # always false in v2; do not enable
auto_recovery_max_retries: 2
implementation_timeout: 1200 # seconds
review_timeout: 1200
fix_timeout: 1200
ci_timeout: 900
ci_poll_interval: 30
harnesses:
implementer: claude # legacy key accepted but ignored
reviewer: codex # legacy key accepted but ignored
models:
planning: sonnet
review: opus
fix: sonnet
conventions_md_path: CLAUDE.md # excerpt embedded in prompts
domain_name: lyric-utils
domain_description: a quantitative finance Python library
If absent, defaults from core/scripts/types.ts:DEFAULT_CONFIG apply. The Claude-side pipeline is harness-relative: Claude Code is always primary for planning, implementation, fixes, and docs update; Codex is always secondary for review/adversarial review. Legacy .github/pipeline.yml harnesses keys are accepted for compatibility but ignored so repo config cannot invert a Claude-invoked pipeline run.
For every invocation:
gh api /repos/{repo}/issues/{N} to detect
issue vs PR. PRs follow the closingIssuesReferences link./tmp/pipeline-{domain}.disabled — if present, exit./tmp/pipeline-{domain}.lock — PID-based, auto-recovers stale.pipeline:* label
with a message explaining how to opt in (pipeline:ready manually).while iter < 12 and not at ready-to-deploy and not blocked:
read current stage from labels
dispatch to the stage handler (planning, review, fix, pre_merge, …)
print one-line transition
if --once: break
Each iteration may block for up to ~20 minutes (heavy stages run implementer/reviewer harnesses against the full repo). Worst-case full path is 9 transitions, ~2 hours.
A foreground bash invocation will be killed at the harness's 10-minute timeout — long before a planning stage finishes (~20 min cap each). For the default advance mode, Claude must orchestrate the run as follows:
node ${CLAUDE_PLUGIN_ROOT}/skills/pipeline/scripts/pipeline.mjs <N> --status
Confirms target exists, has a pipeline:* label, isn't already at a
terminal/blocked state. If anything looks wrong, surface it and stop —
do not start an advance.
cd <repo_dir>
node ${CLAUDE_PLUGIN_ROOT}/skills/pipeline/scripts/pipeline.mjs <N> \
> /tmp/pipeline-<domain>-<N>.log 2>&1
Run with run_in_background: true. The bash tool returns the task ID
immediately; the pipeline runs detached.
Arm a persistent Monitor on the log file with this filter (matches the pipeline.ts transition lines + structured failure markers):
tail -f /tmp/pipeline-<domain>-<N>.log | grep -E --line-buffered \
"^\[pipeline\]|^\[exit code|FAILED|timed out|blocked label|approved|needs-attention|→ "
Set persistent: true, timeout_ms: 3600000 (1 hour — re-arm if
needed). Each emitted line lands in Claude's notification stream.
Known false-positives to ignore:
Traceback: and verdict and other prompt content echoed verbatim
through the harness's stdout. These are NOT real stage events —
they're the prompt being read back by claude/codex during streaming.
The grep matches them anyway because we deliberately broaden the
filter to catch real failures (FAILED, timed out, etc.). The
real stage signal is always a line starting with [pipeline].[pipeline] eventFor every Monitor event that is a real [pipeline] line (i.e., not the
known prompt-echo false-positives), call PushNotification with a short
one-line message. The state machine has only 9 transitions max and each
emits ≤2 visible [pipeline] lines, so this caps at ~12–18 pushes per
full run — coarse enough to not be spammy, fine enough that the user
never wonders "is anything happening?" between major arrows.
Examples that DO push:
[pipeline] #N: starting at stage=<x>[pipeline] #N: planning (impl=claude)[pipeline] #N: worktree at <path>[pipeline] #N: implementation done (Xs, harness=Y)[pipeline] #N: PR #M created[pipeline] #N: ready → review-1: PR #M opened[pipeline] #N: review-1 by codex[pipeline] #N: verdict=approve findings=0[pipeline] #N: review-1 → review-2: standard review approved→ ready-to-deployExamples that do NOT push (false-positives the grep filter still catches):
Traceback: and verdict and other prompt content echoed verbatim
through the harness's stdout. Real stage signals always start with
[pipeline]. If a Monitor event line doesn't start with [pipeline],
surface in chat for context but skip the push.pre_merge.advancePolling
re-enters the gate check every ci_poll_interval seconds (default 30s)
and emits [pipeline] #N: pre-merge gate each time. Push the FIRST
occurrence per stage entry; suppress subsequent identical lines in the
same polling burst. The next material event is the eventual
→ ready-to-deploy or → blocked transition — don't bury it under
30 spam pushes.The "err toward not sending" guidance in the PushNotification docs is
about ambient noise — but /pipeline N is a foreground operation the
user explicitly invoked, not background ambient state. They asked for
this push stream; deliver it.
The harness fires a separate task-notification for the background
bash with <status>completed</status> when pipeline.ts exits. On that
event, call TaskStop with the Monitor's task_id and surface the
final summary inline by reading the tail of the log.
Read the last 30 lines of /tmp/pipeline-<domain>-<N>.log and surface
inline: starting stage → ending stage, transitions made, wall-clock
elapsed, PR URL if one was opened. Also send one final
PushNotification with the terminal state.
--status — read-only, completes in seconds--unblock "<answer>" — one comment + label clear, completes in seconds--dry-run — logs what would happen, no harness callsRun those synchronously, no Monitor, no background, no Push.
--once still needs the orchestration because a single heavy stage
(planning especially) can hit its 20-min timeout. Use the same
background + Monitor + Push pattern as default mode; just expect at
most one transition before the run exits.
For multi-stage runs, blocked runs with substantial context, or any run whose final state is easier to understand visually, generate a self-contained HTML report in artifacts/reports/pipeline-<N>.html inside the target repo/worktree. Keep the chat summary short and include the artifact path.
The report should include:
HTML report constraints: inline CSS/SVG/JS only; no external scripts, stylesheets, CDNs, tracking, network calls, or remote assets. If the report includes interactive controls, include a copy/export block that serializes the selected state back to Markdown/JSON/prompt text.
Do not create HTML for simple /pipeline N --status, --dry-run, or one-step summaries unless the user asks.
When the loop ends, the skill prints:
gh not authenticated → tell user gh auth login, exit.gh error, exit 1.pipeline:* label → refuse with opt-in instructions.blocked label + structured comment
with reason; loop terminates and shows the latest blocker.false only).pipeline:* opt-in label gate.--once.--dry-run mode.ANTHROPIC_API_KEY.core/scripts/types.ts — STAGES, PipelineConfig, Outcome, ReviewVerdictcore/scripts/config.ts — load .github/pipeline.yml + defaultscore/scripts/gh.ts — typed wrappers for the gh CLIcore/scripts/worktree.ts — pipeline-{N}-{slug} worktree lifecyclecore/scripts/harness.ts — invoke("claude" | "codex", cwd, prompt)core/scripts/lock.ts — PID-based lock at /tmp/pipeline-{domain}.lockcore/scripts/stages/*.ts — one file per stage (planning, review, fix, pre_merge, deploy_ready, auto_recover)core/scripts/prompts/*.md — prompt templates with {{placeholders}}core/scripts/pipeline.ts — top-level orchestrator + CLIREADME.md — human-facing docsProvides UI/UX resources: 50+ styles, color palettes, font pairings, guidelines, charts for web/mobile across React, Next.js, Vue, Svelte, Tailwind, React Native, Flutter. Aids planning, building, reviewing interfaces.
Fetches up-to-date documentation from Context7 for libraries and frameworks like React, Next.js, Prisma. Use for setup questions, API references, and code examples.
npx claudepluginhub accidental-hedge-fund/agent-pipeline --plugin pipeline