agileflow 3.3.0 → 3.4.1
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.
- package/CHANGELOG.md +10 -0
- package/README.md +6 -6
- package/lib/skill-loader.js +0 -1
- package/package.json +1 -1
- package/scripts/agileflow-statusline.sh +81 -0
- package/scripts/agileflow-welcome.js +79 -0
- package/scripts/claude-tmux.sh +90 -23
- package/scripts/claude-watchdog.sh +225 -0
- package/scripts/generators/agent-registry.js +14 -1
- package/scripts/generators/inject-babysit.js +22 -9
- package/scripts/generators/inject-help.js +19 -9
- package/scripts/lib/ac-test-matcher.js +452 -0
- package/scripts/lib/audit-cleanup.js +250 -0
- package/scripts/lib/audit-registry.js +304 -0
- package/scripts/lib/configure-features.js +35 -0
- package/scripts/lib/feature-catalog.js +3 -3
- package/scripts/lib/gate-enforcer.js +295 -0
- package/scripts/lib/model-profiles.js +118 -0
- package/scripts/lib/quality-gates.js +163 -0
- package/scripts/lib/signal-detectors.js +44 -1
- package/scripts/lib/skill-catalog.js +557 -0
- package/scripts/lib/skill-recommender.js +311 -0
- package/scripts/lib/status-writer.js +255 -0
- package/scripts/lib/story-claiming.js +128 -45
- package/scripts/lib/task-sync.js +32 -38
- package/scripts/lib/tdd-phase-manager.js +455 -0
- package/scripts/lib/team-events.js +34 -3
- package/scripts/lib/tmux-audit-monitor.js +611 -0
- package/scripts/lib/tmux-group-colors.js +113 -0
- package/scripts/lib/tool-registry.yaml +241 -0
- package/scripts/lib/tool-shed.js +441 -0
- package/scripts/messaging-bridge.js +209 -1
- package/scripts/native-team-observer.js +219 -0
- package/scripts/obtain-context.js +14 -0
- package/scripts/ralph-loop.js +30 -5
- package/scripts/smart-detect.js +21 -0
- package/scripts/spawn-audit-sessions.js +877 -0
- package/scripts/team-manager.js +56 -16
- package/scripts/tmux-close-windows.sh +180 -0
- package/src/core/agents/a11y-analyzer-aria.md +155 -0
- package/src/core/agents/a11y-analyzer-forms.md +162 -0
- package/src/core/agents/a11y-analyzer-keyboard.md +175 -0
- package/src/core/agents/a11y-analyzer-semantic.md +153 -0
- package/src/core/agents/a11y-analyzer-visual.md +158 -0
- package/src/core/agents/a11y-consensus.md +248 -0
- package/src/core/agents/ads-audit-budget.md +181 -0
- package/src/core/agents/ads-audit-compliance.md +169 -0
- package/src/core/agents/ads-audit-creative.md +164 -0
- package/src/core/agents/ads-audit-google.md +226 -0
- package/src/core/agents/ads-audit-meta.md +183 -0
- package/src/core/agents/ads-audit-tracking.md +197 -0
- package/src/core/agents/ads-consensus.md +396 -0
- package/src/core/agents/ads-generate.md +145 -0
- package/src/core/agents/ads-performance-tracker.md +197 -0
- package/src/core/agents/api-quality-analyzer-conventions.md +148 -0
- package/src/core/agents/api-quality-analyzer-docs.md +176 -0
- package/src/core/agents/api-quality-analyzer-errors.md +183 -0
- package/src/core/agents/api-quality-analyzer-pagination.md +171 -0
- package/src/core/agents/api-quality-analyzer-versioning.md +143 -0
- package/src/core/agents/api-quality-consensus.md +214 -0
- package/src/core/agents/arch-analyzer-circular.md +148 -0
- package/src/core/agents/arch-analyzer-complexity.md +171 -0
- package/src/core/agents/arch-analyzer-coupling.md +146 -0
- package/src/core/agents/arch-analyzer-layering.md +151 -0
- package/src/core/agents/arch-analyzer-patterns.md +162 -0
- package/src/core/agents/arch-consensus.md +227 -0
- package/src/core/agents/brainstorm-analyzer-features.md +169 -0
- package/src/core/agents/brainstorm-analyzer-growth.md +161 -0
- package/src/core/agents/brainstorm-analyzer-integration.md +172 -0
- package/src/core/agents/brainstorm-analyzer-market.md +147 -0
- package/src/core/agents/brainstorm-analyzer-ux.md +167 -0
- package/src/core/agents/brainstorm-consensus.md +237 -0
- package/src/core/agents/completeness-consensus.md +5 -5
- package/src/core/agents/perf-consensus.md +2 -2
- package/src/core/agents/security-consensus.md +2 -2
- package/src/core/agents/seo-analyzer-content.md +167 -0
- package/src/core/agents/seo-analyzer-images.md +187 -0
- package/src/core/agents/seo-analyzer-performance.md +206 -0
- package/src/core/agents/seo-analyzer-schema.md +176 -0
- package/src/core/agents/seo-analyzer-sitemap.md +172 -0
- package/src/core/agents/seo-analyzer-technical.md +144 -0
- package/src/core/agents/seo-consensus.md +289 -0
- package/src/core/agents/test-consensus.md +2 -2
- package/src/core/commands/adr.md +1 -0
- package/src/core/commands/ads/audit.md +375 -0
- package/src/core/commands/ads/budget.md +97 -0
- package/src/core/commands/ads/competitor.md +112 -0
- package/src/core/commands/ads/creative.md +85 -0
- package/src/core/commands/ads/generate.md +238 -0
- package/src/core/commands/ads/google.md +112 -0
- package/src/core/commands/ads/health.md +327 -0
- package/src/core/commands/ads/landing.md +119 -0
- package/src/core/commands/ads/linkedin.md +112 -0
- package/src/core/commands/ads/meta.md +91 -0
- package/src/core/commands/ads/microsoft.md +115 -0
- package/src/core/commands/ads/plan.md +321 -0
- package/src/core/commands/ads/test-plan.md +317 -0
- package/src/core/commands/ads/tiktok.md +129 -0
- package/src/core/commands/ads/track.md +288 -0
- package/src/core/commands/ads/youtube.md +124 -0
- package/src/core/commands/ads.md +140 -0
- package/src/core/commands/assign.md +1 -0
- package/src/core/commands/audit.md +43 -6
- package/src/core/commands/babysit.md +315 -1266
- package/src/core/commands/baseline.md +1 -0
- package/src/core/commands/blockers.md +1 -0
- package/src/core/commands/board.md +1 -0
- package/src/core/commands/changelog.md +1 -0
- package/src/core/commands/choose.md +1 -0
- package/src/core/commands/ci.md +1 -0
- package/src/core/commands/code/accessibility.md +347 -0
- package/src/core/commands/code/api.md +297 -0
- package/src/core/commands/code/architecture.md +297 -0
- package/src/core/commands/{audit → code}/completeness.md +72 -25
- package/src/core/commands/{audit → code}/legal.md +63 -16
- package/src/core/commands/{audit → code}/logic.md +64 -16
- package/src/core/commands/{audit → code}/performance.md +67 -20
- package/src/core/commands/{audit → code}/security.md +69 -19
- package/src/core/commands/{audit → code}/test.md +67 -20
- package/src/core/commands/configure.md +1 -0
- package/src/core/commands/council.md +1 -0
- package/src/core/commands/deploy.md +1 -0
- package/src/core/commands/diagnose.md +1 -0
- package/src/core/commands/docs.md +1 -0
- package/src/core/commands/epic/edit.md +213 -0
- package/src/core/commands/epic.md +1 -0
- package/src/core/commands/export.md +238 -0
- package/src/core/commands/help.md +16 -1
- package/src/core/commands/{discovery → ideate}/brief.md +12 -12
- package/src/core/commands/{discovery/new.md → ideate/discover.md} +20 -16
- package/src/core/commands/ideate/features.md +496 -0
- package/src/core/commands/ideate/new.md +158 -124
- package/src/core/commands/impact.md +1 -0
- package/src/core/commands/learn/explain.md +118 -0
- package/src/core/commands/learn/glossary.md +135 -0
- package/src/core/commands/learn/patterns.md +138 -0
- package/src/core/commands/learn/tour.md +126 -0
- package/src/core/commands/migrate/codemods.md +151 -0
- package/src/core/commands/migrate/plan.md +131 -0
- package/src/core/commands/migrate/scan.md +114 -0
- package/src/core/commands/migrate/validate.md +119 -0
- package/src/core/commands/multi-expert.md +1 -0
- package/src/core/commands/pr.md +1 -0
- package/src/core/commands/review.md +1 -0
- package/src/core/commands/seo/audit.md +373 -0
- package/src/core/commands/seo/competitor.md +174 -0
- package/src/core/commands/seo/content.md +107 -0
- package/src/core/commands/seo/geo.md +229 -0
- package/src/core/commands/seo/hreflang.md +140 -0
- package/src/core/commands/seo/images.md +96 -0
- package/src/core/commands/seo/page.md +198 -0
- package/src/core/commands/seo/plan.md +163 -0
- package/src/core/commands/seo/programmatic.md +131 -0
- package/src/core/commands/seo/references/cwv-thresholds.md +64 -0
- package/src/core/commands/seo/references/eeat-framework.md +110 -0
- package/src/core/commands/seo/references/quality-gates.md +91 -0
- package/src/core/commands/seo/references/schema-types.md +102 -0
- package/src/core/commands/seo/schema.md +183 -0
- package/src/core/commands/seo/sitemap.md +97 -0
- package/src/core/commands/seo/technical.md +100 -0
- package/src/core/commands/seo.md +107 -0
- package/src/core/commands/skill/list.md +68 -212
- package/src/core/commands/skill/recommend.md +216 -0
- package/src/core/commands/sprint.md +1 -0
- package/src/core/commands/status/undo.md +191 -0
- package/src/core/commands/status.md +1 -0
- package/src/core/commands/story/edit.md +204 -0
- package/src/core/commands/story/view.md +29 -7
- package/src/core/commands/story-validate.md +1 -0
- package/src/core/commands/story.md +1 -0
- package/src/core/commands/tdd-next.md +238 -0
- package/src/core/commands/tdd.md +211 -0
- package/src/core/commands/team/start.md +10 -6
- package/src/core/commands/tests.md +1 -0
- package/src/core/commands/verify.md +27 -1
- package/src/core/commands/workflow.md +2 -0
- package/src/core/experts/_core-expertise.yaml +105 -0
- package/src/core/experts/analytics/expertise.yaml +5 -99
- package/src/core/experts/codebase-query/expertise.yaml +3 -72
- package/src/core/experts/compliance/expertise.yaml +6 -72
- package/src/core/experts/database/expertise.yaml +9 -52
- package/src/core/experts/documentation/expertise.yaml +7 -140
- package/src/core/experts/integrations/expertise.yaml +7 -127
- package/src/core/experts/mentor/expertise.yaml +8 -35
- package/src/core/experts/monitoring/expertise.yaml +7 -49
- package/src/core/experts/performance/expertise.yaml +1 -26
- package/src/core/experts/security/expertise.yaml +9 -34
- package/src/core/experts/ui/expertise.yaml +6 -36
- package/src/core/knowledge/ads/ad-audit-checklist-scoring.md +424 -0
- package/src/core/knowledge/ads/ad-optimization-logic.md +590 -0
- package/src/core/knowledge/ads/ad-technical-specifications.md +385 -0
- package/src/core/knowledge/ads/definitive-advertising-reference-2026.md +506 -0
- package/src/core/knowledge/ads/paid-advertising-research-2026.md +445 -0
- package/src/core/teams/backend.json +41 -0
- package/src/core/teams/frontend.json +41 -0
- package/src/core/teams/qa.json +41 -0
- package/src/core/teams/solo.json +35 -0
- package/src/core/templates/agileflow-metadata.json +20 -1
- package/tools/cli/commands/setup.js +85 -3
- package/tools/cli/commands/update.js +42 -0
- package/tools/cli/installers/ide/_base-ide.js +42 -5
- package/tools/cli/installers/ide/claude-code.js +71 -3
- package/tools/cli/lib/content-injector.js +160 -12
- package/tools/cli/lib/docs-setup.js +1 -1
- package/src/core/commands/skill/create.md +0 -698
- package/src/core/commands/skill/delete.md +0 -316
- package/src/core/commands/skill/edit.md +0 -359
- package/src/core/commands/skill/test.md +0 -394
- package/src/core/commands/skill/upgrade.md +0 -552
- package/src/core/templates/skill-template.md +0 -117
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# claude-watchdog.sh - Background watchdog that detects and kills frozen Claude processes
|
|
3
|
+
#
|
|
4
|
+
# Usage: claude-watchdog.sh <session-name>
|
|
5
|
+
#
|
|
6
|
+
# Runs in the background, checking every WATCHDOG_INTERVAL seconds for Claude
|
|
7
|
+
# processes that appear frozen. A process is considered frozen when ALL of:
|
|
8
|
+
# 1. Running for > WATCHDOG_MAX_AGE_HOURS hours
|
|
9
|
+
# 2. Using > WATCHDOG_MAX_MEMORY_MB megabytes of RSS
|
|
10
|
+
# 3. No JSONL file modification in > WATCHDOG_MAX_IDLE_MINUTES minutes
|
|
11
|
+
#
|
|
12
|
+
# Recovery sequence: Ctrl+C x2 (5s wait) → SIGTERM (5s wait) → SIGKILL
|
|
13
|
+
# After kill, the pane stays open with a shell prompt (tab is NOT closed).
|
|
14
|
+
#
|
|
15
|
+
# Logs kills to ~/.claude/watchdog.log
|
|
16
|
+
#
|
|
17
|
+
# Environment variable configuration:
|
|
18
|
+
# WATCHDOG_INTERVAL Check interval in seconds (default: 120)
|
|
19
|
+
# WATCHDOG_MAX_AGE_HOURS Minimum process age to consider (default: 6)
|
|
20
|
+
# WATCHDOG_MAX_MEMORY_MB Minimum RSS in MB to consider (default: 400)
|
|
21
|
+
# WATCHDOG_MAX_IDLE_MINUTES Minutes since last JSONL write (default: 60)
|
|
22
|
+
#
|
|
23
|
+
# NOTE: Linux-only (requires /proc filesystem and GNU ps). macOS not supported.
|
|
24
|
+
|
|
25
|
+
set -euo pipefail
|
|
26
|
+
|
|
27
|
+
SESSION_NAME="${1:-}"
|
|
28
|
+
if [ -z "$SESSION_NAME" ]; then
|
|
29
|
+
echo "Usage: claude-watchdog.sh <session-name>" >&2
|
|
30
|
+
exit 1
|
|
31
|
+
fi
|
|
32
|
+
|
|
33
|
+
# Configuration (all overridable via environment)
|
|
34
|
+
INTERVAL="${WATCHDOG_INTERVAL:-120}"
|
|
35
|
+
MAX_AGE_HOURS="${WATCHDOG_MAX_AGE_HOURS:-6}"
|
|
36
|
+
MAX_MEMORY_MB="${WATCHDOG_MAX_MEMORY_MB:-400}"
|
|
37
|
+
MAX_IDLE_MINUTES="${WATCHDOG_MAX_IDLE_MINUTES:-60}"
|
|
38
|
+
|
|
39
|
+
# Validate numeric configuration
|
|
40
|
+
for _var_name in INTERVAL MAX_AGE_HOURS MAX_MEMORY_MB MAX_IDLE_MINUTES; do
|
|
41
|
+
_var_val="${!_var_name}"
|
|
42
|
+
if ! [[ "$_var_val" =~ ^[0-9]+$ ]]; then
|
|
43
|
+
echo "ERROR: $_var_name must be a positive integer, got: '$_var_val'" >&2
|
|
44
|
+
exit 1
|
|
45
|
+
fi
|
|
46
|
+
done
|
|
47
|
+
|
|
48
|
+
LOG_FILE="$HOME/.claude/watchdog.log"
|
|
49
|
+
mkdir -p "$(dirname "$LOG_FILE")"
|
|
50
|
+
|
|
51
|
+
log() {
|
|
52
|
+
local timestamp
|
|
53
|
+
timestamp=$(date '+%Y-%m-%d %H:%M:%S')
|
|
54
|
+
echo "[$timestamp] [watchdog:$SESSION_NAME] $*" >> "$LOG_FILE"
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
log "Started (interval=${INTERVAL}s, max_age=${MAX_AGE_HOURS}h, max_mem=${MAX_MEMORY_MB}MB, max_idle=${MAX_IDLE_MINUTES}m)"
|
|
58
|
+
|
|
59
|
+
# Clean exit when session is destroyed
|
|
60
|
+
cleanup() {
|
|
61
|
+
log "Stopping (session gone or signal received)" || true
|
|
62
|
+
exit 0
|
|
63
|
+
}
|
|
64
|
+
trap cleanup INT TERM
|
|
65
|
+
|
|
66
|
+
# Check if a process's JSONL files have been modified recently
|
|
67
|
+
# Returns 0 if idle (no recent writes), 1 if active
|
|
68
|
+
is_process_idle() {
|
|
69
|
+
local pid="$1"
|
|
70
|
+
local idle_minutes="$2"
|
|
71
|
+
|
|
72
|
+
# Find the working directory of the process to locate .claude/ project dirs
|
|
73
|
+
local cwd
|
|
74
|
+
cwd=$(readlink "/proc/$pid/cwd" 2>/dev/null) || return 1
|
|
75
|
+
|
|
76
|
+
# Build the project path Claude Code uses for JSONL session files
|
|
77
|
+
local proj_dir
|
|
78
|
+
proj_dir=$(echo "$cwd" | sed 's|/|-|g' | sed 's|^-||')
|
|
79
|
+
local sessions_dir="$HOME/.claude/projects/-$proj_dir"
|
|
80
|
+
|
|
81
|
+
if [ ! -d "$sessions_dir" ]; then
|
|
82
|
+
# No session dir means no activity tracking — assume idle
|
|
83
|
+
return 0
|
|
84
|
+
fi
|
|
85
|
+
|
|
86
|
+
# Check if any JSONL file was modified within idle_minutes
|
|
87
|
+
local recent_file
|
|
88
|
+
recent_file=$(find "$sessions_dir" -name '*.jsonl' -mmin "-$idle_minutes" -print -quit 2>/dev/null)
|
|
89
|
+
|
|
90
|
+
if [ -n "$recent_file" ]; then
|
|
91
|
+
# Recently modified — process is active
|
|
92
|
+
return 1
|
|
93
|
+
fi
|
|
94
|
+
|
|
95
|
+
# No recent modifications — process is idle
|
|
96
|
+
return 0
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
# Get process RSS in MB (Linux /proc-based, ps fallback)
|
|
100
|
+
get_rss_mb() {
|
|
101
|
+
local pid="$1"
|
|
102
|
+
local rss_kb
|
|
103
|
+
if [ -f "/proc/$pid/status" ]; then
|
|
104
|
+
rss_kb=$(awk '/^VmRSS:/ { print $2 }' "/proc/$pid/status" 2>/dev/null) || return 1
|
|
105
|
+
[ -z "$rss_kb" ] && return 1 # process died between stat and read
|
|
106
|
+
echo $(( rss_kb / 1024 ))
|
|
107
|
+
else
|
|
108
|
+
rss_kb=$(ps -o rss= -p "$pid" 2>/dev/null | tr -d ' ') || return 1
|
|
109
|
+
[ -z "$rss_kb" ] && return 1
|
|
110
|
+
echo $(( rss_kb / 1024 ))
|
|
111
|
+
fi
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
# Get process age in hours
|
|
115
|
+
get_age_hours() {
|
|
116
|
+
local pid="$1"
|
|
117
|
+
local elapsed_seconds
|
|
118
|
+
elapsed_seconds=$(ps -o etimes= -p "$pid" 2>/dev/null | tr -d ' ') || return 1
|
|
119
|
+
[ -z "$elapsed_seconds" ] && return 1
|
|
120
|
+
echo $(( elapsed_seconds / 3600 ))
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
# Gracefully kill a frozen process with escalating signals
|
|
124
|
+
kill_frozen_process() {
|
|
125
|
+
local pid="$1"
|
|
126
|
+
local pane_id="$2"
|
|
127
|
+
local age_h="$3"
|
|
128
|
+
local mem_mb="$4"
|
|
129
|
+
|
|
130
|
+
log "FROZEN DETECTED: PID=$pid pane=$pane_id age=${age_h}h mem=${mem_mb}MB"
|
|
131
|
+
log "Recovery: sending Ctrl+C x2 to pane $pane_id"
|
|
132
|
+
|
|
133
|
+
# Step 1: Try Ctrl+C twice via tmux (gentlest approach)
|
|
134
|
+
tmux send-keys -t "$pane_id" C-c 2>/dev/null || true
|
|
135
|
+
sleep 1
|
|
136
|
+
tmux send-keys -t "$pane_id" C-c 2>/dev/null || true
|
|
137
|
+
sleep 4
|
|
138
|
+
|
|
139
|
+
# Check if process is still alive
|
|
140
|
+
if ! kill -0 "$pid" 2>/dev/null; then
|
|
141
|
+
log "Process $pid terminated after Ctrl+C"
|
|
142
|
+
return 0
|
|
143
|
+
fi
|
|
144
|
+
|
|
145
|
+
# Step 2: SIGTERM
|
|
146
|
+
log "Recovery: sending SIGTERM to PID $pid"
|
|
147
|
+
kill -TERM "$pid" 2>/dev/null || true
|
|
148
|
+
sleep 5
|
|
149
|
+
|
|
150
|
+
if ! kill -0 "$pid" 2>/dev/null; then
|
|
151
|
+
log "Process $pid terminated after SIGTERM"
|
|
152
|
+
return 0
|
|
153
|
+
fi
|
|
154
|
+
|
|
155
|
+
# Step 3: SIGKILL (last resort)
|
|
156
|
+
log "Recovery: sending SIGKILL to PID $pid"
|
|
157
|
+
kill -KILL "$pid" 2>/dev/null || true
|
|
158
|
+
sleep 1
|
|
159
|
+
|
|
160
|
+
if ! kill -0 "$pid" 2>/dev/null; then
|
|
161
|
+
log "Process $pid terminated after SIGKILL"
|
|
162
|
+
else
|
|
163
|
+
log "WARNING: Process $pid survived SIGKILL — zombie or kernel issue"
|
|
164
|
+
fi
|
|
165
|
+
|
|
166
|
+
return 0
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
# Main check loop
|
|
170
|
+
while true; do
|
|
171
|
+
# Exit if session no longer exists
|
|
172
|
+
if ! tmux has-session -t "$SESSION_NAME" 2>/dev/null; then
|
|
173
|
+
log "Session '$SESSION_NAME' no longer exists"
|
|
174
|
+
break
|
|
175
|
+
fi
|
|
176
|
+
|
|
177
|
+
# Iterate over all panes in the session
|
|
178
|
+
while IFS= read -r pane_info; do
|
|
179
|
+
[ -z "$pane_info" ] && continue
|
|
180
|
+
|
|
181
|
+
pane_id="${pane_info%% *}"
|
|
182
|
+
pane_pid="${pane_info#* }"
|
|
183
|
+
|
|
184
|
+
# Find claude child processes under this pane's shell
|
|
185
|
+
# Look for processes whose command contains "claude" under the pane PID
|
|
186
|
+
while IFS= read -r child_line; do
|
|
187
|
+
[ -z "$child_line" ] && continue
|
|
188
|
+
|
|
189
|
+
child_pid="${child_line%% *}"
|
|
190
|
+
child_cmd="${child_line#* }"
|
|
191
|
+
|
|
192
|
+
# Skip non-claude processes and skip ourselves
|
|
193
|
+
case "$child_cmd" in
|
|
194
|
+
*claude-watchdog*|*watchdog*) continue ;;
|
|
195
|
+
*claude*) ;; # This is a Claude process — check it
|
|
196
|
+
*) continue ;;
|
|
197
|
+
esac
|
|
198
|
+
|
|
199
|
+
# Criterion 1: Age check
|
|
200
|
+
age_h=$(get_age_hours "$child_pid" 2>/dev/null) || continue
|
|
201
|
+
if [ "$age_h" -lt "$MAX_AGE_HOURS" ]; then
|
|
202
|
+
continue
|
|
203
|
+
fi
|
|
204
|
+
|
|
205
|
+
# Criterion 2: Memory check
|
|
206
|
+
mem_mb=$(get_rss_mb "$child_pid" 2>/dev/null) || continue
|
|
207
|
+
if [ "$mem_mb" -lt "$MAX_MEMORY_MB" ]; then
|
|
208
|
+
continue
|
|
209
|
+
fi
|
|
210
|
+
|
|
211
|
+
# Criterion 3: Idle check (most important — prevents killing active work)
|
|
212
|
+
if ! is_process_idle "$child_pid" "$MAX_IDLE_MINUTES"; then
|
|
213
|
+
# Process has recent JSONL activity — NOT frozen, just long-running
|
|
214
|
+
continue
|
|
215
|
+
fi
|
|
216
|
+
|
|
217
|
+
# All three criteria met — this process is frozen
|
|
218
|
+
kill_frozen_process "$child_pid" "$pane_id" "$age_h" "$mem_mb"
|
|
219
|
+
|
|
220
|
+
done < <(ps --ppid "$pane_pid" -o pid=,args= 2>/dev/null || true)
|
|
221
|
+
|
|
222
|
+
done < <(tmux list-panes -t "$SESSION_NAME" -F '#{pane_id} #{pane_pid}' 2>/dev/null || true)
|
|
223
|
+
|
|
224
|
+
sleep "$INTERVAL"
|
|
225
|
+
done
|
|
@@ -15,6 +15,19 @@ const path = require('path');
|
|
|
15
15
|
const { extractFrontmatter, normalizeTools } = require('../lib/frontmatter-parser');
|
|
16
16
|
const { getCached, setCached } = require('../../lib/registry-cache');
|
|
17
17
|
|
|
18
|
+
// Lazy-load model-profiles to avoid circular deps and missing-module crashes
|
|
19
|
+
let _resolveModel;
|
|
20
|
+
function getResolveModel() {
|
|
21
|
+
if (_resolveModel === undefined) {
|
|
22
|
+
try {
|
|
23
|
+
_resolveModel = require('../lib/model-profiles').resolveModel;
|
|
24
|
+
} catch (_) {
|
|
25
|
+
_resolveModel = null;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return _resolveModel;
|
|
29
|
+
}
|
|
30
|
+
|
|
18
31
|
// Debug mode: set DEBUG_REGISTRY=1 to see why files are skipped
|
|
19
32
|
const DEBUG = process.env.DEBUG_REGISTRY === '1';
|
|
20
33
|
|
|
@@ -110,7 +123,7 @@ async function scanAgents(agentsDir) {
|
|
|
110
123
|
displayName: frontmatter.name || name,
|
|
111
124
|
description: frontmatter.description || '',
|
|
112
125
|
tools,
|
|
113
|
-
model:
|
|
126
|
+
model: (getResolveModel() || ((_, fm) => fm || 'haiku'))(null, frontmatter.model),
|
|
114
127
|
color: frontmatter.color || 'blue',
|
|
115
128
|
category: categorizeAgent(name, frontmatter.description || ''),
|
|
116
129
|
});
|
|
@@ -14,9 +14,11 @@ const { scanAgents } = require('./agent-registry');
|
|
|
14
14
|
const { scanCommands } = require('./command-registry');
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
|
-
* Generate agent list content with
|
|
17
|
+
* Generate agent list content as category summary with counts.
|
|
18
|
+
* Uses compact format with discovery pointer instead of listing every agent name.
|
|
19
|
+
* Research (arXiv:2602.11988): Full lists increase context cost without improving performance.
|
|
18
20
|
* @param {Array} agents - Array of agent metadata
|
|
19
|
-
* @returns {string} Formatted agent
|
|
21
|
+
* @returns {string} Formatted agent category summary
|
|
20
22
|
*/
|
|
21
23
|
function generateAgentList(agents) {
|
|
22
24
|
const lines = [];
|
|
@@ -24,16 +26,27 @@ function generateAgentList(agents) {
|
|
|
24
26
|
lines.push(`**AVAILABLE AGENTS** (${agents.length} total):`);
|
|
25
27
|
lines.push('');
|
|
26
28
|
|
|
27
|
-
|
|
29
|
+
// Group agents by category for compact output (counts only, not full names)
|
|
30
|
+
const categories = {};
|
|
28
31
|
for (const agent of agents) {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
const cat = agent.category || 'Other';
|
|
33
|
+
if (!categories[cat]) categories[cat] = { count: 0, examples: [] };
|
|
34
|
+
categories[cat].count++;
|
|
35
|
+
// Keep first 3 names as examples
|
|
36
|
+
if (categories[cat].examples.length < 3) {
|
|
37
|
+
categories[cat].examples.push(agent.name);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
for (const [category, data] of Object.entries(categories)) {
|
|
42
|
+
const examples = data.examples.join(', ');
|
|
43
|
+
const more = data.count > 3 ? `, +${data.count - 3} more` : '';
|
|
44
|
+
lines.push(`**${category}** (${data.count}): ${examples}${more}`);
|
|
35
45
|
}
|
|
36
46
|
|
|
47
|
+
lines.push('');
|
|
48
|
+
lines.push('Browse all: `ls .agileflow/agents/` or run `/agileflow:help agents`');
|
|
49
|
+
|
|
37
50
|
return lines.join('\n');
|
|
38
51
|
}
|
|
39
52
|
|
|
@@ -13,9 +13,11 @@ const path = require('path');
|
|
|
13
13
|
const { scanCommands } = require('./command-registry');
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
|
-
* Generate command list content
|
|
16
|
+
* Generate command list content as category summary with counts and examples.
|
|
17
|
+
* Uses compact format with discovery pointer instead of listing every command.
|
|
18
|
+
* Research (arXiv:2602.11988): Full lists increase context cost without improving performance.
|
|
17
19
|
* @param {Array} commands - Array of command metadata
|
|
18
|
-
* @returns {string} Formatted command
|
|
20
|
+
* @returns {string} Formatted command category summary
|
|
19
21
|
*/
|
|
20
22
|
function generateCommandList(commands) {
|
|
21
23
|
const lines = [];
|
|
@@ -29,16 +31,24 @@ function generateCommandList(commands) {
|
|
|
29
31
|
categories[cmd.category].push(cmd);
|
|
30
32
|
}
|
|
31
33
|
|
|
32
|
-
|
|
34
|
+
lines.push(
|
|
35
|
+
`**${commands.length} commands** across ${Object.keys(categories).length} categories:`
|
|
36
|
+
);
|
|
37
|
+
lines.push('');
|
|
38
|
+
|
|
39
|
+
// Generate compact category summary with examples
|
|
33
40
|
for (const [category, cmds] of Object.entries(categories)) {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}
|
|
39
|
-
lines.push(
|
|
41
|
+
const examples = cmds
|
|
42
|
+
.slice(0, 3)
|
|
43
|
+
.map(c => c.name)
|
|
44
|
+
.join(', ');
|
|
45
|
+
const more = cmds.length > 3 ? `, +${cmds.length - 3} more` : '';
|
|
46
|
+
lines.push(`- **${category}** (${cmds.length}): ${examples}${more}`);
|
|
40
47
|
}
|
|
41
48
|
|
|
49
|
+
lines.push('');
|
|
50
|
+
lines.push('Browse all: `ls .agileflow/commands/` or run `/agileflow:help`');
|
|
51
|
+
|
|
42
52
|
return lines.join('\n');
|
|
43
53
|
}
|
|
44
54
|
|