Skip to content
Closed
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -610,6 +610,7 @@ You're never locked in. The system adapts.
| `/gsd-next` | Auto-detect state and run the next step |
| `/gsd-help` | Show all commands and usage guide |
| `/gsd-update` | Update GSD with changelog preview |
| `/gsd-feedback [text]` | File a bug, feature request, or question with diagnostics attached |
| `/gsd-join-discord` | Join the GSD Discord community |
| `/gsd-manager` | Interactive command center for managing multiple phases |

Expand Down
55 changes: 55 additions & 0 deletions commands/gsd/feedback.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
---
type: prompt
name: gsd:feedback
description: File GSD bugs, feature requests, or questions with diagnostics auto-attached
argument-hint: "[freeform description]"
allowed-tools:
- Read
- Bash
- AskUserQuestion
---

<objective>
Collect user feedback from inside a GSD session, attach actionable diagnostics automatically,
and file a GitHub issue against `gsd-build/get-shit-done`.

Preferred path: create the issue with `gh`.
Fallback path: open a prefilled GitHub issue URL.
Final fallback: always return the full markdown body for manual paste.
</objective>

<execution_context>
@~/.claude/get-shit-done/workflows/feedback.md
</execution_context>

<context>
**Issue types:**
- `bug`
- `feature`
- `question`

**Repo target:**
- `gsd-build/get-shit-done`

**Input:**
- `$ARGUMENTS` may contain a freeform seed for the title and description
</context>

<process>
Read and execute the feedback workflow from @~/.claude/get-shit-done/workflows/feedback.md end-to-end.
</process>

<success_criteria>
- User intent captured as `bug`, `feature`, or `question`
- Diagnostics attached from current runtime and project state
- `gh issue create` attempted first when available
- Prefilled GitHub issue URL generated as fallback
- Full markdown body returned for manual filing even if submission fails
</success_criteria>

<critical_rules>
- Prefer machine-readable diagnostics from GSD helpers over ad hoc parsing
- Do not discard `$ARGUMENTS`; use it as a seed whenever possible
- Always return enough information for manual filing
- Never block on browser launch failure
</critical_rules>
6 changes: 3 additions & 3 deletions docs/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ User-facing entry points. Each file contains YAML frontmatter (name, description
- **Copilot:** Slash commands (`/gsd-command-name`)
- **Antigravity:** Skills

**Total commands:** 75
**Total commands:** 76

### Workflows (`get-shit-done/workflows/*.md`)

Expand All @@ -124,7 +124,7 @@ Orchestration logic that commands reference. Contains the step-by-step process i
- State update patterns
- Error handling and recovery

**Total workflows:** 72
**Total workflows:** 74

### Agents (`agents/*.md`)

Expand Down Expand Up @@ -409,7 +409,7 @@ UI-SPEC.md (per phase) ───────────────────

```
~/.claude/ # Claude Code (global install)
├── commands/gsd/*.md # 75 slash commands
├── commands/gsd/*.md # 76 slash commands
├── get-shit-done/
│ ├── bin/gsd-tools.cjs # CLI utility
│ ├── bin/lib/*.cjs # 19 domain modules
Expand Down
18 changes: 17 additions & 1 deletion docs/COMMANDS.md
Original file line number Diff line number Diff line change
Expand Up @@ -825,7 +825,8 @@ Post-mortem investigation of failed or stuck GSD workflows.
- STATE.md anomalies and session history
- Uncommitted work, conflicts, abandoned changes
- At least 4 anomaly types checked (stuck loop, missing artifacts, abandoned work, crash/interruption)
- GitHub issue creation offered if actionable findings exist
- GitHub issue creation offered if actionable findings exist (delegates to shared `file-issue.md` workflow — same submission path as `/gsd-feedback`)
- Auto-derived or custom title when filing (custom path uses `/gsd-feedback` intake)

```bash
/gsd-forensics # Interactive — prompted for problem
Expand Down Expand Up @@ -1020,6 +1021,21 @@ Update GSD with changelog preview.
/gsd-update # Check for updates and install
```

### `/gsd-feedback [text]`

File a GSD bug, feature request, or question without leaving the current session.

**Behavior:**
- Collects a short intake for `bug`, `feature`, or `question`
- Attaches runtime and GSD state diagnostics automatically
- For `bug` type, offers optional `/gsd-forensics` enrichment (runs investigation steps 2–4 and attaches findings)
- Delegates issue filing to shared `file-issue.md` workflow (`gh issue create` → prefilled URL → raw markdown fallback)

```bash
/gsd-feedback # Guided feedback intake
/gsd-feedback planner skipped my context file # Seed title/description from text
```

### `/gsd-reapply-patches`

Restore local modifications after a GSD update.
Expand Down
162 changes: 162 additions & 0 deletions get-shit-done/workflows/feedback.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
<purpose>
Collect structured feedback, attach diagnostics from the current GSD session, and file a GitHub issue against `gsd-build/get-shit-done`. Issue submission is delegated to the shared `file-issue.md` workflow so that `/gsd-feedback` and `/gsd-forensics` use one canonical filing path.
</purpose>

<required_reading>
Read all files referenced by the invoking prompt's execution_context before starting.
</required_reading>

<process>

<step name="collect_feedback">
Start from `$ARGUMENTS` if present.

If type is not already clear, ask the user to choose one:
- `bug`
- `feature`
- `question`

Then collect:
- `ISSUE_TITLE`
- `ISSUE_DESCRIPTION`

If `$ARGUMENTS` already contains enough detail, refine it instead of re-asking from scratch.

Keep the intake short. The goal is to get a fileable issue, not run a long interview.

### Optional forensics enrichment (bug type only)

If `ISSUE_TYPE` is `bug`, ask the user:

> "Want me to run a quick forensics investigation first? This checks git history, planning state, and artifacts for anomalies that might explain the bug. [Y/n]"

If yes:
1. Execute Steps 2–4 from `@~/.claude/get-shit-done/workflows/forensics.md` (Gather Evidence → Detect Anomalies → Generate Report). Skip Steps 5–8 (presentation, interactive investigation, issue creation, STATE update — those are handled here).
2. Read the generated report from `.planning/forensics/report-{timestamp}.md`.
3. Set `INVESTIGATION_FINDINGS` to the redacted report contents.
Comment thread
ElliotDrel marked this conversation as resolved.
Outdated

If no (or if `ISSUE_TYPE` is `feature` or `question`):
- Set `INVESTIGATION_FINDINGS` to empty string.
</step>

<step name="gather_diagnostics">
Gather diagnostics from existing GSD helpers first.

**1. Version and runtime context**
Derive the invoking config dir from the execution context path when possible and prefer its sibling `get-shit-done/VERSION` file:

```bash
PREFERRED_CONFIG_DIR=""
case "$PWD" in
*"/get-shit-done/workflows"*)
PREFERRED_CONFIG_DIR="${PWD%/get-shit-done/workflows*}"
;;
esac

GSD_VERSION=""
for candidate in \
"$PREFERRED_CONFIG_DIR/get-shit-done/VERSION" \
"$HOME/.claude/get-shit-done/VERSION" \
"$HOME/.codex/get-shit-done/VERSION" \
".claude/get-shit-done/VERSION" \
".codex/get-shit-done/VERSION"
do
Comment thread
coderabbitai[bot] marked this conversation as resolved.
if [ -n "$candidate" ] && [ -f "$candidate" ]; then
GSD_VERSION="$(cat "$candidate")"
break
fi
done

if [ -z "$GSD_VERSION" ] && [ -f package.json ]; then
GSD_VERSION=$(node -e "const fs=require('fs'); const pkg=JSON.parse(fs.readFileSync('package.json','utf8')); console.log(pkg.version || '')" 2>/dev/null)
fi

NODE_VERSION=$(node -v 2>/dev/null || echo "unknown")
OS_NAME=$(uname -s 2>/dev/null || echo "$OS")
ARCH_NAME=$(uname -m 2>/dev/null || node -p "process.arch" 2>/dev/null || echo "unknown")
CURRENT_DIR=$(pwd)
ACTIVE_WORKSTREAM=${GSD_WORKSTREAM:-none}
```

**2. State and phase diagnostics**
```bash
STATE_JSON=$(gsd-sdk query state.json 2>/dev/null || echo "{}")
STATE_SNAPSHOT=$(gsd-sdk query state-snapshot 2>/dev/null || echo "{}")

CURRENT_PHASE=$(printf '%s' "$STATE_SNAPSHOT" | jq -r '.current_phase // "none"' 2>/dev/null || echo "none")
CURRENT_PHASE_NAME=$(printf '%s' "$STATE_SNAPSHOT" | jq -r '.current_phase_name // "none"' 2>/dev/null || echo "none")
STATUS=$(printf '%s' "$STATE_SNAPSHOT" | jq -r '.status // "unknown"' 2>/dev/null || echo "unknown")
LAST_ACTIVITY=$(printf '%s' "$STATE_SNAPSHOT" | jq -r '.last_activity // "unknown"' 2>/dev/null || echo "unknown")
LAST_ACTIVITY_DESC=$(printf '%s' "$STATE_SNAPSHOT" | jq -r '.last_activity_desc // "unknown"' 2>/dev/null || echo "unknown")
RESUME_FILE=$(printf '%s' "$STATE_SNAPSHOT" | jq -r '.session.resume_file // "none"' 2>/dev/null || echo "none")
```

**3. Small config excerpt**
Prefer direct GSD queries:

```bash
MODEL_PROFILE=$(gsd-sdk query config-get model_profile 2>/dev/null || echo "unset")
BASE_BRANCH=$(gsd-sdk query config-get git.base_branch 2>/dev/null || echo "unset")
USE_WORKTREES=$(gsd-sdk query config-get workflow.use_worktrees 2>/dev/null || echo "unset")
COMMIT_DOCS=$(gsd-sdk query config-get commit_docs 2>/dev/null || echo "unset")
```

If `.planning/config.json` exists, include only a short relevant snippet rather than dumping the whole file.
</step>

<step name="render_diagnostics">
Render the gathered diagnostics into `DIAGNOSTICS_MARKDOWN`:

````markdown
- GSD version: {GSD_VERSION}
- Node: {NODE_VERSION}
- OS / arch: {OS_NAME} / {ARCH_NAME}
- Working directory: {CURRENT_DIR}
- Workstream: {ACTIVE_WORKSTREAM}
- Current phase: {CURRENT_PHASE} - {CURRENT_PHASE_NAME}
- Status: {STATUS}
- Last activity: {LAST_ACTIVITY}
- Last activity detail: {LAST_ACTIVITY_DESC}
- Resume file: {RESUME_FILE}
- Config excerpt:
- model_profile: {MODEL_PROFILE}
- git.base_branch: {BASE_BRANCH}
- workflow.use_worktrees: {USE_WORKTREES}
- commit_docs: {COMMIT_DOCS}

### Raw State JSON

```json
{STATE_JSON}
```

### Raw State Snapshot

```json
{STATE_SNAPSHOT}
```
Comment thread
ElliotDrel marked this conversation as resolved.
Outdated
Comment on lines +137 to +141
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Implement the redaction logic for STATE_SNAPSHOT_REDACTED.

Line 140 uses STATE_SNAPSHOT_REDACTED but the workflow never defines how to produce it from STATE_SNAPSHOT (collected at line 94). The past review comment requested redaction of sensitive keys (paths, tokens, secrets) and truncation to cap payload size, but no implementation guidance is provided.

🔧 Suggested implementation before line 117
# Redact sensitive fields from state snapshot
STATE_SNAPSHOT_REDACTED=$(printf '%s' "$STATE_SNAPSHOT" | jq '
  # Redact absolute paths - replace home directory
  walk(if type == "string" then gsub(env.HOME; "~") else . end)
  # Remove potentially sensitive keys
  | del(.session.auth_token, .session.api_keys, .secrets)
  # Truncate to reasonable size (keep first 50 keys/2KB)
' 2>/dev/null | head -c 2048)

# Add ellipsis if truncated
if [ ${`#STATE_SNAPSHOT_REDACTED`} -eq 2048 ]; then
  STATE_SNAPSHOT_REDACTED="${STATE_SNAPSHOT_REDACTED}... [truncated]"
fi

Add this to the gather_diagnostics or render_diagnostics step.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@get-shit-done/workflows/feedback.md` around lines 137 - 141, STATE_SNAPSHOT
is collected but STATE_SNAPSHOT_REDACTED is never produced; add a redaction step
(in the gather_diagnostics or render_diagnostics function/block, before
STATE_SNAPSHOT_REDACTED is referenced) that takes STATE_SNAPSHOT, uses jq to:
replace absolute home paths with "~" (gsub(env.HOME;"~")), delete sensitive keys
like .session.auth_token, .session.api_keys, .secrets (del(...)), and then
truncate the output to a safe size (e.g., head -c 2048) and append an ellipsis
marker if truncated, assigning the result to STATE_SNAPSHOT_REDACTED so the
workflow emits the sanitized snapshot.

````
</step>

<step name="file_issue">
Set the variables required by the shared issue-filing workflow, then delegate:

- `ISSUE_TYPE` — from step 1
- `ISSUE_TITLE` — from step 1
- `ISSUE_DESCRIPTION` — from step 1
- `DIAGNOSTICS_MARKDOWN` — from step 3
- `INVESTIGATION_FINDINGS` — from step 1 forensics enrichment (empty if skipped)
- `REPO` — `gsd-build/get-shit-done`

Execute `@~/.claude/get-shit-done/workflows/file-issue.md` end-to-end. It handles rendering the final issue body, `gh issue create`, URL fallback, and raw markdown fallback.
</step>

</process>

<success_criteria>
- Intake completes with type, title, and description
- Diagnostics come from `gsd-sdk query` helpers where available
- Bug-type issues offer optional forensics enrichment via `/gsd-forensics` steps 2–4
- Issue filing delegates to `@~/.claude/get-shit-done/workflows/file-issue.md`
- `DIAGNOSTICS_MARKDOWN` and `INVESTIGATION_FINDINGS` are set before delegation
</success_criteria>
Loading
Loading