Skip to content
Development
Command

/issue

Create a well-structured GitHub issue that the pipeline can consume reliably

BOOST
From plugin
forgedock
11980 skills80 commands
Install
> /plugin marketplace add RapierCraftStudios/ForgeDock
> /plugin install forgedock@forgedock

How it fires

How this command gets triggered: by you, by Claude, or both.

  • Fires itselfClaude auto-loads it when your prompt matches the work.
  • You can call itInvoke it directly when you want it.
  • Slash command/issue

Context preview

What this command does when you run it.

Create a well-structured GitHub issue that the pipeline can consume reliably

Command definition

issue.md
description: Create a well-structured GitHub issue that the pipeline can consume reliably
argument-hint: "[description of the problem or feature] [--dry-run] | --title \"...\" --body-file <path> --label \"...\" [--milestone \"...\"] [--dry-run]"

<!-- SPDX-FileCopyrightText: Copyright (c) RapierCraft Studios --> <!-- SPDX-License-Identifier: AGPL-3.0-or-later -->

/issue — Deterministic Issue Creator

> **Skill names**: `{FORGE_SKILL_PREFIX}` is `forgedock:` (plugin install) or empty (`install.sh`), resolved once per run by `commands/work-on.md` § Skill Name Resolution. If the skill is not found under either name, STOP and report "skill not found" — never run the phase inline.

**Input**: $ARGUMENTS

You create GitHub issues with the structure the `/work-on` pipeline expects. Every deterministic step (argument parsing, body-file integrity, dedup, mandatory sections, REST create with token read-back, milestone, project board) runs in `scripts/issue-create.sh`. This spec holds only routing and the drafting judgment. Issues are created by default once the checks pass; `--dry-run` prints the draft instead.

**Agent model policy**: `model: "{DEFAULT_MODEL}"` — resolved from forge.yaml `agents.default_model`, else "sonnet". Fallback: `model: "opus"` if rate-limited. Feature gate: pass `effort` in Task/Skill spawns only on Claude Code >= 2.1.154. **NEVER use plan mode (EnterPlanMode).**

Arguments

| Flag | Effect | |------|--------| | (none) | Interactive: read code, draft, then create through the script (below). | | `--dry-run` | Validate and print the draft; create nothing. Never bypasses the dedup STOP. | | `--greenfield` | Affected Files may be *planned* paths, validated against the spike doc's declared repo layout (Validate, below). Also on automatically when the spike doc has a `Repo layout` heading. <!-- Added: forge#4172 --> | | `--spike <path>` | Spike doc for greenfield mode (implies `--greenfield`). Default `docs/engineering/technical-spike.md`, repo-relative. | | `--title "..."` | **The sole programmatic-mode trigger.** Final title; skips drafting. | | `--body "..."` / `--body-file <path>` | Final body; exactly one is required with `--title`. | | `--label "..."` | One label; repeatable. | | `--milestone "..."` | Milestone title (optional). | | `--exclude "N,N,..."` | Issue numbers removed from the dedup candidate set (a deliberate supersede, e.g. a P3 batch issue restating its members). Narrows the set; NOT a `--force` equivalent. |

Programmatic Mode (`--title` present)

Run exactly one call and relay its result. Do not read code, draft, or re-run any check yourself.

type forge_resolve >/dev/null 2>&1 || { setopt nonomatch 2>/dev/null || true; FORGE_SOURCED_ROOT='${CLAUDE_PLUGIN_ROOT}'; for _r in "$(cygpath -u "${FORGEDOCK_HOME:-}" 2>/dev/null || printf %s "${FORGEDOCK_HOME:-}")" '${CLAUDE_PLUGIN_ROOT}' "${FORGE_ROOT:-}" "${FORGE_HOME:-}" "$(readlink -f "$HOME/.claude/commands/work-on.md" 2>/dev/null | sed 's|/commands/work-on\.md$||')" "$(head -n 1 "${CODEX_HOME:-$HOME/.codex}/forge-home" 2>/dev/null)" "$HOME/.claude/plugins/marketplaces/forgedock" "${CLAUDE_CONFIG_DIR:-$HOME/.claude}"/plugins/cache/forgedock/forgedock/* "$HOME/.claude"/plugins/cache/forgedock/forgedock/*; do case "$_r" in /*) [ -f "$_r/scripts/lib/forge-resolve.sh" ] && { . "$_r/scripts/lib/forge-resolve.sh"; break; };; esac; done; type forge_resolve >/dev/null 2>&1 || forge_resolve() { :; }; }
ISSUE_CREATE_SCRIPT=$(forge_resolve issue-create.sh)
[ -n "$ISSUE_CREATE_SCRIPT" ] || { echo "ERROR: issue-create.sh not found in a trusted ForgeDock install" >&2; echo "ISSUE_CREATE_RESULT:ERROR"; exit 3; }
bash "$ISSUE_CREATE_SCRIPT" --args "$ARGUMENTS"

The script prints exactly one result line; report it verbatim and exit with its code:

| Exit | Line | Meaning | |------|------|---------| | 0 | `ISSUE_CREATE_RESULT:CREATED number=N url=U` | Created; the create-token read-back (and, for `--body-file`, the integrity marker read-back) passed | | 0 | `ISSUE_CREATE_RESULT:DRY_RUN` | `--dry-run`: draft printed, nothing created | | 1 | `ISSUE_CREATE_RESULT:DEDUP number=N` | Open near-duplicate #N; nothing created. STOP | | 2 | `ISSUE_CREATE_RESULT:USAGE` | Bad flags, body, integrity marker or dedup invocation; fix the call | | 3 | `ISSUE_CREATE_RESULT:ERROR` | GitHub rejected the create or a read-back failed; never report success |

The repo comes from `forge.yaml` (`project.owner/project.repo`); pass `--repo OWNER/NAME` outside `--args` for a satellite repo. Missing `## Problem`, `## Affected Files` or `## Acceptance Criteria` sections get placeholders, never a failure.

`--body-file` integrity contract (MANDATORY for the caller)

Do not use a generic name under shared `/tmp`, even with `mktemp`. Prefer the session scratchpad (or a repo-relative scratch directory): a Windows-native `gh` may not resolve Git Bash `/tmp`. Never hand-roll a temporary path or use a single-segment root path such as `/tmp_invbody_31076.txt`, which can require interactive deletion approval and hang unattended runs. Make the filename include the target issue or PR number and an agent-unique token, and let `mktemp` add the random suffix:

SCRATCHPAD="${FORGE_SCRATCHPAD:-$PWD/.forge-scratch}"
AGENT_TOKEN="${AGENT_ID:-${HOSTNAME:-agent}-$$}"
mkdir -p "$SCRATCHPAD"
BODY_MARKER="FORGE:BODY-INTEGRITY:${PR_NUMBER}_review_${AGENT_TOKEN}"
BODY_FILE=$(mktemp "$SCRATCHPAD/${PR_NUMBER}_review_${AGENT_TOKEN}.XXXXXX.md")
printf '%s\n<!-- %s -->\n' "$BODY" "$BODY_MARKER" > "$BODY_FILE"

The body MUST contain exactly one marker `<!-- FORGE:BODY-INTEGRITY:<entity>_<role>_<agent-token> -->` on its own line. The script refuses a body with zero or several markers, and after creation re-reads the issue and requires that exact line: a path collision can substitute another agent's plausible-looking body (forge#2843).

Interactive Mode (free text)

1. Parse the request

  • **Repo**: default from `forge.yaml`; a `{satellite_
Read more
Ships withforgedock

ForgeDock — autonomous AI dev pipeline for Claude Code. GitHub as agent memory: issue in, PR out.

Get the whole plugin

Other commands on forgedock.