@paulduvall/claude-dev-toolkit 0.0.1-alpha.1 → 0.0.1-alpha.4

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 (117) hide show
  1. package/README.md +44 -6
  2. package/bin/claude-commands +20 -0
  3. package/commands/active/xarchitecture.md +393 -0
  4. package/commands/active/xconfig.md +127 -0
  5. package/commands/active/xdebug.md +130 -0
  6. package/commands/active/xdocs.md +178 -0
  7. package/commands/active/xgit.md +149 -0
  8. package/commands/active/xpipeline.md +152 -0
  9. package/commands/active/xquality.md +96 -0
  10. package/commands/active/xrefactor.md +198 -0
  11. package/commands/active/xrelease.md +142 -0
  12. package/commands/active/xsecurity.md +92 -0
  13. package/commands/active/xspec.md +174 -0
  14. package/commands/active/xtdd.md +151 -0
  15. package/commands/active/xtest.md +89 -0
  16. package/commands/experiments/xact.md +742 -0
  17. package/commands/experiments/xanalytics.md +113 -0
  18. package/commands/experiments/xanalyze.md +70 -0
  19. package/commands/experiments/xapi.md +161 -0
  20. package/commands/experiments/xatomic.md +112 -0
  21. package/commands/experiments/xaws.md +85 -0
  22. package/commands/experiments/xcicd.md +337 -0
  23. package/commands/experiments/xcommit.md +122 -0
  24. package/commands/experiments/xcompliance.md +182 -0
  25. package/commands/experiments/xconstraints.md +89 -0
  26. package/commands/experiments/xcoverage.md +90 -0
  27. package/commands/experiments/xdb.md +102 -0
  28. package/commands/experiments/xdesign.md +121 -0
  29. package/commands/experiments/xevaluate.md +111 -0
  30. package/commands/experiments/xfootnote.md +12 -0
  31. package/commands/experiments/xgenerate.md +117 -0
  32. package/commands/experiments/xgovernance.md +149 -0
  33. package/commands/experiments/xgreen.md +66 -0
  34. package/commands/experiments/xiac.md +118 -0
  35. package/commands/experiments/xincident.md +137 -0
  36. package/commands/experiments/xinfra.md +115 -0
  37. package/commands/experiments/xknowledge.md +115 -0
  38. package/commands/experiments/xmaturity.md +120 -0
  39. package/commands/experiments/xmetrics.md +118 -0
  40. package/commands/experiments/xmonitoring.md +128 -0
  41. package/commands/experiments/xnew.md +898 -0
  42. package/commands/experiments/xobservable.md +114 -0
  43. package/commands/experiments/xoidc.md +165 -0
  44. package/commands/experiments/xoptimize.md +115 -0
  45. package/commands/experiments/xperformance.md +112 -0
  46. package/commands/experiments/xplanning.md +131 -0
  47. package/commands/experiments/xpolicy.md +115 -0
  48. package/commands/experiments/xproduct.md +98 -0
  49. package/commands/experiments/xreadiness.md +75 -0
  50. package/commands/experiments/xred.md +55 -0
  51. package/commands/experiments/xrisk.md +128 -0
  52. package/commands/experiments/xrules.md +124 -0
  53. package/commands/experiments/xsandbox.md +120 -0
  54. package/commands/experiments/xscan.md +102 -0
  55. package/commands/experiments/xsetup.md +123 -0
  56. package/commands/experiments/xtemplate.md +116 -0
  57. package/commands/experiments/xtrace.md +212 -0
  58. package/commands/experiments/xux.md +171 -0
  59. package/commands/experiments/xvalidate.md +104 -0
  60. package/commands/experiments/xworkflow.md +113 -0
  61. package/hooks/README.md +231 -0
  62. package/hooks/file-logger.sh +98 -0
  63. package/hooks/lib/argument-parser.sh +422 -0
  64. package/hooks/lib/config-constants.sh +230 -0
  65. package/hooks/lib/context-manager.sh +549 -0
  66. package/hooks/lib/error-handler.sh +412 -0
  67. package/hooks/lib/execution-engine.sh +627 -0
  68. package/hooks/lib/file-utils.sh +375 -0
  69. package/hooks/lib/subagent-discovery.sh +465 -0
  70. package/hooks/lib/subagent-validator.sh +597 -0
  71. package/hooks/on-error-debug.sh +221 -0
  72. package/hooks/pre-commit-quality.sh +204 -0
  73. package/hooks/pre-write-security.sh +107 -0
  74. package/hooks/prevent-credential-exposure.sh +265 -0
  75. package/hooks/subagent-trigger-simple.sh +193 -0
  76. package/hooks/subagent-trigger.sh +253 -0
  77. package/lib/config.js +186 -3
  78. package/lib/hook-installer-core.js +2 -2
  79. package/lib/result.js +138 -0
  80. package/lib/subagent-formatter.js +278 -0
  81. package/lib/subagents-core.js +237 -0
  82. package/lib/subagents.js +508 -0
  83. package/lib/types.d.ts +183 -0
  84. package/package.json +14 -3
  85. package/subagents/api-guardian.md +29 -0
  86. package/subagents/audit-trail-verifier.md +24 -0
  87. package/subagents/change-scoper.md +23 -0
  88. package/subagents/ci-pipeline-curator.md +24 -0
  89. package/subagents/code-review-assistant.md +258 -0
  90. package/subagents/continuous-release-orchestrator.md +29 -0
  91. package/subagents/contract-tester.md +24 -0
  92. package/subagents/data-steward.md +29 -0
  93. package/subagents/debug-context.md +197 -0
  94. package/subagents/debug-specialist.md +138 -0
  95. package/subagents/dependency-steward.md +24 -0
  96. package/subagents/deployment-strategist.md +29 -0
  97. package/subagents/documentation-curator.md +29 -0
  98. package/subagents/environment-guardian.md +29 -0
  99. package/subagents/license-compliance-guardian.md +29 -0
  100. package/subagents/observability-engineer.md +25 -0
  101. package/subagents/performance-guardian.md +29 -0
  102. package/subagents/product-owner-proxy.md +28 -0
  103. package/subagents/requirements-reviewer.md +26 -0
  104. package/subagents/rollback-first-responder.md +24 -0
  105. package/subagents/sbom-provenance.md +25 -0
  106. package/subagents/security-auditor.md +29 -0
  107. package/subagents/style-enforcer.md +23 -0
  108. package/subagents/test-writer.md +24 -0
  109. package/subagents/trunk-guardian.md +29 -0
  110. package/subagents/workflow-coordinator.md +26 -0
  111. package/templates/README.md +100 -0
  112. package/templates/basic-settings.json +30 -0
  113. package/templates/comprehensive-settings.json +206 -0
  114. package/templates/hybrid-hook-config.yaml +133 -0
  115. package/templates/security-focused-settings.json +62 -0
  116. package/templates/subagent-hooks.yaml +188 -0
  117. package/tsconfig.json +37 -0
@@ -0,0 +1,627 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # Execution Engine Module for Subagent-Hook Integration
4
+ #
5
+ # This module provides functionality to execute subagents with proper
6
+ # timeout handling, blocking/non-blocking modes, and result processing.
7
+
8
+ # Source required modules
9
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
10
+ source "$SCRIPT_DIR/config-constants.sh"
11
+ source "$SCRIPT_DIR/file-utils.sh"
12
+ source "$SCRIPT_DIR/error-handler.sh"
13
+
14
+ ##################################
15
+ # Execution State Management
16
+ ##################################
17
+
18
+ # Global variables for execution state (compatible with older bash versions)
19
+ EXECUTION_PID=""
20
+ EXECUTION_START_TIME=""
21
+ EXECUTION_OUTPUT_FILE=""
22
+ EXECUTION_ERROR_FILE=""
23
+ EXECUTION_RESULT=""
24
+
25
+ ##################################
26
+ # Execution Mode Functions
27
+ ##################################
28
+
29
+ determine_execution_mode() {
30
+ local event_type="$1"
31
+ local forced_mode="${2:-auto}"
32
+
33
+ log_debug "Determining execution mode for event: $event_type (forced: $forced_mode)"
34
+
35
+ # Check for forced mode from arguments
36
+ if [[ "$forced_mode" != "auto" ]]; then
37
+ echo "$forced_mode"
38
+ log_debug "Using forced execution mode: $forced_mode"
39
+ return $EXIT_SUCCESS
40
+ fi
41
+
42
+ # Determine based on event type
43
+ local blocking_events=("pre_write" "pre_commit" "security_check")
44
+ local event
45
+
46
+ for event in "${blocking_events[@]}"; do
47
+ if [[ "$event_type" == "$event" ]]; then
48
+ echo "blocking"
49
+ log_debug "Using blocking mode for event: $event_type"
50
+ return $EXIT_SUCCESS
51
+ fi
52
+ done
53
+
54
+ # Default to non-blocking
55
+ echo "non-blocking"
56
+ log_debug "Using non-blocking mode for event: $event_type"
57
+ return $EXIT_SUCCESS
58
+ }
59
+
60
+ get_timeout_for_execution() {
61
+ local event_type="$1"
62
+ local subagent_name="$2"
63
+ local custom_timeout="${SUBAGENT_TIMEOUT:-}"
64
+
65
+ # Use custom timeout if provided
66
+ if [[ -n "$custom_timeout" ]]; then
67
+ echo "$custom_timeout"
68
+ log_debug "Using custom timeout: ${custom_timeout}ms"
69
+ return $EXIT_SUCCESS
70
+ fi
71
+
72
+ # Use event-specific timeout
73
+ local timeout
74
+ timeout=$(get_timeout_for_event "$event_type")
75
+ echo "$timeout"
76
+ log_debug "Using event-specific timeout: ${timeout}ms for $event_type"
77
+ return $EXIT_SUCCESS
78
+ }
79
+
80
+ ##################################
81
+ # Subagent Execution Functions
82
+ ##################################
83
+
84
+ execute_subagent() {
85
+ local subagent_file="$1"
86
+ local context_file="$2"
87
+ local execution_mode="${3:-non-blocking}"
88
+ local timeout="${4:-$DEFAULT_TIMEOUT}"
89
+
90
+ if [[ -z "$subagent_file" ]] || [[ -z "$context_file" ]]; then
91
+ log_error "Subagent file and context file are required"
92
+ return $EXIT_VALIDATION_FAILED
93
+ fi
94
+
95
+ local subagent_name
96
+ subagent_name=$(basename "$subagent_file" "$SUBAGENT_FILE_EXTENSION")
97
+
98
+ log_info "Executing subagent: $subagent_name (mode: $execution_mode, timeout: ${timeout}ms)"
99
+
100
+ # Prepare execution environment
101
+ if ! prepare_execution_environment "$subagent_name"; then
102
+ log_error "Failed to prepare execution environment"
103
+ return $EXIT_EXECUTION_FAILED
104
+ fi
105
+
106
+ # Execute based on mode
107
+ case "$execution_mode" in
108
+ "blocking")
109
+ execute_subagent_blocking "$subagent_file" "$context_file" "$timeout"
110
+ ;;
111
+ "non-blocking")
112
+ execute_subagent_non_blocking "$subagent_file" "$context_file" "$timeout"
113
+ ;;
114
+ "dry-run")
115
+ execute_subagent_dry_run "$subagent_file" "$context_file"
116
+ ;;
117
+ *)
118
+ log_error "Unknown execution mode: $execution_mode"
119
+ return $EXIT_VALIDATION_FAILED
120
+ ;;
121
+ esac
122
+ }
123
+
124
+ execute_subagent_blocking() {
125
+ local subagent_file="$1"
126
+ local context_file="$2"
127
+ local timeout="$3"
128
+
129
+ local subagent_name
130
+ subagent_name=$(basename "$subagent_file" "$SUBAGENT_FILE_EXTENSION")
131
+
132
+ log_debug "Starting blocking execution of: $subagent_name"
133
+ EXECUTION_START_TIME=$(date +%s)
134
+
135
+ # In a real implementation, this would invoke Claude with the subagent
136
+ # For now, we simulate the execution with a mock implementation
137
+ if ! execute_subagent_simulation "$subagent_file" "$context_file" "$timeout"; then
138
+ log_error "Subagent execution failed: $subagent_name"
139
+ return $EXIT_EXECUTION_FAILED
140
+ fi
141
+
142
+ # Process execution results
143
+ if ! process_execution_results "$subagent_name" "blocking"; then
144
+ log_error "Failed to process execution results: $subagent_name"
145
+ return $EXIT_EXECUTION_FAILED
146
+ fi
147
+
148
+ log_info "Blocking execution completed: $subagent_name"
149
+ return $EXIT_SUCCESS
150
+ }
151
+
152
+ execute_subagent_non_blocking() {
153
+ local subagent_file="$1"
154
+ local context_file="$2"
155
+ local timeout="$3"
156
+
157
+ local subagent_name
158
+ subagent_name=$(basename "$subagent_file" "$SUBAGENT_FILE_EXTENSION")
159
+
160
+ log_debug "Starting non-blocking execution of: $subagent_name"
161
+ EXECUTION_START_TIME=$(date +%s)
162
+
163
+ # Execute in background
164
+ (
165
+ if ! execute_subagent_simulation "$subagent_file" "$context_file" "$timeout"; then
166
+ log_error "Background subagent execution failed: $subagent_name"
167
+ exit $EXIT_EXECUTION_FAILED
168
+ fi
169
+ exit $EXIT_SUCCESS
170
+ ) &
171
+
172
+ EXECUTION_PID=$!
173
+ log_debug "Non-blocking execution started with PID: $EXECUTION_PID"
174
+
175
+ # For non-blocking, we don't wait for completion
176
+ log_info "Non-blocking execution initiated: $subagent_name (PID: $EXECUTION_PID)"
177
+ return $EXIT_SUCCESS
178
+ }
179
+
180
+ execute_subagent_dry_run() {
181
+ local subagent_file="$1"
182
+ local context_file="$2"
183
+
184
+ local subagent_name
185
+ subagent_name=$(basename "$subagent_file" "$SUBAGENT_FILE_EXTENSION")
186
+
187
+ log_info "DRY RUN: Would execute subagent: $subagent_name"
188
+
189
+ # Show what would be executed
190
+ cat <<EOF
191
+ Dry Run Execution Plan:
192
+ ======================
193
+ Subagent: $subagent_name
194
+ File: $subagent_file
195
+ Context: $context_file
196
+ Output: $EXECUTION_OUTPUT_FILE
197
+ Error Log: $EXECUTION_ERROR_FILE
198
+
199
+ Context Summary:
200
+ $(head -10 "$context_file" 2>/dev/null || echo "Context file not readable")
201
+
202
+ Subagent Metadata:
203
+ $(extract_subagent_metadata "$subagent_file")
204
+
205
+ Execution would proceed with simulated Claude invocation.
206
+ EOF
207
+
208
+ log_info "Dry run completed: $subagent_name"
209
+ return $EXIT_SUCCESS
210
+ }
211
+
212
+ ##################################
213
+ # Subagent Simulation Functions
214
+ ##################################
215
+
216
+ execute_subagent_simulation() {
217
+ local subagent_file="$1"
218
+ local context_file="$2"
219
+ local timeout="$3"
220
+
221
+ local subagent_name
222
+ subagent_name=$(basename "$subagent_file" "$SUBAGENT_FILE_EXTENSION")
223
+
224
+ log_debug "Simulating subagent execution: $subagent_name"
225
+
226
+ # Extract subagent configuration
227
+ local tools description
228
+ tools=$(extract_frontmatter_field "$subagent_file" "tools" false 2>/dev/null || echo "all")
229
+ description=$(extract_frontmatter_field "$subagent_file" "description" false 2>/dev/null || echo "No description")
230
+
231
+ # Create simulated output
232
+ local simulation_output
233
+ simulation_output=$(cat <<EOF
234
+ Subagent Execution Report
235
+ ========================
236
+ Name: $subagent_name
237
+ Description: $description
238
+ Tools: ${tools:-all}
239
+ Execution Time: $(date)
240
+ Status: Executed successfully
241
+
242
+ Context Analysis:
243
+ $(analyze_context_for_simulation "$context_file")
244
+
245
+ Recommendations:
246
+ - Operation appears safe to proceed
247
+ - No security violations detected
248
+ - Code style conforms to standards
249
+ - Continue with planned action
250
+
251
+ Execution Summary:
252
+ - Analysis completed successfully
253
+ - No blocking issues found
254
+ - Ready for next step in workflow
255
+ EOF
256
+ )
257
+
258
+ # Write to output file
259
+ if ! echo "$simulation_output" > "$EXECUTION_OUTPUT_FILE"; then
260
+ log_error "Failed to write simulation output"
261
+ return $EXIT_EXECUTION_FAILED
262
+ fi
263
+
264
+ # Simulate processing time (shorter for testing)
265
+ sleep 1
266
+
267
+ # Check for timeout simulation
268
+ local execution_time=$(($(date +%s) - EXECUTION_START_TIME))
269
+ local timeout_seconds=$((timeout / 1000))
270
+
271
+ if [[ $execution_time -gt $timeout_seconds ]]; then
272
+ log_error "Simulated timeout exceeded: ${execution_time}s > ${timeout_seconds}s"
273
+ return $EXIT_TIMEOUT
274
+ fi
275
+
276
+ log_debug "Subagent simulation completed successfully: $subagent_name"
277
+ return $EXIT_SUCCESS
278
+ }
279
+
280
+ analyze_context_for_simulation() {
281
+ local context_file="$1"
282
+
283
+ if [[ ! -f "$context_file" ]]; then
284
+ echo "Context file not available"
285
+ return
286
+ fi
287
+
288
+ # Extract key information from context
289
+ local event_type file_path git_branch
290
+
291
+ if command -v jq >/dev/null 2>&1; then
292
+ event_type=$(jq -r '.event.type // "unknown"' "$context_file" 2>/dev/null)
293
+ file_path=$(jq -r '.file.path // "none"' "$context_file" 2>/dev/null)
294
+ git_branch=$(jq -r '.git.branch // "unknown"' "$context_file" 2>/dev/null)
295
+ else
296
+ event_type="unknown"
297
+ file_path="none"
298
+ git_branch="unknown"
299
+ fi
300
+
301
+ cat <<EOF
302
+ - Event Type: $event_type
303
+ - Target File: $file_path
304
+ - Git Branch: $git_branch
305
+ - Analysis: Standard workflow operation detected
306
+ EOF
307
+ }
308
+
309
+ ##################################
310
+ # Result Processing Functions
311
+ ##################################
312
+
313
+ process_execution_results() {
314
+ local subagent_name="$1"
315
+ local execution_mode="$2"
316
+
317
+ log_debug "Processing execution results for: $subagent_name"
318
+
319
+ if [[ ! -f "$EXECUTION_OUTPUT_FILE" ]]; then
320
+ log_error "Execution output file not found: $EXECUTION_OUTPUT_FILE"
321
+ return $EXIT_EXECUTION_FAILED
322
+ fi
323
+
324
+ # Read execution output
325
+ local output_content
326
+ if ! output_content=$(read_file_safely "$EXECUTION_OUTPUT_FILE"); then
327
+ log_error "Failed to read execution output"
328
+ return $EXIT_EXECUTION_FAILED
329
+ fi
330
+
331
+ EXECUTION_RESULT="$output_content"
332
+
333
+ # Check for blocking conditions in output
334
+ if check_for_blocking_conditions "$output_content"; then
335
+ log_warning "Subagent $subagent_name recommends BLOCKING the operation"
336
+
337
+ if [[ "$execution_mode" == "blocking" ]]; then
338
+ # In blocking mode, this should fail the hook
339
+ display_blocking_message "$subagent_name" "$output_content"
340
+ return $EXIT_EXECUTION_FAILED
341
+ else
342
+ # In non-blocking mode, just log the warning
343
+ log_warning "Non-blocking mode: continuing despite blocking recommendation"
344
+ fi
345
+ fi
346
+
347
+ # Log success
348
+ log_info "Execution results processed successfully: $subagent_name"
349
+ return $EXIT_SUCCESS
350
+ }
351
+
352
+ check_for_blocking_conditions() {
353
+ local output_content="$1"
354
+
355
+ # First check for positive/safe patterns - these override blocking
356
+ local safe_patterns=(
357
+ "Operation appears safe to proceed"
358
+ "Continue with planned action"
359
+ "No security violations detected"
360
+ "Status: Executed successfully"
361
+ "safe to proceed"
362
+ "continue with"
363
+ )
364
+
365
+ local pattern
366
+ for pattern in "${safe_patterns[@]}"; do
367
+ if echo "$output_content" | grep -qi "$pattern"; then
368
+ log_debug "Safe operation pattern found: $pattern"
369
+ return $EXIT_GENERAL_ERROR # No blocking condition - safe to proceed
370
+ fi
371
+ done
372
+
373
+ # Look for explicit blocking directives only
374
+ local blocking_patterns=(
375
+ "OPERATION MUST BE BLOCKED"
376
+ "SECURITY VIOLATION DETECTED"
377
+ "CRITICAL ERROR - STOP"
378
+ "STOP EXECUTION IMMEDIATELY"
379
+ "ABORT OPERATION"
380
+ "BLOCK THIS OPERATION"
381
+ )
382
+
383
+ for pattern in "${blocking_patterns[@]}"; do
384
+ if echo "$output_content" | grep -qi "$pattern"; then
385
+ log_debug "Blocking pattern found: $pattern"
386
+ return $EXIT_SUCCESS # Found blocking condition
387
+ fi
388
+ done
389
+
390
+ # Default: if no explicit safe or blocking patterns, allow operation
391
+ log_debug "No explicit blocking conditions found, allowing operation"
392
+ return $EXIT_GENERAL_ERROR # No blocking condition found
393
+ }
394
+
395
+ display_blocking_message() {
396
+ local subagent_name="$1"
397
+ local output_content="$2"
398
+
399
+ echo "🚨 OPERATION BLOCKED by subagent: $subagent_name" >&2
400
+ echo "" >&2
401
+ echo "Reason:" >&2
402
+ echo "$output_content" | head -20 >&2
403
+ echo "" >&2
404
+ echo "The operation has been blocked for safety. Please review the subagent's feedback above." >&2
405
+ }
406
+
407
+ ##################################
408
+ # Multiple Subagent Execution
409
+ ##################################
410
+
411
+ execute_multiple_subagents() {
412
+ local event_type="$1"
413
+ local context_file="$2"
414
+ local execution_mode="${3:-auto}"
415
+
416
+ log_info "Executing multiple subagents for event: $event_type"
417
+
418
+ # Get subagents for the event
419
+ local subagents
420
+ if ! subagents=$(get_subagents_for_event "$event_type"); then
421
+ log_error "Failed to get subagents for event: $event_type"
422
+ return $EXIT_GENERAL_ERROR
423
+ fi
424
+
425
+ if [[ -z "$subagents" ]]; then
426
+ log_info "No subagents configured for event: $event_type"
427
+ return $EXIT_SUCCESS
428
+ fi
429
+
430
+ local any_failures=false
431
+ local executed_count=0
432
+
433
+ # Execute each subagent
434
+ while IFS= read -r subagent_name; do
435
+ [[ -z "$subagent_name" ]] && continue
436
+
437
+ ((executed_count++))
438
+ log_info "Executing subagent $executed_count: $subagent_name"
439
+
440
+ # Find subagent file
441
+ local subagent_file
442
+ if ! subagent_file=$(find_subagent "$subagent_name"); then
443
+ log_error "Subagent not found: $subagent_name"
444
+ any_failures=true
445
+ continue
446
+ fi
447
+
448
+ # Determine execution mode for this subagent
449
+ local subagent_mode
450
+ subagent_mode=$(determine_execution_mode "$event_type" "$execution_mode")
451
+
452
+ # Get timeout for this execution
453
+ local timeout
454
+ timeout=$(get_timeout_for_execution "$event_type" "$subagent_name")
455
+
456
+ # Execute the subagent
457
+ if ! execute_subagent "$subagent_file" "$context_file" "$subagent_mode" "$timeout"; then
458
+ log_error "Failed to execute subagent: $subagent_name"
459
+ any_failures=true
460
+
461
+ # In blocking mode, stop on first failure
462
+ if [[ "$subagent_mode" == "blocking" ]]; then
463
+ log_error "Blocking execution failed, stopping remaining subagents"
464
+ break
465
+ fi
466
+ else
467
+ log_info "Successfully executed subagent: $subagent_name"
468
+ fi
469
+ done <<< "$subagents"
470
+
471
+ log_info "Multiple subagent execution completed (executed: $executed_count)"
472
+
473
+ if [[ "$any_failures" == true ]]; then
474
+ log_error "Some subagent executions failed"
475
+ return $EXIT_EXECUTION_FAILED
476
+ fi
477
+
478
+ return $EXIT_SUCCESS
479
+ }
480
+
481
+ ##################################
482
+ # Execution Environment Functions
483
+ ##################################
484
+
485
+ prepare_execution_environment() {
486
+ local subagent_name="$1"
487
+
488
+ log_debug "Preparing execution environment for: $subagent_name"
489
+
490
+ # Create output files
491
+ EXECUTION_OUTPUT_FILE=$(create_temp_file "$OUTPUT_FILE_PREFIX" "$subagent_name-$$")
492
+ if [[ $? -ne $EXIT_SUCCESS ]]; then
493
+ log_error "Failed to create output file"
494
+ return $EXIT_GENERAL_ERROR
495
+ fi
496
+
497
+ EXECUTION_ERROR_FILE="${EXECUTION_OUTPUT_FILE}.err"
498
+ if ! touch "$EXECUTION_ERROR_FILE"; then
499
+ log_error "Failed to create error file"
500
+ return $EXIT_GENERAL_ERROR
501
+ fi
502
+
503
+ # Set secure permissions
504
+ chmod "$SECURE_FILE_PERMISSIONS" "$EXECUTION_OUTPUT_FILE" "$EXECUTION_ERROR_FILE"
505
+
506
+ log_debug "Execution environment prepared:"
507
+ log_debug " Output: $EXECUTION_OUTPUT_FILE"
508
+ log_debug " Error: $EXECUTION_ERROR_FILE"
509
+
510
+ return $EXIT_SUCCESS
511
+ }
512
+
513
+ cleanup_execution_environment() {
514
+ local keep_logs="${1:-false}"
515
+
516
+ log_debug "Cleaning up execution environment"
517
+
518
+ # Clean up output files unless keeping logs
519
+ if [[ "$keep_logs" != true ]]; then
520
+ [[ -n "$EXECUTION_OUTPUT_FILE" ]] && rm -f "$EXECUTION_OUTPUT_FILE"
521
+ [[ -n "$EXECUTION_ERROR_FILE" ]] && rm -f "$EXECUTION_ERROR_FILE"
522
+ fi
523
+
524
+ # Kill background processes if any
525
+ if [[ -n "$EXECUTION_PID" ]]; then
526
+ if kill -0 "$EXECUTION_PID" 2>/dev/null; then
527
+ log_debug "Terminating background execution: $EXECUTION_PID"
528
+ kill "$EXECUTION_PID" 2>/dev/null || true
529
+ fi
530
+ fi
531
+
532
+ # Reset global variables
533
+ EXECUTION_PID=""
534
+ EXECUTION_START_TIME=""
535
+ EXECUTION_OUTPUT_FILE=""
536
+ EXECUTION_ERROR_FILE=""
537
+ EXECUTION_RESULT=""
538
+
539
+ log_debug "Execution environment cleanup completed"
540
+ return $EXIT_SUCCESS
541
+ }
542
+
543
+ ##################################
544
+ # Execution Status Functions
545
+ ##################################
546
+
547
+ get_execution_status() {
548
+ if [[ -n "$EXECUTION_PID" ]]; then
549
+ if kill -0 "$EXECUTION_PID" 2>/dev/null; then
550
+ echo "running"
551
+ else
552
+ echo "completed"
553
+ fi
554
+ else
555
+ echo "not_started"
556
+ fi
557
+ }
558
+
559
+ wait_for_execution() {
560
+ local timeout_seconds="${1:-30}"
561
+
562
+ if [[ -z "$EXECUTION_PID" ]]; then
563
+ log_debug "No execution to wait for"
564
+ return $EXIT_SUCCESS
565
+ fi
566
+
567
+ log_debug "Waiting for execution to complete (timeout: ${timeout_seconds}s)"
568
+
569
+ local waited=0
570
+ while kill -0 "$EXECUTION_PID" 2>/dev/null; do
571
+ sleep 1
572
+ ((waited++))
573
+
574
+ if [[ $waited -ge $timeout_seconds ]]; then
575
+ log_warning "Execution timeout reached, terminating process"
576
+ kill "$EXECUTION_PID" 2>/dev/null || true
577
+ return $EXIT_TIMEOUT
578
+ fi
579
+ done
580
+
581
+ # Get exit status
582
+ wait "$EXECUTION_PID" 2>/dev/null
583
+ local exit_status=$?
584
+
585
+ log_debug "Execution completed with status: $exit_status"
586
+ return $exit_status
587
+ }
588
+
589
+ ##################################
590
+ # Utility Functions
591
+ ##################################
592
+
593
+ extract_subagent_metadata() {
594
+ local subagent_file="$1"
595
+
596
+ if [[ ! -f "$subagent_file" ]]; then
597
+ echo "File not found"
598
+ return
599
+ fi
600
+
601
+ local name description version tools
602
+ name=$(extract_frontmatter_field "$subagent_file" "name" false 2>/dev/null || echo "Unknown")
603
+ description=$(extract_frontmatter_field "$subagent_file" "description" false 2>/dev/null || echo "No description")
604
+ version=$(extract_frontmatter_field "$subagent_file" "version" false 2>/dev/null || echo "Unknown")
605
+ tools=$(extract_frontmatter_field "$subagent_file" "tools" false 2>/dev/null || echo "All")
606
+
607
+ cat <<EOF
608
+ Name: $name
609
+ Description: $description
610
+ Version: $version
611
+ Tools: $tools
612
+ EOF
613
+ }
614
+
615
+ ##################################
616
+ # Initialization
617
+ ##################################
618
+
619
+ initialize_execution_engine() {
620
+ log_debug "Execution engine module initialized"
621
+
622
+ # Set up signal handlers for cleanup
623
+ trap 'cleanup_execution_environment' EXIT
624
+ trap 'cleanup_execution_environment; exit 130' INT TERM
625
+
626
+ return $EXIT_SUCCESS
627
+ }