Skip to content
Back to skills

Mastermind Issue Detail

BSecurity

Mastermind issue-detail — inspect and manage one org task: thread, run history, comments, sub-issues, attachments, assignment, closing and recovery.

  • 21 stars
  • 0 votes
  • 0 copies
  • 3 views
  • Added September 10, 2026
ai-agentspythongobash

Security analysis

B88/100
  • criticalSends environment variables or credentials to an external URL

Pro shows the line behind each finding and how to fix it

Scanned October 1, 2026

npx -y skills add monoes/monomind --skill mastermind-issue-detail --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Mastermind Issue Detail?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Mastermind Issue Detail
[![Security: B — Skills Directory](https://www.skillsdirectory.com/api/skills/monoes-mastermind-issue-detail/badge)](https://www.skillsdirectory.com/skills/monoes-mastermind-issue-detail)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: mastermind-issue-detail
description: "Mastermind issue-detail — inspect and manage one org task: thread, run history, comments, sub-issues, attachments, assignment, closing and recovery."
type: domain-skill
default_mode: auto
pick: low
---

# Mastermind Issue Detail

This skill is invoked directly via `/mastermind-issue-detail`.

---

## Inputs

- `brain_context`: BRAIN CONTEXT block (injected by command, or loaded below if standalone)
- `org_name`: org the issue belongs to (required)
- `issue_id`: issue id/slug (required)
- `action`: show | thread | runs | sub-issues | attachments | comment | assign | close | reopen | recover
- `comment_body`: comment text (required for comment action)
- `assignee_id`: agent id to assign (required for assign action)
- `recovery_action`: accept | reject (for recover action)
- `days`: lookback window for run history (default 14)
- `caller`: command | master

---

## Issue Status Flow

```
todo → in_progress → in_review → done
         ↓
      blocked → in_progress
         ↓
    cancelled
```

Recovery actions apply when an issue enters `needs_recovery` state after a failed run.

---

## Step 0 — Brain Load (standalone only)

If `caller` is not "command", load brain context following mastermind-protocol/SKILL.md Brain Load Procedure with namespace: `ops`.

---

## Step 1 — Load Issue Data

```bash
orgFile=".monomind/orgs/${org_name}.json"
[ ! -f "$orgFile" ] && { echo "ERROR: Org '${org_name}' not found."; exit 1; }

issuesFile=".monomind/orgs/${org_name}-issues.json"
[ ! -f "$issuesFile" ] && { echo "ERROR: No issues file for org '$org_name'. Create issues via /mastermind-issues --action create."; exit 1; }

issueDef=$(jq -r --arg id "$issue_id" '(.issues // [])[] | select(.id == $id or .slug == $id)' "$issuesFile")
[ -z "$issueDef" ] && { echo "ERROR: Issue '$issue_id' not found in org '$org_name'."; exit 1; }

resolvedId=$(echo "$issueDef" | jq -r '.id')
activityFile=".monomind/orgs/${org_name}-activity.jsonl"
threadFile=".monomind/orgs/${org_name}-threads.jsonl"
days=${days:-14}
cutoff=$(date -u -v-${days}d +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -u -d "${days} days ago" +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || echo "")
```

Normalize any legacy records written by a pre-2.10 version of these skills. Idempotent — safe to run on every load.

```bash
python3 - "$issuesFile" <<'PYEOF'
import json, sys
path = sys.argv[1]
data = json.load(open(path))
RENAME = {
    "assignee_id": "assigneeId", "assigned_to": "assigneeId",
    "created_at": "createdAt", "updated_at": "updatedAt",
    "closed_at": "closedAt", "project_id": "projectId",
    "parent_id": "parentId", "recovery_status": "recoveryStatus",
    "lastActivityAt": "updatedAt",
}
changed = False
for iss in data.get("issues", []):
    for old, new in RENAME.items():
        if old in iss:
            iss.setdefault(new, iss.pop(old))
            iss.pop(old, None)
            changed = True
    if iss.get("status") == "open":
        iss["status"] = "todo"
        changed = True
if changed:
    tmp = path + ".tmp"
    with open(tmp, "w") as f:
        json.dump(data, f, indent=2)
    import os; os.replace(tmp, path)
PYEOF
```

---

## Step 2 — Execute Action

### show (default)

```bash
echo "ISSUE DETAIL — $issue_id @ $org_name"
echo "────────────────────────────────────────────────────────"

echo "$issueDef" | jq -r '
  "  ID:            \(.id)",
  "  Title:         \(.title // "(no title)")",
  "  Status:        \(.status // "todo")",
  "  Priority:      \(.priority // "medium")",
  "  Assignee:      \(.assigneeId // "(unassigned)")",
  "  Agent:         \(.assigneeAgentId // "(none)")",
  "  Project:       \(.projectId // "(none)")",
  "  Created:       \(.createdAt // "-")",
  "  Updated:       \(.updatedAt // "-")"
'

# Sub-issues
subCount=$(jq --arg pid "$resolvedId" '[(.issues // [])[] | select(.parentId == $pid)] | length' "$issuesFile" 2>/dev/null || echo 0)
echo "  Sub-issues:    $subCount"

# Attachments
attCount=$(echo "$issueDef" | jq -r '(.attachments // []) | length')
echo "  Attachments:   $attCount"

# Recovery
recoveryStatus=$(echo "$issueDef" | jq -r '.recoveryStatus // "none"')
[ "$recoveryStatus" != "none" ] && echo "" && echo "  RECOVERY STATUS: $recoveryStatus"

# Description
desc=$(echo "$issueDef" | jq -r '.description // ""')
if [ -n "$desc" ]; then
  echo ""
  echo "DESCRIPTION"
  echo "────────────────────────────────────────────────────────"
  echo "$desc" | head -10
fi
```

### thread

```bash
echo "THREAD — $issue_id"
echo "────────────────────────────────────────────────────────"

found=0
if [ -f "$threadFile" ]; then
  while IFS= read -r line; do
    iid=$(echo "$line" | jq -r '.issue_id // ""')
    [ "$iid" != "$resolvedId" ] && continue
    ts=$(echo "$line" | jq -r '.ts // ""')
    role=$(echo "$line" | jq -r '.role // "agent"')
    body=$(echo "$line" | jq -r '.body // ""' | head -3)
    msgType=$(echo "$line" | jq -r '.type // "message"')
    printf "\n  [%s] %-10s (%s)\n" "$ts" "$role" "$msgType"
    echo "$body" | while IFS= read -r l; do echo "    $l"; done
    found=$((found + 1))
  done < "$threadFile"
fi

[ "$found" -eq 0 ] && echo "  No thread messages for this issue."
echo ""
echo "  $found message(s). To add a comment: --action comment --comment-body '...'"
```

### runs

```bash
echo "RUN HISTORY — $issue_id (last ${days} days)"
echo "────────────────────────────────────────────────────────"
printf "%-26s %-12s %-8s %-14s %s\n" "TIMESTAMP" "STATUS" "TOKENS" "AGENT" "SUMMARY"
echo "────────────────────────────────────────────────────────"

found=0
if [ -f "$activityFile" ]; then
  while IFS= read -r line; do
    iid=$(echo "$line" | jq -r '.issue_id // ""')
    [ "$iid" != "$resolvedId" ] && continue
    ts=$(echo "$line" | jq -r '.ts // ""')
    [ -n "$cutoff" ] && [ "$ts" \< "$cutoff" ] && continue
    st=$(echo "$line" | jq -r '.status // "-"')
    tok=$(echo "$line" | jq -r '.tokens // "-"')
    ag=$(echo "$line" | jq -r '.agent // "-"')
    summary=$(echo "$line" | jq -r '.summary // .type // "-"' | cut -c1-30)
    printf "%-26s %-12s %-8s %-14s %s\n" "$ts" "$st" "$tok" "$ag" "$summary"
    found=$((found + 1))
  done < "$activityFile"
fi

[ "$found" -eq 0 ] && echo "  No runs found in the last $days days."
```

### sub-issues

```bash
echo "SUB-ISSUES — $issue_id"
echo "────────────────────────────────────────────────────────"
printf "%-24s %-12s %-10s %s\n" "ID" "STATUS" "PRIORITY" "TITLE"
echo "────────────────────────────────────────────────────────"

count=0
jq -r --arg pid "$resolvedId" '(.issues // [])[] | select(.parentId == $pid) |
  [.id, (.status // "todo"), (.priority // "medium"), (.title // "(no title)")] | @tsv' \
  "$issuesFile" 2>/dev/null | while IFS=$'\t' read -r id st pri title; do
  printf "%-24s %-12s %-10s %s\n" "$id" "$st" "$pri" "$title"
  count=$((count + 1))
done

echo ""
echo "To create a sub-issue: /mastermind-issues --org $org_name --action create --title '<title>' --parent-id $issue_id"
```

### attachments

```bash
echo "ATTACHMENTS — $issue_id"
echo "────────────────────────────────────────────────────────"
atts=$(echo "$issueDef" | jq -r '(.attachments // [])[]' 2>/dev/null)
if [ -z "$atts" ]; then
  echo "  No attachments."
else
  echo "$issueDef" | jq -r '(.attachments // [])[] |
    "  [\(.type // "file")] \(.name // .path // "unnamed") — \(.size_bytes // "?") bytes — added \(.added_at // "?")"'
fi
```

### comment

```bash
[ -z "$comment_body" ] && { echo "ERROR: --comment-body required."; exit 1; }
ts=$(date -u +%Y-%m-%dT%H:%M:%SZ)

entry=$(jq -cn --arg iid "$resolvedId" --arg body "$comment_body" --arg ts "$ts" \
  '{"issue_id":$iid,"role":"user","type":"comment","body":$body,"ts":$ts}')
echo "$entry" >> "$threadFile"

echo "Comment added to issue '$issue_id'."
echo "  Body: $comment_body"
echo "  Time: $ts"
```

### assign

```bash
[ -z "$assignee_id" ] && { echo "ERROR: --assignee-id required."; exit 1; }

# Validate agent exists in org
exists=$(jq --arg id "$assignee_id" '[(.roles // [])[] | select(.id == $id)] | length' "$orgFile")
[ "$exists" -eq 0 ] && echo "WARNING: Agent '$assignee_id' not found in org '$org_name'. Assigning anyway."

ts=$(date -u +%Y-%m-%dT%H:%M:%SZ)
tmp="${issuesFile}.tmp"
jq --arg id "$resolvedId" --arg ag "$assignee_id" --arg ts "$ts" \
  '.issues = [(.issues // [])[] | if .id == $id then .assigneeId = $ag | .assigneeAgentId = $ag | .assigneeUserId = null | .updatedAt = $ts else . end]' \
  "$issuesFile" > "$tmp" && mv "$tmp" "$issuesFile"

echo "Issue '$issue_id' assigned to '$assignee_id'."

activityFile=".monomind/orgs/${org_name}-activity.jsonl"
currentStatus=$(jq -r --arg id "$resolvedId" '(.issues // [])[] | select(.id == $id) | .status // "todo"' "$issuesFile")
jq -cn --arg iid "$resolvedId" --arg ts "$ts" --arg st "$currentStatus" --arg ag "$assignee_id" --arg sm "assign $resolvedId" \
  '{issue_id:$iid, ts:$ts, status:$st, tokens:null, agent:$ag, type:"assign", summary:$sm}' \
  >> "$activityFile"
```

### close

```bash
ts=$(date -u +%Y-%m-%dT%H:%M:%SZ)
tmp="${issuesFile}.tmp"
jq --arg id "$resolvedId" --arg ts "$ts" \
  '.issues = [(.issues // [])[] | if .id == $id then .status = "done" | .updatedAt = $ts | .closedAt = $ts else . end]' \
  "$issuesFile" > "$tmp" && mv "$tmp" "$issuesFile"
echo "Issue '$issue_id' → done (closed at $ts)."

activityFile=".monomind/orgs/${org_name}-activity.jsonl"
jq -cn --arg iid "$resolvedId" --arg ts "$ts" --arg st "done" --arg ag "operator" --arg sm "close $resolvedId" \
  '{issue_id:$iid, ts:$ts, status:$st, tokens:null, agent:$ag, type:"close", summary:$sm}' \
  >> "$activityFile"
```

### reopen

```bash
ts=$(date -u +%Y-%m-%dT%H:%M:%SZ)
tmp="${issuesFile}.tmp"
jq --arg id "$resolvedId" --arg ts "$ts" \
  '.issues = [(.issues // [])[] | if .id == $id then .status = "todo" | .updatedAt = $ts | .closedAt = null else . end]' \
  "$issuesFile" > "$tmp" && mv "$tmp" "$issuesFile"
echo "Issue '$issue_id' → reopened."

activityFile=".monomind/orgs/${org_name}-activity.jsonl"
jq -cn --arg iid "$resolvedId" --arg ts "$ts" --arg st "todo" --arg ag "operator" --arg sm "reopen $resolvedId" \
  '{issue_id:$iid, ts:$ts, status:$st, tokens:null, agent:$ag, type:"reopen", summary:$sm}' \
  >> "$activityFile"
```

### recover

```bash
[ -z "$recovery_action" ] && { echo "ERROR: --recovery-action required (accept|reject)."; exit 1; }
case "$recovery_action" in accept|reject) : ;; *)
  echo "ERROR: --recovery-action must be 'accept' or 'reject'."; exit 1 ;;
esac

ts=$(date -u +%Y-%m-%dT%H:%M:%SZ)
newStatus=$([ "$recovery_action" = "accept" ] && echo "in_progress" || echo "cancelled")

tmp="${issuesFile}.tmp"
jq --arg id "$resolvedId" --arg st "$newStatus" --arg ts "$ts" --arg ra "$recovery_action" \
  '.issues = [(.issues // [])[] | if .id == $id then
     .status = $st | .recoveryStatus = $ra | .updatedAt = $ts
   else . end]' \
  "$issuesFile" > "$tmp" && mv "$tmp" "$issuesFile"

echo "Recovery action '$recovery_action' applied to '$issue_id'."
echo "  New status: $newStatus"

activityFile=".monomind/orgs/${org_name}-activity.jsonl"
jq -cn --arg iid "$resolvedId" --arg ts "$ts" --arg st "$newStatus" --arg ag "operator" --arg sm "recover $resolvedId" \
  '{issue_id:$iid, ts:$ts, status:$st, tokens:null, agent:$ag, type:"recover", summary:$sm}' \
  >> "$activityFile"
```

---

## Step 3 — Return Output

```yaml
domain: ops
status: complete
action: <action>
org: <org_name>
issue_id: <issue_id>
issue_status: <status>
```

---

## Step 4 — Brain Write (standalone only)

If `caller` is not "command", follow mastermind-protocol/SKILL.md Brain Write Procedure for domain `ops`.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…