@paulduvall/claude-dev-toolkit 0.0.1-alpha.2 → 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.
- package/README.md +44 -6
- package/commands/active/xarchitecture.md +393 -0
- package/commands/active/xconfig.md +127 -0
- package/commands/active/xdebug.md +130 -0
- package/commands/active/xdocs.md +178 -0
- package/commands/active/xgit.md +149 -0
- package/commands/active/xpipeline.md +152 -0
- package/commands/active/xquality.md +96 -0
- package/commands/active/xrefactor.md +198 -0
- package/commands/active/xrelease.md +142 -0
- package/commands/active/xsecurity.md +92 -0
- package/commands/active/xspec.md +174 -0
- package/commands/active/xtdd.md +151 -0
- package/commands/active/xtest.md +89 -0
- package/commands/experiments/xact.md +742 -0
- package/commands/experiments/xanalytics.md +113 -0
- package/commands/experiments/xanalyze.md +70 -0
- package/commands/experiments/xapi.md +161 -0
- package/commands/experiments/xatomic.md +112 -0
- package/commands/experiments/xaws.md +85 -0
- package/commands/experiments/xcicd.md +337 -0
- package/commands/experiments/xcommit.md +122 -0
- package/commands/experiments/xcompliance.md +182 -0
- package/commands/experiments/xconstraints.md +89 -0
- package/commands/experiments/xcoverage.md +90 -0
- package/commands/experiments/xdb.md +102 -0
- package/commands/experiments/xdesign.md +121 -0
- package/commands/experiments/xevaluate.md +111 -0
- package/commands/experiments/xfootnote.md +12 -0
- package/commands/experiments/xgenerate.md +117 -0
- package/commands/experiments/xgovernance.md +149 -0
- package/commands/experiments/xgreen.md +66 -0
- package/commands/experiments/xiac.md +118 -0
- package/commands/experiments/xincident.md +137 -0
- package/commands/experiments/xinfra.md +115 -0
- package/commands/experiments/xknowledge.md +115 -0
- package/commands/experiments/xmaturity.md +120 -0
- package/commands/experiments/xmetrics.md +118 -0
- package/commands/experiments/xmonitoring.md +128 -0
- package/commands/experiments/xnew.md +898 -0
- package/commands/experiments/xobservable.md +114 -0
- package/commands/experiments/xoidc.md +165 -0
- package/commands/experiments/xoptimize.md +115 -0
- package/commands/experiments/xperformance.md +112 -0
- package/commands/experiments/xplanning.md +131 -0
- package/commands/experiments/xpolicy.md +115 -0
- package/commands/experiments/xproduct.md +98 -0
- package/commands/experiments/xreadiness.md +75 -0
- package/commands/experiments/xred.md +55 -0
- package/commands/experiments/xrisk.md +128 -0
- package/commands/experiments/xrules.md +124 -0
- package/commands/experiments/xsandbox.md +120 -0
- package/commands/experiments/xscan.md +102 -0
- package/commands/experiments/xsetup.md +123 -0
- package/commands/experiments/xtemplate.md +116 -0
- package/commands/experiments/xtrace.md +212 -0
- package/commands/experiments/xux.md +171 -0
- package/commands/experiments/xvalidate.md +104 -0
- package/commands/experiments/xworkflow.md +113 -0
- package/hooks/README.md +231 -0
- package/hooks/file-logger.sh +98 -0
- package/hooks/lib/argument-parser.sh +422 -0
- package/hooks/lib/config-constants.sh +230 -0
- package/hooks/lib/context-manager.sh +549 -0
- package/hooks/lib/error-handler.sh +412 -0
- package/hooks/lib/execution-engine.sh +627 -0
- package/hooks/lib/file-utils.sh +375 -0
- package/hooks/lib/subagent-discovery.sh +465 -0
- package/hooks/lib/subagent-validator.sh +597 -0
- package/hooks/on-error-debug.sh +221 -0
- package/hooks/pre-commit-quality.sh +204 -0
- package/hooks/pre-write-security.sh +107 -0
- package/hooks/prevent-credential-exposure.sh +265 -0
- package/hooks/subagent-trigger-simple.sh +193 -0
- package/hooks/subagent-trigger.sh +253 -0
- package/lib/hook-installer-core.js +2 -2
- package/package.json +3 -1
- package/templates/README.md +100 -0
- package/templates/basic-settings.json +30 -0
- package/templates/comprehensive-settings.json +206 -0
- package/templates/hybrid-hook-config.yaml +133 -0
- package/templates/security-focused-settings.json +62 -0
- package/templates/subagent-hooks.yaml +188 -0
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
# Claude Code Hook: File Logger
|
|
5
|
+
#
|
|
6
|
+
# Purpose: Simple demonstration of hook functionality
|
|
7
|
+
# Trigger: PreToolUse for Edit, Write, MultiEdit tools
|
|
8
|
+
# Blocking: No - just logs activity
|
|
9
|
+
#
|
|
10
|
+
# This hook demonstrates basic hook functionality by logging file operations
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
##################################
|
|
14
|
+
# Configuration
|
|
15
|
+
##################################
|
|
16
|
+
HOOK_NAME="file-logger"
|
|
17
|
+
LOG_FILE="$HOME/.claude/logs/file-logger.log"
|
|
18
|
+
|
|
19
|
+
# Ensure log directory exists with secure permissions
|
|
20
|
+
mkdir -p "$(dirname "$LOG_FILE")"
|
|
21
|
+
chmod 700 "$(dirname "$LOG_FILE")"
|
|
22
|
+
|
|
23
|
+
# Create log file with restrictive permissions if it doesn't exist
|
|
24
|
+
touch "$LOG_FILE"
|
|
25
|
+
chmod 600 "$LOG_FILE"
|
|
26
|
+
|
|
27
|
+
##################################
|
|
28
|
+
# Logging Functions
|
|
29
|
+
##################################
|
|
30
|
+
log() {
|
|
31
|
+
echo "[$(date +'%Y-%m-%d %H:%M:%S')] [$HOOK_NAME] $*" | tee -a "$LOG_FILE"
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
##################################
|
|
35
|
+
# Dependency Validation
|
|
36
|
+
##################################
|
|
37
|
+
validate_hook_dependencies() {
|
|
38
|
+
local deps=("wc" "file")
|
|
39
|
+
local missing=()
|
|
40
|
+
|
|
41
|
+
for dep in "${deps[@]}"; do
|
|
42
|
+
if ! command -v "$dep" &> /dev/null; then
|
|
43
|
+
missing+=("$dep")
|
|
44
|
+
fi
|
|
45
|
+
done
|
|
46
|
+
|
|
47
|
+
if [[ ${#missing[@]} -gt 0 ]]; then
|
|
48
|
+
log "ERROR: Missing required dependencies: ${missing[*]}"
|
|
49
|
+
echo "Install missing tools and retry"
|
|
50
|
+
exit 1
|
|
51
|
+
fi
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
##################################
|
|
55
|
+
# Main Hook Logic
|
|
56
|
+
##################################
|
|
57
|
+
main() {
|
|
58
|
+
# Validate dependencies first
|
|
59
|
+
validate_hook_dependencies
|
|
60
|
+
local tool_name="${CLAUDE_TOOL:-unknown}"
|
|
61
|
+
local file_path="${CLAUDE_FILE:-unknown}"
|
|
62
|
+
|
|
63
|
+
log "Hook triggered!"
|
|
64
|
+
log "Tool: $tool_name"
|
|
65
|
+
log "File: $file_path"
|
|
66
|
+
|
|
67
|
+
# Only process file modification tools
|
|
68
|
+
case "$tool_name" in
|
|
69
|
+
"Edit"|"Write"|"MultiEdit")
|
|
70
|
+
log "Processing file modification tool: $tool_name"
|
|
71
|
+
;;
|
|
72
|
+
*)
|
|
73
|
+
log "Skipping non-file tool: $tool_name"
|
|
74
|
+
exit 0
|
|
75
|
+
;;
|
|
76
|
+
esac
|
|
77
|
+
|
|
78
|
+
# Get basic file info if file exists
|
|
79
|
+
if [[ -n "$file_path" ]] && [[ "$file_path" != "unknown" ]] && [[ -f "$file_path" ]]; then
|
|
80
|
+
local file_size=$(wc -c < "$file_path" 2>/dev/null || echo "0")
|
|
81
|
+
local file_lines=$(wc -l < "$file_path" 2>/dev/null || echo "0")
|
|
82
|
+
|
|
83
|
+
log "File size: $file_size bytes"
|
|
84
|
+
log "File lines: $file_lines"
|
|
85
|
+
log "File type: $(file -b "$file_path" 2>/dev/null || echo "unknown")"
|
|
86
|
+
else
|
|
87
|
+
log "File does not exist yet or path unknown"
|
|
88
|
+
fi
|
|
89
|
+
|
|
90
|
+
# Always allow the operation to proceed
|
|
91
|
+
log "Operation allowed - no blocking behavior"
|
|
92
|
+
exit 0
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
##################################
|
|
96
|
+
# Execute Main Function
|
|
97
|
+
##################################
|
|
98
|
+
main "$@"
|
|
@@ -0,0 +1,422 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
|
|
3
|
+
# Argument Parser Module for Subagent-Hook Integration
|
|
4
|
+
#
|
|
5
|
+
# This module provides command-line argument parsing and validation
|
|
6
|
+
# for the subagent-hook integration system.
|
|
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/error-handler.sh"
|
|
12
|
+
|
|
13
|
+
##################################
|
|
14
|
+
# Argument Structure
|
|
15
|
+
##################################
|
|
16
|
+
|
|
17
|
+
# Global variables to store parsed arguments (compatible with older bash versions)
|
|
18
|
+
PARSED_SUBAGENT_NAME=""
|
|
19
|
+
PARSED_EVENT_TYPE=""
|
|
20
|
+
PARSED_ADDITIONAL_CONTEXT=""
|
|
21
|
+
PARSED_EXECUTION_MODE=""
|
|
22
|
+
PARSED_DEBUG_MODE=false
|
|
23
|
+
PARSED_DRY_RUN=false
|
|
24
|
+
PARSED_HELP_REQUESTED=false
|
|
25
|
+
|
|
26
|
+
##################################
|
|
27
|
+
# Usage Functions
|
|
28
|
+
##################################
|
|
29
|
+
|
|
30
|
+
show_usage() {
|
|
31
|
+
cat <<EOF
|
|
32
|
+
Usage: subagent-trigger.sh [OPTIONS] <subagent-name> [event-type] [additional-context]
|
|
33
|
+
OR: subagent-trigger.sh [OPTIONS] --event <event-type>
|
|
34
|
+
|
|
35
|
+
Trigger subagents based on Claude Code events for automated assistance.
|
|
36
|
+
|
|
37
|
+
ARGUMENTS:
|
|
38
|
+
subagent-name Name of the subagent to execute
|
|
39
|
+
event-type Type of event triggering the subagent (default: manual)
|
|
40
|
+
additional-context Additional context to pass to the subagent
|
|
41
|
+
|
|
42
|
+
SPECIAL MODES:
|
|
43
|
+
--event <event-type> Run all subagents configured for the specified event
|
|
44
|
+
|
|
45
|
+
OPTIONS:
|
|
46
|
+
--debug Enable debug logging and verbose output
|
|
47
|
+
--dry-run Show what would be executed without running
|
|
48
|
+
--help, -h Show this help message and exit
|
|
49
|
+
--timeout <ms> Override default timeout (max: $MAX_SUBAGENT_TIMEOUT ms)
|
|
50
|
+
--non-blocking Force non-blocking execution mode
|
|
51
|
+
--blocking Force blocking execution mode
|
|
52
|
+
--config <file> Use custom configuration file
|
|
53
|
+
|
|
54
|
+
SUPPORTED EVENTS:
|
|
55
|
+
EOF
|
|
56
|
+
|
|
57
|
+
local event
|
|
58
|
+
for event in "${SUPPORTED_EVENTS[@]}"; do
|
|
59
|
+
echo " - $event"
|
|
60
|
+
done
|
|
61
|
+
|
|
62
|
+
cat <<EOF
|
|
63
|
+
|
|
64
|
+
EXAMPLES:
|
|
65
|
+
# Run security-auditor for pre-write event
|
|
66
|
+
subagent-trigger.sh security-auditor pre_write
|
|
67
|
+
|
|
68
|
+
# Run all subagents configured for pre_commit event
|
|
69
|
+
subagent-trigger.sh --event pre_commit
|
|
70
|
+
|
|
71
|
+
# Debug mode with custom timeout
|
|
72
|
+
subagent-trigger.sh --debug --timeout 10000 style-enforcer pre_write
|
|
73
|
+
|
|
74
|
+
# Dry run to see what would be executed
|
|
75
|
+
subagent-trigger.sh --dry-run --event security_check
|
|
76
|
+
|
|
77
|
+
EXIT CODES:
|
|
78
|
+
$EXIT_SUCCESS - Success
|
|
79
|
+
$EXIT_GENERAL_ERROR - General error
|
|
80
|
+
$EXIT_VALIDATION_FAILED - Validation failed
|
|
81
|
+
$EXIT_SUBAGENT_NOT_FOUND - Subagent not found
|
|
82
|
+
$EXIT_EXECUTION_FAILED - Execution failed
|
|
83
|
+
$EXIT_TIMEOUT - Operation timed out
|
|
84
|
+
$EXIT_SECURITY_VIOLATION - Security violation detected
|
|
85
|
+
|
|
86
|
+
For more information, see: ~/.claude/logs/subagent-hooks.log
|
|
87
|
+
EOF
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
show_version() {
|
|
91
|
+
cat <<EOF
|
|
92
|
+
Subagent Hook Trigger v$SUBAGENT_HOOK_VERSION
|
|
93
|
+
API Version: $API_VERSION
|
|
94
|
+
Compatible with Claude Code: $COMPATIBLE_CLAUDE_VERSION
|
|
95
|
+
|
|
96
|
+
Configuration:
|
|
97
|
+
Subagents Directory: $SUBAGENTS_DIR
|
|
98
|
+
Configuration File: $CONFIG_FILE
|
|
99
|
+
Log File: $LOG_FILE
|
|
100
|
+
|
|
101
|
+
System Information:
|
|
102
|
+
User: $USER
|
|
103
|
+
Working Directory: $(pwd)
|
|
104
|
+
Git Branch: $(git branch --show-current 2>/dev/null || echo 'not-in-git')
|
|
105
|
+
Timestamp: $(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
|
106
|
+
EOF
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
##################################
|
|
110
|
+
# Argument Validation Functions
|
|
111
|
+
##################################
|
|
112
|
+
|
|
113
|
+
validate_subagent_name() {
|
|
114
|
+
local name="$1"
|
|
115
|
+
|
|
116
|
+
if [[ -z "$name" ]]; then
|
|
117
|
+
log_error "Subagent name cannot be empty"
|
|
118
|
+
return $EXIT_VALIDATION_FAILED
|
|
119
|
+
fi
|
|
120
|
+
|
|
121
|
+
if [[ ${#name} -gt $MAX_SUBAGENT_NAME_LENGTH ]]; then
|
|
122
|
+
log_error "Subagent name too long: ${#name} chars (max: $MAX_SUBAGENT_NAME_LENGTH)"
|
|
123
|
+
return $EXIT_VALIDATION_FAILED
|
|
124
|
+
fi
|
|
125
|
+
|
|
126
|
+
if [[ ! "$name" =~ $SUBAGENT_NAME_PATTERN ]]; then
|
|
127
|
+
log_error "Invalid subagent name format: $name"
|
|
128
|
+
log_error "Name must match pattern: $SUBAGENT_NAME_PATTERN"
|
|
129
|
+
return $EXIT_VALIDATION_FAILED
|
|
130
|
+
fi
|
|
131
|
+
|
|
132
|
+
return $EXIT_SUCCESS
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
validate_event_type() {
|
|
136
|
+
local event="$1"
|
|
137
|
+
|
|
138
|
+
if [[ -z "$event" ]]; then
|
|
139
|
+
log_error "Event type cannot be empty"
|
|
140
|
+
return $EXIT_VALIDATION_FAILED
|
|
141
|
+
fi
|
|
142
|
+
|
|
143
|
+
if [[ ! "$event" =~ $EVENT_NAME_PATTERN ]]; then
|
|
144
|
+
log_error "Invalid event name format: $event"
|
|
145
|
+
log_error "Event must match pattern: $EVENT_NAME_PATTERN"
|
|
146
|
+
return $EXIT_VALIDATION_FAILED
|
|
147
|
+
fi
|
|
148
|
+
|
|
149
|
+
if ! is_supported_event "$event"; then
|
|
150
|
+
log_error "Unsupported event type: $event"
|
|
151
|
+
log_error "Supported events: ${SUPPORTED_EVENTS[*]}"
|
|
152
|
+
return $EXIT_VALIDATION_FAILED
|
|
153
|
+
fi
|
|
154
|
+
|
|
155
|
+
return $EXIT_SUCCESS
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
validate_timeout_value() {
|
|
159
|
+
local timeout="$1"
|
|
160
|
+
|
|
161
|
+
if [[ ! "$timeout" =~ ^[0-9]+$ ]]; then
|
|
162
|
+
log_error "Timeout must be a positive integer: $timeout"
|
|
163
|
+
return $EXIT_VALIDATION_FAILED
|
|
164
|
+
fi
|
|
165
|
+
|
|
166
|
+
if [[ "$timeout" -gt "$MAX_SUBAGENT_TIMEOUT" ]]; then
|
|
167
|
+
log_error "Timeout exceeds maximum: $timeout ms (max: $MAX_SUBAGENT_TIMEOUT ms)"
|
|
168
|
+
return $EXIT_VALIDATION_FAILED
|
|
169
|
+
fi
|
|
170
|
+
|
|
171
|
+
if [[ "$timeout" -lt 100 ]]; then
|
|
172
|
+
log_error "Timeout too small: $timeout ms (min: 100 ms)"
|
|
173
|
+
return $EXIT_VALIDATION_FAILED
|
|
174
|
+
fi
|
|
175
|
+
|
|
176
|
+
return $EXIT_SUCCESS
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
validate_config_file() {
|
|
180
|
+
local config_file="$1"
|
|
181
|
+
|
|
182
|
+
if [[ ! -f "$config_file" ]]; then
|
|
183
|
+
log_error "Configuration file not found: $config_file"
|
|
184
|
+
return $EXIT_GENERAL_ERROR
|
|
185
|
+
fi
|
|
186
|
+
|
|
187
|
+
if [[ ! -r "$config_file" ]]; then
|
|
188
|
+
log_error "Configuration file not readable: $config_file"
|
|
189
|
+
return $EXIT_GENERAL_ERROR
|
|
190
|
+
fi
|
|
191
|
+
|
|
192
|
+
# Basic YAML validation
|
|
193
|
+
if ! grep -q "^[a-z_][a-z0-9_-]*:" "$config_file"; then
|
|
194
|
+
log_error "Configuration file appears to be invalid YAML: $config_file"
|
|
195
|
+
return $EXIT_VALIDATION_FAILED
|
|
196
|
+
fi
|
|
197
|
+
|
|
198
|
+
return $EXIT_SUCCESS
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
##################################
|
|
202
|
+
# Argument Parsing Functions
|
|
203
|
+
##################################
|
|
204
|
+
|
|
205
|
+
parse_arguments() {
|
|
206
|
+
local args=("$@")
|
|
207
|
+
local arg_count=${#args[@]}
|
|
208
|
+
local current_arg=0
|
|
209
|
+
|
|
210
|
+
# Reset global variables
|
|
211
|
+
PARSED_SUBAGENT_NAME=""
|
|
212
|
+
PARSED_EVENT_TYPE="${CLAUDE_HOOK_TRIGGER:-manual}"
|
|
213
|
+
PARSED_ADDITIONAL_CONTEXT=""
|
|
214
|
+
PARSED_EXECUTION_MODE="auto"
|
|
215
|
+
PARSED_DEBUG_MODE=false
|
|
216
|
+
PARSED_DRY_RUN=false
|
|
217
|
+
PARSED_HELP_REQUESTED=false
|
|
218
|
+
|
|
219
|
+
# Handle no arguments
|
|
220
|
+
if [[ $arg_count -eq 0 ]]; then
|
|
221
|
+
log_error "No arguments provided"
|
|
222
|
+
show_usage
|
|
223
|
+
return $EXIT_VALIDATION_FAILED
|
|
224
|
+
fi
|
|
225
|
+
|
|
226
|
+
# Parse arguments
|
|
227
|
+
while [[ $current_arg -lt $arg_count ]]; do
|
|
228
|
+
local arg="${args[$current_arg]}"
|
|
229
|
+
|
|
230
|
+
case "$arg" in
|
|
231
|
+
--help|-h)
|
|
232
|
+
PARSED_HELP_REQUESTED=true
|
|
233
|
+
return $EXIT_SUCCESS
|
|
234
|
+
;;
|
|
235
|
+
--version|-v)
|
|
236
|
+
show_version
|
|
237
|
+
return $EXIT_SUCCESS
|
|
238
|
+
;;
|
|
239
|
+
--debug)
|
|
240
|
+
PARSED_DEBUG_MODE=true
|
|
241
|
+
export DEBUG=true
|
|
242
|
+
log_debug "Debug mode enabled"
|
|
243
|
+
;;
|
|
244
|
+
--dry-run)
|
|
245
|
+
PARSED_DRY_RUN=true
|
|
246
|
+
log_info "Dry run mode enabled"
|
|
247
|
+
;;
|
|
248
|
+
--non-blocking)
|
|
249
|
+
PARSED_EXECUTION_MODE="non-blocking"
|
|
250
|
+
log_debug "Forced non-blocking execution mode"
|
|
251
|
+
;;
|
|
252
|
+
--blocking)
|
|
253
|
+
PARSED_EXECUTION_MODE="blocking"
|
|
254
|
+
log_debug "Forced blocking execution mode"
|
|
255
|
+
;;
|
|
256
|
+
--timeout)
|
|
257
|
+
((current_arg++))
|
|
258
|
+
if [[ $current_arg -ge $arg_count ]]; then
|
|
259
|
+
log_error "--timeout requires a value"
|
|
260
|
+
return $EXIT_VALIDATION_FAILED
|
|
261
|
+
fi
|
|
262
|
+
local timeout_value="${args[$current_arg]}"
|
|
263
|
+
if ! validate_timeout_value "$timeout_value"; then
|
|
264
|
+
return $EXIT_VALIDATION_FAILED
|
|
265
|
+
fi
|
|
266
|
+
export SUBAGENT_TIMEOUT="$timeout_value"
|
|
267
|
+
log_debug "Custom timeout set: ${timeout_value}ms"
|
|
268
|
+
;;
|
|
269
|
+
--config)
|
|
270
|
+
((current_arg++))
|
|
271
|
+
if [[ $current_arg -ge $arg_count ]]; then
|
|
272
|
+
log_error "--config requires a file path"
|
|
273
|
+
return $EXIT_VALIDATION_FAILED
|
|
274
|
+
fi
|
|
275
|
+
local config_file="${args[$current_arg]}"
|
|
276
|
+
if ! validate_config_file "$config_file"; then
|
|
277
|
+
return $EXIT_VALIDATION_FAILED
|
|
278
|
+
fi
|
|
279
|
+
export CONFIG_FILE="$config_file"
|
|
280
|
+
log_debug "Custom config file: $config_file"
|
|
281
|
+
;;
|
|
282
|
+
--event)
|
|
283
|
+
((current_arg++))
|
|
284
|
+
if [[ $current_arg -ge $arg_count ]]; then
|
|
285
|
+
log_error "--event requires an event type"
|
|
286
|
+
return $EXIT_VALIDATION_FAILED
|
|
287
|
+
fi
|
|
288
|
+
PARSED_EXECUTION_MODE="event-based"
|
|
289
|
+
PARSED_EVENT_TYPE="${args[$current_arg]}"
|
|
290
|
+
if ! validate_event_type "$PARSED_EVENT_TYPE"; then
|
|
291
|
+
return $EXIT_VALIDATION_FAILED
|
|
292
|
+
fi
|
|
293
|
+
log_debug "Event-based execution for: $PARSED_EVENT_TYPE"
|
|
294
|
+
;;
|
|
295
|
+
--*)
|
|
296
|
+
log_error "Unknown option: $arg"
|
|
297
|
+
return $EXIT_VALIDATION_FAILED
|
|
298
|
+
;;
|
|
299
|
+
*)
|
|
300
|
+
# Positional arguments
|
|
301
|
+
if [[ -z "$PARSED_SUBAGENT_NAME" ]] && [[ "$PARSED_EXECUTION_MODE" != "event-based" ]]; then
|
|
302
|
+
PARSED_SUBAGENT_NAME="$arg"
|
|
303
|
+
if ! validate_subagent_name "$PARSED_SUBAGENT_NAME"; then
|
|
304
|
+
return $EXIT_VALIDATION_FAILED
|
|
305
|
+
fi
|
|
306
|
+
elif [[ -z "$PARSED_EVENT_TYPE" ]] || [[ "$PARSED_EVENT_TYPE" == "manual" ]]; then
|
|
307
|
+
PARSED_EVENT_TYPE="$arg"
|
|
308
|
+
if ! validate_event_type "$PARSED_EVENT_TYPE"; then
|
|
309
|
+
return $EXIT_VALIDATION_FAILED
|
|
310
|
+
fi
|
|
311
|
+
elif [[ -z "$PARSED_ADDITIONAL_CONTEXT" ]]; then
|
|
312
|
+
PARSED_ADDITIONAL_CONTEXT="$arg"
|
|
313
|
+
else
|
|
314
|
+
log_error "Too many positional arguments: $arg"
|
|
315
|
+
return $EXIT_VALIDATION_FAILED
|
|
316
|
+
fi
|
|
317
|
+
;;
|
|
318
|
+
esac
|
|
319
|
+
|
|
320
|
+
((current_arg++))
|
|
321
|
+
done
|
|
322
|
+
|
|
323
|
+
# Validate required arguments based on execution mode
|
|
324
|
+
if [[ "$PARSED_EXECUTION_MODE" == "event-based" ]]; then
|
|
325
|
+
if [[ -z "$PARSED_EVENT_TYPE" ]]; then
|
|
326
|
+
log_error "Event type is required for event-based execution"
|
|
327
|
+
return $EXIT_VALIDATION_FAILED
|
|
328
|
+
fi
|
|
329
|
+
else
|
|
330
|
+
if [[ -z "$PARSED_SUBAGENT_NAME" ]]; then
|
|
331
|
+
log_error "Subagent name is required for direct execution"
|
|
332
|
+
return $EXIT_VALIDATION_FAILED
|
|
333
|
+
fi
|
|
334
|
+
fi
|
|
335
|
+
|
|
336
|
+
log_debug "Arguments parsed successfully:"
|
|
337
|
+
log_debug " Subagent: ${PARSED_SUBAGENT_NAME:-'(event-based)'}"
|
|
338
|
+
log_debug " Event: $PARSED_EVENT_TYPE"
|
|
339
|
+
log_debug " Context: ${PARSED_ADDITIONAL_CONTEXT:-'none'}"
|
|
340
|
+
log_debug " Mode: $PARSED_EXECUTION_MODE"
|
|
341
|
+
|
|
342
|
+
return $EXIT_SUCCESS
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
##################################
|
|
346
|
+
# Argument Access Functions
|
|
347
|
+
##################################
|
|
348
|
+
|
|
349
|
+
get_parsed_subagent_name() {
|
|
350
|
+
echo "$PARSED_SUBAGENT_NAME"
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
get_parsed_event_type() {
|
|
354
|
+
echo "$PARSED_EVENT_TYPE"
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
get_parsed_additional_context() {
|
|
358
|
+
echo "$PARSED_ADDITIONAL_CONTEXT"
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
get_parsed_execution_mode() {
|
|
362
|
+
echo "$PARSED_EXECUTION_MODE"
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
is_debug_mode() {
|
|
366
|
+
[[ "$PARSED_DEBUG_MODE" == true ]]
|
|
367
|
+
return $?
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
is_dry_run() {
|
|
371
|
+
[[ "$PARSED_DRY_RUN" == true ]]
|
|
372
|
+
return $?
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
is_help_requested() {
|
|
376
|
+
[[ "$PARSED_HELP_REQUESTED" == true ]]
|
|
377
|
+
return $?
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
##################################
|
|
381
|
+
# Argument Logging
|
|
382
|
+
##################################
|
|
383
|
+
|
|
384
|
+
log_parsed_arguments() {
|
|
385
|
+
log_info "Parsed Arguments:"
|
|
386
|
+
log_info " Execution Mode: $PARSED_EXECUTION_MODE"
|
|
387
|
+
|
|
388
|
+
if [[ -n "$PARSED_SUBAGENT_NAME" ]]; then
|
|
389
|
+
log_info " Subagent Name: $PARSED_SUBAGENT_NAME"
|
|
390
|
+
fi
|
|
391
|
+
|
|
392
|
+
log_info " Event Type: $PARSED_EVENT_TYPE"
|
|
393
|
+
|
|
394
|
+
if [[ -n "$PARSED_ADDITIONAL_CONTEXT" ]]; then
|
|
395
|
+
log_info " Additional Context: $PARSED_ADDITIONAL_CONTEXT"
|
|
396
|
+
fi
|
|
397
|
+
|
|
398
|
+
if [[ "$PARSED_DEBUG_MODE" == true ]]; then
|
|
399
|
+
log_info " Debug Mode: enabled"
|
|
400
|
+
fi
|
|
401
|
+
|
|
402
|
+
if [[ "$PARSED_DRY_RUN" == true ]]; then
|
|
403
|
+
log_info " Dry Run: enabled"
|
|
404
|
+
fi
|
|
405
|
+
|
|
406
|
+
if [[ -n "${SUBAGENT_TIMEOUT:-}" ]]; then
|
|
407
|
+
log_info " Custom Timeout: ${SUBAGENT_TIMEOUT}ms"
|
|
408
|
+
fi
|
|
409
|
+
|
|
410
|
+
if [[ "${CONFIG_FILE:-$HOME/.claude/subagent-hooks.yaml}" != "$HOME/.claude/subagent-hooks.yaml" ]]; then
|
|
411
|
+
log_info " Custom Config: $CONFIG_FILE"
|
|
412
|
+
fi
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
##################################
|
|
416
|
+
# Initialization
|
|
417
|
+
##################################
|
|
418
|
+
|
|
419
|
+
initialize_argument_parser() {
|
|
420
|
+
log_debug "Argument parser module initialized"
|
|
421
|
+
return $EXIT_SUCCESS
|
|
422
|
+
}
|