@paulduvall/claude-dev-toolkit 0.0.1-alpha.1 → 0.0.1-alpha.11
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 +74 -23
- package/bin/claude-commands +263 -64
- 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/backup-restore-command.js +140 -0
- package/lib/base/base-command.js +252 -0
- package/lib/base/command-result.js +184 -0
- package/lib/config/constants.js +255 -0
- package/lib/config.js +228 -3
- package/lib/configure-command.js +428 -0
- package/lib/dependency-validator.js +64 -5
- package/lib/hook-installer-core.js +2 -2
- package/lib/installation-instruction-generator-backup.js +579 -0
- package/lib/installation-instruction-generator.js +213 -495
- package/lib/installer.js +134 -56
- package/lib/oidc-command.js +363 -0
- package/lib/result.js +138 -0
- package/lib/services/backup-list-service.js +226 -0
- package/lib/services/backup-service.js +230 -0
- package/lib/services/command-installer-service.js +217 -0
- package/lib/services/logger-service.js +201 -0
- package/lib/services/package-manager-service.js +319 -0
- package/lib/services/platform-instruction-service.js +294 -0
- package/lib/services/recovery-instruction-service.js +348 -0
- package/lib/services/restore-service.js +221 -0
- package/lib/setup-command.js +309 -0
- package/lib/subagent-formatter.js +278 -0
- package/lib/subagents-core.js +237 -0
- package/lib/subagents.js +508 -0
- package/lib/types.d.ts +183 -0
- package/lib/utils/claude-path-config.js +184 -0
- package/lib/utils/file-system-utils.js +152 -0
- package/lib/utils.js +8 -4
- package/lib/verify-command.js +430 -0
- package/package.json +17 -4
- package/scripts/postinstall.js +28 -10
- package/subagents/api-guardian.md +29 -0
- package/subagents/audit-trail-verifier.md +24 -0
- package/subagents/change-scoper.md +23 -0
- package/subagents/ci-pipeline-curator.md +24 -0
- package/subagents/code-review-assistant.md +258 -0
- package/subagents/continuous-release-orchestrator.md +29 -0
- package/subagents/contract-tester.md +24 -0
- package/subagents/data-steward.md +29 -0
- package/subagents/debug-context.md +197 -0
- package/subagents/debug-specialist.md +138 -0
- package/subagents/dependency-steward.md +24 -0
- package/subagents/deployment-strategist.md +29 -0
- package/subagents/documentation-curator.md +29 -0
- package/subagents/environment-guardian.md +29 -0
- package/subagents/license-compliance-guardian.md +29 -0
- package/subagents/observability-engineer.md +25 -0
- package/subagents/performance-guardian.md +29 -0
- package/subagents/product-owner-proxy.md +28 -0
- package/subagents/requirements-reviewer.md +26 -0
- package/subagents/rollback-first-responder.md +24 -0
- package/subagents/sbom-provenance.md +25 -0
- package/subagents/security-auditor.md +29 -0
- package/subagents/style-enforcer.md +23 -0
- package/subagents/test-writer.md +24 -0
- package/subagents/trunk-guardian.md +29 -0
- package/subagents/workflow-coordinator.md +26 -0
- 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
- package/tsconfig.json +37 -0
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
|
|
3
|
+
# File Utilities Module for Subagent-Hook Integration
|
|
4
|
+
#
|
|
5
|
+
# This module provides standardized file operations with proper error handling,
|
|
6
|
+
# security checks, and logging 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
|
+
|
|
12
|
+
##################################
|
|
13
|
+
# Directory Operations
|
|
14
|
+
##################################
|
|
15
|
+
|
|
16
|
+
ensure_directory_exists() {
|
|
17
|
+
local dir_path="$1"
|
|
18
|
+
local permissions="${2:-$SECURE_DIR_PERMISSIONS}"
|
|
19
|
+
|
|
20
|
+
if [[ -z "$dir_path" ]]; then
|
|
21
|
+
return $EXIT_GENERAL_ERROR
|
|
22
|
+
fi
|
|
23
|
+
|
|
24
|
+
if [[ ! -d "$dir_path" ]]; then
|
|
25
|
+
if ! mkdir -p "$dir_path" 2>/dev/null; then
|
|
26
|
+
return $EXIT_GENERAL_ERROR
|
|
27
|
+
fi
|
|
28
|
+
fi
|
|
29
|
+
|
|
30
|
+
if ! chmod "$permissions" "$dir_path" 2>/dev/null; then
|
|
31
|
+
return $EXIT_GENERAL_ERROR
|
|
32
|
+
fi
|
|
33
|
+
|
|
34
|
+
return $EXIT_SUCCESS
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
ensure_required_directories() {
|
|
38
|
+
ensure_directory_exists "$CLAUDE_BASE_DIR" "$SECURE_DIR_PERMISSIONS" || return $?
|
|
39
|
+
ensure_directory_exists "$SUBAGENTS_DIR" "$SECURE_DIR_PERMISSIONS" || return $?
|
|
40
|
+
ensure_directory_exists "$LOGS_DIR" "$SECURE_DIR_PERMISSIONS" || return $?
|
|
41
|
+
|
|
42
|
+
return $EXIT_SUCCESS
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
##################################
|
|
46
|
+
# File Reading Operations
|
|
47
|
+
##################################
|
|
48
|
+
|
|
49
|
+
read_file_safely() {
|
|
50
|
+
local file_path="$1"
|
|
51
|
+
|
|
52
|
+
if [[ -z "$file_path" ]]; then
|
|
53
|
+
return $EXIT_GENERAL_ERROR
|
|
54
|
+
fi
|
|
55
|
+
|
|
56
|
+
if [[ ! -f "$file_path" ]]; then
|
|
57
|
+
return $EXIT_GENERAL_ERROR
|
|
58
|
+
fi
|
|
59
|
+
|
|
60
|
+
if [[ ! -r "$file_path" ]]; then
|
|
61
|
+
return $EXIT_GENERAL_ERROR
|
|
62
|
+
fi
|
|
63
|
+
|
|
64
|
+
# Check if file is binary (avoid reading binary files)
|
|
65
|
+
if file "$file_path" 2>/dev/null | grep -q "binary"; then
|
|
66
|
+
return $EXIT_GENERAL_ERROR
|
|
67
|
+
fi
|
|
68
|
+
|
|
69
|
+
cat "$file_path" 2>/dev/null
|
|
70
|
+
return $?
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
read_file_with_size_limit() {
|
|
74
|
+
local file_path="$1"
|
|
75
|
+
local max_size="${2:-$MAX_CONTEXT_FILE_SIZE}"
|
|
76
|
+
|
|
77
|
+
if [[ -z "$file_path" ]]; then
|
|
78
|
+
return $EXIT_GENERAL_ERROR
|
|
79
|
+
fi
|
|
80
|
+
|
|
81
|
+
# Check file size
|
|
82
|
+
if [[ -f "$file_path" ]]; then
|
|
83
|
+
local file_size
|
|
84
|
+
file_size=$(stat -f%z "$file_path" 2>/dev/null || stat -c%s "$file_path" 2>/dev/null)
|
|
85
|
+
|
|
86
|
+
if [[ "$file_size" -gt "$max_size" ]]; then
|
|
87
|
+
return $EXIT_GENERAL_ERROR
|
|
88
|
+
fi
|
|
89
|
+
fi
|
|
90
|
+
|
|
91
|
+
read_file_safely "$file_path"
|
|
92
|
+
return $?
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
##################################
|
|
96
|
+
# File Writing Operations
|
|
97
|
+
##################################
|
|
98
|
+
|
|
99
|
+
write_file_safely() {
|
|
100
|
+
local file_path="$1"
|
|
101
|
+
local content="$2"
|
|
102
|
+
local permissions="${3:-$SECURE_FILE_PERMISSIONS}"
|
|
103
|
+
|
|
104
|
+
if [[ -z "$file_path" ]]; then
|
|
105
|
+
return $EXIT_GENERAL_ERROR
|
|
106
|
+
fi
|
|
107
|
+
|
|
108
|
+
# Ensure parent directory exists
|
|
109
|
+
local parent_dir
|
|
110
|
+
parent_dir="$(dirname "$file_path")"
|
|
111
|
+
if ! ensure_directory_exists "$parent_dir"; then
|
|
112
|
+
return $EXIT_GENERAL_ERROR
|
|
113
|
+
fi
|
|
114
|
+
|
|
115
|
+
# Write content
|
|
116
|
+
if ! echo "$content" > "$file_path" 2>/dev/null; then
|
|
117
|
+
return $EXIT_GENERAL_ERROR
|
|
118
|
+
fi
|
|
119
|
+
|
|
120
|
+
# Set permissions
|
|
121
|
+
if ! chmod "$permissions" "$file_path" 2>/dev/null; then
|
|
122
|
+
return $EXIT_GENERAL_ERROR
|
|
123
|
+
fi
|
|
124
|
+
|
|
125
|
+
return $EXIT_SUCCESS
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
create_temp_file() {
|
|
129
|
+
local prefix="${1:-$CONTEXT_FILE_PREFIX}"
|
|
130
|
+
local suffix="${2:-$$}"
|
|
131
|
+
|
|
132
|
+
local temp_file="${prefix}-${suffix}.tmp"
|
|
133
|
+
|
|
134
|
+
# Create empty temp file with secure permissions
|
|
135
|
+
if ! touch "$temp_file" 2>/dev/null; then
|
|
136
|
+
return $EXIT_GENERAL_ERROR
|
|
137
|
+
fi
|
|
138
|
+
|
|
139
|
+
if ! chmod "$SECURE_FILE_PERMISSIONS" "$temp_file" 2>/dev/null; then
|
|
140
|
+
rm -f "$temp_file" 2>/dev/null
|
|
141
|
+
return $EXIT_GENERAL_ERROR
|
|
142
|
+
fi
|
|
143
|
+
|
|
144
|
+
echo "$temp_file"
|
|
145
|
+
return $EXIT_SUCCESS
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
write_context_file() {
|
|
149
|
+
local context_data="$1"
|
|
150
|
+
local temp_file="$2"
|
|
151
|
+
|
|
152
|
+
if [[ -z "$context_data" ]] || [[ -z "$temp_file" ]]; then
|
|
153
|
+
return $EXIT_GENERAL_ERROR
|
|
154
|
+
fi
|
|
155
|
+
|
|
156
|
+
write_file_safely "$temp_file" "$context_data" "$SECURE_FILE_PERMISSIONS"
|
|
157
|
+
return $?
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
##################################
|
|
161
|
+
# File Validation Operations
|
|
162
|
+
##################################
|
|
163
|
+
|
|
164
|
+
file_exists_and_readable() {
|
|
165
|
+
local file_path="$1"
|
|
166
|
+
|
|
167
|
+
[[ -n "$file_path" ]] && [[ -f "$file_path" ]] && [[ -r "$file_path" ]]
|
|
168
|
+
return $?
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
file_has_extension() {
|
|
172
|
+
local file_path="$1"
|
|
173
|
+
local expected_extension="$2"
|
|
174
|
+
|
|
175
|
+
if [[ -z "$file_path" ]] || [[ -z "$expected_extension" ]]; then
|
|
176
|
+
return $EXIT_GENERAL_ERROR
|
|
177
|
+
fi
|
|
178
|
+
|
|
179
|
+
[[ "$file_path" == *"$expected_extension" ]]
|
|
180
|
+
return $?
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
is_valid_subagent_file() {
|
|
184
|
+
local file_path="$1"
|
|
185
|
+
|
|
186
|
+
# Check file exists and is readable
|
|
187
|
+
if ! file_exists_and_readable "$file_path"; then
|
|
188
|
+
return $EXIT_GENERAL_ERROR
|
|
189
|
+
fi
|
|
190
|
+
|
|
191
|
+
# Check file extension
|
|
192
|
+
if ! file_has_extension "$file_path" "$SUBAGENT_FILE_EXTENSION"; then
|
|
193
|
+
return $EXIT_GENERAL_ERROR
|
|
194
|
+
fi
|
|
195
|
+
|
|
196
|
+
# Check file size
|
|
197
|
+
local file_content
|
|
198
|
+
if ! file_content=$(read_file_with_size_limit "$file_path"); then
|
|
199
|
+
return $EXIT_GENERAL_ERROR
|
|
200
|
+
fi
|
|
201
|
+
|
|
202
|
+
# Basic YAML frontmatter validation
|
|
203
|
+
if ! echo "$file_content" | head -1 | grep -q "$YAML_FRONTMATTER_START"; then
|
|
204
|
+
return $EXIT_GENERAL_ERROR
|
|
205
|
+
fi
|
|
206
|
+
|
|
207
|
+
return $EXIT_SUCCESS
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
##################################
|
|
211
|
+
# File Cleanup Operations
|
|
212
|
+
##################################
|
|
213
|
+
|
|
214
|
+
cleanup_temp_files() {
|
|
215
|
+
local pattern="${1:-$TEMP_FILE_PATTERN}"
|
|
216
|
+
local max_age_minutes="${2:-60}"
|
|
217
|
+
|
|
218
|
+
# Find and remove old temp files
|
|
219
|
+
find /tmp -name "$pattern" -type f -mmin +$max_age_minutes -delete 2>/dev/null || true
|
|
220
|
+
|
|
221
|
+
return $EXIT_SUCCESS
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
cleanup_specific_temp_file() {
|
|
225
|
+
local temp_file="$1"
|
|
226
|
+
|
|
227
|
+
if [[ -n "$temp_file" ]] && [[ -f "$temp_file" ]]; then
|
|
228
|
+
rm -f "$temp_file" 2>/dev/null || true
|
|
229
|
+
fi
|
|
230
|
+
|
|
231
|
+
return $EXIT_SUCCESS
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
##################################
|
|
235
|
+
# File Path Operations
|
|
236
|
+
##################################
|
|
237
|
+
|
|
238
|
+
resolve_subagent_path() {
|
|
239
|
+
local subagent_name="$1"
|
|
240
|
+
|
|
241
|
+
if [[ -z "$subagent_name" ]]; then
|
|
242
|
+
return $EXIT_GENERAL_ERROR
|
|
243
|
+
fi
|
|
244
|
+
|
|
245
|
+
local subagent_file="${subagent_name}${SUBAGENT_FILE_EXTENSION}"
|
|
246
|
+
|
|
247
|
+
# Check project-level subagents first (higher priority)
|
|
248
|
+
local project_path="${PROJECT_SUBAGENTS_DIR}/${subagent_file}"
|
|
249
|
+
if file_exists_and_readable "$project_path"; then
|
|
250
|
+
echo "$project_path"
|
|
251
|
+
return $EXIT_SUCCESS
|
|
252
|
+
fi
|
|
253
|
+
|
|
254
|
+
# Check user-level subagents
|
|
255
|
+
local user_path="${SUBAGENTS_DIR}/${subagent_file}"
|
|
256
|
+
if file_exists_and_readable "$user_path"; then
|
|
257
|
+
echo "$user_path"
|
|
258
|
+
return $EXIT_SUCCESS
|
|
259
|
+
fi
|
|
260
|
+
|
|
261
|
+
return $EXIT_SUBAGENT_NOT_FOUND
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
get_absolute_path() {
|
|
265
|
+
local path="$1"
|
|
266
|
+
|
|
267
|
+
if [[ -z "$path" ]]; then
|
|
268
|
+
return $EXIT_GENERAL_ERROR
|
|
269
|
+
fi
|
|
270
|
+
|
|
271
|
+
# Convert to absolute path
|
|
272
|
+
if [[ "$path" = /* ]]; then
|
|
273
|
+
echo "$path"
|
|
274
|
+
else
|
|
275
|
+
echo "$(pwd)/$path"
|
|
276
|
+
fi
|
|
277
|
+
|
|
278
|
+
return $EXIT_SUCCESS
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
##################################
|
|
282
|
+
# File Permission Operations
|
|
283
|
+
##################################
|
|
284
|
+
|
|
285
|
+
validate_file_permissions() {
|
|
286
|
+
local file_path="$1"
|
|
287
|
+
|
|
288
|
+
if [[ -z "$file_path" ]] || [[ ! -f "$file_path" ]]; then
|
|
289
|
+
return $EXIT_GENERAL_ERROR
|
|
290
|
+
fi
|
|
291
|
+
|
|
292
|
+
# Check if file is world-writable (security risk)
|
|
293
|
+
local permissions
|
|
294
|
+
permissions=$(stat -f%A "$file_path" 2>/dev/null || stat -c%a "$file_path" 2>/dev/null)
|
|
295
|
+
|
|
296
|
+
if [[ -z "$permissions" ]]; then
|
|
297
|
+
return $EXIT_GENERAL_ERROR
|
|
298
|
+
fi
|
|
299
|
+
|
|
300
|
+
# Check if world-writable (last digit should not be writable)
|
|
301
|
+
local world_perms=$((permissions % 10))
|
|
302
|
+
if [[ $((world_perms & 2)) -eq 2 ]]; then
|
|
303
|
+
return $EXIT_SECURITY_VIOLATION
|
|
304
|
+
fi
|
|
305
|
+
|
|
306
|
+
return $EXIT_SUCCESS
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
set_secure_permissions() {
|
|
310
|
+
local file_path="$1"
|
|
311
|
+
local permissions="${2:-$SECURE_FILE_PERMISSIONS}"
|
|
312
|
+
|
|
313
|
+
if [[ -z "$file_path" ]] || [[ ! -f "$file_path" ]]; then
|
|
314
|
+
return $EXIT_GENERAL_ERROR
|
|
315
|
+
fi
|
|
316
|
+
|
|
317
|
+
chmod "$permissions" "$file_path" 2>/dev/null
|
|
318
|
+
return $?
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
##################################
|
|
322
|
+
# Logging File Operations
|
|
323
|
+
##################################
|
|
324
|
+
|
|
325
|
+
ensure_log_files() {
|
|
326
|
+
# Create log files with secure permissions if they don't exist
|
|
327
|
+
if [[ ! -f "$LOG_FILE" ]]; then
|
|
328
|
+
write_file_safely "$LOG_FILE" "" "$SECURE_FILE_PERMISSIONS" || return $?
|
|
329
|
+
fi
|
|
330
|
+
|
|
331
|
+
if [[ ! -f "$VIOLATION_LOG" ]]; then
|
|
332
|
+
write_file_safely "$VIOLATION_LOG" "" "$SECURE_FILE_PERMISSIONS" || return $?
|
|
333
|
+
fi
|
|
334
|
+
|
|
335
|
+
return $EXIT_SUCCESS
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
##################################
|
|
339
|
+
# Path Validation (Security)
|
|
340
|
+
##################################
|
|
341
|
+
|
|
342
|
+
validate_path_safety() {
|
|
343
|
+
local path="$1"
|
|
344
|
+
|
|
345
|
+
if [[ -z "$path" ]]; then
|
|
346
|
+
return $EXIT_GENERAL_ERROR
|
|
347
|
+
fi
|
|
348
|
+
|
|
349
|
+
# Check for path traversal attempts
|
|
350
|
+
if [[ "$path" == *".."* ]] || [[ "$path" == *"/./"* ]]; then
|
|
351
|
+
return $EXIT_SECURITY_VIOLATION
|
|
352
|
+
fi
|
|
353
|
+
|
|
354
|
+
# Check for absolute paths outside allowed directories
|
|
355
|
+
if [[ "$path" = /* ]]; then
|
|
356
|
+
# Allow paths within Claude base directory
|
|
357
|
+
if [[ "$path" == "$CLAUDE_BASE_DIR"* ]]; then
|
|
358
|
+
return $EXIT_SUCCESS
|
|
359
|
+
fi
|
|
360
|
+
|
|
361
|
+
# Allow paths within project directory
|
|
362
|
+
if [[ "$path" == "$(pwd)"* ]]; then
|
|
363
|
+
return $EXIT_SUCCESS
|
|
364
|
+
fi
|
|
365
|
+
|
|
366
|
+
# Allow temp files
|
|
367
|
+
if [[ "$path" == "/tmp/claude-subagent"* ]]; then
|
|
368
|
+
return $EXIT_SUCCESS
|
|
369
|
+
fi
|
|
370
|
+
|
|
371
|
+
return $EXIT_SECURITY_VIOLATION
|
|
372
|
+
fi
|
|
373
|
+
|
|
374
|
+
return $EXIT_SUCCESS
|
|
375
|
+
}
|