agentsclimarketplace

Issue

Skill chris-peterson/anchor/skills/issue

bridge.ai/anchor: skills for consistent and effective source control

Install
npx -y skills add chris-peterson/anchor --skill issue

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

File a new forge issue (or update an existing one) that leads with WHY the work is needed. Use when filing, creating, drafting, or updating a single issue or ticket. To find, browse, or pick which issue to work on next, use the `issues` skill instead.

SKILL.md

13.0 KB, ~3.2k tokens by cl100k_base, as published. Nobody here has run it

Issue

File a new issue whose job is to convey why the work is needed and how the author intends to approach it — written for a reader who has never seen this part of the system. This is the singular, authoring counterpart to the issues skill: issue drafts and writes one issue (a new one, or an update to a known one), while issues surveys the backlog to find the next thing to work on. An issue describes work to be done, so unlike commit and prepare-review there is no diff to read from: the raw material is the author's intent, gathered up front.

Don't narrate your work. Every step below is an operating instruction, not a script to read aloud — follow the execute-quietly discipline: ${CLAUDE_PLUGIN_ROOT}/guides/execute-quietly.md. For this skill, the only things worth surfacing are a question you need answered, the drafted issue with its options, and the final URL.

Issue = a GitHub issue or a GitLab issue. Pick the forge tool by the origin remote.

%%{ init: { 'look': 'handDrawn' } }%%
flowchart TD
    Start(["/issue"]) --> Mode{Issue ref given?}

    subgraph "Step 1: Resolve the issue"
        Mode -->|Yes| Update["Update: fetch current body as baseline"]
        Mode -->|No| Create["Create: new issue"]
    end

    subgraph "Step 2: Gather intent"
        Update --> Why["Ask the WHY + consumer + acceptance"]
        Create --> Why
    end

    subgraph "Step 3: Guard against duplicates"
        Why --> FromCreate{Creating a new issue?}
        FromCreate -->|Yes, unsure| Check["Offer /issues to check for a match"]
        Check --> Match{Already tracked?}
        Match -->|Yes| Reuse["Switch to update: fetch its body as baseline"]
    end

    subgraph "Step 4: Draft"
        Tmpl["Honor forge template + anchor.* config"]
        Tmpl --> Draft["Draft title + body"]
    end

    FromCreate -->|No, or new| Tmpl
    Match -->|No, file new| Tmpl
    Reuse --> Tmpl

    subgraph "Step 5: Output"
        Draft --> Out{Disposition?}
        Out -->|Write| Forge(["Create / update issue"])
        Out -->|Copy| CopyOnly(["Print for paste"])
        Out -->|Edit| Revise["Revise (moor or chat)"] --> Draft
    end

Target repo

By default this operates on the repo backing the working directory — pick the forge from its origin remote (gh for GitHub, glab for GitLab). But an issue is often filed against a different repo than the one you're sitting in ("file this against payments-api", "open an issue in customer-svc"). Don't guess from cwd or improvise a -R from a half-remembered slug — resolve the name through tack's repo db:

bash "${CLAUDE_PLUGIN_ROOT}/scripts/resolve-target.sh" <name>

Act on TARGET_VIA:

  • cwd — no tack, or no match (TARGET_NOTE says which). Fall back to the cwd origin, exactly as today. If the user clearly meant a repo that didn't resolve, say so rather than silently filing against the cwd repo.
  • ambiguousTARGET_CANDIDATES holds the matches as [{key,url,local}]. Present them with AskUserQuestion and let the user pick; proceed with the chosen entry.
  • tack — exactly one match. Use the emitted fields for every forge call below:
    • TARGET_FORGE picks the CLI (gh / glab).
    • GitHub: add -R <TARGET_PROJECT> to the gh issue … calls.
    • GitLab: the create/update use glab api projects/:fullpath/…, but :fullpath resolves from the cwd git dir — substitute the URL-encoded TARGET_PROJECT for :fullpath and add --hostname <TARGET_HOST> (required for self-hosted, harmless elsewhere).
    • TARGET_LOCAL — the checkout, when one exists. Only the template step needs it; create/update are pure-remote and work without it (the common case for a repo you don't have checked out).

Step 1: Resolve the issue

Pick the forge per Target repo above (gh for GitHub, glab for GitLab).

  • An issue URL or number was providedupdate that issue. Pull its current body to a temp file now ($(mktemp -u "${TMPDIR:-/tmp}/issue-current.XXXXXX").md); Step 5 diffs the draft against it:

    # GitHub
    gh issue view <num> --json body --jq '.body' > <current-path>
    
    # GitLab
    glab issue view <iid> --output json | jq -r '.description' > <current-path>
    
  • No issue referencecreate a new issue.

Step 2: Gather intent before drafting

There is no diff to mine, so the author's answers are the issue. Ask for what's missing — don't draft around a gap:

  • Why — what problem this solves or what need it serves, and why it matters now.
  • Consumer — who is the primary caller or consumer of the change?
  • Acceptance — what does "done" look like? Concrete criteria or scenarios.
  • Approach (if the author has one in mind) — the intended plan and any key design decisions. If they don't yet, the issue can be a problem statement without a proposed approach; don't invent one.

Wait for answers before drafting. If the only open item is the WHY, ask:

What problem does this solve, and why does it matter? A sentence or two is enough — and who's the primary consumer of the change?

Step 3: Guard against duplicates

This step runs only on the create path — skip it when updating a known issue. A duplicate issue splits the discussion, so before drafting a brand-new issue, make sure one doesn't already cover this need.

Finding and picking issues is the issues skill's job — don't re-implement a forge search here. If it's unclear whether this need is already tracked, say so and offer to run issues (scoped to a keyword or two distilled from the intent — the subject of the work, not the WHY prose) to survey open and closed issues first. If the user already knows it's new, or a quick look turns up nothing that genuinely overlaps, continue to Step 4 without further comment.

If it turns out the need is already tracked, this is an update, not a new issue: take that issue's number and switch to the update path — fetch its current body as the baseline (the Step 1 fetch), then draft against it.

Step 4: Draft the issue

Honor an existing forge template

Before drafting, check whether the project ships an issue template. This reads the repo's files, so it needs a local checkout — look under the cwd repo, or under TARGET_LOCAL when a tack target resolved one (ls <TARGET_LOCAL>/.gitlab/issue_templates/*.md). When the target is remote-only (TARGET_LOCAL empty), skip template detection and note that a project template, if the repo has one, wasn't applied — don't block the issue on a checkout you don't have.

  • GitLab: .gitlab/issue_templates/*.md (respect the configured default if more than one)
  • GitHub: .github/ISSUE_TEMPLATE/*.md, or the legacy .github/ISSUE_TEMPLATE.md. A .yml issue form is a structured format — don't compose prose into it; surface it and let the author fill it in the web UI.

If a template exists, it's the team's required scaffolding — compose into it, don't replace it. Fill the sections it defines, preserve its checklists and headings verbatim, and strip any "delete before publishing" instruction block after following its guidance. On a structure conflict the team template wins. The composition rules live in the "Honoring a project's forge template" section of templates/issue-description.md.

Honor anchor.* config

Read the project + global anchor keys once:

git config --get-regexp '^anchor\.' 2>/dev/null

--get-regexp returns the names lowercased (anchor.issuerules); match them case-insensitively. Apply the keys relevant to an issue; absent keys keep anchor's defaults — never invent a value:

  • anchor.workTrackerBaseUri — when the author mentions a ticket (a full tracker URL, or a bare id), link it in the Context section: use a full URL as-is, or build <base-uri><id> from a bare id. No mention, no link.
  • anchor.issueRules — an extra standing rule layered onto every issue (the escape hatch for anything without a dedicated key).

anchor.reviewBudgetMins does not apply to issues. See ${CLAUDE_PLUGIN_ROOT}/guides/configuring.md for the full key set.

Body structure

Draft a concise imperative title (under 72 characters), then the body following the section template in templates/issue-description.md: Context, Proposed approach, Acceptance criteria, and Considerations (optional). The template owns the shape; the discipline below owns the technique.

  • Lead with why, write for the unfamiliar reader — the same ELI5 audience assumption prepare-review uses. Establish the system/business context in a sentence or two before the detail.
  • Keep the approach about the plan, not the code — what's being built and why the load-bearing decisions were made, not how every class is wired.
  • Define unfamiliar terms with short callouts (> **Term?** …), sparingly and only where a newcomer would be lost.
  • Diagram only when it carries shape prose hides — anchor's mermaid conventions (hand-drawn look, no \n/<br> in labels).
  • Same "what to avoid" discipline as a CR description — no loaded framing (${CLAUDE_PLUGIN_ROOT}/guides/loaded-framing.md), no drift artifacts, no leaked deliberation, nothing the reader can already see.
  • Watch the rendering gotchas — the body is pasted into a markdown renderer; the bundled ${CLAUDE_PLUGIN_ROOT}/guides/markdown-gotchas.md lists the traps (character escaping, nested fences, mermaid, <details>, tables in lists).

Step 5: Output

Write the drafted body to a temp file ($(mktemp -u "${TMPDIR:-/tmp}/issue-draft.XXXXXX").md).

Present the change. When updating an existing issue, diff the draft against the baseline captured in Step 1 and present it in a fenced diff block:

git --no-pager diff --no-index <current-path> <draft-path>

When creating a new issue, display the full title and body in a fenced code block.

Then ask the user how to proceed with the AskUserQuestion tool. Use header Disposition and these options (default first):

  • Yes (write) — create the issue (or push the updated body). The body comes from <draft-path>. On a 401/403 or similar auth failure, surface it and ask the user to refresh credentials — don't silently fall back to copy-only (per the fail-fast-on-auth rule).
  • No (copy only) — print the title and body for the user to paste into the web UI themselves.
  • Edit — adjust something, then re-present.

Yes (write)

anchor assigns new issues to you. The canonical invocations — including the glab api-then-glab issue update two-step GitLab needs for a file-sourced body, and the update-from-file forms — live in the bundled forge cookbook (${CLAUDE_PLUGIN_ROOT}/guides/forge-cookbook.md), sections "Issue create" and "Issue description update from a file".

When a tack target resolved (see Target repo), retarget these off the cwd repo: add -R <TARGET_PROJECT> to the gh issue calls; on GitLab substitute the URL-encoded TARGET_PROJECT for :fullpath and add --hostname <TARGET_HOST> on the glab api calls, and -R <TARGET_URL> on glab issue update.

# GitHub — create
gh issue create --title "<title>" --body-file <draft-path> --assignee @me

# GitHub — update
gh issue edit <num> --body-file <draft-path>
# GitLab — create (API form so the body can come from a file), then assign
glab api -X POST projects/:fullpath/issues -F title="<title>" -F "description=@<draft-path>"
glab issue update <iid> --assignee <username>

# GitLab — update
glab api -X PUT projects/:fullpath/issues/<iid> -F "description=@<draft-path>"

After the issue lands, print its URL.

Edit

A visual review is the preferred edit surface but optional — it runs when a review backend (moor by default, or revdiff) is available. When one is, open a one-off review of the current body vs. the draft (when updating) or the draft alone, launched via the dispatcher as a background Bash call so it doesn't hold the turn open:

bash "${CLAUDE_PLUGIN_ROOT}/scripts/review-diff.sh" --files \
  <current-path> <draft-path> \
  --title 'Issue body — proposed edits' \
  --detail repo=<repo>

Read the verdict back with the BashOutput tool (not tail / $(...)). Only REVIEW_VERDICT approved is approval; changes-requested carries comments in REVIEW_OUTPUT.comments to fold in before re-presenting (the fix-now entries when severitySource is graded, else every comment); incomplete / no-verdict mean the review didn't complete — surface what happened and fall back to chat rather than treating silence as approval. (The full verdict contract matches the prepare-review skill's Step 4.) If no review backend is available, fall back to chat: ask what to change, revise, and re-present.

What ships with it

Read from the repository

Just SKILL.md. No reference files, no scripts.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.