agileflow 2.98.0 → 2.99.0

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.
@@ -2,20 +2,21 @@
2
2
  # claude-tmux.sh - Wrapper script that auto-starts Claude Code in a tmux session
3
3
  #
4
4
  # Usage:
5
- # ./claude-tmux.sh # Start in tmux with default session
5
+ # ./claude-tmux.sh # Always creates fresh tmux + resumes Claude conversation
6
+ # ./claude-tmux.sh --attach # Reattach to existing session (if you know it's alive)
6
7
  # ./claude-tmux.sh --no-tmux # Start without tmux (regular claude)
7
8
  # ./claude-tmux.sh -n # Same as --no-tmux
8
- # ./claude-tmux.sh --fresh # Kill and restart with latest scripts
9
- # ./claude-tmux.sh -f # Same as --fresh
10
- # ./claude-tmux.sh --rescue # Kill frozen session and restart fresh
11
9
  # ./claude-tmux.sh --kill # Kill existing session completely
12
10
  # ./claude-tmux.sh --help # Show help with keybinds
13
11
  #
14
12
  # When already in tmux: Just runs claude normally
15
13
  # When not in tmux: Creates a tmux session and runs claude inside it
16
14
  #
17
- # FREEZE RECOVERY:
18
- # If Claude freezes inside tmux, use these keybinds:
15
+ # The default behavior always kills any existing session and creates a fresh one.
16
+ # This prevents frozen sessions from blocking you. Your Claude conversation is
17
+ # preserved via --resume regardless of the tmux session state.
18
+ #
19
+ # FREEZE RECOVERY (while inside tmux):
19
20
  # - Alt+k Send Ctrl+C twice (soft interrupt)
20
21
  # - Alt+K Force kill the pane immediately
21
22
  # - Alt+R Respawn pane with fresh shell
@@ -25,10 +26,9 @@ set -e
25
26
 
26
27
  # Parse arguments
27
28
  NO_TMUX=false
28
- RESCUE=false
29
29
  KILL_SESSION=false
30
30
  SHOW_HELP=false
31
- FRESH_START=false
31
+ ATTACH_ONLY=false
32
32
  USE_RESUME=false
33
33
  RESUME_SESSION_ID=""
34
34
 
@@ -38,12 +38,16 @@ for arg in "$@"; do
38
38
  NO_TMUX=true
39
39
  shift
40
40
  ;;
41
+ --attach|-a)
42
+ ATTACH_ONLY=true
43
+ shift
44
+ ;;
41
45
  --fresh|-f)
42
- FRESH_START=true
46
+ # Kept for backwards compat, but this is now the default behavior
43
47
  shift
44
48
  ;;
45
49
  --rescue|-r)
46
- RESCUE=true
50
+ # Kept for backwards compat, same as default now
47
51
  shift
48
52
  ;;
49
53
  --kill)
@@ -67,12 +71,14 @@ USAGE:
67
71
  agileflow [options] [claude-args...]
68
72
 
69
73
  OPTIONS:
70
- --fresh, -f Kill existing session and start fresh (use after updates)
74
+ --attach, -a Reattach to existing session (skip fresh start)
71
75
  --no-tmux, -n Run claude without tmux
72
- --rescue, -r Kill frozen session and restart fresh
73
76
  --kill Kill existing session completely
74
77
  --help, -h Show this help
75
78
 
79
+ By default, af always creates a fresh tmux session and resumes your
80
+ Claude conversation. This prevents frozen sessions from blocking you.
81
+
76
82
  TMUX KEYBINDS:
77
83
  Alt+1-9 Switch to window N
78
84
  Alt+c Create new window
@@ -91,11 +97,6 @@ FREEZE RECOVERY:
91
97
  Alt+k Send Ctrl+C twice (soft interrupt)
92
98
  Alt+K Force kill pane immediately
93
99
  Alt+R Respawn pane with fresh shell
94
-
95
- If Claude is completely frozen and keybinds don't work:
96
- 1. Open a new terminal
97
- 2. Run: af --rescue (kills and restarts)
98
- 3. Or: af --kill (just kills, doesn't restart)
99
100
  EOF
100
101
  exit 0
101
102
  fi
@@ -105,7 +106,7 @@ if [ "$NO_TMUX" = true ]; then
105
106
  exec claude "$@"
106
107
  fi
107
108
 
108
- # Generate session name based on current directory (needed for rescue/kill)
109
+ # Generate session name based on current directory (needed for all modes)
109
110
  DIR_NAME=$(basename "$(pwd)")
110
111
  SESSION_NAME="claude-${DIR_NAME}"
111
112
 
@@ -121,47 +122,33 @@ if [ "$KILL_SESSION" = true ]; then
121
122
  exit 0
122
123
  fi
123
124
 
124
- # Handle --rescue flag (kill and restart)
125
- if [ "$RESCUE" = true ]; then
125
+ # Handle --attach flag (reattach to existing session without killing it)
126
+ if [ "$ATTACH_ONLY" = true ]; then
126
127
  if tmux has-session -t "$SESSION_NAME" 2>/dev/null; then
127
- echo "Killing frozen session: $SESSION_NAME"
128
- tmux kill-session -t "$SESSION_NAME"
129
- echo "Session killed. Restarting..."
130
- sleep 0.5
128
+ echo "Attaching to existing session: $SESSION_NAME"
129
+ exec tmux attach-session -t "$SESSION_NAME"
131
130
  else
132
- echo "No existing session to rescue. Starting fresh..."
131
+ echo "No existing session. Creating new one..."
132
+ # Fall through to create new session
133
133
  fi
134
- # Continue to create new session below
135
134
  fi
136
135
 
137
- # Handle --fresh flag (kill old session and start fresh with latest scripts + resume conversation)
138
- if [ "$FRESH_START" = true ]; then
139
- if tmux has-session -t "$SESSION_NAME" 2>/dev/null; then
140
- echo "Killing old session: $SESSION_NAME"
141
- tmux kill-session -t "$SESSION_NAME"
142
- echo "Starting fresh with latest scripts..."
143
- sleep 0.3
144
- else
145
- echo "No existing session. Starting fresh..."
146
- fi
136
+ # Default behavior: always kill existing session and start fresh
137
+ # This prevents frozen sessions from blocking you
138
+ if tmux has-session -t "$SESSION_NAME" 2>/dev/null; then
139
+ tmux kill-session -t "$SESSION_NAME" 2>/dev/null || true
140
+ fi
147
141
 
148
- # Find the most recent session for this directory
149
- PROJ_DIR=$(pwd | sed 's|/|-|g' | sed 's|^-||')
150
- SESSIONS_DIR="$HOME/.claude/projects/-$PROJ_DIR"
151
-
152
- if [ -d "$SESSIONS_DIR" ]; then
153
- # Get most recent non-agent session (main conversations only)
154
- RECENT_SESSION=$(ls -t "$SESSIONS_DIR"/*.jsonl 2>/dev/null | grep -v "agent-" | head -1)
155
- if [ -n "$RECENT_SESSION" ] && [ -s "$RECENT_SESSION" ]; then
156
- # Extract session ID from filename (remove path and .jsonl extension)
157
- RESUME_SESSION_ID=$(basename "$RECENT_SESSION" .jsonl)
158
- echo "Found recent conversation: $RESUME_SESSION_ID"
159
- USE_RESUME=true
160
- else
161
- echo "No previous conversation found. Starting fresh."
162
- fi
163
- else
164
- echo "No session history found. Starting fresh."
142
+ # Find the most recent conversation to resume
143
+ PROJ_DIR=$(pwd | sed 's|/|-|g' | sed 's|^-||')
144
+ SESSIONS_DIR="$HOME/.claude/projects/-$PROJ_DIR"
145
+
146
+ if [ -d "$SESSIONS_DIR" ]; then
147
+ # Get most recent non-agent session (main conversations only)
148
+ RECENT_SESSION=$(ls -t "$SESSIONS_DIR"/*.jsonl 2>/dev/null | grep -v "agent-" | head -1)
149
+ if [ -n "$RECENT_SESSION" ] && [ -s "$RECENT_SESSION" ]; then
150
+ RESUME_SESSION_ID=$(basename "$RECENT_SESSION" .jsonl)
151
+ USE_RESUME=true
165
152
  fi
166
153
  fi
167
154
 
@@ -184,6 +171,20 @@ if [ -f "$METADATA_FILE" ]; then
184
171
  fi
185
172
  fi
186
173
 
174
+ # Check for default Claude flags from metadata (e.g., --dangerously-skip-permissions)
175
+ if [ -f "$METADATA_FILE" ]; then
176
+ META_FLAGS=$(node -e "
177
+ try {
178
+ const meta = JSON.parse(require('fs').readFileSync('$METADATA_FILE', 'utf8'));
179
+ console.log(meta.features?.claudeFlags?.enabled ? (meta.features.claudeFlags.defaultFlags || '') : '');
180
+ } catch(e) { console.log(''); }
181
+ " 2>/dev/null || echo "")
182
+ if [ -n "$META_FLAGS" ]; then
183
+ CLAUDE_SESSION_FLAGS="${CLAUDE_SESSION_FLAGS:+$CLAUDE_SESSION_FLAGS }$META_FLAGS"
184
+ export CLAUDE_SESSION_FLAGS
185
+ fi
186
+ fi
187
+
187
188
  # Check if we're already inside tmux
188
189
  if [ -n "$TMUX" ]; then
189
190
  # Already in tmux, just run claude
@@ -200,18 +201,13 @@ if ! command -v tmux &> /dev/null; then
200
201
  exec claude "$@"
201
202
  fi
202
203
 
203
- # SESSION_NAME already generated above (needed for --rescue and --kill)
204
-
205
- # Check if session already exists
206
- if tmux has-session -t "$SESSION_NAME" 2>/dev/null; then
207
- echo "Attaching to existing session: $SESSION_NAME"
208
- exec tmux attach-session -t "$SESSION_NAME"
209
- fi
210
-
211
204
  # Create new tmux session with Claude
212
205
  echo "Starting Claude in tmux session: $SESSION_NAME"
213
206
 
214
- # Create session in detached mode first
207
+ # Set base-index globally BEFORE creating session so first window gets index 1
208
+ tmux set-option -g base-index 1
209
+
210
+ # Create session in detached mode first (will use base-index 1)
215
211
  tmux new-session -d -s "$SESSION_NAME" -n "main"
216
212
 
217
213
  # ══════════════════════════════════════════════════════════════════════════════
@@ -229,7 +225,8 @@ tmux set-option -t "$SESSION_NAME" -ga terminal-overrides ",xterm-256color:Tc"
229
225
 
230
226
  # Status bar position and refresh
231
227
  tmux set-option -t "$SESSION_NAME" status-position bottom
232
- tmux set-option -t "$SESSION_NAME" status-interval 5
228
+ # Reduce refresh rate to prevent CPU overhead and freezes (was 5s, now 30s)
229
+ tmux set-option -t "$SESSION_NAME" status-interval 30
233
230
 
234
231
  # Enable 2-line status bar
235
232
  tmux set-option -t "$SESSION_NAME" status 2
@@ -237,9 +234,11 @@ tmux set-option -t "$SESSION_NAME" status 2
237
234
  # Base styling - Tokyo Night inspired dark theme
238
235
  tmux set-option -t "$SESSION_NAME" status-style "bg=#1a1b26,fg=#a9b1d6"
239
236
 
237
+ # Capture git branch once at startup (avoids spawning process every refresh)
238
+ GIT_BRANCH=$(git branch --show-current 2>/dev/null || echo '-')
239
+
240
240
  # Line 0 (top): Session name (stripped of claude- prefix) + Keybinds + Git branch
241
- # Shows freeze recovery keys: Alt+k (soft kill), Alt+K (hard kill)
242
- tmux set-option -t "$SESSION_NAME" status-format[0] "#[bg=#1a1b26] #[fg=#e8683a bold]#{s/claude-//:session_name} #[fg=#3b4261]· #[fg=#7aa2f7]󰘬 #(git branch --show-current 2>/dev/null || echo '-') #[align=right]#[fg=#7a7e8a]Alt+k freeze Alt+x close Alt+q detach "
241
+ tmux set-option -t "$SESSION_NAME" status-format[0] "#[bg=#1a1b26] #[fg=#e8683a bold]#{s/claude-//:session_name} #[fg=#3b4261]· #[fg=#7aa2f7]󰘬 ${GIT_BRANCH} #[align=right]#[fg=#7a7e8a]Alt+k interrupt Alt+x close Alt+q detach "
243
242
 
244
243
  # Line 1 (bottom): Window tabs with smart truncation and brand color
245
244
  # - Active window: full name (max 15 chars), brand orange highlight
@@ -255,8 +254,7 @@ tmux set-option -t "$SESSION_NAME" message-style "bg=#e8683a,fg=#1a1b26,bold"
255
254
 
256
255
  # ─── Keybindings ──────────────────────────────────────────────────────────────
257
256
 
258
- # Window numbering starts at 1 (not 0)
259
- tmux set-option -t "$SESSION_NAME" base-index 1
257
+ # base-index 1 is set globally before session creation (so first window is 1)
260
258
 
261
259
  # Alt+number to switch windows (1-9)
262
260
  for i in 1 2 3 4 5 6 7 8 9; do
@@ -52,6 +52,10 @@ const FEATURES = {
52
52
  metadataOnly: true,
53
53
  description: 'Auto-kill duplicate Claude processes in same directory to prevent freezing',
54
54
  },
55
+ claudeflags: {
56
+ metadataOnly: true,
57
+ description: 'Default flags for Claude CLI (e.g., --dangerously-skip-permissions)',
58
+ },
55
59
  };
56
60
 
57
61
  const PROFILES = {
@@ -298,6 +302,27 @@ function enableFeature(feature, options = {}, version) {
298
302
  return true;
299
303
  }
300
304
 
305
+ // Handle claude flags (e.g., --dangerously-skip-permissions)
306
+ if (feature === 'claudeflags') {
307
+ const defaultFlags = options.flags || '--dangerously-skip-permissions';
308
+ updateMetadata(
309
+ {
310
+ features: {
311
+ claudeFlags: {
312
+ enabled: true,
313
+ defaultFlags,
314
+ version,
315
+ at: new Date().toISOString(),
316
+ },
317
+ },
318
+ },
319
+ version
320
+ );
321
+ success(`Default Claude flags configured: ${defaultFlags}`);
322
+ info('These flags will be passed to Claude when launched via "af" or "agileflow"');
323
+ return true;
324
+ }
325
+
301
326
  // Handle shell aliases
302
327
  if (feature === 'shellaliases') {
303
328
  const result = enableShellAliases();
@@ -684,6 +709,26 @@ function disableFeature(feature, version) {
684
709
  return true;
685
710
  }
686
711
 
712
+ // Disable claude flags
713
+ if (feature === 'claudeflags') {
714
+ updateMetadata(
715
+ {
716
+ features: {
717
+ claudeFlags: {
718
+ enabled: false,
719
+ defaultFlags: '',
720
+ version,
721
+ at: new Date().toISOString(),
722
+ },
723
+ },
724
+ },
725
+ version
726
+ );
727
+ success('Default Claude flags disabled');
728
+ info('Claude will launch with default permissions (prompts for each action)');
729
+ return true;
730
+ }
731
+
687
732
  // Disable shell aliases
688
733
  if (feature === 'shellaliases') {
689
734
  const result = disableShellAliases();
@@ -1093,6 +1138,15 @@ function enableShellAliases() {
1093
1138
  { name: 'zsh', path: path.join(homeDir, '.zshrc') },
1094
1139
  ];
1095
1140
 
1141
+ // Lines that belong to AgileFlow alias blocks (old and new markers)
1142
+ const ALIAS_BLOCK_LINES = [
1143
+ '# AgileFlow tmux wrapper',
1144
+ '# AgileFlow tmux shortcuts (claude stays normal)',
1145
+ '# Use \'af\' or \'agileflow\' for tmux, \'claude\' stays normal',
1146
+ 'alias af="bash .agileflow/scripts/af"',
1147
+ 'alias agileflow="bash .agileflow/scripts/af"',
1148
+ ];
1149
+
1096
1150
  for (const rc of rcFiles) {
1097
1151
  try {
1098
1152
  // Check if RC file exists
@@ -1103,13 +1157,24 @@ function enableShellAliases() {
1103
1157
 
1104
1158
  const content = fs.readFileSync(rc.path, 'utf8');
1105
1159
 
1106
- // Check if aliases already exist
1107
- if (content.includes(SHELL_ALIAS_MARKER)) {
1108
- result.skipped.push(`${rc.name} (already configured)`);
1160
+ // Check for ANY existing af alias (covers old and new markers)
1161
+ if (content.includes('alias af="bash .agileflow/scripts/af"')) {
1162
+ // Clean up: remove ALL existing alias block lines, then re-add one clean copy
1163
+ const lines = content.split('\n');
1164
+ const cleaned = lines.filter(line => {
1165
+ const trimmed = line.trim();
1166
+ return !ALIAS_BLOCK_LINES.includes(trimmed);
1167
+ });
1168
+ // Remove trailing empty lines from cleanup
1169
+ while (cleaned.length > 0 && cleaned[cleaned.length - 1].trim() === '') {
1170
+ cleaned.pop();
1171
+ }
1172
+ fs.writeFileSync(rc.path, cleaned.join('\n') + SHELL_ALIAS_BLOCK);
1173
+ result.configured.push(rc.name);
1109
1174
  continue;
1110
1175
  }
1111
1176
 
1112
- // Append aliases to RC file
1177
+ // First time: just append
1113
1178
  fs.appendFileSync(rc.path, SHELL_ALIAS_BLOCK);
1114
1179
  result.configured.push(rc.name);
1115
1180
  } catch (err) {
@@ -1140,6 +1205,15 @@ function disableShellAliases() {
1140
1205
  { name: 'zsh', path: path.join(homeDir, '.zshrc') },
1141
1206
  ];
1142
1207
 
1208
+ // Lines that belong to AgileFlow alias blocks (old and new markers)
1209
+ const ALIAS_BLOCK_LINES = [
1210
+ '# AgileFlow tmux wrapper',
1211
+ '# AgileFlow tmux shortcuts (claude stays normal)',
1212
+ '# Use \'af\' or \'agileflow\' for tmux, \'claude\' stays normal',
1213
+ 'alias af="bash .agileflow/scripts/af"',
1214
+ 'alias agileflow="bash .agileflow/scripts/af"',
1215
+ ];
1216
+
1143
1217
  for (const rc of rcFiles) {
1144
1218
  try {
1145
1219
  if (!fs.existsSync(rc.path)) {
@@ -1148,37 +1222,25 @@ function disableShellAliases() {
1148
1222
 
1149
1223
  const content = fs.readFileSync(rc.path, 'utf8');
1150
1224
 
1151
- if (!content.includes(SHELL_ALIAS_MARKER)) {
1225
+ // Check for any AgileFlow alias (covers old and new markers)
1226
+ if (!content.includes('alias af="bash .agileflow/scripts/af"') &&
1227
+ !content.includes(SHELL_ALIAS_MARKER)) {
1152
1228
  continue;
1153
1229
  }
1154
1230
 
1155
- // Remove the alias block
1231
+ // Remove all alias block lines
1156
1232
  const lines = content.split('\n');
1157
- const filteredLines = [];
1158
- let inBlock = false;
1233
+ const filteredLines = lines.filter(line => {
1234
+ const trimmed = line.trim();
1235
+ return !ALIAS_BLOCK_LINES.includes(trimmed);
1236
+ });
1159
1237
 
1160
- for (const line of lines) {
1161
- if (line.includes(SHELL_ALIAS_MARKER)) {
1162
- inBlock = true;
1163
- continue;
1164
- }
1165
- if (
1166
- inBlock &&
1167
- (line.startsWith('# Use ') ||
1168
- line.startsWith('alias af=') ||
1169
- line.startsWith('alias agileflow='))
1170
- ) {
1171
- continue;
1172
- }
1173
- if (inBlock && line.trim() === '') {
1174
- inBlock = false;
1175
- continue;
1176
- }
1177
- inBlock = false;
1178
- filteredLines.push(line);
1238
+ // Remove trailing empty lines from cleanup
1239
+ while (filteredLines.length > 0 && filteredLines[filteredLines.length - 1].trim() === '') {
1240
+ filteredLines.pop();
1179
1241
  }
1180
1242
 
1181
- fs.writeFileSync(rc.path, filteredLines.join('\n'), 'utf8');
1243
+ fs.writeFileSync(rc.path, filteredLines.join('\n') + '\n', 'utf8');
1182
1244
  result.removed.push(rc.name);
1183
1245
  } catch (err) {
1184
1246
  result.skipped.push(`${rc.name} (error: ${err.message})`);
@@ -450,9 +450,15 @@ function createBashHook() {
450
450
 
451
451
  /**
452
452
  * Test command against a single pattern rule
453
+ * Skips patterns that fail ReDoS validation
453
454
  */
454
455
  function matchesPattern(command, rule) {
455
456
  try {
457
+ // Validate pattern for ReDoS safety before use
458
+ const validation = validatePattern(rule.pattern);
459
+ if (!validation.safe) {
460
+ return false;
461
+ }
456
462
  const flags = rule.flags || '';
457
463
  const regex = new RegExp(rule.pattern, flags);
458
464
  return regex.test(command);
@@ -517,6 +523,37 @@ function createBashHook() {
517
523
  };
518
524
  }
519
525
 
526
+ /**
527
+ * Detect ReDoS-vulnerable patterns (nested quantifiers)
528
+ *
529
+ * Checks for patterns like (a+)+ or (a*b?)* that cause
530
+ * catastrophic backtracking on pathological inputs.
531
+ *
532
+ * @param {string} pattern - Regex pattern string to validate
533
+ * @returns {{ safe: boolean, reason?: string }}
534
+ */
535
+ function validatePattern(pattern) {
536
+ if (!pattern || typeof pattern !== 'string') {
537
+ return { safe: false, reason: 'Empty or invalid pattern' };
538
+ }
539
+
540
+ // Detect nested quantifiers: a group with a quantifier containing inner quantifiers
541
+ // Matches patterns like (x+)*, (x+)+, (x*)+, (x+){2,}, etc.
542
+ const nestedQuantifierRe = /\([^)]*[+*][^)]*\)[+*{]/;
543
+ if (nestedQuantifierRe.test(pattern)) {
544
+ return { safe: false, reason: `Nested quantifier detected in: ${pattern}` };
545
+ }
546
+
547
+ // Try to compile the regex to catch syntax errors
548
+ try {
549
+ new RegExp(pattern);
550
+ } catch (e) {
551
+ return { safe: false, reason: `Invalid regex: ${e.message}` };
552
+ }
553
+
554
+ return { safe: true };
555
+ }
556
+
520
557
  module.exports = {
521
558
  c,
522
559
  findProjectRoot,
@@ -529,6 +566,7 @@ module.exports = {
529
566
  parseBashPatterns,
530
567
  parsePathPatterns,
531
568
  validatePathAgainstPatterns,
569
+ validatePattern,
532
570
  createPathHook,
533
571
  createBashHook,
534
572
  CONFIG_PATHS,
@@ -1,9 +1,7 @@
1
1
  ---
2
2
  name: code-reviewer
3
3
  description: Comprehensive code review specialist with security, performance, maintainability, and best practices analysis
4
- tools: - Read
5
- - Glob
6
- - Grep
4
+ tools: Read, Glob, Grep
7
5
  model: sonnet
8
6
  team_role: utility
9
7
  ---
@@ -1,10 +1,7 @@
1
1
  ---
2
2
  name: error-analyzer
3
3
  description: Error diagnosis specialist that analyzes stack traces, correlates logs, identifies root causes, and suggests fixes before external research is needed
4
- tools: - Read
5
- - Glob
6
- - Grep
7
- - Bash
4
+ tools: Read, Glob, Grep, Bash
8
5
  model: sonnet
9
6
  team_role: utility
10
7
  ---
@@ -1,9 +1,7 @@
1
1
  ---
2
2
  name: logic-analyzer-edge
3
3
  description: Edge case analyzer for boundary conditions, off-by-one errors, empty inputs, and wraparound issues
4
- tools: - Read
5
- - Glob
6
- - Grep
4
+ tools: Read, Glob, Grep
7
5
  model: haiku
8
6
  team_role: utility
9
7
  ---
@@ -1,9 +1,7 @@
1
1
  ---
2
2
  name: logic-analyzer-flow
3
3
  description: Control flow analyzer for dead code, unreachable branches, infinite loops, and missing return paths
4
- tools: - Read
5
- - Glob
6
- - Grep
4
+ tools: Read, Glob, Grep
7
5
  model: haiku
8
6
  team_role: utility
9
7
  ---
@@ -1,9 +1,7 @@
1
1
  ---
2
2
  name: logic-analyzer-invariant
3
3
  description: Invariant analyzer for pre/post conditions, state consistency, loop invariants, and contract violations
4
- tools: - Read
5
- - Glob
6
- - Grep
4
+ tools: Read, Glob, Grep
7
5
  model: haiku
8
6
  team_role: utility
9
7
  ---
@@ -1,9 +1,7 @@
1
1
  ---
2
2
  name: logic-analyzer-race
3
3
  description: Race condition analyzer for async patterns, event timing issues, shared state mutations, and concurrency bugs
4
- tools: - Read
5
- - Glob
6
- - Grep
4
+ tools: Read, Glob, Grep
7
5
  model: haiku
8
6
  team_role: utility
9
7
  ---
@@ -1,9 +1,7 @@
1
1
  ---
2
2
  name: logic-analyzer-type
3
3
  description: Type safety analyzer for implicit coercion bugs, null propagation, undefined behavior, and type confusion
4
- tools: - Read
5
- - Glob
6
- - Grep
4
+ tools: Read, Glob, Grep
7
5
  model: haiku
8
6
  team_role: utility
9
7
  ---
@@ -1,11 +1,7 @@
1
1
  ---
2
2
  name: logic-consensus
3
3
  description: Consensus coordinator for logic analysis - validates findings, votes on issues, resolves conflicts, and generates the final audit report
4
- tools: - Read
5
- - Write
6
- - Edit
7
- - Glob
8
- - Grep
4
+ tools: Read, Write, Edit, Glob, Grep
9
5
  model: sonnet
10
6
  team_role: lead
11
7
  ---
@@ -202,3 +202,36 @@ learnings:
202
202
  - "rpi: Research-Plan-Implement workflow with phase transitions"
203
203
  - "workflow: Parameterized workflow templates (built-in + custom)"
204
204
  notes: "All 9 files follow consistent documentation template extracted from source .md files: quick start, parameters table, detailed descriptions, usage examples with output, status indicators, best practices, error handling, and related commands. Ready for docs site publication."
205
+
206
+ - date: 2026-02-07
207
+ context: "Audited and fixed command documentation drift"
208
+ insight: "Systematically compared all 50 source commands against their documentation counterparts. Found critical drift in configure.mdx (50% outdated) and babysit.mdx (missing Smart Detection, Story Claiming, Logic Audit features). Fixed both with comprehensive updates preserving all source details."
209
+ modified_files:
210
+ - "apps/docs/content/docs/commands/configure.mdx (major rewrite - 200+ lines added)"
211
+ - "apps/docs/content/docs/commands/babysit.mdx (200+ lines added)"
212
+ drift_issues_fixed:
213
+ - "configure.mdx: Added 5 profile types (full, basic, minimal, experimental, none)"
214
+ - "configure.mdx: Added hierarchical menu system documentation (5 categories, 4 max options)"
215
+ - "configure.mdx: Added custom profiles (save, export, import, delete)"
216
+ - "configure.mdx: Added all available features (8 total: SessionStart, PreCompact, RalphLoop, SelfImprove, Archival, StatusLine, AskUserQuestion, Tmux, Shell Aliases, Auto-Update, CLAUDE.md Rules)"
217
+ - "configure.mdx: Added maintenance commands (detect, migrate, upgrade, repair, list-scripts)"
218
+ - "configure.mdx: Added troubleshooting section with solutions"
219
+ - "babysit.mdx: Added Smart Detection section (auto-enable Loop/Visual/Coverage/Conditions modes)"
220
+ - "babysit.mdx: Added Story Claiming section (multi-session coordination, prevent conflicts)"
221
+ - "babysit.mdx: Added Logic Audit integration (post-implementation quality check)"
222
+ - "babysit.mdx: Updated Loop Mode to show auto-detection instead of explicit parameters"
223
+ verified_good:
224
+ - "council.mdx: Comprehensive and current"
225
+ - "audit.mdx: Good alignment with source"
226
+ - "choose.mdx: Good alignment with source"
227
+ quality_gates:
228
+ - "Description matches source frontmatter ✓"
229
+ - "Parameters documented with types and defaults ✓"
230
+ - "Examples are copy-paste ready ✓"
231
+ - "Usage patterns match source implementation ✓"
232
+ - "Links to related commands accurate ✓"
233
+ - "No outdated information remains ✓"
234
+ - "All new features from source documented ✓"
235
+ - "Formatting consistent (tables, code blocks, bullets) ✓"
236
+ source: "packages/cli/src/core/commands/*.md vs apps/docs/content/docs/commands/*.mdx"
237
+ notes: "Used systematic comparison approach: extracted descriptions, parameters, and features from 50 source commands against documentation. Prioritized commands with most feature additions: babysit (Smart Detection, Story Claiming, Logic Audit), configure (profiles, hierarchical menus). All changes preserve source accuracy while making docs more discoverable and comprehensive."
@@ -16,7 +16,7 @@ version: "1.0.0"
16
16
 
17
17
  bashToolPatterns:
18
18
  # ─── File System Destruction ───
19
- - pattern: '\brm\s+(-[rRf]+\s+)*/'
19
+ - pattern: '\brm\s+(-[rRf]+\s+)?/'
20
20
  reason: "rm with absolute path - could delete system files"
21
21
 
22
22
  - pattern: '\brm\s+-[rRf]*\s+\.\.'
@@ -25,7 +25,7 @@ bashToolPatterns:
25
25
  - pattern: '\brm\s+-rf\s+'
26
26
  reason: "Recursive force delete - extremely dangerous"
27
27
 
28
- - pattern: '\brmdir\s+(-p\s+)*/'
28
+ - pattern: '\brmdir\s+(-p\s+)?/'
29
29
  reason: "rmdir with absolute path"
30
30
 
31
31
  # ─── Git Destructive Operations ───