원클릭으로
capture-issue
Use when asked to capture or create an issue from conversation or natural language.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Use when asked to capture or create an issue from conversation or natural language.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Rewrite an issue's Implementation Steps, Acceptance Criteria, and Files to Modify in place from its own accumulated research findings, without appending or bulldozing human prose
Use when asked to audit documentation accuracy, coverage, or find documentation gaps.
Use when asked about project health, velocity, bug trends, or whether we're making progress.
Use when asked for an adversarial go/no-go review or whether an issue is worth implementing.
Use when asked to manually compact a session's memory, trigger session summarization, or reduce a long session's context footprint.
Use when asked to manually compact a session's memory, trigger session summarization, or reduce a long session's context footprint.
| name | capture-issue |
| description | Use when asked to capture or create an issue from conversation or natural language. |
| args | [description] [--quick] [--parent EPIC-NNN] |
| argument-hint | [description] |
| allowed-tools | ["Read","Glob","Grep","Write","Bash(ll-issues:*, git:*)","Bash(ll-session:*)"] |
| arguments | [{"name":"input","description":"Natural language description of the issue (optional - analyzes conversation if omitted)","required":false},{"name":"flags","description":"Optional flags (--quick for minimal template, --parent EPIC-NNN to link as child)","required":false}] |
| metadata | {"short-description":"Use when asked to capture or create an issue from conversation or natural langua"} |
You are tasked with capturing issues from either a natural language description or the current conversation context, with automatic duplicate detection and support for reopening completed issues.
This command uses project configuration from .ll/ll-config.json:
{{config.issues.base_dir}}{{config.issues.capture_template}} (full or minimal){{config.issues.duplicate_detection.exact_threshold}} (default: 0.8){{config.issues.duplicate_detection.similar_threshold}} (default: 0.5)open, in_progress, blocked, deferred, done, cancelled — see .claude/CLAUDE.md § Issue File Format for full enum and forbidden synonyms.$ARGUMENTS
--quick - Use minimal template regardless of config setting--parent EPIC-NNN - Link the new issue as a child of the given EPIC: sets parent: in child frontmatter and updates the EPIC's relates_to: list and ## Children sectionParse flags:
FLAGS="${flags:-}"
QUICK_MODE=false
if [[ "$FLAGS" == *"--quick"* ]]; then QUICK_MODE=true; fi
PARENT_ID=""
if [[ "$FLAGS" =~ --parent[[:space:]]+([A-Z]+-[0-9]+) ]]; then
PARENT_ID="${BASH_REMATCH[1]}"
fi
If --parent was given, validate it before proceeding:
{{config.issues.base_dir}}/epics/ for a file whose frontmatter id: matches PARENT_ID.❌ Parent EPIC not found: [PARENT_ID]. Check the ID and try again.
PARENT_EPIC_PATH for use in Phase 4c.Check the arguments to determine mode:
IF input argument is provided:
MODE = "direct"
ELSE:
MODE = "conversation"
Parse the natural language description to extract:
Analyze the current conversation session to identify potential issues:
For each potential issue found, extract:
Present all identified issues to the user:
## Issues Identified from Conversation
| # | Type | Priority | Title |
|---|------|----------|-------|
| 1 | BUG | P2 | [title] |
| 2 | ENH | P3 | [title] |
| 3 | FEAT | P3 | [title] |
| 4 | EPIC | P2 | [title] |
### Issue 1: [Title]
- **Type**: BUG (inferred from: "this keeps failing...")
- **Context**: [Brief quote from conversation]
### Issue 2: [Title]
- **Type**: ENH (inferred from: "we should improve...")
- **Context**: [Brief quote from conversation]
Use AskUserQuestion to let user select which issues to capture (multi-select):
questions:
- question: "Which issues would you like to capture?"
header: "Select issues"
options:
- label: "Issue 1: [title]"
description: "[type] - [brief context]"
- label: "Issue 2: [title]"
description: "[type] - [brief context]"
multiSelect: true
If no issues are identified, inform the user:
No actionable issues found in this conversation. You can run this command with an input argument:
/ll:capture-issue "description of the issue"
For each issue to capture, search for existing duplicates. This phase performs three checks: (1) Jaccard scoring against active issues, (2) Jaccard scoring against completed/cancelled issues, and (3) an FTS5 near-duplicate check against the session history DB using ll-session search --fts "<keywords>" --kind issue --limit 5 2>/dev/null || true. If .ll/history.db is absent or the query returns no results, proceed silently without warning.
Issue status lives in YAML frontmatter (status: open|done|deferred|cancelled),
not in directory location. Active issues are those with status: open (or
absent, which defaults to open).
# List all .md files under category dirs and filter to status: open
for dir in {{config.issues.base_dir}}/bugs/ {{config.issues.base_dir}}/features/ {{config.issues.base_dir}}/enhancements/ {{config.issues.base_dir}}/epics/; do
for f in "$dir"*.md; do
[ -f "$f" ] || continue
# Treat missing status: as "open"
status=$(awk '/^---$/{n++; next} n==1 && /^status:/{print $2; exit}' "$f")
case "${status:-open}" in
open|in_progress|blocked) echo "$f" ;;
esac
done
done
For each existing issue file:
# [TYPE]-[NNN]: [Title] headerScoring:
intersection / union of word setsCompleted issues live alongside active issues in their type directories,
distinguished by status: done (or cancelled) in frontmatter:
# Find completed issues by scanning type dirs and filtering status: done
ll-issues list --status done --format path
Apply same scoring. If a completed issue has score >= {{config.issues.duplicate_detection.similar_threshold}}, it's a candidate for reopening.
After Jaccard scoring, query the session history for recently closed or deferred issues matching the new issue's title keywords:
KEYWORDS=$(echo "<title>" | tr '[:upper:]' '[:lower:]' | grep -oE '\b[a-z]{3,}\b' | grep -vE '^(the|and|for|are|was|but|not|all|can|had|its|our|out|who|did|how|get|has|let|use|via|were|with|from|they|that|this|have|will|been|into|also|just|more|some|when|what|then|than|them|your|does|both|like)$' | tr '\n' ' ')
HIST_DUPES=$(ll-session search --fts "$KEYWORDS" --kind issue --limit 5 2>/dev/null || true)
If results include issues with status: done or status: deferred and >{{config.history.capture_issue.dup_overlap_threshold}} (default 0.7) title word overlap with the new issue title, surface a warning before writing the file:
Warning: Similar closed issue found: [ID] ([status]) — closed/deferred [N] days ago
Title: [existing issue title]
Proceed with new capture, or link to the existing issue instead?
Ask the user whether to proceed with capture or link to the existing issue. If .ll/history.db is absent or the query returns no results, proceed silently without warning.
Based on duplicate detection results, take appropriate action. See templates.md for detailed duplicate/similar handling flows including:
Proceed directly to issue creation without user confirmation.
Get next globally unique issue number:
ll-issues next-id
This prints the next available issue number as 3 digits (e.g., 071).
Determine target directory based on type:
{{config.issues.base_dir}}/bugs/{{config.issues.base_dir}}/features/{{config.issues.base_dir}}/enhancements/{{config.issues.base_dir}}/epics/Generate filename:
P[priority]-[TYPE]-[NNN]-[slug].mdP3-BUG-071-login-button-unresponsive.mdCreate issue file:
Determine template style:
IF QUICK_MODE is true:
TEMPLATE_STYLE = "minimal"
ELSE IF config.issues.capture_template is set:
TEMPLATE_STYLE = {{config.issues.capture_template}}
ELSE:
TEMPLATE_STYLE = "full"
Build issue from shared template:
ll-issues sections {type} to get the per-type template where {type} is bug, feat, enh, or epic based on the issue type (v2.0 - optimized for AI implementation)creation_variants.[TEMPLATE_STYLE] to determine which sections to includeinclude_common, use common_sections.[name].creation_template as placeholder contentinclude_type_sections is true, also include sections from type_sections that have a creation_templatecaptured_at (ISO 8601 UTC timestamp, e.g. "2026-04-18T14:32:07Z" — use shell date -u +"%Y-%m-%dT%H:%M:%SZ" format), discovered_date (date-only, same day), and discovered_by: capture-issue. If PARENT_ID is set, also include parent: [PARENT_ID] in the frontmatter.testable: false — after building the frontmatter, scan the issue title and description for doc-only signal keywords:
testable: false to frontmatter and log ℹ️ Set testable: false (inferred: documentation-only issue)testable from frontmatter (absence means testable)New sections in v2.0 (auto-included based on template variant):
See templates.md for the complete issue file template structure.
## Session Log
- `/ll:capture-issue` - [ISO timestamp] - `[path to current session JSONL]`
To find the current session JSONL: look in ~/.claude/projects/ for the directory matching the current project (path encoded with dashes), find the most recently modified .jsonl file (excluding agent-*). Add the ## Session Log section before the --- / ## Status footer.
For FEAT or EPIC captures, append a decision entry to the log (silent no-op when the decisions log is absent; skip entirely for BUG type). The log is hybrid storage — a legacy .ll/decisions.yaml flat file and/or .ll/decisions.d/*.json fragments — so gate on either (a fresh, never-compacted install has only the fragment dir):
if [ "$ISSUE_TYPE" != "BUG" ] && { [ -f .ll/decisions.yaml ] || [ -d .ll/decisions.d ]; }; then
ll-issues decisions add \
--type=decision \
--category="architecture" \
--issue="$ISSUE_ID" \
--rule="Captured: $ISSUE_TITLE" \
--rationale="$ISSUE_SUMMARY" \
--scope=issue \
2>/dev/null || true
fi
git add "{{config.issues.base_dir}}/[category]/[filename]"
Duplicate-ID recovery: If the PostToolUse hook reports that the just-written file was deleted (duplicate integer ID detected), the
Writecall will have returned success but the file no longer exists. Re-allocate a fresh ID by callingll-issues next-idagain, generate a new filename with the new number, and repeat from step 3. Do not reuse the original ID.
See templates.md for the complete document linking process including:
.ll/ll-config.jsonSkip this phase if:
documents.enabled is not true in .ll/ll-config.jsondocuments.categories--parent was given)Skip this phase if PARENT_ID is empty.
After the child issue file is created and staged, update the EPIC at PARENT_EPIC_PATH:
relates_to: frontmatterRead the EPIC file's frontmatter. The relates_to: field may be:
relates_to: [CHILD_ID] after the last frontmatter fieldrelates_to: [] — replace with relates_to: [CHILD_ID]Use Edit to apply the change in-place. Example:
# Before
relates_to: [ENH-100, ENH-101]
# After
relates_to: [ENH-100, ENH-101, CHILD_ID]
## Children sectionIf the EPIC body already contains a ## Children section, append a new bullet at the end of it:
- **CHILD_ID** — [one-sentence child title from the child's Summary]
If no ## Children section exists, insert one before ## Status (or at end of file if no Status footer):
## Children
- **CHILD_ID** — [one-sentence child title]
Use Edit to apply the change. Do not rewrite the whole file.
git add "PARENT_EPIC_PATH"
Append an "Additional Context" section to the existing issue:
cat >> "[path-to-existing-issue]" << 'EOF'
---
## Additional Context
- **Date**: [YYYY-MM-DD]
- **Source**: capture-issue
[New context/findings from the description or conversation]
EOF
Stage the updated file:
git add "[path-to-existing-issue]"
Issue status lives in frontmatter — reopening means flipping status: done
back to status: open. The file stays where it is in its type directory.
Update the file's frontmatter and append a Reopened section:
status: done).ll-issues set-status ISSUE_ID open to flip the status atomically.
If the issue has no id: field (legacy file), fall back to Edit to insert
status: open into the YAML frontmatter block.---
## Reopened
- **Date**: [YYYY-MM-DD]
- **By**: capture-issue
- **Reason**: Issue recurred or was not fully resolved
### New Findings
[Context from the new description or conversation that prompted reopening]
Stage the changes:
git add "[path-to-issue]"
See templates.md for complete output report templates including:
# Capture issue from explicit description (bug)
/ll:capture-issue "The login button doesn't respond on mobile Safari"
# Capture issue from explicit description (feature)
/ll:capture-issue "We should add dark mode support to the settings page"
# Capture issue from explicit description (enhancement)
/ll:capture-issue "The API response time could be improved with caching"
# Analyze current conversation for issues to capture
/ll:capture-issue
# Capture with minimal template (quick mode)
/ll:capture-issue "Quick note: cache is slow" --quick
# Analyze conversation and use minimal templates
/ll:capture-issue --quick
# Capture a child issue and link it to an existing EPIC
/ll:capture-issue "Add retry logic to sprint runner" --parent EPIC-1663
# Child with minimal template
/ll:capture-issue "Fix log output truncation" --parent EPIC-1626 --quick
After capturing issues:
cat [issue-path] to verify content/ll:ready-issue [ID] to check accuracy/ll:prioritize-issues if priority needs adjustment/ll:link-epics to assign parentless issues to open epics/ll:commit to save new issues/ll:manage-issue [type] [action] [ID] to implement