Skip to main content

issue-resolver

Create an atomic PR closing a GitHub issue end-to-end via a 6-step pipeline. Use to resolve, fix, or implement issue #N. Don't use for analysis without fixing (/issue-analysis), reviewing a PR (/issue-pr-review), or bulk backlog work (/auto-pilot).

Informações da origem

Repositório
luongnv89/idd
Última atividade na origem
22 de outubro de 2026 às 11:54
Idioma detectado do SKILL.md
inglês
Estrelas
13
Forks
2

Opções de instalação

Por padrão, está selecionado o prompt que primeiro revisa a origem. Você pode mudar para um comando direto ou baixar uma cópia local.

Revise os arquivos de origem

Leia o SKILL.md e os arquivos complementares exibidos pelo SkillsMP antes de decidir se vai instalar.

Explorador de arquivos
51 arquivos

Exibindo SKILL.md

SKILL.md
Instruções da origem · Visualização somente leitura
name
issue-resolver
description
Create an atomic PR closing a GitHub issue end-to-end via a 6-step pipeline. Use to resolve, fix, or implement issue #N. Don't use for analysis without fixing (/issue-analysis), reviewing a PR (/issue-pr-review), or bulk backlog work (/auto-pilot).
license
MIT
compatibility
Requires git and GitHub CLI (gh) with authentication and push access. Self-contained — uses shared agents from shared/agents/.
metadata
{"version":"0.21.0","author":"Luong NGUYEN <luongnv89@gmail.com>","effort":"max"}
# /issue-resolver N Issue → atomic PR in 6 steps. ## Invocation | Invocation (`N` = issue number) | What happens | |------------|--------------| | `/issue-resolver <N>` | Interactive; user picks the plan | | `/issue-resolver <N> --auto` | No prompts; set by `/auto-pilot` | | `/issue-resolver <N> --no-run-log` | Modifier, **orthogonal to `--auto`**: append nothing to `.idd/runs.jsonl`, return telemetry (*Run-log entry*) | | `/issue-resolver <N> --resume` | Modifier: resume a killed run from its progress record (*Progress record*); the only way `--auto` resumes, while interactive also offers it whenever a record exists | ## Context re-entry <!-- a:ctx-reentry --> **Only when `compaction.enabled` is true; otherwise skip this section** (`references/docs/context-threshold.md`). After a compaction mid-run, durable state is git plus GitHub; the *Progress record* serves only a killed session and is never read here. - **Caller-managed lane** (`IDD_CALLER_WORKTREE=1`, this conversation's `parallel_lane` record) first: recover that record, then re-run Step 0e's caller-managed validation from a command that starts `cd -- "$IDD_WORKTREE_PATH" && …`, its exports repeated. Bind the branch and PR only inside that validated root. A record not recovered intact stops the lane with `failure_step: preflight`, `status: blocked_dirty`. **Never fall back to the ambient checkout.** - Re-bind the branch live, `branch="$(git rev-parse --abbrev-ref HEAD)"`, then the PR with `gh pr list --head "$branch" --json number,state` — never a branch name pasted from the compaction summary. - Read the current step from this conversation's `[N/5]` lines and re-read that step's reference file. Before repeating a push, `gh pr create`, comment or label change, confirm with a live `--json` read that it has not happened. - **Step 4 loop:** if **either** the cycle count **or** the premise-reset ledger cannot be read from this conversation, treat the cycle cap as reached and take Step 4's cap-reached path: deliver with known issues and **no** QA marker. Interactive re-entry also treats the premise gate as blocked, so no `continue` sends another fix. **Never restart the loop at cycle 1.** ## Prerequisites Run these checks in order before any operation. A non-zero exit or empty output stops the run: print that check's `references/error-messages.md` error and the *Closing Summary* `BLOCKED` block. 1. Git repository: `git rev-parse --git-dir`. 2. `gh` installed: `which gh`. 3. `gh` authenticated: `gh auth status`. 4. Remote present: `git remote -v` prints at least one line. ## Repo Sync Before Edits (mandatory) In-place path only; worktree paths start from the fetched base, and an invalid `IDD_CALLER_WORKTREE=1` is a stop, never a sync bypass. Use the **stash-first pattern**: copy the snippet and recovery from `references/docs/sync-conventions.md` (*Quick Reference (Copy-Paste Snippet)*), never a bare rebase on a dirty tree. A missing `origin` or a conflict stops and asks (interactive), or aborts (auto). ## Configuration Load config once; never re-read it. Run `python3 references/scripts/gi-config.py` — **Working directory:** the repo root; **Script path:** absolute, as the *Bundled dependency precheck* resolves its list. It prints `{"config": …, "config_file": …, "first_run": …}` merged over the defaults below (rationale: `references/steps/step-0-preflight.md`, *Configuration load*). - **Exit 0** — use `config`. - **Exit 3** — invalid `.idd.yml`: print the `references/error-messages.md` error (*Invalid config*), stop. - **Script file absent** — a broken install and not a degrade: stop, print `✗ Missing bundled dependency`. - **Anything else** (no `python3`, non-zero exit, unparsable stdout) — print `⚠ gi-config unavailable — reading .idd.yml by hand` and read it yourself *instead of* the script (else legacy `.gitissue.yml`, printing `⚠ legacy .gitissue.yml found — rename to .idd.yml`), over the keys and defaults below. Either path: no `.idd.yml` (`first_run`) prints `○ First run — using default config. Run /init-idd to customize.` **Capture the run clock here:** chain that same `python3` invocation as `python3 …; ec=$?; date +%s >&2; exit "$ec"`; the stderr epoch is `run_started_epoch`, the *Run Stats Footer*'s `elapsed` anchor. Take `date +%s` again as each `[N/5]` step starts and at the terminal outcome: those boundaries are the run log's `phases` (`references/report-templates.md`). **Context threshold.** <!-- a:ctx-check --> Only when `compaction.enabled` is true (`references/docs/context-threshold.md`). At each `[N/5]` step start, beside that clock read, compare the remaining-context figure the host placed in your context (none: skip silently, never estimate) with `compaction.threshold.issue-resolver`. At or below it, interactive prints the `⚠` line and a `/compact <focus>` line (skill, `#N`, step id and name only) and pauses **at most once per run**; `--auto` / `IDD_AUTO_MODE=1` prints one `⚠` line per run and continues — never a pause or stop. Defaults and behavior per key: `references/docs/config-schema.md` — `issue.auto_normalize` · `resolve.approval_gate` · `resolve.branch_prefix` · `resolve.auto_test` · `resolve.test_timeout` · `resolve.max_commits` · `resolve.qa_max_cycles` · `resolve.adaptive_effort` · `resolve.ui_review.browser_review` · `resolve.borrow_skills: false` · `compaction.enabled: true` · `compaction.threshold.issue-resolver: 40`. --- ## Subagent Architecture Heavy work goes to subagents (`shared/agents/`), keeping the main agent's **context window** lean: it owns Step 0, Step 4's loop and Step 5; Steps 1-3 each spawn one (*Subagent Architecture Diagram*). Prompts: `references/agents/<name>.md`; conventions: `references/docs/shared-agent-conventions.md`. Without the Agent tool (e.g. Claude.ai), run each step inline via its fallback instructions. ### Spawning a subagent (canonical pattern) Role, description and prompt file change per step. **Do NOT set `subagent_type`**: ```python Agent( description="{role} — {action} issue #N", prompt=<{agent-file}.md prompt with {variables} replaced>, # never subagent_type — the default general-purpose agent, not "code-reviewer" ) ``` **Per-role overrides:** at every spawn apply `references/docs/agent-overrides.md` — the resolved `agents.model.<role>` / `agents.effort.<role>` for the spawned role (`codebase-researcher`, `synthesizer`, `implementer`, `code-reviewer`, `ui-reviewer`, `fixer`); `null` (the default) passes nothing. ### Orchestrating the agents Name the role in `description`, size model/effort per `references/docs/agent-model-effort.md`, and read each return before advancing: a missing or blocking return stops (interactive) or takes the auto behavior (*Orchestrating the agents*). ### Bundled dependency precheck Check every path below exists relative to this SKILL.md's directory. A missing path stops the run: print the `✗ Missing bundled dependency` block from `references/error-messages.md` (*Bundled dependencies*); never guess a prompt. ```text references/agents/codebase-researcher.md references/agents/synthesizer.md references/agents/implementer.md references/agents/code-reviewer.md references/agents/ui-reviewer.md references/agents/fixer.md references/pipeline-steps.md references/steps/step-0-preflight.md references/steps/step-0h-analysis-reuse.md references/steps/step-0i-caller-payload.md references/steps/step-0j-progress-record.md references/steps/step-1-research.md references/steps/step-2-plan.md references/steps/step-3-implement.md references/steps/step-4-qa.md references/steps/step-5-deliver.md references/report-templates.md references/run-stats.md references/bug-verification.md references/skill-index.md references/error-messages.md references/docs/sync-conventions.md references/docs/naming-conventions.md references/docs/pre-commit-security.md references/docs/idd-methodology.md references/docs/github-projects-sync.md references/docs/run-log-schema.md references/docs/config-schema.md references/docs/agent-model-effort.md references/docs/agent-overrides.md references/docs/shared-agent-conventions.md references/docs/platform-github.md references/docs/terminal-style.md references/docs/ui-review.md references/docs/context-threshold.md references/scripts/gi-config.py references/scripts/gi-runlog.py references/scripts/gi-secscan.py references/scripts/gi-branch.py references/scripts/gi-gh.py references/scripts/gi-issue.py references/scripts/gi-state.py references/scripts/gi-receipt.py references/scripts/gi-sensitive.py references/scripts/gi-premise.py references/scripts/gi-sketch.py references/scripts/gi-recipe.py references/scripts/gi-progress.py ``` --- ## Progress record <!-- a:rs-progress --> A killed session can resume (`--resume`). Read the record after the precheck, before *0a*; from *0c* on, write it with `references/scripts/gi-progress.py` at every `[N/5]` start, at each Step 4 cycle, and before every effect. It holds only what git and GitHub cannot reproduce: the step, the plan summary, cycle counts, the premise ledger, open findings, the last effect. **A record never satisfies or skips a safety gate:** every gate re-runs live, and any doubt is stale (start from Step 0). Write points, resume, validation and reconciliation: `references/steps/step-0j-progress-record.md` (*Step 0j — Progress record*) — **read it now**. --- ## Pipeline Overview 6 steps (0-5) — Preflight, Research, Plan, Implement, QA, Deliver — each printing a `[N/5]` line (`●` → `✓`/`✗`); expected output example: `references/report-templates.md` (*Expected Inline Pipeline Output*). ### Step completion reports Each step closes with `√`/`×` per check and a `Result: PASS | PARTIAL | FAIL` line (*Step Completion Reports* in `references/report-templates.md`, **read it now**). A step is incomplete until `Result:` prints. --- ## Step 0 — Preflight Open with `● Preflight check for issue #N...`. ### 0a — Fetch issue GitHub reads share the boundary in `references/scripts/gi-gh.py`. Classify any framed caller payload first (`/auto-pilot` captured it in mode-neutral *Step 1.2b*); *Step 0i — Caller payload gate* in `references/steps/step-0i-caller-payload.md` is its single home — `issue_payload = supplied | partial | absent`, the mandatory live `gh issue view N --json state,comments,updatedAt` under `supplied`, the exact match between retained and live `updatedAt` before 0d, discard-and-refresh on mismatch (identical for individual, array, and keyed-map payloads), never a gate. Then run `python3 references/scripts/gi-issue.py {N} --fields number,title,body,labels,assignees,state,comments,updatedAt`, reading `.issue` unless the gate substitutes a payload. **Capture `updatedAt` here** — 0d's `gh issue edit` bumps it, so *0h* uses this pre-normalization value. Exit 3 stops; anything else degrades to `gh issue view {N} --json number,title,body,labels,assignees,state,comments,updatedAt`. **0d rewrites the body, so it MUST end with `python3 references/scripts/gi-issue.py {N} --invalidate`.** <!-- a:rs-0a-payload-concurrency --> **Not found:** error, stop. **Closed:** warning, stop. ### 0b — Check for existing work 1. List branches: `git branch -a | grep -i "{N}"`. 2. List open PRs: `gh pr list --state open --json number,title,body,headRefName --limit 20`. A PR targets the issue when its body has `Closes #N`, `Fixes #N` or `Resolves #N`. 3. If an **open** PR targets it: print the `⚠ PR already targets issue` block from `references/error-messages.md` (*Guards*), stop, return `status: pr_in_progress` with its `pr_number` and `branch_name`, and **never close the issue** (*Early exit*) — unless a resume's ownership check (*Progress record*) proves the PR is this run's own. Only a **merged** PR or a closing commit on the default branch is `already_resolved`. ### 0c — Guards **Interactive:** warn and ask if assigned elsewhere, or on `wontfix`/`blocked`/`do-not-merge` labels. **Auto:** skip the assignment guard, log blocking labels, never stop. ### 0d — Auto-normalize If `issue.auto_normalize` is true and the body lacks a `<!-- idd:normalized v1 -->` marker (a legacy `gitissue:normalized` one counts): 1. **Security label check (SPEC §1.4)** — before any rewrite scan labels for `security`, `CVE`, `vulnerability` (case-insensitive). On a match: - **Auto mode (`--auto` / `IDD_AUTO_MODE=1`):** print the `⚠ … Skipping auto-normalization` warning (`references/error-messages.md` → *Security-labeled issue (skip)*), first matching label as `{label}`, continue **without** rewriting. - **Interactive mode:** same warning, then ask for explicit operator confirmation; default **no**, a decline continuing without normalization. 2. **Normalize inline** — otherwise, structure-only as `/issue-creator` Normalize mode (the resolver does **not** invoke `/issue-creator` as a subprocess): 1. Classify the type and generate the body with the marker. 2. Back up the original body in a comment. 3. Run `gh issue edit`, then `python3 references/scripts/gi-issue.py {N} --invalidate`, then re-fetch. 4. On any failure, **warn** and continue with the original body (`references/error-messages.md` → *Auto-normalization failed*). ### 0e — Workspace (interactive only) Derive one `{branch_name}` first: `python3 references/scripts/gi-branch.py {N} --from-issue --type {type}`, reading `.branch`. **`--from-issue` is mandatory** — never put the issue title or configured prefix on the command line (`references/steps/step-0-preflight.md` → *Step 0e — Workspace*). `{type}` is one of six classified literals. Exit 3 stops; anything else degrades to `references/docs/naming-conventions.md`.
Ver no GitHub
Este SKILL.md e muito grande, entao o SkillsMP mostra aqui apenas a primeira secao. Ver no GitHub