@claude-flow/cli 3.0.0-alpha.37 → 3.0.0-alpha.39

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 (37) hide show
  1. package/.claude/helpers/README.md +97 -0
  2. package/.claude/helpers/adr-compliance.sh +186 -0
  3. package/.claude/helpers/auto-commit.sh +178 -0
  4. package/.claude/helpers/checkpoint-manager.sh +251 -0
  5. package/.claude/helpers/daemon-manager.sh +252 -0
  6. package/.claude/helpers/ddd-tracker.sh +144 -0
  7. package/.claude/helpers/github-safe.js +106 -0
  8. package/.claude/helpers/github-setup.sh +28 -0
  9. package/.claude/helpers/guidance-hook.sh +13 -0
  10. package/.claude/helpers/guidance-hooks.sh +102 -0
  11. package/.claude/helpers/health-monitor.sh +108 -0
  12. package/.claude/helpers/learning-hooks.sh +329 -0
  13. package/.claude/helpers/learning-optimizer.sh +127 -0
  14. package/.claude/helpers/learning-service.mjs +1144 -0
  15. package/.claude/helpers/metrics-db.mjs +488 -0
  16. package/.claude/helpers/pattern-consolidator.sh +86 -0
  17. package/.claude/helpers/perf-worker.sh +160 -0
  18. package/.claude/helpers/quick-start.sh +19 -0
  19. package/.claude/helpers/security-scanner.sh +127 -0
  20. package/.claude/helpers/setup-mcp.sh +18 -0
  21. package/.claude/helpers/standard-checkpoint-hooks.sh +189 -0
  22. package/.claude/helpers/swarm-comms.sh +353 -0
  23. package/.claude/helpers/swarm-hooks.sh +761 -0
  24. package/.claude/helpers/swarm-monitor.sh +211 -0
  25. package/.claude/helpers/sync-v3-metrics.sh +245 -0
  26. package/.claude/helpers/update-v3-progress.sh +166 -0
  27. package/.claude/helpers/v3-quick-status.sh +58 -0
  28. package/.claude/helpers/v3.sh +111 -0
  29. package/.claude/helpers/validate-v3-config.sh +216 -0
  30. package/.claude/helpers/worker-manager.sh +170 -0
  31. package/dist/src/init/executor.d.ts.map +1 -1
  32. package/dist/src/init/executor.js +103 -26
  33. package/dist/src/init/executor.js.map +1 -1
  34. package/dist/src/init/mcp-generator.js +2 -2
  35. package/dist/src/init/mcp-generator.js.map +1 -1
  36. package/dist/tsconfig.tsbuildinfo +1 -1
  37. package/package.json +1 -1
@@ -0,0 +1,251 @@
1
+ #!/bin/bash
2
+ # Claude Checkpoint Manager
3
+ # Provides easy rollback and management of Claude Code checkpoints
4
+
5
+ set -e
6
+
7
+ # Colors
8
+ RED='\033[0;31m'
9
+ GREEN='\033[0;32m'
10
+ YELLOW='\033[1;33m'
11
+ BLUE='\033[0;34m'
12
+ NC='\033[0m' # No Color
13
+
14
+ # Configuration
15
+ CHECKPOINT_DIR=".claude/checkpoints"
16
+ BACKUP_DIR=".claude/backups"
17
+
18
+ # Help function
19
+ show_help() {
20
+ cat << EOF
21
+ Claude Checkpoint Manager
22
+ ========================
23
+
24
+ Usage: $0 <command> [options]
25
+
26
+ Commands:
27
+ list List all checkpoints
28
+ show <id> Show details of a specific checkpoint
29
+ rollback <id> Rollback to a specific checkpoint
30
+ diff <id> Show diff since checkpoint
31
+ clean Clean old checkpoints (older than 7 days)
32
+ summary Show session summary
33
+
34
+ Options:
35
+ --hard For rollback: use git reset --hard (destructive)
36
+ --soft For rollback: use git reset --soft (default)
37
+ --branch For rollback: create new branch from checkpoint
38
+
39
+ Examples:
40
+ $0 list
41
+ $0 show checkpoint-20240130-143022
42
+ $0 rollback checkpoint-20240130-143022 --branch
43
+ $0 diff session-end-session-20240130-150000
44
+ EOF
45
+ }
46
+
47
+ # List all checkpoints
48
+ function list_checkpoints() {
49
+ echo -e "${BLUE}📋 Available Checkpoints:${NC}"
50
+ echo ""
51
+
52
+ # List checkpoint tags
53
+ echo -e "${YELLOW}Git Tags:${NC}"
54
+ local tags=$(git tag -l 'checkpoint-*' -l 'session-end-*' -l 'task-*' --sort=-creatordate | head -20)
55
+ if [ -n "$tags" ]; then
56
+ echo "$tags"
57
+ else
58
+ echo "No checkpoint tags found"
59
+ fi
60
+
61
+ echo ""
62
+
63
+ # List checkpoint branches
64
+ echo -e "${YELLOW}Checkpoint Branches:${NC}"
65
+ local branches=$(git branch -a | grep "checkpoint/" | sed 's/^[ *]*//')
66
+ if [ -n "$branches" ]; then
67
+ echo "$branches"
68
+ else
69
+ echo "No checkpoint branches found"
70
+ fi
71
+
72
+ echo ""
73
+
74
+ # List checkpoint files
75
+ if [ -d "$CHECKPOINT_DIR" ]; then
76
+ echo -e "${YELLOW}Recent Checkpoint Files:${NC}"
77
+ find "$CHECKPOINT_DIR" -name "*.json" -type f -printf "%T@ %p\n" | \
78
+ sort -rn | head -10 | cut -d' ' -f2- | xargs -I {} basename {}
79
+ fi
80
+ }
81
+
82
+ # Show checkpoint details
83
+ function show_checkpoint() {
84
+ local checkpoint_id="$1"
85
+
86
+ echo -e "${BLUE}📍 Checkpoint Details: $checkpoint_id${NC}"
87
+ echo ""
88
+
89
+ # Check if it's a tag
90
+ if git tag -l "$checkpoint_id" | grep -q "$checkpoint_id"; then
91
+ echo -e "${YELLOW}Type:${NC} Git Tag"
92
+ echo -e "${YELLOW}Commit:${NC} $(git rev-list -n 1 "$checkpoint_id")"
93
+ echo -e "${YELLOW}Date:${NC} $(git log -1 --format=%ai "$checkpoint_id")"
94
+ echo -e "${YELLOW}Message:${NC}"
95
+ git log -1 --format=%B "$checkpoint_id" | sed 's/^/ /'
96
+ echo ""
97
+ echo -e "${YELLOW}Files changed:${NC}"
98
+ git diff-tree --no-commit-id --name-status -r "$checkpoint_id" | sed 's/^/ /'
99
+ # Check if it's a branch
100
+ elif git branch -a | grep -q "$checkpoint_id"; then
101
+ echo -e "${YELLOW}Type:${NC} Git Branch"
102
+ echo -e "${YELLOW}Latest commit:${NC}"
103
+ git log -1 --oneline "$checkpoint_id"
104
+ else
105
+ echo -e "${RED}❌ Checkpoint not found: $checkpoint_id${NC}"
106
+ exit 1
107
+ fi
108
+ }
109
+
110
+ # Rollback to checkpoint
111
+ function rollback_checkpoint() {
112
+ local checkpoint_id="$1"
113
+ local mode="$2"
114
+
115
+ echo -e "${YELLOW}🔄 Rolling back to checkpoint: $checkpoint_id${NC}"
116
+ echo ""
117
+
118
+ # Verify checkpoint exists
119
+ if ! git tag -l "$checkpoint_id" | grep -q "$checkpoint_id" && \
120
+ ! git branch -a | grep -q "$checkpoint_id"; then
121
+ echo -e "${RED}❌ Checkpoint not found: $checkpoint_id${NC}"
122
+ exit 1
123
+ fi
124
+
125
+ # Create backup before rollback
126
+ local backup_name="backup-$(date +%Y%m%d-%H%M%S)"
127
+ echo "Creating backup: $backup_name"
128
+ git tag "$backup_name" -m "Backup before rollback to $checkpoint_id"
129
+
130
+ case "$mode" in
131
+ "--hard")
132
+ echo -e "${RED}⚠️ Performing hard reset (destructive)${NC}"
133
+ git reset --hard "$checkpoint_id"
134
+ echo -e "${GREEN}✅ Rolled back to $checkpoint_id (hard reset)${NC}"
135
+ ;;
136
+ "--branch")
137
+ local branch_name="rollback-$checkpoint_id-$(date +%Y%m%d-%H%M%S)"
138
+ echo "Creating new branch: $branch_name"
139
+ git checkout -b "$branch_name" "$checkpoint_id"
140
+ echo -e "${GREEN}✅ Created branch $branch_name from $checkpoint_id${NC}"
141
+ ;;
142
+ "--stash"|*)
143
+ echo "Stashing current changes..."
144
+ git stash push -m "Stash before rollback to $checkpoint_id"
145
+ git reset --soft "$checkpoint_id"
146
+ echo -e "${GREEN}✅ Rolled back to $checkpoint_id (soft reset)${NC}"
147
+ echo "Your changes are stashed. Use 'git stash pop' to restore them."
148
+ ;;
149
+ esac
150
+ }
151
+
152
+ # Show diff since checkpoint
153
+ function diff_checkpoint() {
154
+ local checkpoint_id="$1"
155
+
156
+ echo -e "${BLUE}📊 Changes since checkpoint: $checkpoint_id${NC}"
157
+ echo ""
158
+
159
+ if git tag -l "$checkpoint_id" | grep -q "$checkpoint_id"; then
160
+ git diff "$checkpoint_id"
161
+ elif git branch -a | grep -q "$checkpoint_id"; then
162
+ git diff "$checkpoint_id"
163
+ else
164
+ echo -e "${RED}❌ Checkpoint not found: $checkpoint_id${NC}"
165
+ exit 1
166
+ fi
167
+ }
168
+
169
+ # Clean old checkpoints
170
+ function clean_checkpoints() {
171
+ local days=${1:-7}
172
+
173
+ echo -e "${YELLOW}🧹 Cleaning checkpoints older than $days days...${NC}"
174
+ echo ""
175
+
176
+ # Clean old checkpoint files
177
+ if [ -d "$CHECKPOINT_DIR" ]; then
178
+ find "$CHECKPOINT_DIR" -name "*.json" -type f -mtime +$days -delete
179
+ echo "✅ Cleaned old checkpoint files"
180
+ fi
181
+
182
+ # List old tags (but don't delete automatically)
183
+ echo ""
184
+ echo "Old checkpoint tags (manual deletion required):"
185
+ git tag -l 'checkpoint-*' --sort=-creatordate | tail -n +50 || echo "No old tags found"
186
+ }
187
+
188
+ # Show session summary
189
+ function show_summary() {
190
+ echo -e "${BLUE}📊 Session Summary${NC}"
191
+ echo ""
192
+
193
+ # Find most recent session summary
194
+ if [ -d "$CHECKPOINT_DIR" ]; then
195
+ local latest_summary=$(find "$CHECKPOINT_DIR" -name "summary-*.md" -type f -printf "%T@ %p\n" | \
196
+ sort -rn | head -1 | cut -d' ' -f2-)
197
+
198
+ if [ -n "$latest_summary" ]; then
199
+ echo -e "${YELLOW}Latest session summary:${NC}"
200
+ cat "$latest_summary"
201
+ else
202
+ echo "No session summaries found"
203
+ fi
204
+ fi
205
+ }
206
+
207
+ # Main command handling
208
+ case "$1" in
209
+ list)
210
+ list_checkpoints
211
+ ;;
212
+ show)
213
+ if [ -z "$2" ]; then
214
+ echo -e "${RED}Error: Please specify a checkpoint ID${NC}"
215
+ show_help
216
+ exit 1
217
+ fi
218
+ show_checkpoint "$2"
219
+ ;;
220
+ rollback)
221
+ if [ -z "$2" ]; then
222
+ echo -e "${RED}Error: Please specify a checkpoint ID${NC}"
223
+ show_help
224
+ exit 1
225
+ fi
226
+ rollback_checkpoint "$2" "$3"
227
+ ;;
228
+ diff)
229
+ if [ -z "$2" ]; then
230
+ echo -e "${RED}Error: Please specify a checkpoint ID${NC}"
231
+ show_help
232
+ exit 1
233
+ fi
234
+ diff_checkpoint "$2"
235
+ ;;
236
+ clean)
237
+ clean_checkpoints "$2"
238
+ ;;
239
+ summary)
240
+ show_summary
241
+ ;;
242
+ help|--help|-h)
243
+ show_help
244
+ ;;
245
+ *)
246
+ echo -e "${RED}Error: Unknown command: $1${NC}"
247
+ echo ""
248
+ show_help
249
+ exit 1
250
+ ;;
251
+ esac
@@ -0,0 +1,252 @@
1
+ #!/bin/bash
2
+ # Claude Flow V3 - Daemon Manager
3
+ # Manages background services for real-time statusline updates
4
+
5
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
6
+ PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
7
+ PID_DIR="$PROJECT_ROOT/.claude-flow/pids"
8
+ LOG_DIR="$PROJECT_ROOT/.claude-flow/logs"
9
+ METRICS_DIR="$PROJECT_ROOT/.claude-flow/metrics"
10
+
11
+ # Ensure directories exist
12
+ mkdir -p "$PID_DIR" "$LOG_DIR" "$METRICS_DIR"
13
+
14
+ # PID files
15
+ SWARM_MONITOR_PID="$PID_DIR/swarm-monitor.pid"
16
+ METRICS_DAEMON_PID="$PID_DIR/metrics-daemon.pid"
17
+
18
+ # Log files
19
+ DAEMON_LOG="$LOG_DIR/daemon.log"
20
+
21
+ # Colors
22
+ GREEN='\033[0;32m'
23
+ YELLOW='\033[1;33m'
24
+ RED='\033[0;31m'
25
+ CYAN='\033[0;36m'
26
+ RESET='\033[0m'
27
+
28
+ log() {
29
+ local msg="[$(date '+%Y-%m-%d %H:%M:%S')] $1"
30
+ echo -e "${CYAN}$msg${RESET}"
31
+ echo "$msg" >> "$DAEMON_LOG"
32
+ }
33
+
34
+ success() {
35
+ local msg="[$(date '+%Y-%m-%d %H:%M:%S')] SUCCESS: $1"
36
+ echo -e "${GREEN}$msg${RESET}"
37
+ echo "$msg" >> "$DAEMON_LOG"
38
+ }
39
+
40
+ error() {
41
+ local msg="[$(date '+%Y-%m-%d %H:%M:%S')] ERROR: $1"
42
+ echo -e "${RED}$msg${RESET}"
43
+ echo "$msg" >> "$DAEMON_LOG"
44
+ }
45
+
46
+ # Check if a process is running
47
+ is_running() {
48
+ local pid_file="$1"
49
+ if [ -f "$pid_file" ]; then
50
+ local pid=$(cat "$pid_file")
51
+ if ps -p "$pid" > /dev/null 2>&1; then
52
+ return 0
53
+ fi
54
+ fi
55
+ return 1
56
+ }
57
+
58
+ # Start the swarm monitor daemon
59
+ start_swarm_monitor() {
60
+ local interval="${1:-3}"
61
+
62
+ if is_running "$SWARM_MONITOR_PID"; then
63
+ log "Swarm monitor already running (PID: $(cat "$SWARM_MONITOR_PID"))"
64
+ return 0
65
+ fi
66
+
67
+ log "Starting swarm monitor daemon (interval: ${interval}s)..."
68
+
69
+ # Run the monitor in background
70
+ nohup "$SCRIPT_DIR/swarm-monitor.sh" monitor "$interval" >> "$LOG_DIR/swarm-monitor.log" 2>&1 &
71
+ local pid=$!
72
+
73
+ echo "$pid" > "$SWARM_MONITOR_PID"
74
+ success "Swarm monitor started (PID: $pid)"
75
+
76
+ return 0
77
+ }
78
+
79
+ # Start the metrics update daemon
80
+ start_metrics_daemon() {
81
+ local interval="${1:-30}" # Default 30 seconds for V3 sync
82
+
83
+ if is_running "$METRICS_DAEMON_PID"; then
84
+ log "Metrics daemon already running (PID: $(cat "$METRICS_DAEMON_PID"))"
85
+ return 0
86
+ fi
87
+
88
+ log "Starting metrics daemon (interval: ${interval}s, using SQLite)..."
89
+
90
+ # Use SQLite-based metrics (10.5x faster than bash/JSON)
91
+ # Run as Node.js daemon process
92
+ nohup node "$SCRIPT_DIR/metrics-db.mjs" daemon "$interval" >> "$LOG_DIR/metrics-daemon.log" 2>&1 &
93
+ local pid=$!
94
+
95
+ echo "$pid" > "$METRICS_DAEMON_PID"
96
+ success "Metrics daemon started (PID: $pid) - SQLite backend"
97
+
98
+ return 0
99
+ }
100
+
101
+ # Stop a daemon by PID file
102
+ stop_daemon() {
103
+ local pid_file="$1"
104
+ local name="$2"
105
+
106
+ if [ -f "$pid_file" ]; then
107
+ local pid=$(cat "$pid_file")
108
+ if ps -p "$pid" > /dev/null 2>&1; then
109
+ log "Stopping $name (PID: $pid)..."
110
+ kill "$pid" 2>/dev/null
111
+ sleep 1
112
+
113
+ # Force kill if still running
114
+ if ps -p "$pid" > /dev/null 2>&1; then
115
+ kill -9 "$pid" 2>/dev/null
116
+ fi
117
+
118
+ success "$name stopped"
119
+ fi
120
+ rm -f "$pid_file"
121
+ else
122
+ log "$name not running"
123
+ fi
124
+ }
125
+
126
+ # Start all daemons
127
+ start_all() {
128
+ log "Starting all Claude Flow daemons..."
129
+ start_swarm_monitor "${1:-3}"
130
+ start_metrics_daemon "${2:-5}"
131
+
132
+ # Initial metrics update
133
+ "$SCRIPT_DIR/swarm-monitor.sh" check > /dev/null 2>&1
134
+
135
+ success "All daemons started"
136
+ show_status
137
+ }
138
+
139
+ # Stop all daemons
140
+ stop_all() {
141
+ log "Stopping all Claude Flow daemons..."
142
+ stop_daemon "$SWARM_MONITOR_PID" "Swarm monitor"
143
+ stop_daemon "$METRICS_DAEMON_PID" "Metrics daemon"
144
+ success "All daemons stopped"
145
+ }
146
+
147
+ # Restart all daemons
148
+ restart_all() {
149
+ stop_all
150
+ sleep 1
151
+ start_all "$@"
152
+ }
153
+
154
+ # Show daemon status
155
+ show_status() {
156
+ echo ""
157
+ echo -e "${CYAN}═══════════════════════════════════════════════════${RESET}"
158
+ echo -e "${CYAN} Claude Flow V3 Daemon Status${RESET}"
159
+ echo -e "${CYAN}═══════════════════════════════════════════════════${RESET}"
160
+ echo ""
161
+
162
+ # Swarm Monitor
163
+ if is_running "$SWARM_MONITOR_PID"; then
164
+ echo -e " ${GREEN}●${RESET} Swarm Monitor ${GREEN}RUNNING${RESET} (PID: $(cat "$SWARM_MONITOR_PID"))"
165
+ else
166
+ echo -e " ${RED}○${RESET} Swarm Monitor ${RED}STOPPED${RESET}"
167
+ fi
168
+
169
+ # Metrics Daemon
170
+ if is_running "$METRICS_DAEMON_PID"; then
171
+ echo -e " ${GREEN}●${RESET} Metrics Daemon ${GREEN}RUNNING${RESET} (PID: $(cat "$METRICS_DAEMON_PID"))"
172
+ else
173
+ echo -e " ${RED}○${RESET} Metrics Daemon ${RED}STOPPED${RESET}"
174
+ fi
175
+
176
+ # MCP Server
177
+ local mcp_count=$(ps aux 2>/dev/null | grep -E "mcp.*start" | grep -v grep | wc -l)
178
+ if [ "$mcp_count" -gt 0 ]; then
179
+ echo -e " ${GREEN}●${RESET} MCP Server ${GREEN}RUNNING${RESET}"
180
+ else
181
+ echo -e " ${YELLOW}○${RESET} MCP Server ${YELLOW}NOT DETECTED${RESET}"
182
+ fi
183
+
184
+ # Agentic Flow
185
+ local af_count=$(ps aux 2>/dev/null | grep -E "agentic-flow" | grep -v grep | grep -v "daemon-manager" | wc -l)
186
+ if [ "$af_count" -gt 0 ]; then
187
+ echo -e " ${GREEN}●${RESET} Agentic Flow ${GREEN}ACTIVE${RESET} ($af_count processes)"
188
+ else
189
+ echo -e " ${YELLOW}○${RESET} Agentic Flow ${YELLOW}IDLE${RESET}"
190
+ fi
191
+
192
+ echo ""
193
+ echo -e "${CYAN}───────────────────────────────────────────────────${RESET}"
194
+
195
+ # Show latest metrics
196
+ if [ -f "$METRICS_DIR/swarm-activity.json" ]; then
197
+ local last_update=$(jq -r '.timestamp // "unknown"' "$METRICS_DIR/swarm-activity.json" 2>/dev/null)
198
+ local agent_count=$(jq -r '.swarm.agent_count // 0' "$METRICS_DIR/swarm-activity.json" 2>/dev/null)
199
+ echo -e " Last Update: ${last_update}"
200
+ echo -e " Active Agents: ${agent_count}"
201
+ fi
202
+
203
+ echo -e "${CYAN}═══════════════════════════════════════════════════${RESET}"
204
+ echo ""
205
+ }
206
+
207
+ # Main command handling
208
+ case "${1:-status}" in
209
+ "start")
210
+ start_all "${2:-3}" "${3:-5}"
211
+ ;;
212
+ "stop")
213
+ stop_all
214
+ ;;
215
+ "restart")
216
+ restart_all "${2:-3}" "${3:-5}"
217
+ ;;
218
+ "status")
219
+ show_status
220
+ ;;
221
+ "start-swarm")
222
+ start_swarm_monitor "${2:-3}"
223
+ ;;
224
+ "start-metrics")
225
+ start_metrics_daemon "${2:-5}"
226
+ ;;
227
+ "help"|"-h"|"--help")
228
+ echo "Claude Flow V3 Daemon Manager"
229
+ echo ""
230
+ echo "Usage: $0 [command] [options]"
231
+ echo ""
232
+ echo "Commands:"
233
+ echo " start [swarm_interval] [metrics_interval] Start all daemons"
234
+ echo " stop Stop all daemons"
235
+ echo " restart [swarm_interval] [metrics_interval] Restart all daemons"
236
+ echo " status Show daemon status"
237
+ echo " start-swarm [interval] Start swarm monitor only"
238
+ echo " start-metrics [interval] Start metrics daemon only"
239
+ echo " help Show this help"
240
+ echo ""
241
+ echo "Examples:"
242
+ echo " $0 start # Start with defaults (3s swarm, 5s metrics)"
243
+ echo " $0 start 2 3 # Start with 2s swarm, 3s metrics intervals"
244
+ echo " $0 status # Show current status"
245
+ echo " $0 stop # Stop all daemons"
246
+ ;;
247
+ *)
248
+ error "Unknown command: $1"
249
+ echo "Use '$0 help' for usage information"
250
+ exit 1
251
+ ;;
252
+ esac
@@ -0,0 +1,144 @@
1
+ #!/bin/bash
2
+ # Claude Flow V3 - DDD Progress Tracker Worker
3
+ # Tracks Domain-Driven Design implementation progress
4
+
5
+ set -euo pipefail
6
+
7
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
8
+ PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
9
+ METRICS_DIR="$PROJECT_ROOT/.claude-flow/metrics"
10
+ DDD_FILE="$METRICS_DIR/ddd-progress.json"
11
+ V3_PROGRESS="$METRICS_DIR/v3-progress.json"
12
+ LAST_RUN_FILE="$METRICS_DIR/.ddd-last-run"
13
+
14
+ mkdir -p "$METRICS_DIR"
15
+
16
+ # V3 Target Domains
17
+ DOMAINS=("agent-lifecycle" "task-execution" "memory-management" "coordination" "shared-kernel")
18
+
19
+ should_run() {
20
+ if [ ! -f "$LAST_RUN_FILE" ]; then return 0; fi
21
+ local last_run=$(cat "$LAST_RUN_FILE" 2>/dev/null || echo "0")
22
+ local now=$(date +%s)
23
+ [ $((now - last_run)) -ge 600 ] # 10 minutes
24
+ }
25
+
26
+ check_domain() {
27
+ local domain="$1"
28
+ local domain_path="$PROJECT_ROOT/v3/@claude-flow/$domain"
29
+ local alt_path="$PROJECT_ROOT/src/domains/$domain"
30
+
31
+ local score=0
32
+ local max_score=100
33
+
34
+ # Check if domain directory exists (20 points)
35
+ if [ -d "$domain_path" ] || [ -d "$alt_path" ]; then
36
+ score=$((score + 20))
37
+ local path="${domain_path:-$alt_path}"
38
+ [ -d "$domain_path" ] && path="$domain_path" || path="$alt_path"
39
+
40
+ # Check for domain layer (15 points)
41
+ [ -d "$path/domain" ] || [ -d "$path/src/domain" ] && score=$((score + 15))
42
+
43
+ # Check for application layer (15 points)
44
+ [ -d "$path/application" ] || [ -d "$path/src/application" ] && score=$((score + 15))
45
+
46
+ # Check for infrastructure layer (15 points)
47
+ [ -d "$path/infrastructure" ] || [ -d "$path/src/infrastructure" ] && score=$((score + 15))
48
+
49
+ # Check for API/interface layer (10 points)
50
+ [ -d "$path/api" ] || [ -d "$path/src/api" ] && score=$((score + 10))
51
+
52
+ # Check for tests (15 points)
53
+ local test_count=$(find "$path" -name "*.test.ts" -o -name "*.spec.ts" 2>/dev/null | wc -l)
54
+ [ "$test_count" -gt 0 ] && score=$((score + 15))
55
+
56
+ # Check for index/exports (10 points)
57
+ [ -f "$path/index.ts" ] || [ -f "$path/src/index.ts" ] && score=$((score + 10))
58
+ fi
59
+
60
+ echo "$score"
61
+ }
62
+
63
+ count_entities() {
64
+ local type="$1"
65
+ local pattern="$2"
66
+
67
+ find "$PROJECT_ROOT/v3" "$PROJECT_ROOT/src" -name "*.ts" 2>/dev/null | \
68
+ xargs grep -l "$pattern" 2>/dev/null | \
69
+ grep -v node_modules | grep -v ".test." | wc -l || echo "0"
70
+ }
71
+
72
+ track_ddd() {
73
+ echo "[$(date +%H:%M:%S)] Tracking DDD progress..."
74
+
75
+ local total_score=0
76
+ local domain_scores=""
77
+ local completed_domains=0
78
+
79
+ for domain in "${DOMAINS[@]}"; do
80
+ local score=$(check_domain "$domain")
81
+ total_score=$((total_score + score))
82
+ domain_scores="$domain_scores\"$domain\": $score, "
83
+
84
+ [ "$score" -ge 50 ] && completed_domains=$((completed_domains + 1))
85
+ done
86
+
87
+ # Calculate overall progress
88
+ local max_total=$((${#DOMAINS[@]} * 100))
89
+ local progress=$((total_score * 100 / max_total))
90
+
91
+ # Count DDD artifacts
92
+ local entities=$(count_entities "entities" "class.*Entity\|interface.*Entity")
93
+ local value_objects=$(count_entities "value-objects" "class.*VO\|ValueObject")
94
+ local aggregates=$(count_entities "aggregates" "class.*Aggregate\|AggregateRoot")
95
+ local repositories=$(count_entities "repositories" "interface.*Repository\|Repository")
96
+ local services=$(count_entities "services" "class.*Service\|Service")
97
+ local events=$(count_entities "events" "class.*Event\|DomainEvent")
98
+
99
+ # Write DDD metrics
100
+ cat > "$DDD_FILE" << EOF
101
+ {
102
+ "timestamp": "$(date -Iseconds)",
103
+ "progress": $progress,
104
+ "domains": {
105
+ ${domain_scores%,*}
106
+ },
107
+ "completed": $completed_domains,
108
+ "total": ${#DOMAINS[@]},
109
+ "artifacts": {
110
+ "entities": $entities,
111
+ "valueObjects": $value_objects,
112
+ "aggregates": $aggregates,
113
+ "repositories": $repositories,
114
+ "services": $services,
115
+ "domainEvents": $events
116
+ }
117
+ }
118
+ EOF
119
+
120
+ # Update v3-progress.json
121
+ if [ -f "$V3_PROGRESS" ] && command -v jq &>/dev/null; then
122
+ jq --argjson progress "$progress" --argjson completed "$completed_domains" \
123
+ '.ddd.progress = $progress | .domains.completed = $completed' \
124
+ "$V3_PROGRESS" > "$V3_PROGRESS.tmp" && mv "$V3_PROGRESS.tmp" "$V3_PROGRESS"
125
+ fi
126
+
127
+ echo "[$(date +%H:%M:%S)] ✓ DDD: ${progress}% | Domains: $completed_domains/${#DOMAINS[@]} | Entities: $entities | Services: $services"
128
+
129
+ date +%s > "$LAST_RUN_FILE"
130
+ }
131
+
132
+ case "${1:-check}" in
133
+ "run"|"track") track_ddd ;;
134
+ "check") should_run && track_ddd || echo "[$(date +%H:%M:%S)] Skipping (throttled)" ;;
135
+ "force") rm -f "$LAST_RUN_FILE"; track_ddd ;;
136
+ "status")
137
+ if [ -f "$DDD_FILE" ]; then
138
+ jq -r '"Progress: \(.progress)% | Domains: \(.completed)/\(.total) | Entities: \(.artifacts.entities) | Services: \(.artifacts.services)"' "$DDD_FILE"
139
+ else
140
+ echo "No DDD data available"
141
+ fi
142
+ ;;
143
+ *) echo "Usage: $0 [run|check|force|status]" ;;
144
+ esac