A central entrypoint for executing development tasks. It enforces strict workflow rules based on tracked issues or PRs.

Install

mkdir -p .claude/skills/dev-loop && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/19471" && unzip -o skill.zip -d .claude/skills/dev-loop && rm skill.zip

Installs to .claude/skills/dev-loop

Activation

This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.

Single public dev-loop entrypoint. Resolve canonical current state first, then load only route-specific internal skills.
120 charsno explicit “when” trigger
Advanced

Key capabilities

  • →Resolve canonical current state
  • →Load route-specific internal skills
  • →Build workflow handoff envelope
  • →Validate PR gate pipeline
  • →Promote refinable items to pickup column

How it works

The skill resolves the authoritative state of a development task from a GitHub issue or PR, then builds a handoff envelope to determine the necessary files and actions.

Inputs & outputs

You give it
GitHub issue number or PR identifier
You get back
Workflow handoff envelope containing required reads and next actions

When to use dev-loop

  • →Start a new development task
  • →Check progress on an active issue
  • →Sync implementation with a GitHub PR

About this skill

No-implicit-start rule: Never start implementation without explicit instruction.

Work-origin rule: All work must originate from a tracked artifact: a GitHub issue (tracker-first), a persisted markdown plan file (local-planning), or — on the sanctioned lightweight path — the PR description itself as the spec-of-record (--lightweight, canonicalSpecSource: pr_body; no committed plan artifact; issue-less PR-first is size-gated by the light-mode threshold unless localImplementation.issueless sanctions it at any change scope). See Artifact Authority Contract for canonical mode definitions and settings. No work may originate from a PR (other than the sanctioned lightweight PR-body-as-spec path) or a direct local change unless explicitly requested.

Unified Dev Loop

This is the public dev-loop façade — a summary of the authoritative routing contract. The authoritative contract is Public Dev Loop Contract. Runtime evaluator: @dev-loops/core/loop/public-dev-loop-routing. For status/progress/readiness/merge-state/next-step queries, resolve authoritative artifact identity first; for issue targets, identity resolution is handled by the startup resolver. Fail closed to reconcile/unknown when unresolved. When an open linked PR exists, treat it as the single canonical artifact for the issue and reuse it instead of opening another PR.

Installed skill layout

Required installed runtime contract docs are shared bundled copies under ../docs/ from this skill directory. Read those bundled ../docs/ files from the installed skill layout — do not assume a source checkout. If a required bundled contract doc is missing, treat it as a packaging/installer bug.

Startup procedure

Review intent short-circuit (issue #1850): A plain review request against a PR ("review PR #N", "review this PR") is NOT a continue/fix/merge request. In interactive intent handling, recognize it before ordinary startup and dispatch to the Review Skill (/dev-loops:loop-review <pr>, or /loop-review <pr> in this repo). A harness that drives startup directly selects the same route deterministically with loop startup --pr <n> --review; the selector is read-only and ownership-exempt, so routing no longer depends on an agent interpreting intent prose. The route performs no assignee claim, branch push, fix commit, merge, board move, or lifecycle gate evidence. Any continue/fix/merge/watch request proceeds through ordinary startup and remains ownership-gated as before.

"Run the gates" is NOT review intent (issue #1913): review is a GATE_NAME but it gates nothing (informational, blocks no transition — see the tier comment in scripts/github/_gate-names.mjs: LIFECYCLE_GATES vs REVIEW_GATE). So a request phrased around gating — "run this PR through the gates", "gate this PR", "gate PR #N" — with NO explicit "review" word MUST NOT match the review short-circuit above. The discriminator is the same one question the vocabulary encodes: does it block a lifecycle transition? "Run the gates" means the lifecycle gates (draft_gate, pre_approval_gate), which run inside the ordinary loop via the startup flow below — NOT the standalone review command. Route these requests through loop startup/resolve-dev-loop-startup.mjs like any other continue request; do not dispatch /loop-review.

<!-- pi-only -->

Main agent (read-only)

The main agent must always dispatch the dev-loop async subagent for any dev-loop work. Do not run node <dev-loops-package-root>/cli/index.mjs loop startup or any startup resolver in the main agent. For async-required routes (config workflow.asyncStartMode, default required) the resolver needs async-context evidence: pi-subagents ≥ 0.65 marks each async child with PI_SUBAGENT_CHILD=1 plus PI_SUBAGENT_PARENT_SESSION (pi-subagents ≤ 0.64 injected the legacy PI_SUBAGENT_RUN_ID alias instead), so that native marker pair is the async-start evidence; the Pi subagent tool has no env parameter, so the main agent cannot inject a run id — a neutral DEVLOOPS_RUN_ID already present in the child's own environment is honored as the primary carrier; under the Claude Code harness the requirement is relaxed automatically (no marker needed). With no run-id carrier present, the run id is synthesized from the child's own PI_SESSION_ID (falling back to PI_SUBAGENT_PARENT_SESSION), so sibling children of one parent session stay distinct runners. The startup resolver also runs without a marker for non-async routes. Regardless, only the dev-loop subagent runs it — never the main agent.

After async dispatch, follow Async dispatch posture: return control to the user without subagent_wait, except for explicitly requested run-to-completion or a skill that must finish in one turn. Pi wakes the session on completion or needs-attention.

<!-- /pi-only -->

Resolve authoritative state

For an initial Codex conductor spawn, MAIN first consumes the config-only gate resolve-role --conductor --harness codex result and applies its native overrides per Codex coordinator dispatch. Startup remains the child's first workflow action; configuration/native refusal stops dispatch without an inherited replacement.

Under the Claude Code harness the dev-loop runs as a single agent: run these steps directly — no separate async-subagent dispatch. The coordinator has an opt-in read-only boundary for tracked repo files and code-verification/build commands (DEVLOOPS_COORDINATOR_READONLY=1, enforced by the guard hooks). See Main Agent Contract.

<!-- pi-only -->

CLI invocation (<dev-loops-package-root>): dev-loop CLI commands below are invoked as node <dev-loops-package-root>/cli/index.mjs <verb...> using the package-local CLI rather than npx, so they resolve unambiguously from the installed package without a global install. Resolve <dev-loops-package-root> via the first of these bounded candidates whose cli/index.mjs exists — never assume a single fixed layout (under a Pi user-level install the package lives at ~/.pi/agent/npm/node_modules/dev-loops/, so the old ../../.. package-relative guess from skills/dev-loop/SKILL.md overshoots the package root):

  1. Live source checkout (wins unconditionally — checkout wins by presence, no version comparison): walk up from cwd (the mandatory worktree cwd) for a dir whose package.json name === "dev-loops" with a sibling scripts/ dir; the first such ancestor is <dev-loops-package-root>, used unconditionally when found. This mirrors .claude/bin/dev-loops-run's isCheckout/findCheckout so local-checkout precedence is uniform across harnesses: a live checkout wins even over a newer install under ~/.pi/agent/npm, so a dogfooder's live edits always run and a stale user-level install never silently shadows the checkout. The walk-up is bounded to cwd ancestors and terminates at the filesystem root — never find /. Probe: node -e 'const fs=require("node:fs"),p=require("node:path");const isCheckout=d=>{const j=p.join(d,"package.json");if(!fs.existsSync(j)||!fs.existsSync(p.join(d,"scripts")))return false;try{return JSON.parse(fs.readFileSync(j,"utf8")).name==="dev-loops"}catch{return false}};let d=process.cwd();for(;;){if(isCheckout(d)){console.log(d);process.exit(0)}const parent=p.dirname(d);if(parent===d)process.exit(1);d=parent}' prints the checkout root and exits 0 on a hit; a non-zero exit means "no checkout ancestor, try the next candidate" (non-fatal). Only when no checkout is found does resolution fall through to the candidates below.
  2. Node module resolution (best-effort, tried after the checkout walk-up): node -e "try{const p=require('node:path');console.log(p.resolve(p.dirname(require.resolve('dev-loops/cli/index.mjs')),'..'))}catch{process.exit(1)}" — resolves the package root when dev-loops is reachable from Node's module search path (notably under ~/.pi/agent/npm); this is cwd-dependent and commonly misses from a target-repo cwd, so the probe is wrapped in try/catch (no stack trace, exits non-zero on miss) — treat a non-zero exit as "probe missed, try the next candidate", not a hard failure.
  3. Pi user-agent npm root (reliable for user-level installs): ~/.pi/agent/npm/node_modules/dev-loops.
  4. Package-relative (legacy): ../../.. from this skill's own directory (the original package-local install layout).
  5. Global npm root: $(npm root -g)/dev-loops.

NEVER fall back to find / or any unbounded filesystem walk to locate the CLI — it stalls and trips the needs-attention timeout. If every bounded candidate fails, stop and ask the orchestrator/operator for the dev-loops package root rather than searching. (The dev-loop agent resolves it analogously — same checkout-first walk-up, same "checkout wins, no version comparison" rule.)

<!-- /pi-only -->

Resolve authoritative state via the startup resolver (node <dev-loops-package-root>/cli/index.mjs loop startup --issue <n> for issues, node <dev-loops-package-root>/cli/index.mjs loop startup --pr <n> for PRs), then immediately build the handoff envelope via node <dev-loops-package-root>/cli/index.mjs loop build-envelope --input <resolver-output.json> (exception: when the dispatch prompt is a pull pointer, the pulled coordinator work order is the handoff envelope and no new envelope is built; see "Pull-pointer dispatch" in agents/dev-loop.agent.md). The envelope determines requiredReads, nextAction, stopRules, and acceptance — load only those files, execute only that bounded task. It is the first handoff artifact consumed before loading any route pack. See Workflow Handoff Contract for the derivation contract.

**Retrospect


Content truncated.

When not to use it

  • →Starting implementation without explicit instruction
  • →Running startup resolver in the main agent

Prerequisites

gh authdev-loops package

Limitations

  • →No gate exemptions for PRs
  • →Fail closed to reconcile when state is unresolved

How it compares

It enforces a strict authority contract by requiring a tracked artifact before allowing any development work to proceed.

Compared to similar skills

dev-loop side by side with the closest alternatives in the catalog.

SkillInstallsUpdatedSafetyDifficulty
dev-loop (this skill)03moReviewAdvanced
resolve-conflicts8111moReviewIntermediate
openspec-onboard108moReviewBeginner
codex-cli-bridge912moReviewIntermediate

Try saying

Example prompts that trigger this skill in your AI assistant.

Search skills

Search the agent skills registry