@paulduvall/claude-dev-toolkit 0.0.1-alpha.12 → 0.0.1-alpha.14

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 (41) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +16 -16
  3. package/bin/claude-commands +72 -9
  4. package/commands/active/xcontinue.md +92 -0
  5. package/commands/active/xexplore.md +94 -0
  6. package/commands/active/xverify.md +80 -0
  7. package/commands/experiments/xdevcontainer.md +238 -0
  8. package/commands/experiments/xnew.md +5 -0
  9. package/hooks/README.md +32 -0
  10. package/hooks/file-logger.sh +4 -2
  11. package/hooks/lib/argument-parser.sh +7 -2
  12. package/hooks/lib/config-constants.sh +4 -4
  13. package/hooks/lib/context-manager.sh +19 -8
  14. package/hooks/lib/error-handler.sh +21 -10
  15. package/hooks/lib/execution-engine.sh +11 -194
  16. package/hooks/lib/execution-results.sh +113 -0
  17. package/hooks/lib/execution-simulation.sh +114 -0
  18. package/hooks/lib/field-validators.sh +104 -0
  19. package/hooks/lib/file-utils.sh +49 -26
  20. package/hooks/lib/subagent-discovery.sh +9 -6
  21. package/hooks/lib/subagent-validator.sh +19 -209
  22. package/hooks/lib/validation-reporter.sh +134 -0
  23. package/hooks/on-error-debug.sh +16 -11
  24. package/hooks/pre-commit-test-runner.sh +132 -0
  25. package/hooks/pre-write-security.sh +14 -6
  26. package/hooks/prevent-credential-exposure.sh +55 -45
  27. package/hooks/subagent-trigger-simple.sh +17 -8
  28. package/hooks/verify-before-edit.sh +135 -0
  29. package/lib/setup-wizard.js +155 -262
  30. package/lib/uninstall-command.js +100 -0
  31. package/package.json +2 -2
  32. package/scripts/postinstall.js +168 -171
  33. package/subagents/debug-specialist.md +6 -0
  34. package/templates/README.md +15 -0
  35. package/templates/basic-settings.json +33 -19
  36. package/templates/comprehensive-settings.json +68 -171
  37. package/templates/global-claude.md +344 -0
  38. package/templates/security-focused-settings.json +58 -41
  39. package/lib/installation-instruction-generator-backup.js +0 -579
  40. package/lib/package-manager-service.js +0 -270
  41. package/subagents/debug-context.md +0 -197
@@ -37,6 +37,19 @@ log_violation() {
37
37
  echo "[$(date +'%Y-%m-%d %H:%M:%S')] VIOLATION: $*" | tee -a "$VIOLATION_LOG"
38
38
  }
39
39
 
40
+ ##################################
41
+ # JSON Utilities
42
+ ##################################
43
+ json_escape() {
44
+ local input="$1"
45
+ input="${input//\\/\\\\}"
46
+ input="${input//\"/\\\"}"
47
+ input="${input//$'\n'/\\n}"
48
+ input="${input//$'\r'/\\r}"
49
+ input="${input//$'\t'/\\t}"
50
+ printf '%s' "$input"
51
+ }
52
+
40
53
  ##################################
41
54
  # Notification Functions
42
55
  ##################################
@@ -44,20 +57,27 @@ notify_security_team() {
44
57
  local violation_type="$1"
45
58
  local file_path="$2"
46
59
  local pattern="$3"
47
-
60
+
48
61
  if [[ -n "$NOTIFICATION_WEBHOOK" ]]; then
62
+ local safe_type safe_path safe_pattern safe_user safe_ts
63
+ safe_type=$(json_escape "$violation_type")
64
+ safe_path=$(json_escape "$file_path")
65
+ safe_pattern=$(json_escape "$pattern")
66
+ safe_user=$(json_escape "$USER")
67
+ safe_ts=$(json_escape "$(date)")
68
+
49
69
  curl -s -X POST "$NOTIFICATION_WEBHOOK" \
50
70
  -H "Content-Type: application/json" \
51
71
  -d "{
52
- \"text\": \"🚨 SECURITY ALERT: Credential exposure prevented\",
72
+ \"text\": \"SECURITY ALERT: Credential exposure prevented\",
53
73
  \"attachments\": [{
54
74
  \"color\": \"danger\",
55
75
  \"fields\": [
56
- {\"title\": \"Violation Type\", \"value\": \"$violation_type\", \"short\": true},
57
- {\"title\": \"File\", \"value\": \"$file_path\", \"short\": true},
58
- {\"title\": \"Pattern\", \"value\": \"$pattern\", \"short\": false},
59
- {\"title\": \"User\", \"value\": \"$USER\", \"short\": true},
60
- {\"title\": \"Timestamp\", \"value\": \"$(date)\", \"short\": true}
76
+ {\"title\": \"Violation Type\", \"value\": \"$safe_type\", \"short\": true},
77
+ {\"title\": \"File\", \"value\": \"$safe_path\", \"short\": true},
78
+ {\"title\": \"Pattern\", \"value\": \"$safe_pattern\", \"short\": false},
79
+ {\"title\": \"User\", \"value\": \"$safe_user\", \"short\": true},
80
+ {\"title\": \"Timestamp\", \"value\": \"$safe_ts\", \"short\": true}
61
81
  ]
62
82
  }]
63
83
  }" 2>/dev/null || log "Failed to send security notification"
@@ -68,33 +88,33 @@ notify_security_team() {
68
88
  # Credential Detection Patterns
69
89
  ##################################
70
90
  # High-confidence patterns for common credential types
71
- declare -A CREDENTIAL_PATTERNS=(
72
- # API Keys
73
- ["anthropic_api_key"]='sk-ant-[a-zA-Z0-9]{95}'
74
- ["openai_api_key"]='sk-[a-zA-Z0-9]{32,}'
75
- ["github_token"]='gh[po]_[a-zA-Z0-9]{36}'
76
- ["aws_access_key"]='AKIA[0-9A-Z]{16}'
77
- ["azure_key"]='[a-zA-Z0-9/+]{86}=='
78
-
79
- # Database URLs with credentials
80
- ["database_url_with_password"]='(mysql|postgresql|mongodb)://[^:]+:[^@]+@'
81
-
82
- # Generic high-entropy patterns
83
- ["generic_api_key"]='["\']?[a-zA-Z0-9_-]*[aA][pP][iI][_-]?[kK][eE][yY]["\']?\s*[:=]\s*["\'][a-zA-Z0-9+/=]{20,}["\']'
84
- ["generic_secret"]='["\']?[a-zA-Z0-9_-]*[sS][eE][cC][rR][eE][tT]["\']?\s*[:=]\s*["\'][a-zA-Z0-9+/=]{20,}["\']'
85
- ["generic_password"]='["\']?[a-zA-Z0-9_-]*[pP][aA][sS][sS][wW][oO][rR][dD]["\']?\s*[:=]\s*["\'][^"\']{8,}["\']'
86
-
87
- # JWT Tokens
88
- ["jwt_token"]='eyJ[a-zA-Z0-9+/=]{20,}\.[a-zA-Z0-9+/=]{20,}\.[a-zA-Z0-9+/=_-]{20,}'
89
-
90
- # Private Keys
91
- ["private_key"]='-----BEGIN [A-Z ]*PRIVATE KEY-----'
92
- ["ssh_private_key"]='-----BEGIN OPENSSH PRIVATE KEY-----'
93
-
94
- # Cloud Provider Specific
95
- ["gcp_service_account_key"]='"type":\s*"service_account"'
96
- ["slack_webhook"]='hooks\.slack\.com/services/[A-Z0-9]{9}/[A-Z0-9]{11}/[a-zA-Z0-9]{24}'
97
- )
91
+ declare -A CREDENTIAL_PATTERNS
92
+
93
+ # API Keys
94
+ CREDENTIAL_PATTERNS["anthropic_api_key"]='sk-ant-[a-zA-Z0-9]{95}'
95
+ CREDENTIAL_PATTERNS["openai_api_key"]='sk-[a-zA-Z0-9]{32,}'
96
+ CREDENTIAL_PATTERNS["github_token"]='gh[po]_[a-zA-Z0-9]{36}'
97
+ CREDENTIAL_PATTERNS["aws_access_key"]='AKIA[0-9A-Z]{16}'
98
+ CREDENTIAL_PATTERNS["azure_key"]='[a-zA-Z0-9/+]{86}=='
99
+
100
+ # Database URLs with credentials
101
+ CREDENTIAL_PATTERNS["database_url_with_password"]='(mysql|postgresql|mongodb)://[^:]+:[^@]+@'
102
+
103
+ # Generic high-entropy patterns
104
+ CREDENTIAL_PATTERNS["generic_api_key"]='["'"'"']?[a-zA-Z0-9_-]*[aA][pP][iI][_-]?[kK][eE][yY]["'"'"']?\s*[:=]\s*["'"'"'][a-zA-Z0-9+/=]{20,}["'"'"']'
105
+ CREDENTIAL_PATTERNS["generic_secret"]='["'"'"']?[a-zA-Z0-9_-]*[sS][eE][cC][rR][eE][tT]["'"'"']?\s*[:=]\s*["'"'"'][a-zA-Z0-9+/=]{20,}["'"'"']'
106
+ CREDENTIAL_PATTERNS["generic_password"]='["'"'"']?[a-zA-Z0-9_-]*[pP][aA][sS][sS][wW][oO][rR][dD]["'"'"']?\s*[:=]\s*["'"'"'][^"'"'"']{8,}["'"'"']'
107
+
108
+ # JWT Tokens
109
+ CREDENTIAL_PATTERNS["jwt_token"]='eyJ[a-zA-Z0-9+/=]{20,}\.[a-zA-Z0-9+/=]{20,}\.[a-zA-Z0-9+/=_-]{20,}'
110
+
111
+ # Private Keys
112
+ CREDENTIAL_PATTERNS["private_key"]='-----BEGIN [A-Z ]*PRIVATE KEY-----'
113
+ CREDENTIAL_PATTERNS["ssh_private_key"]='-----BEGIN OPENSSH PRIVATE KEY-----'
114
+
115
+ # Cloud Provider Specific
116
+ CREDENTIAL_PATTERNS["gcp_service_account_key"]='"type":\s*"service_account"'
117
+ CREDENTIAL_PATTERNS["slack_webhook"]='hooks\.slack\.com/services/[A-Z0-9]{9}/[A-Z0-9]{11}/[a-zA-Z0-9]{24}'
98
118
 
99
119
  ##################################
100
120
  # Content Analysis Functions
@@ -235,18 +255,8 @@ main() {
235
255
  echo "- Add files to .gitignore if they contain test data"
236
256
  echo "- Use placeholder values in examples"
237
257
  echo ""
238
- echo "For emergency override (NOT RECOMMENDED):"
239
- echo "export CLAUDE_SECURITY_OVERRIDE=true"
240
-
241
258
  log_violation "BLOCKED: $total_violations violations in $file_path"
242
-
243
- # Check for emergency override
244
- if [[ "${CLAUDE_SECURITY_OVERRIDE:-false}" == "true" ]]; then
245
- log "WARNING: Security override used - allowing dangerous operation"
246
- echo "⚠️ WARNING: Security override enabled - proceeding with credential exposure risk"
247
- exit 0
248
- fi
249
-
259
+
250
260
  exit 1
251
261
  fi
252
262
 
@@ -18,7 +18,8 @@ LIB_DIR="$SCRIPT_DIR/lib"
18
18
 
19
19
  # Load only essential modules for lightweight operation
20
20
  source "$LIB_DIR/config-constants.sh"
21
- source "$LIB_DIR/context-manager.sh"
21
+ source "$LIB_DIR/file-utils.sh"
22
+ source "$LIB_DIR/context-manager.sh"
22
23
  source "$LIB_DIR/error-handler.sh"
23
24
 
24
25
  ##################################
@@ -53,23 +54,31 @@ gather_simple_context() {
53
54
  local additional_context="$3"
54
55
 
55
56
  # Create lightweight context - much simpler than the original
57
+ local safe_name safe_event safe_ctx safe_user safe_wd safe_branch
58
+ safe_name=$(json_escape "$subagent_name")
59
+ safe_event=$(json_escape "$event_type")
60
+ safe_ctx=$(json_escape "$additional_context")
61
+ safe_user=$(json_escape "$USER")
62
+ safe_wd=$(json_escape "$(pwd)")
63
+ safe_branch=$(json_escape "$(git branch --show-current 2>/dev/null || echo 'not-in-git')")
64
+
56
65
  local context_data
57
66
  context_data=$(cat <<EOF
58
67
  {
59
68
  "trigger": "simple_subagent_trigger",
60
- "subagent": "$subagent_name",
61
- "event": "$event_type",
62
- "additional_context": "$additional_context",
69
+ "subagent": "$safe_name",
70
+ "event": "$safe_event",
71
+ "additional_context": "$safe_ctx",
63
72
  "environment": {
64
73
  "tool": "${CLAUDE_TOOL:-unknown}",
65
- "file": "${CLAUDE_FILE:-none}",
66
- "user": "$USER",
67
- "working_directory": "$(pwd)",
74
+ "file": "${CLAUDE_FILE:-none}",
75
+ "user": "$safe_user",
76
+ "working_directory": "$safe_wd",
68
77
  "timestamp": "$(date -u +"%Y-%m-%dT%H:%M:%SZ")",
69
78
  "session_id": "${CLAUDE_SESSION_ID:-$$}"
70
79
  },
71
80
  "project": {
72
- "git_branch": "$(git branch --show-current 2>/dev/null || echo 'not-in-git')"
81
+ "git_branch": "$safe_branch"
73
82
  }
74
83
  }
75
84
  EOF
@@ -0,0 +1,135 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ # Claude Code Hook: Verify Before Edit
5
+ #
6
+ # Description: Warns about potentially fabricated references in file edits
7
+ # Purpose: Prevent use of fabricated URLs, account IDs, or asset paths by validating references
8
+ # Trigger: PreToolUse
9
+ # Blocking: No
10
+ # Tools: Edit, Write, MultiEdit
11
+ # Author: Claude Dev Toolkit
12
+ # Version: 1.0.0
13
+ # Category: security
14
+ #
15
+ # This hook checks for placeholder or fabricated identifiers to prevent
16
+ # accidental use of invalid references in code and configuration files.
17
+
18
+ ##################################
19
+ # Configuration
20
+ ##################################
21
+ HOOK_NAME="verify-before-edit"
22
+ LOG_FILE="$HOME/.claude/logs/verify-before-edit.log"
23
+
24
+ mkdir -p "$(dirname "$LOG_FILE")"
25
+ chmod 700 "$(dirname "$LOG_FILE")"
26
+ touch "$LOG_FILE"
27
+ chmod 600 "$LOG_FILE"
28
+
29
+ ##################################
30
+ # Logging
31
+ ##################################
32
+ log() {
33
+ echo "[$(date +'%Y-%m-%d %H:%M:%S')] [$HOOK_NAME] $*" >> "$LOG_FILE"
34
+ }
35
+
36
+ warn() {
37
+ echo "[WARN] $*" >&2
38
+ log "WARNING: $*"
39
+ }
40
+
41
+ ##################################
42
+ # Skip Checks
43
+ ##################################
44
+ should_skip_file() {
45
+ local file="$1"
46
+ case "$file" in
47
+ *test*|*spec*|*example*|*fixture*|*mock*|*stub*)
48
+ return 0 ;;
49
+ *)
50
+ return 1 ;;
51
+ esac
52
+ }
53
+
54
+ ##################################
55
+ # Pattern Scanning
56
+ ##################################
57
+ scan_for_placeholders() {
58
+ local content="$1"
59
+
60
+ local patterns=(
61
+ 'your-api-key-here'
62
+ 'REPLACE_ME'
63
+ '<INSERT>'
64
+ 'your-.*-here'
65
+ 'xxx-.*-xxx'
66
+ 'TODO:.*http'
67
+ 'placeholder'
68
+ )
69
+
70
+ for pattern in "${patterns[@]}"; do
71
+ if echo "$content" | grep -qiE "$pattern"; then
72
+ warn "Suspicious placeholder detected: $pattern"
73
+ fi
74
+ done
75
+ }
76
+
77
+ scan_for_fabricated_ids() {
78
+ local content="$1"
79
+
80
+ if echo "$content" | grep -qE '000000|123456|111111'; then
81
+ warn "Sequential/zero ID detected — check if valid"
82
+ fi
83
+
84
+ if echo "$content" | grep -qE 'G-[A-Z0-9]{10}|UA-[0-9]{9}' 2>/dev/null; then
85
+ warn "Analytics ID found — validate against project config"
86
+ fi
87
+ }
88
+
89
+ ##################################
90
+ # Main Hook Logic
91
+ ##################################
92
+ main() {
93
+ local tool_name="${CLAUDE_TOOL:-unknown}"
94
+ local file_path="${CLAUDE_FILE:-}"
95
+ local content="${CLAUDE_CONTENT:-}"
96
+
97
+ log "Hook triggered for tool: $tool_name, file: $file_path"
98
+
99
+ case "$tool_name" in
100
+ "Edit"|"Write"|"MultiEdit") ;;
101
+ *)
102
+ log "Skipping non-edit tool: $tool_name"
103
+ exit 0 ;;
104
+ esac
105
+
106
+ if should_skip_file "$file_path"; then
107
+ log "Skipping check for test/example file: $file_path"
108
+ exit 0
109
+ fi
110
+
111
+ if [[ -z "$content" ]] && [[ -n "$file_path" ]] && [[ -f "$file_path" ]]; then
112
+ content=$(cat "$file_path" 2>/dev/null || echo "")
113
+ fi
114
+
115
+ if [[ -z "$content" ]]; then
116
+ log "No content to validate"
117
+ exit 0
118
+ fi
119
+
120
+ scan_for_placeholders "$content"
121
+ scan_for_fabricated_ids "$content"
122
+
123
+ log "Security validation complete for $file_path"
124
+ exit 0
125
+ }
126
+
127
+ ##################################
128
+ # Error Handling
129
+ ##################################
130
+ trap 'log "Hook failed with error on line $LINENO"' ERR
131
+
132
+ ##################################
133
+ # Execute
134
+ ##################################
135
+ main "$@"