agileflow 3.0.1 → 3.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/README.md +3 -3
  3. package/lib/api-server.js +3 -2
  4. package/lib/flag-detection.js +4 -2
  5. package/lib/git-operations.js +4 -2
  6. package/lib/process-executor.js +24 -9
  7. package/lib/skill-loader.js +11 -3
  8. package/package.json +1 -1
  9. package/scripts/agileflow-welcome.js +65 -25
  10. package/scripts/claude-tmux.sh +9 -3
  11. package/scripts/damage-control-multi-agent.js +14 -10
  12. package/scripts/lib/bus-utils.js +3 -1
  13. package/scripts/lib/configure-detect.js +12 -9
  14. package/scripts/lib/configure-features.js +12 -7
  15. package/scripts/lib/configure-repair.js +6 -5
  16. package/scripts/lib/context-formatter.js +13 -3
  17. package/scripts/lib/damage-control-utils.js +5 -1
  18. package/scripts/lib/lifecycle-detector.js +5 -3
  19. package/scripts/lib/process-cleanup.js +8 -4
  20. package/scripts/lib/scale-detector.js +47 -8
  21. package/scripts/lib/signal-detectors.js +117 -59
  22. package/scripts/lib/task-registry.js +5 -1
  23. package/scripts/lib/team-events.js +4 -4
  24. package/scripts/messaging-bridge.js +7 -1
  25. package/scripts/ralph-loop.js +10 -8
  26. package/scripts/smart-detect.js +32 -11
  27. package/scripts/team-manager.js +1 -1
  28. package/scripts/tmux-task-name.sh +75 -0
  29. package/scripts/tmux-task-watcher.sh +177 -0
  30. package/src/core/commands/babysit.md +75 -42
  31. package/src/core/commands/blockers.md +7 -7
  32. package/src/core/commands/configure.md +5 -36
  33. package/src/core/commands/discovery/brief.md +363 -0
  34. package/src/core/commands/discovery/new.md +395 -0
  35. package/src/core/commands/ideate/new.md +5 -5
  36. package/src/core/commands/logic/audit.md +5 -5
  37. package/src/core/commands/review.md +7 -1
  38. package/src/core/commands/rpi.md +61 -26
  39. package/src/core/commands/sprint.md +7 -6
  40. package/src/core/templates/product-brief.md +136 -0
  41. package/tools/cli/installers/ide/claude-code.js +67 -2
  42. package/src/core/agents/configuration/archival.md +0 -350
  43. package/src/core/agents/configuration/attribution.md +0 -343
  44. package/src/core/agents/configuration/ci.md +0 -1103
  45. package/src/core/agents/configuration/damage-control.md +0 -375
  46. package/src/core/agents/configuration/git-config.md +0 -537
  47. package/src/core/agents/configuration/hooks.md +0 -623
  48. package/src/core/agents/configuration/precompact.md +0 -302
  49. package/src/core/agents/configuration/status-line.md +0 -557
  50. package/src/core/agents/configuration/verify.md +0 -618
  51. package/src/core/agents/configuration-damage-control.md +0 -259
  52. package/src/core/agents/configuration-visual-e2e.md +0 -339
@@ -428,15 +428,17 @@ function runCoverage(rootDir) {
428
428
 
429
429
  // Get screenshots directory from metadata or default
430
430
  function getScreenshotsDir(rootDir) {
431
- return tryOptional(() => {
432
- const metadataPath = path.join(rootDir, 'docs/00-meta/agileflow-metadata.json');
433
- if (fs.existsSync(metadataPath)) {
434
- const metadata = JSON.parse(fs.readFileSync(metadataPath, 'utf8'));
435
- if (metadata.ralph_loop?.screenshots_dir) {
436
- return metadata.ralph_loop.screenshots_dir;
431
+ return (
432
+ tryOptional(() => {
433
+ const metadataPath = path.join(rootDir, 'docs/00-meta/agileflow-metadata.json');
434
+ if (fs.existsSync(metadataPath)) {
435
+ const metadata = JSON.parse(fs.readFileSync(metadataPath, 'utf8'));
436
+ if (metadata.ralph_loop?.screenshots_dir) {
437
+ return metadata.ralph_loop.screenshots_dir;
438
+ }
437
439
  }
438
- }
439
- }, 'metadata read') || './screenshots';
440
+ }, 'metadata read') || './screenshots'
441
+ );
440
442
  }
441
443
 
442
444
  // Run screenshot verification (Visual Mode)
@@ -54,7 +54,13 @@ try {
54
54
  return { ok: false, error: e.message };
55
55
  }
56
56
  };
57
- tryOptional = (fn, _label) => { try { return fn(); } catch { return undefined; } };
57
+ tryOptional = (fn, _label) => {
58
+ try {
59
+ return fn();
60
+ } catch {
61
+ return undefined;
62
+ }
63
+ };
58
64
  }
59
65
 
60
66
  // =============================================================================
@@ -121,11 +127,17 @@ function extractSignals(prefetched, sessionState, metadata) {
121
127
  // File existence checks
122
128
  const files = {
123
129
  tsconfig: fs.existsSync('tsconfig.json'),
124
- eslintrc: fs.existsSync('.eslintrc.js') || fs.existsSync('.eslintrc.json') || fs.existsSync('.eslintrc.yml'),
130
+ eslintrc:
131
+ fs.existsSync('.eslintrc.js') ||
132
+ fs.existsSync('.eslintrc.json') ||
133
+ fs.existsSync('.eslintrc.yml'),
125
134
  coverage: fs.existsSync('coverage/coverage-summary.json'),
126
135
  playwright: fs.existsSync('playwright.config.ts') || fs.existsSync('playwright.config.js'),
127
136
  screenshots: fs.existsSync('screenshots'),
128
- ciConfig: fs.existsSync('.github/workflows') || fs.existsSync('.gitlab-ci.yml') || fs.existsSync('Jenkinsfile'),
137
+ ciConfig:
138
+ fs.existsSync('.github/workflows') ||
139
+ fs.existsSync('.gitlab-ci.yml') ||
140
+ fs.existsSync('Jenkinsfile'),
129
141
  expertiseDir: fs.existsSync('.agileflow/expertise'),
130
142
  };
131
143
 
@@ -255,7 +267,11 @@ function analyze(prefetched, sessionState, metadata) {
255
267
  const rawRecommendations = runDetectorsForPhases(relevantPhases, signals);
256
268
 
257
269
  // Filter and categorize
258
- const { immediate, available } = filterRecommendations(rawRecommendations, metadata, sessionState);
270
+ const { immediate, available } = filterRecommendations(
271
+ rawRecommendations,
272
+ metadata,
273
+ sessionState
274
+ );
259
275
 
260
276
  // Auto-enabled features (existing babysit modes)
261
277
  const autoEnabled = detectAutoModes(signals);
@@ -304,7 +320,7 @@ function detectAutoModes(signals) {
304
320
  const readyInEpic = Object.entries(statusJson.stories).filter(
305
321
  ([, s]) => s.epic === story.epic && s.status === 'ready'
306
322
  ).length;
307
- loopMode = readyInEpic >= 3 && !!(packageJson?.scripts?.test);
323
+ loopMode = readyInEpic >= 3 && !!packageJson?.scripts?.test;
308
324
  }
309
325
 
310
326
  // Visual mode: UI-related story or visual e2e setup
@@ -342,10 +358,9 @@ function writeRecommendations(results, outputPath) {
342
358
 
343
359
  if (require.main === module) {
344
360
  // Run standalone - gather our own data
345
- const statusJsonResult = safeReadJSON(
346
- path.join(process.cwd(), 'docs/09-agents/status.json'),
347
- { defaultValue: {} }
348
- );
361
+ const statusJsonResult = safeReadJSON(path.join(process.cwd(), 'docs/09-agents/status.json'), {
362
+ defaultValue: {},
363
+ });
349
364
  const sessionStateResult = safeReadJSON(
350
365
  path.join(process.cwd(), 'docs/09-agents/session-state.json'),
351
366
  { defaultValue: {} }
@@ -357,8 +372,14 @@ if (require.main === module) {
357
372
 
358
373
  // Build minimal prefetched structure
359
374
  const { execSync } = require('child_process');
360
- const gitBranch = tryOptional(() => execSync('git branch --show-current', { encoding: 'utf8' }).trim(), 'git branch') || '';
361
- const gitStatus = tryOptional(() => execSync('git status --short', { encoding: 'utf8' }).trim(), 'git status') || '';
375
+ const gitBranch =
376
+ tryOptional(
377
+ () => execSync('git branch --show-current', { encoding: 'utf8' }).trim(),
378
+ 'git branch'
379
+ ) || '';
380
+ const gitStatus =
381
+ tryOptional(() => execSync('git status --short', { encoding: 'utf8' }).trim(), 'git status') ||
382
+ '';
362
383
 
363
384
  const prefetched = {
364
385
  json: {
@@ -204,7 +204,7 @@ function startTeam(rootDir, templateName) {
204
204
  const sessionStatePath = paths.getSessionStatePath(rootDir);
205
205
  const fileLock = getFileLock();
206
206
 
207
- const updateState = (state) => {
207
+ const updateState = state => {
208
208
  state.active_team = {
209
209
  template: templateName,
210
210
  mode,
@@ -0,0 +1,75 @@
1
+ #!/usr/bin/env bash
2
+ # tmux-task-name.sh - Rename current tmux window based on task/work description
3
+ #
4
+ # Called by Claude Code when starting work on a task (via TaskCreate/TaskUpdate).
5
+ # Reads the task subject from ~/.claude/tasks/ or accepts it as an argument.
6
+ #
7
+ # Usage:
8
+ # tmux-task-name.sh "Fix auth middleware" # Rename to task subject
9
+ # tmux-task-name.sh --scan # Auto-detect from task files
10
+ # tmux-task-name.sh --reset # Reset to default "claude-N"
11
+ #
12
+ # The script is best-effort: silently exits if not inside tmux.
13
+
14
+ set -euo pipefail
15
+
16
+ # Exit silently if not in tmux
17
+ [ -n "${TMUX:-}" ] || exit 0
18
+
19
+ MAX_LEN=30
20
+
21
+ truncate_name() {
22
+ local name="$1"
23
+ if [ ${#name} -gt $MAX_LEN ]; then
24
+ echo "${name:0:$((MAX_LEN - 1))}…"
25
+ else
26
+ echo "$name"
27
+ fi
28
+ }
29
+
30
+ # Mode: reset to default sequential name
31
+ if [ "${1:-}" = "--reset" ]; then
32
+ N=$(( $(tmux list-windows -F '#{window_name}' 2>/dev/null | grep -c '^claude') ))
33
+ [ "$N" -eq 0 ] && N=1
34
+ tmux rename-window "claude-$N" 2>/dev/null || true
35
+ exit 0
36
+ fi
37
+
38
+ # Mode: scan ~/.claude/tasks/ for most recently modified in-progress task
39
+ if [ "${1:-}" = "--scan" ]; then
40
+ TASKS_DIR="${HOME}/.claude/tasks"
41
+ [ -d "$TASKS_DIR" ] || exit 0
42
+
43
+ BEST_SUBJECT=""
44
+ BEST_MTIME=0
45
+
46
+ for dir in "$TASKS_DIR"/*/; do
47
+ [ -d "$dir" ] || continue
48
+ for f in "$dir"*.json; do
49
+ [ -f "$f" ] || continue
50
+ # Check if task is in_progress and get subject
51
+ status=$(python3 -c "import json,sys; d=json.load(open('$f')); print(d.get('status',''))" 2>/dev/null || echo "")
52
+ if [ "$status" = "in_progress" ]; then
53
+ mtime=$(stat -c %Y "$f" 2>/dev/null || stat -f %m "$f" 2>/dev/null || echo "0")
54
+ if [ "$mtime" -gt "$BEST_MTIME" ]; then
55
+ BEST_MTIME=$mtime
56
+ BEST_SUBJECT=$(python3 -c "import json; d=json.load(open('$f')); print(d.get('subject',''))" 2>/dev/null || echo "")
57
+ fi
58
+ fi
59
+ done
60
+ done
61
+
62
+ if [ -n "$BEST_SUBJECT" ]; then
63
+ tmux rename-window "$(truncate_name "$BEST_SUBJECT")" 2>/dev/null || true
64
+ fi
65
+ exit 0
66
+ fi
67
+
68
+ # Mode: direct - rename to provided argument
69
+ if [ -n "${1:-}" ]; then
70
+ tmux rename-window "$(truncate_name "$1")" 2>/dev/null || true
71
+ exit 0
72
+ fi
73
+
74
+ echo "Usage: tmux-task-name.sh <task-subject> | --scan | --reset" >&2
75
+ exit 1
@@ -0,0 +1,177 @@
1
+ #!/usr/bin/env bash
2
+ # tmux-task-watcher.sh - Auto-rename tmux window based on Claude Code tasks
3
+ #
4
+ # Launched automatically by SessionStart hook. Self-backgrounds immediately.
5
+ # Polls ~/.claude/tasks/<session-id>/ for in-progress tasks every few seconds.
6
+ # Renames the tmux window to match the active task subject.
7
+ #
8
+ # Usage:
9
+ # tmux-task-watcher.sh # Start watcher (backgrounds itself)
10
+ # tmux-task-watcher.sh stop # Stop watcher for current pane
11
+ #
12
+ # Requirements:
13
+ # - Must be inside tmux ($TMUX set)
14
+ # - Node.js available (for JSON parsing)
15
+ # - Claude Code session active ($CLAUDECODE=1)
16
+
17
+ set -euo pipefail
18
+
19
+ # Only run inside tmux
20
+ [ -n "${TMUX:-}" ] || exit 0
21
+
22
+ MODE="${1:-start}"
23
+ MAX_LEN=30
24
+
25
+ # Get current pane ID for per-pane tracking
26
+ PANE_ID=$(tmux display-message -p '#{pane_id}' 2>/dev/null || true)
27
+ [ -n "$PANE_ID" ] || exit 0
28
+
29
+ # PID file keyed by pane to allow multiple watchers (one per window)
30
+ SAFE_PANE_ID="${PANE_ID//[^a-zA-Z0-9]/_}"
31
+ PID_FILE="/tmp/tmux-task-watcher-${SAFE_PANE_ID}.pid"
32
+
33
+ # --- Stop mode ---
34
+ if [ "$MODE" = "stop" ]; then
35
+ if [ -f "$PID_FILE" ]; then
36
+ kill "$(cat "$PID_FILE")" 2>/dev/null || true
37
+ rm "$PID_FILE" 2>/dev/null || true
38
+ fi
39
+ exit 0
40
+ fi
41
+
42
+ # --- Start mode ---
43
+ if [ "$MODE" = "start" ]; then
44
+ # Kill any existing watcher for this pane first
45
+ if [ -f "$PID_FILE" ]; then
46
+ kill "$(cat "$PID_FILE")" 2>/dev/null || true
47
+ rm "$PID_FILE" 2>/dev/null || true
48
+ fi
49
+
50
+ # Self-background: parent exits immediately so hook completes fast
51
+ _WATCHER_BG=1 nohup "$0" "_run" >/dev/null 2>&1 &
52
+ echo $! > "$PID_FILE"
53
+ exit 0
54
+ fi
55
+
56
+ # --- _run mode: skip to background worker below ---
57
+
58
+ # ============================================================
59
+ # Background watcher logic (runs in forked process)
60
+ # ============================================================
61
+
62
+ # Disable strict mode for background worker - we handle errors ourselves
63
+ set +eu
64
+
65
+ # Derive Claude Code project dir from PWD
66
+ CLAUDE_PROJECT_DIR="${HOME}/.claude/projects/$(pwd | sed 's|/|-|g')"
67
+
68
+ # Find current session ID: most recently CREATED JSONL in project dir
69
+ # Uses birth time (stat %W) to avoid picking up other sessions' modified files
70
+ find_session_id() {
71
+ [ -d "$CLAUDE_PROJECT_DIR" ] || return 1
72
+ local best_file="" best_birth=0
73
+ for f in "$CLAUDE_PROJECT_DIR"/*.jsonl; do
74
+ [ -f "$f" ] || continue
75
+ local birth
76
+ birth=$(stat -c '%W' "$f" 2>/dev/null || echo "0")
77
+ if [ "$birth" -gt "$best_birth" ] 2>/dev/null; then
78
+ best_birth=$birth
79
+ best_file=$f
80
+ fi
81
+ done
82
+ [ -n "$best_file" ] || return 1
83
+ basename "$best_file" .jsonl
84
+ }
85
+
86
+ # Wait briefly for session file to be created/updated
87
+ sleep 2
88
+
89
+ SESSION_ID=$(find_session_id || true)
90
+ if [ -z "$SESSION_ID" ]; then
91
+ # Retry after a longer wait
92
+ sleep 5
93
+ SESSION_ID=$(find_session_id || true)
94
+ fi
95
+
96
+ # Store session ID as tmux pane option (for debugging/other scripts)
97
+ if [ -n "$SESSION_ID" ]; then
98
+ tmux set-option -p @claude_session_id "$SESSION_ID" 2>/dev/null || true
99
+ fi
100
+
101
+ TASKS_DIR="${HOME}/.claude/tasks/${SESSION_ID}"
102
+ LAST_WINDOW_NAME=""
103
+ POLL_INTERVAL=5
104
+ MAX_RUNTIME=$((12 * 3600)) # 12 hours safety limit
105
+ START_TIME=$(date +%s)
106
+
107
+ # Parse task files and find the most recent in-progress task subject
108
+ get_active_task() {
109
+ [ -d "$TASKS_DIR" ] || return
110
+ node -e "
111
+ const fs = require('fs'), path = require('path');
112
+ const dir = process.argv[1];
113
+ let best = { mtime: 0, subject: '' };
114
+ try {
115
+ for (const f of fs.readdirSync(dir)) {
116
+ if (!f.endsWith('.json') || f === '.lock') continue;
117
+ const fp = path.join(dir, f);
118
+ const data = JSON.parse(fs.readFileSync(fp, 'utf8'));
119
+ if (data.status === 'in_progress') {
120
+ const mt = fs.statSync(fp).mtimeMs;
121
+ if (mt > best.mtime) {
122
+ best = { mtime: mt, subject: data.subject || data.activeForm || '' };
123
+ }
124
+ }
125
+ }
126
+ } catch(e) {}
127
+ if (best.subject) process.stdout.write(best.subject);
128
+ " "$TASKS_DIR" 2>/dev/null || true
129
+ }
130
+
131
+ truncate_name() {
132
+ local name="$1"
133
+ if [ ${#name} -gt $MAX_LEN ]; then
134
+ printf '%s' "${name:0:$((MAX_LEN - 1))}"
135
+ else
136
+ printf '%s' "$name"
137
+ fi
138
+ }
139
+
140
+ # Main polling loop
141
+ while true; do
142
+ # Safety timeout
143
+ NOW=$(date +%s)
144
+ if [ $((NOW - START_TIME)) -gt $MAX_RUNTIME ]; then
145
+ break
146
+ fi
147
+
148
+ # Check if our pane is still alive
149
+ if ! tmux list-panes -a -F '#{pane_id}' 2>/dev/null | grep -qF "$PANE_ID"; then
150
+ break
151
+ fi
152
+
153
+ # If we don't have a session ID yet, retry finding it
154
+ if [ -z "$SESSION_ID" ]; then
155
+ SESSION_ID=$(find_session_id || true)
156
+ if [ -n "$SESSION_ID" ]; then
157
+ tmux set-option -p @claude_session_id "$SESSION_ID" 2>/dev/null || true
158
+ TASKS_DIR="${HOME}/.claude/tasks/${SESSION_ID}"
159
+ fi
160
+ fi
161
+
162
+ # Get active task subject
163
+ ACTIVE_TASK=$(get_active_task 2>/dev/null || true)
164
+
165
+ if [ -n "$ACTIVE_TASK" ]; then
166
+ NEW_NAME=$(truncate_name "$ACTIVE_TASK")
167
+ if [ "$NEW_NAME" != "$LAST_WINDOW_NAME" ]; then
168
+ tmux rename-window -t "$PANE_ID" "$NEW_NAME" 2>/dev/null || true
169
+ LAST_WINDOW_NAME="$NEW_NAME"
170
+ fi
171
+ fi
172
+
173
+ sleep "$POLL_INTERVAL"
174
+ done
175
+
176
+ # Cleanup
177
+ rm -f "$PID_FILE"
@@ -13,7 +13,7 @@ compact_context:
13
13
  - "STUCK DETECTION: If same error 2+ times, suggest /agileflow:research:ask with detailed prompt"
14
14
  - "PLAN FILE CONTEXT: BEFORE ExitPlanMode, EDIT plan file to add babysit rules header at TOP - rules survive context clear"
15
15
  - "STORY CLAIMING: claim after selection, release after completion, check others before suggesting"
16
- - "LOGIC AUDIT: After implementation, offer '🔍 Run logic audit' option via AskUserQuestion (not automatic)"
16
+ - "LOGIC AUDIT: ALWAYS suggest '🔍 Run logic audit' after ANY implementation (plan or direct) - it's a standard post-impl step, not optional"
17
17
  state_fields:
18
18
  - current_story
19
19
  - current_epic
@@ -382,8 +382,9 @@ If you end your response without calling AskUserQuestion, you have violated thes
382
382
  |-------|-------------------|-----|
383
383
  | After context gathering | The most impactful ready story | Based on epic progress, blockers, dependencies |
384
384
  | After plan approval | "Start implementing now" | Don't ask permission, suggest action |
385
- | After code is written | "Run tests to verify (Recommended)" | Always verify before committing |
386
- | After tests pass | "Commit and continue to next story" | Keep momentum |
385
+ | After code is written | "Run tests to verify (Recommended)" + logic audit option | Always verify before committing |
386
+ | After tests pass | "🔍 Run logic audit (Recommended)" or "Commit" | Logic audit catches what tests miss |
387
+ | After logic audit | "Commit: '[type]: [summary]' (Recommended)" | All checks done, ready to commit |
387
388
  | After error | "Try [specific alternative approach]" | Don't just say "fix it" |
388
389
  | After expert returns | "Review and apply changes" or "Run tests" | Based on expert output quality |
389
390
 
@@ -421,7 +422,7 @@ If you end your response without calling AskUserQuestion, you have violated thes
421
422
  | User gave detailed instructions | Skip plan mode, follow them |
422
423
  | Everything else | **USE PLAN MODE** |
423
424
 
424
- **Plan mode flow:** EnterPlanMode → Explore with Glob/Grep/Read → Design approach → ExitPlanMode → Implement
425
+ **Plan mode flow:** EnterPlanMode → Explore with Glob/Grep/Read → Design approach → Add smart babysit header to plan → ExitPlanMode → Implement → Smart AskUserQuestion (with logic audit)
425
426
 
426
427
  ---
427
428
 
@@ -512,17 +513,21 @@ if(ready.length)console.log('🔔 Validators ready:',ready.map(t=>t.id).join(','
512
513
  ## ⚠️ MANDATORY IMPLEMENTATION RULES (from /babysit)
513
514
 
514
515
  These rules MUST be followed during implementation:
515
- 1. **ALWAYS end your final response with AskUserQuestion tool** offering next steps
516
+ 1. **ALWAYS end your final response with SMART AskUserQuestion tool** - specific, contextual options with (Recommended) label
516
517
  2. **Use EnterPlanMode** if any NEW non-trivial tasks arise during implementation
517
518
  3. **Delegate complex work** to domain experts via Task tool
518
519
  4. **Track progress** with TaskCreate/TaskUpdate for multi-step work
519
520
 
520
- After implementation completes, you MUST call AskUserQuestion with options like:
521
- - "Run tests to verify"
522
- - "🔍 Run logic audit" (for complex code - uses /agileflow:logic:audit)
523
- - "Continue to next task"
524
- - "Review changes"
525
- - "Pause here"
521
+ **Smart AskUserQuestion format** (NEVER generic - always contextual):
522
+ - Options must reference specific files, test commands, story IDs, and change counts
523
+ - Always mark the best next step with "(Recommended)"
524
+ - Include descriptions with concrete context (e.g., "3 files changed in scripts/")
525
+
526
+ After implementation completes, you MUST call AskUserQuestion. **ALWAYS include logic audit**:
527
+ - "Run `npm test` in packages/cli/ (Recommended)" + description with file count
528
+ - "🔍 Run logic audit on [N] modified files" + "5 analyzers check for edge cases, race conditions, type bugs"
529
+ - "Commit: '[type]: [summary]'" + "All tests pass, ready to commit"
530
+ - "Pause here" + "Changes saved, not committed"
526
531
 
527
532
  ---
528
533
  ```
@@ -534,7 +539,7 @@ After implementation completes, you MUST call AskUserQuestion with options like:
534
539
  # Plan: Add User Profile Feature
535
540
 
536
541
  ## ⚠️ MANDATORY IMPLEMENTATION RULES (from /babysit)
537
- [rules as above]
542
+ [rules as above - with SMART AskUserQuestion and logic audit]
538
543
 
539
544
  ---
540
545
 
@@ -594,22 +599,22 @@ After implementation completes, you MUST call AskUserQuestion with options like:
594
599
  13. Delegate to experts based on scope
595
600
  14. Collect results if async (TaskOutput)
596
601
  15. Verify tests pass
597
- 16. AskUserQuestion with specific test results: "All tests pass - commit changes? (Recommended)"
602
+ 16. **ALWAYS offer logic audit** via smart AskUserQuestion with specific file counts and test results
598
603
 
599
604
  **Phase 4: Completion**
600
- 15. Update status.json (mark story done)
601
- 16. **RELEASE THE STORY claim:**
605
+ 17. Update status.json (mark story done)
606
+ 18. **RELEASE THE STORY claim:**
602
607
  ```bash
603
608
  node .agileflow/scripts/lib/story-claiming.js release <story-id>
604
609
  ```
605
- 17. Present next steps via AskUserQuestion **(including Logic Audit option)**
610
+ 19. Present next steps via smart AskUserQuestion
606
611
 
607
- **Post-Implementation Options** (offer via AskUserQuestion):
608
- - "Run tests to verify" - Standard verification
609
- - "🔍 Run logic audit" - Multi-agent analysis for logic bugs (recommended for complex code)
610
- - "Continue to next story" - Move on
611
- - "Review changes" - Manual review
612
- - "Pause here" - Stop for now
612
+ **Post-Implementation Options** (ALWAYS offer via smart AskUserQuestion):
613
+ - "Run tests to verify (Recommended)" - with specific test command and file count
614
+ - "🔍 Run logic audit on N modified files" - **ALWAYS include this** - 5 analyzers check edge cases, race conditions, type bugs
615
+ - "Commit: '[type]: [summary]'" - with specific commit message suggestion
616
+ - "Continue to next story" - with story ID and epic progress
617
+ - "Pause here" - with summary of what's saved/uncommitted
613
618
 
614
619
  ---
615
620
 
@@ -673,19 +678,37 @@ Present top 3-5 via AskUserQuestion, always include "Other" option.
673
678
 
674
679
  ### LOGIC AUDIT INTEGRATION
675
680
 
676
- After completing an implementation, offer logic audit as an **optional quality check**:
681
+ **ALWAYS suggest logic audit after ANY implementation** - whether from a plan, direct coding, or expert delegation. This is a standard post-implementation step, not optional.
677
682
 
683
+ **Smart AskUserQuestion after implementation:**
678
684
  ```xml
679
685
  <invoke name="AskUserQuestion">
680
686
  <parameter name="questions">[{
681
- "question": "Implementation complete. What would you like to do?",
687
+ "question": "Implementation complete (3 files changed, 85 lines added). What's next?",
682
688
  "header": "Next step",
683
689
  "multiSelect": false,
684
690
  "options": [
685
- {"label": "Run tests (Recommended)", "description": "Verify with test suite"},
686
- {"label": "🔍 Run logic audit", "description": "Multi-agent analysis for edge cases, race conditions, type bugs"},
687
- {"label": "Continue to next story", "description": "Move on without additional checks"},
688
- {"label": "Pause here", "description": "Stop for now"}
691
+ {"label": "Run npm test in packages/cli/ (Recommended)", "description": "3 files changed in scripts/ - verify before committing"},
692
+ {"label": "🔍 Run logic audit on 3 modified files", "description": "5 analyzers check for edge cases, race conditions, type bugs - catches issues tests miss"},
693
+ {"label": "Commit: 'feat: add session tracking'", "description": "Skip verification - only if changes are trivial"},
694
+ {"label": "Pause here", "description": "Changes saved, not committed"}
695
+ ]
696
+ }]</parameter>
697
+ </invoke>
698
+ ```
699
+
700
+ **After tests pass, suggest logic audit again if not yet run:**
701
+ ```xml
702
+ <invoke name="AskUserQuestion">
703
+ <parameter name="questions">[{
704
+ "question": "All 4373 tests pass. Ready to finalize?",
705
+ "header": "Next step",
706
+ "multiSelect": false,
707
+ "options": [
708
+ {"label": "🔍 Run logic audit on 3 modified files (Recommended)", "description": "5 analyzers catch edge cases tests miss - quick check before commit"},
709
+ {"label": "Commit: 'feat: add session tracking'", "description": "All tests pass, skip logic audit"},
710
+ {"label": "Continue to US-0044", "description": "EP-0018 is 85% done - 2 stories left"},
711
+ {"label": "Pause here", "description": "Tests pass, changes not committed"}
689
712
  ]
690
713
  }]</parameter>
691
714
  </invoke>
@@ -696,19 +719,25 @@ After completing an implementation, offer logic audit as an **optional quality c
696
719
  2. Run: `/agileflow:logic:audit <modified-files> DEPTH=quick`
697
720
  3. Review findings with user
698
721
  4. Offer to fix any P0/P1 issues immediately
699
- 5. Then present next steps again
722
+ 5. Then present next steps again with smart AskUserQuestion
700
723
 
701
724
  ---
702
725
 
703
726
  ### SMART ASKUSERQUESTION EXAMPLES
704
727
 
705
728
  After implementation:
706
- - "Run `npm test` in packages/cli/ (Recommended)" + "3 files changed, verify before commit"
707
- - "🔍 Run logic audit on modified files" + "5 analyzers check for edge cases"
729
+ - "Run `npm test` in packages/cli/ (Recommended)" + "3 files changed in scripts/ - verify before committing"
730
+ - "🔍 Run logic audit on 3 modified files" + "5 analyzers check edge cases, race conditions, type bugs"
731
+ - "Pause here" + "Changes saved, not committed"
708
732
 
709
- After tests pass:
710
- - "Commit: 'fix: resolve tmux socket path' (Recommended)" + "All tests pass"
711
- - "Review diff before committing" + "14 files touched"
733
+ After tests pass (logic audit NOT yet run):
734
+ - "🔍 Run logic audit on 3 modified files (Recommended)" + "Quick check catches what tests miss - edge cases, race conditions"
735
+ - "Commit: 'fix: resolve tmux socket path'" + "All 4373 tests pass, skip audit"
736
+ - "Continue to US-0044" + "EP-0018 is 85% done"
737
+
738
+ After tests pass (logic audit already done):
739
+ - "Commit: 'fix: resolve tmux socket path' (Recommended)" + "All tests pass, logic audit clean"
740
+ - "Review diff before committing" + "14 files touched across 3 directories"
712
741
 
713
742
  After error:
714
743
  - "Try alternative: use execFileSync instead (Recommended)" + "Current approach has shell injection risk"
@@ -726,14 +755,14 @@ After error:
726
755
  - Delegate complex work to experts
727
756
  - If stuck 2+ times → research prompt
728
757
  - Use state narration markers (📍🔀🔄⚠️✅) for visibility
758
+ - **LOGIC AUDIT - ALWAYS SUGGEST**: After ANY implementation (plan or direct), ALWAYS include "🔍 Run logic audit" as an option. After tests pass but before commit, make it (Recommended).
729
759
  - **PLAN FILE CONTEXT - CRITICAL:**
730
- BEFORE ExitPlanMode, EDIT the plan file to add babysit rules header at TOP
760
+ BEFORE ExitPlanMode, EDIT the plan file to add babysit rules header at TOP (with smart AskUserQuestion format and logic audit)
731
761
  This ensures rules survive "Clear context and bypass permissions"
732
762
  - **STORY CLAIMING - CRITICAL:**
733
763
  1. BEFORE suggesting: `node .agileflow/scripts/lib/story-claiming.js others` → exclude 🔒
734
764
  2. AFTER user selects: `node .agileflow/scripts/lib/story-claiming.js claim <id>`
735
765
  3. WHEN done: `node .agileflow/scripts/lib/story-claiming.js release <id>`
736
-
737
766
  ---
738
767
 
739
768
  ## 🛑 FINAL ACTION REQUIRED - DO NOT SKIP
@@ -1175,12 +1204,16 @@ When stuck detection triggers:
1175
1204
  ## ⚠️ MANDATORY IMPLEMENTATION RULES (from /babysit)
1176
1205
 
1177
1206
  These rules MUST be followed during implementation:
1178
- 1. ALWAYS end your final response with AskUserQuestion tool
1179
- 2. Use EnterPlanMode if new non-trivial tasks arise
1180
- 3. Delegate complex work to domain experts
1181
- 4. Track progress with TaskCreate/TaskUpdate
1182
-
1183
- After implementation, call AskUserQuestion with next step options.
1207
+ 1. **ALWAYS end with SMART AskUserQuestion** - specific options with (Recommended), contextual descriptions, file counts
1208
+ 2. **Use EnterPlanMode** if new non-trivial tasks arise
1209
+ 3. **Delegate complex work** to domain experts via Task tool
1210
+ 4. **Track progress** with TaskCreate/TaskUpdate for multi-step work
1211
+
1212
+ After implementation, ALWAYS call AskUserQuestion with:
1213
+ - "Run tests (Recommended)" with specific command and file count
1214
+ - "🔍 Run logic audit on N modified files" - ALWAYS include this
1215
+ - "Commit: '[type]: [summary]'" with suggested message
1216
+ - "Pause here" with save state summary
1184
1217
 
1185
1218
  ---
1186
1219
  ```
@@ -156,18 +156,18 @@ DETAILED=true # Show extended details (dependencies, ADRs, research)
156
156
 
157
157
  ## Confirmation & Integration
158
158
 
159
- After displaying blockers:
159
+ After displaying blockers (use actual counts and data from analysis):
160
160
  ```xml
161
161
  <invoke name="AskUserQuestion">
162
162
  <parameter name="questions">[{
163
- "question": "What would you like to do?",
164
- "header": "Blocker Actions",
163
+ "question": "[N] blockers found ([critical] critical, [stale] stale >14d). What next?",
164
+ "header": "Resolve",
165
165
  "multiSelect": false,
166
166
  "options": [
167
- {"label": "Update blocker status", "description": "Mark blocker as resolved"},
168
- {"label": "Create unblocking story", "description": "Create story to unblock"},
169
- {"label": "View ADR details", "description": "See related architecture decisions"},
170
- {"label": "Escalate blocker", "description": "Escalate for decision"}
167
+ {"label": "Resolve [top_blocker_id]: [reason] (Recommended)", "description": "[category] blocker, [age] days old - [resolution_hint]"},
168
+ {"label": "Create unblocking story for [blocker_id]", "description": "[blocker_summary] - needs [effort] to unblock [N] downstream stories"},
169
+ {"label": "View [N] related ADRs/research", "description": "Found [adr_count] ADRs and [research_count] research notes matching blockers"},
170
+ {"label": "Done - report only", "description": "[N] blockers documented, no action needed now"}
171
171
  ]
172
172
  }]</parameter>
173
173
  </invoke>