agentleFS
nexus-a1nexus-a1/claude-skills/skills/report-issue/SKILL.md

report-issue

Skill1 starsChanged 28 days agoMITView on GitHub

Draft and submit a bug report or feature request to the nexus plugin repository, using current conversation context to auto-populate details.

  • Reads credentials

5 other projects use a version of this.

Adopted by

Most recently taken up by

The file

Show its rules and text

We split this skill into the rules it gives an agent

15 rules. 0 are common, 10 are distinctive, and 5 are very specific to this project.

  • 0

    Common

    Most of the 4 edited versions we read keep these.

  • 10

    Distinctive

    This author's own choices. Worth a look.

  • 5

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    If --feature-request is present → TYPE=feature-request, label enhancement

    line 29
  2. Distinctive:

    If the command fails (exit code non-zero), stop immediately:

    line 40
  3. Distinctive:

    Before showing the draft, scan the full body and the title for sensitive content.

    line 144
  4. Distinctive:

    After redaction, surface a summary of what was redacted (by category, not by value):

    line 173
  5. Distinctive:

    If nothing was redacted, say so:

    line 184
  6. Distinctive:

    If the user selects "Yes", use AskUserQuestion again with an open prompt to collect their note.

    line 218
  7. Very specific:

    If the user provides input, append it to the body under a ## Additional Notes section.

    line 220
  8. Distinctive:

    If the user added no note, skip the second scan.

    line 231
  9. Distinctive:

    Use the AskUserQuestion tool:

    line 256
  10. Very specific:

    If No: stop and display Issue cancelled.

    line 264
  11. Very specific:

    If Yes: before invoking gh issue create, run a deterministic regex scan over the body and title.

    line 268
  12. Very specific:

    If the gate hard-blocks, the skill stops here.

    line 324
  13. Distinctive:

    If the deterministic gate passes, create the issue.

    line 328
  14. Distinctive:

    If the conversation has no discernible error or feature request to base the draft on, use the AskUserQuestion tool to ask:

    line 435
  15. Distinctive:

    Use their response as the primary input for the draft.

    line 442

“Common” is measured: kept by at least 6 in 10 of the 4 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Report Issue

Arguments: $ARGUMENTS

Draft a GitHub issue for the nexus plugin repository based on the current conversation context. Invoke this immediately after noticing a bug or wanting to request a feature — while the context is still fresh.

Usage

/report-issue                    # Report a bug (default)
/report-issue --feature-request  # Report a feature request

Step 1: Determine Issue Type

Parse $ARGUMENTS:

  • If --feature-request is present → TYPE=feature-request, label enhancement
  • Otherwise → TYPE=bug, label bug

Step 2: Early Auth Check

gh auth status 2>/dev/null

If the command fails (exit code non-zero), stop immediately:

⚠️  Not authenticated with GitHub. Run: gh auth login
Issue cannot be submitted without authentication.

Step 3: Get Plugin Version

jq -r '.plugins["nexus@claude-skills"][0].version // "unknown"' \
  ~/.claude/plugins/installed_plugins.json 2>/dev/null || echo "unknown"

Store as PLUGIN_VERSION.


Step 4: Build Draft from Conversation Context

Using the current conversation context, extract the following. Be concise — aim for enough detail to reproduce or understand the issue, not a full session dump.

For TYPE=bug

Extract:

  • What happened — the error or unexpected behavior observed
  • Error message — exact error text if visible in the conversation (quote verbatim, but redact secrets — see field instructions below)
  • Context — which skill or agent was running, what the user was trying to do (general terms only, no internal hostnames or paths)
  • Trigger — what action or input caused it

Per-field constraints (apply during extraction, before the Step 5 scan):

  • Description: One sentence summarizing the bug. No file paths, hostnames, tokens, or PII.
  • Error: Quote verbatim if available. If the error contains tokens, passwords, API keys, connection strings, email addresses, internal hostnames, or absolute file paths, replace those substrings with [REDACTED] before including the quote. Keep the structural shape of the error (e.g., connection refused: [REDACTED]).
  • Context: Describe what skill/agent was active and what the user was attempting in general terms. Do NOT include internal hostnames, service names, cluster names, or absolute file paths.
  • Steps to Reproduce: Describe steps abstractly. Do NOT include credentials, absolute paths, or hostnames in step descriptions.
  • Environment: Plugin version only — no OS, shell, CWD, git remote, or username.

Compose the issue body using this template:

## Description

{one-sentence summary of the bug}

## Error

{verbatim error with secrets redacted as [REDACTED]; if no error available, describe behavior}

## Context

{skill/agent that was active, what the user was attempting — general terms only}

## Steps to Reproduce

1. {step 1, abstract — no paths/hosts/credentials}
2. {step 2}
3. {add more if clear from context, otherwise omit}

## Environment

- Plugin version: {PLUGIN_VERSION}

For TYPE=feature-request

Extract:

  • What capability is missing or needed — derived from what the user was trying to do
  • Problem it solves — why this matters based on the conversation

Compose the issue body using this template:

## Description

{one-sentence summary of the requested feature}

## Problem

{what the user was trying to do and why the current behavior falls short}

## Proposed Behavior

{what the skill/agent/workflow should do instead}

## Context

{which skill or agent this relates to, if applicable}

## Environment

- Plugin version: {PLUGIN_VERSION}

Generate a concise issue title:

  • Bug: [bug] {skill-or-agent}: {short description} — e.g., [bug] nexus:commit: unknown skill nexus:git-operator error
  • Feature: [feature] {short description} — e.g., [feature] report-issue: support attaching file paths

Step 5: Sensitivity Check

Before showing the draft, scan the full body and the title for sensitive content. This is a soft, LLM-driven first pass; a deterministic bash gate in Step 7 catches anything missed here.

Patterns to detect

Known prefixes (high-confidence — match by prefix anywhere in the text):

  • AKIA[0-9A-Z]{16}, ASIA[0-9A-Z]{16} — AWS access key IDs
  • ghp_, gho_, ghu_, ghs_, ghr_ followed by alphanumerics — GitHub personal access tokens
  • xox[baprs]- followed by alphanumerics — Slack tokens
  • -----BEGIN (any header) — private keys, certificates, PEM blocks (redact the entire block through -----END ...-----)
  • eyJ followed by a long base64 string with two more .-separated segments — JWTs
  • postgres://, mysql://, mongodb://, redis:// — database connection strings (especially if user:password@ is embedded)
  • AIza[0-9A-Za-z_-]{35} — Google API keys
  • sk_live_…, rk_live_…, pk_live_… — Stripe live keys
  • sk-ant- followed by alphanumerics — Anthropic API keys
  • sk- followed by 32+ alphanumerics — OpenAI-style API keys
  • Authorization: Bearer … and Authorization: Basic … — auth header values (redact the value, keep the header name)

Structural patterns (match by shape):

  • Absolute paths: /home/[name]/…, /Users/[name]/…, C:\Users\…, \\[host]\[share]\…, /mnt/c/Users/…, /private/var/folders/…
  • .env-style assignments where the key name suggests a secret — PASSWORD=, SECRET=, TOKEN=, API_KEY=, PRIVATE_KEY=, DATABASE_URL=, DSN=, AUTH_TOKEN= — redact the value regardless of length
  • Email addresses matching [A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,} — but keep GitHub @username mentions (shape: @ + 1–39 alphanumerics/hyphens, no domain)
  • Internal hostnames or service names that weren't already part of the error/context (e.g., db-prod-1.corp.internal, kafka-east-cluster)

Action

For each match, replace the matched substring with [REDACTED] in both the body and the title. Preserve the surrounding text so the issue remains intelligible.

After redaction, surface a summary of what was redacted (by category, not by value):

⚠️  Sensitivity scan — redacted content:
  - 1× AWS access key ID
  - 2× absolute paths
  - 1× email address

The draft below shows redacted content. Review before confirming.

If nothing was redacted, say so:

✓ Sensitivity scan — no patterns matched.

Step 6: Show Draft and Ask for Additions

Display the full draft:

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Issue Draft
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Repo:  nexus-a1/claude-skills
Type:  {bug | feature-request}
Label: {bug | enhancement}

Title: {title}

{body}
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Then use the AskUserQuestion tool:

header: "Add notes"
question: "Anything to add to this issue before sending?"
options: ["No, looks good", "Yes, I want to add a note"]

If the user selects "Yes", use AskUserQuestion again with an open prompt to collect their note.

If the user provides input, append it to the body under a ## Additional Notes section.

Second sensitivity scan (after notes appended)

If the user added a note, re-run the full Step 5 sensitivity check against the complete updated body (description + error + context + steps + environment + additional notes). User-supplied notes never reach gh issue create without being scanned. If new patterns are detected, redact them in place and surface a fresh summary:

⚠️  Second sensitivity scan (after Additional Notes) — redacted content:
  - 1× GitHub PAT

If the user added no note, skip the second scan.


Step 7: Confirm and Submit

Render exact final payload

Show the user the exact title and body bytes that will be POSTed — not a paraphrase. This must reflect post-Step-5 (and post-Step-6 second-scan) content:

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Final payload (post-redaction)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Repo:  nexus-a1/claude-skills (PUBLIC — visible to anyone, indexed by search engines)
Label: {bug | enhancement}

Title: {final title}

{final body}
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Confirmation

Use the AskUserQuestion tool:

header:   "Confirm"
question: "Submit this issue to nexus-a1/claude-skills (public GitHub repository — will be publicly visible and indexed by search engines)?"
options:  ["Yes, submit to public repo", "No, cancel"]

If No: stop and display Issue cancelled. Draft was not submitted.

Deterministic pre-submit scan gate (hard block)

If Yes: before invoking gh issue create, run a deterministic regex scan over the body and title. This is a non-LLM enforcement layer that catches secrets the Step 5 / Step 6 LLM scans may have missed. A match here hard-blocks submission.

# The draft lives in the project work area, not /tmp, and not under an mktemp
# name. Both matter, for different reasons:
#   - mktemp names do not survive a Bash tool call, and neither does the
#     variable holding one. The submit block below is a separate call, so it
#     could never have named the file the gate scanned.
#   - a PREDICTABLE name in a world-writable directory is the vector mktemp was
#     avoiding: another process can pre-create or symlink /tmp/<known-name>
#     between the write and the read. A private directory under .claude with
#     umask 077 gives a stable name without that exposure.
umask 077
SCAN_DIR=".claude/report-issue"
mkdir -p "$SCAN_DIR"
BODY_FILE="$SCAN_DIR/body.md"
ERROR_FILE_PRE="$SCAN_DIR/error.log"
# A stable name can be pre-created as a SYMLINK by anything that can write the
# directory, and `cat >` follows it: the draft would overwrite the link target
# and then be published from it. Refuse a symlink outright, and remove any
# existing file before writing so `set -C` cannot be satisfied by a leftover.
for _f in "$BODY_FILE" "$ERROR_FILE_PRE" "$SCAN_DIR/scan-patterns.txt"; do
  if [ -L "$_f" ]; then
    echo "⛔ Refusing to write: $_f is a symlink. Remove it and re-run." >&2
    return 1 2>/dev/null || exit 1
  fi
  rm -f "$_f"
done
set -C   # no clobber: a file appearing between the rm and the write is a race
ERROR_FILE="$SCAN_DIR/error.log"
PATTERN_FILE="$SCAN_DIR/scan-patterns.txt"
cat > "$BODY_FILE" << 'REPORT_ISSUE_BODY_EOF'
{full issue body, post-redaction}
REPORT_ISSUE_BODY_EOF

ISSUE_TITLE='{final title, post-redaction}'

# Written to a file as well as used here, so the re-scan in the submit block
# uses THE SAME patterns rather than a second copy that can drift from this one.
SCAN_PATTERNS='AKIA[0-9A-Z]{16}|ASIA[0-9A-Z]{16}|ghp_[A-Za-z0-9_]+|gho_[A-Za-z0-9_]+|ghu_[A-Za-z0-9_]+|ghs_[A-Za-z0-9_]+|ghr_[A-Za-z0-9_]+|xox[baprs]-[A-Za-z0-9-]+|-----BEGIN [A-Z ]+-----|sk_live_[A-Za-z0-9]+|rk_live_[A-Za-z0-9]+|sk-ant-[A-Za-z0-9-]+|AIza[0-9A-Za-z_-]{35}'

printf '%s\n' "$SCAN_PATTERNS" > "$PATTERN_FILE"

if grep -qE "$SCAN_PATTERNS" "$BODY_FILE" || echo "$ISSUE_TITLE" | grep -qE "$SCAN_PATTERNS"; then
  echo "⛔ Submission blocked — deterministic scan detected a high-confidence secret pattern in the draft." >&2
  echo "Matched categories:" >&2
  { grep -oE "$SCAN_PATTERNS" "$BODY_FILE"; echo "$ISSUE_TITLE" | grep -oE "$SCAN_PATTERNS"; } \
    | sed -E 's/(AKIA|ASIA)[0-9A-Z]+/AWS access key/; s/ghp_[A-Za-z0-9_]+/GitHub PAT (ghp_)/; s/gho_[A-Za-z0-9_]+/GitHub PAT (gho_)/; s/ghu_[A-Za-z0-9_]+/GitHub PAT (ghu_)/; s/ghs_[A-Za-z0-9_]+/GitHub PAT (ghs_)/; s/ghr_[A-Za-z0-9_]+/GitHub PAT (ghr_)/; s/xox[baprs]-[A-Za-z0-9-]+/Slack token/; s/-----BEGIN.*-----/PEM key block/; s/sk_live_[A-Za-z0-9]+/Stripe live key/; s/rk_live_[A-Za-z0-9]+/Stripe restricted key/; s/sk-ant-[A-Za-z0-9-]+/Anthropic API key/; s/AIza[0-9A-Za-z_-]+/Google API key/' \
    | sort -u | sed 's/^/  - /' >&2
  echo "" >&2
  echo "The LLM redaction in Steps 5/6 missed at least one secret. Edit the conversation to remove the secret values, then re-run /report-issue." >&2
  rm -f "$BODY_FILE" "$ERROR_FILE" "$PATTERN_FILE"
  false
fi

If the gate hard-blocks, the skill stops here. Do not retry, do not call gh issue create. The user must remove the secret from conversation context (or paste a corrected note) and re-invoke.

Submission

If the deterministic gate passes, create the issue. The scan is re-run here, in the same call as the publish. The gate above runs in a different Bash tool call, and between the two the file can change — the model can edit it, a stale file can be left at the same path by an earlier run, another process can write to it. A scan in one call and a publish in another cannot make the claim this gate exists to make; only a scan and a publish in the same call can, so the last thing before gh issue create is the scan itself.

umask 077
SCAN_DIR=".claude/report-issue"
BODY_FILE="$SCAN_DIR/body.md"
ERROR_FILE="$SCAN_DIR/error.log"
PATTERN_FILE="$SCAN_DIR/scan-patterns.txt"
ISSUE_TITLE='{final title, post-redaction}'
# Same symlink refusal on the read side: publishing through a link would send
# whatever the link points at, which is not what the gate scanned.
for _f in "$BODY_FILE" "$PATTERN_FILE"; do
  if [ -L "$_f" ]; then
    echo "⛔ Refusing to publish: $_f is a symlink, so it is not the file that was scanned." >&2
    false
  fi
done

# Re-scan the exact bytes about to be published, with the patterns the gate
# wrote. Refuse if either file is missing: an unreadable scan is not a clean
# scan, and "the gate already ran" is a claim about a different call.
if [ ! -r "$BODY_FILE" ] || [ ! -r "$PATTERN_FILE" ]; then
  echo "⛔ Refusing to publish: the scanned draft or its patterns are missing — re-run the gate." >&2
  false
else
  grep -qE -f "$PATTERN_FILE" "$BODY_FILE"
  body_rc=$?
  printf '%s' "$ISSUE_TITLE" | grep -qE -f "$PATTERN_FILE"
  title_rc=$?
  if [ "$body_rc" -eq 0 ] || [ "$title_rc" -eq 0 ]; then
    echo "⛔ Refusing to publish: a secret pattern is present in the bytes about to be sent." >&2
    false
  elif [ "$body_rc" -ge 2 ] || [ "$title_rc" -ge 2 ]; then
    echo "⛔ Refusing to publish: the pre-publish scan itself failed (grep exit $body_rc/$title_rc) — that is not a clean scan." >&2
    false
  else

gh issue create \
  --repo "nexus-a1/claude-skills" \
  --title "$ISSUE_TITLE" \
  --body-file "$BODY_FILE" \
  --label "{bug|enhancement}" 2>"$ERROR_FILE"

GH_RC=$?
if [ $GH_RC -ne 0 ]; then
  if grep -qi "label" "$ERROR_FILE"; then
    # Label doesn't exist — retry without it
    gh issue create \
      --repo "nexus-a1/claude-skills" \
      --title "$ISSUE_TITLE" \
      --body-file "$BODY_FILE"
    GH_RC=$?
  else
    # Different error — surface it
    cat "$ERROR_FILE" >&2
  fi
fi

    rm -f "$BODY_FILE" "$ERROR_FILE" "$PATTERN_FILE"
    [ $GH_RC -eq 0 ] || false
  fi
fi

Using --body-file avoids shell quoting issues with error messages, stack traces, and special characters in the body. The title is passed through --title "$ISSUE_TITLE" (argv, never via bash -c or string interpolation) to prevent shell-metacharacter injection. Stderr is captured to a temp file so label-not-found errors trigger a no-label fallback; cleanup runs on every path before the final exit.


Step 8: Report Result

On success:

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✓ Issue Submitted
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

{issue URL}
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

On failure:

⚠️  Could not create issue. gh error:
{error output}

The draft was not submitted. You can create it manually at:
https://github.com/nexus-a1/claude-skills/issues/new

Error Handling

gh not authenticated

⚠️  Not authenticated with GitHub. Run: gh auth login

No conversation context to extract

If the conversation has no discernible error or feature request to base the draft on, use the AskUserQuestion tool to ask:

header: "Describe issue"
question: "What issue would you like to report?"

Use their response as the primary input for the draft.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.