@stackmemoryai/stackmemory 0.3.16 → 0.3.18
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 +48 -2
- package/dist/cli/commands/skills.js +15 -2
- package/dist/cli/commands/skills.js.map +2 -2
- package/dist/cli/index.js +113 -834
- package/dist/cli/index.js.map +3 -3
- package/dist/core/context/dual-stack-manager.js +1 -1
- package/dist/core/context/dual-stack-manager.js.map +1 -1
- package/dist/core/context/frame-manager.js +3 -0
- package/dist/core/context/frame-manager.js.map +2 -2
- package/dist/integrations/claude-code/subagent-client.js +106 -3
- package/dist/integrations/claude-code/subagent-client.js.map +2 -2
- package/dist/servers/railway/config.js +51 -0
- package/dist/servers/railway/config.js.map +7 -0
- package/dist/servers/railway/index-enhanced.js +156 -0
- package/dist/servers/railway/index-enhanced.js.map +7 -0
- package/dist/servers/railway/minimal.js +48 -3
- package/dist/servers/railway/minimal.js.map +2 -2
- package/dist/servers/railway/storage-test.js +455 -0
- package/dist/servers/railway/storage-test.js.map +7 -0
- package/dist/skills/claude-skills.js +13 -12
- package/dist/skills/claude-skills.js.map +2 -2
- package/dist/skills/recursive-agent-orchestrator.js +27 -18
- package/dist/skills/recursive-agent-orchestrator.js.map +2 -2
- package/dist/skills/unified-rlm-orchestrator.js.map +2 -2
- package/package.json +6 -18
- package/scripts/README-TESTING.md +186 -0
- package/scripts/analyze-cli-security.js +288 -0
- package/scripts/archive/add-phase-tasks-to-linear.js +163 -0
- package/scripts/archive/analyze-linear-duplicates.js +214 -0
- package/scripts/archive/analyze-remaining-duplicates.js +230 -0
- package/scripts/archive/analyze-sta-duplicates.js +292 -0
- package/scripts/archive/analyze-sta-graphql.js +399 -0
- package/scripts/archive/cancel-duplicate-tasks.ts +246 -0
- package/scripts/archive/check-all-duplicates.ts +419 -0
- package/scripts/archive/clean-duplicate-tasks.js +114 -0
- package/scripts/archive/cleanup-duplicate-tasks.ts +286 -0
- package/scripts/archive/create-phase-tasks.js +387 -0
- package/scripts/archive/delete-linear-duplicates.js +182 -0
- package/scripts/archive/delete-remaining-duplicates.js +158 -0
- package/scripts/archive/delete-sta-duplicates.js +201 -0
- package/scripts/archive/delete-sta-oauth.js +201 -0
- package/scripts/archive/export-sta-tasks.js +62 -0
- package/scripts/archive/install-auto-sync.js +266 -0
- package/scripts/archive/install-chromadb-hooks.sh +133 -0
- package/scripts/archive/install-enhanced-clear-hooks.sh +431 -0
- package/scripts/archive/install-post-task-hooks.sh +289 -0
- package/scripts/archive/install-stackmemory-hooks.sh +420 -0
- package/scripts/archive/merge-linear-duplicates-safe.ts +362 -0
- package/scripts/archive/merge-linear-duplicates.ts +180 -0
- package/scripts/archive/remove-sta-tasks.js +70 -0
- package/scripts/archive/setup-background-sync.sh +168 -0
- package/scripts/archive/setup-claude-auto-triggers.sh +181 -0
- package/scripts/archive/setup-claude-autostart.sh +305 -0
- package/scripts/archive/setup-git-hooks.sh +25 -0
- package/scripts/archive/setup-linear-oauth.sh +46 -0
- package/scripts/archive/setup-mcp.sh +113 -0
- package/scripts/archive/setup-railway-deployment.sh +81 -0
- package/scripts/auto-handoff.sh +262 -0
- package/scripts/background-sync-manager.js +416 -0
- package/scripts/benchmark-performance.ts +57 -0
- package/scripts/check-redis.ts +48 -0
- package/scripts/chromadb-auto-loader.sh +128 -0
- package/scripts/chromadb-context-loader.js +479 -0
- package/scripts/claude-chromadb-hook.js +460 -0
- package/scripts/claude-code-wrapper.sh +66 -0
- package/scripts/claude-linear-skill.js +455 -0
- package/scripts/claude-pre-commit.sh +302 -0
- package/scripts/claude-sm-autostart.js +532 -0
- package/scripts/claude-sm-setup.sh +367 -0
- package/scripts/claude-with-chromadb.sh +69 -0
- package/scripts/claude-worktree-manager.sh +323 -0
- package/scripts/claude-worktree-monitor.sh +371 -0
- package/scripts/claude-worktree-setup.sh +327 -0
- package/scripts/clean-linear-backlog.js +273 -0
- package/scripts/cleanup-old-sessions.sh +57 -0
- package/scripts/codex-wrapper.sh +88 -0
- package/scripts/create-sandbox.sh +269 -0
- package/scripts/debug-linear-update.js +174 -0
- package/scripts/delete-linear-tasks.js +167 -0
- package/scripts/deploy.sh +89 -0
- package/scripts/deployment/railway.sh +352 -0
- package/scripts/deployment/test-deployment.js +194 -0
- package/scripts/detect-and-rehydrate.js +162 -0
- package/scripts/detect-and-rehydrate.mjs +165 -0
- package/scripts/development/create-demo-tasks.js +143 -0
- package/scripts/development/debug-frame-test.js +16 -0
- package/scripts/development/demo-auto-sync.js +128 -0
- package/scripts/development/fix-all-imports.js +213 -0
- package/scripts/development/fix-imports.js +229 -0
- package/scripts/development/fix-lint-loop.cjs +103 -0
- package/scripts/development/fix-project-id.ts +161 -0
- package/scripts/development/fix-strict-mode-issues.ts +291 -0
- package/scripts/development/reorganize-structure.sh +228 -0
- package/scripts/development/test-persistence-direct.js +148 -0
- package/scripts/development/test-persistence.js +114 -0
- package/scripts/development/test-tasks.js +93 -0
- package/scripts/development/update-imports.js +212 -0
- package/scripts/fetch-linear-status.js +125 -0
- package/scripts/git-hooks/README.md +310 -0
- package/scripts/git-hooks/branch-context-manager.sh +342 -0
- package/scripts/git-hooks/post-checkout-stackmemory.sh +63 -0
- package/scripts/git-hooks/post-commit-stackmemory.sh +305 -0
- package/scripts/git-hooks/pre-commit-stackmemory.sh +275 -0
- package/scripts/hooks/cleanup-shell.sh +130 -0
- package/scripts/hooks/task-complete.sh +114 -0
- package/scripts/initialize.ts +129 -0
- package/scripts/install-claude-hooks-auto.js +104 -0
- package/scripts/install-claude-hooks.sh +133 -0
- package/scripts/install-global.sh +296 -0
- package/scripts/install.sh +235 -0
- package/scripts/linear-auto-sync.js +262 -0
- package/scripts/linear-auto-sync.sh +161 -0
- package/scripts/linear-sync-daemon.js +150 -0
- package/scripts/linear-task-review.js +237 -0
- package/scripts/list-linear-tasks.ts +178 -0
- package/scripts/mcp-proxy.js +66 -0
- package/scripts/opencode-wrapper.sh +85 -0
- package/scripts/publish-local.js +74 -0
- package/scripts/query-chromadb.ts +201 -0
- package/scripts/railway-env-setup.sh +39 -0
- package/scripts/reconcile-local-tasks.js +170 -0
- package/scripts/recreate-frames-db.js +89 -0
- package/scripts/setup/claude-integration.js +138 -0
- package/scripts/setup/configure-alias.js +125 -0
- package/scripts/setup/configure-codex-alias.js +161 -0
- package/scripts/setup/configure-opencode-alias.js +175 -0
- package/scripts/setup-claude-integration.js +204 -0
- package/scripts/setup-claude-integration.sh +183 -0
- package/scripts/setup.sh +31 -0
- package/scripts/show-linear-summary.ts +172 -0
- package/scripts/stackmemory-auto-handoff.sh +231 -0
- package/scripts/stackmemory-daemon.sh +40 -0
- package/scripts/start-linear-sync-daemon.sh +141 -0
- package/scripts/start-temporal-paradox.sh +214 -0
- package/scripts/status.ts +159 -0
- package/scripts/sync-and-clean-tasks.js +258 -0
- package/scripts/sync-frames-from-railway.js +228 -0
- package/scripts/sync-linear-graphql.js +303 -0
- package/scripts/sync-linear-tasks.js +186 -0
- package/scripts/test-auto-triggers.sh +57 -0
- package/scripts/test-browser-mcp.js +74 -0
- package/scripts/test-chromadb-full.js +115 -0
- package/scripts/test-chromadb-hooks.sh +28 -0
- package/scripts/test-chromadb-sync.ts +245 -0
- package/scripts/test-cli-security.js +293 -0
- package/scripts/test-hooks-persistence.sh +220 -0
- package/scripts/test-installation-scenarios.sh +359 -0
- package/scripts/test-installation.sh +224 -0
- package/scripts/test-mcp.js +163 -0
- package/scripts/test-pre-publish-quick.sh +75 -0
- package/scripts/test-quality-gates.sh +263 -0
- package/scripts/test-railway-db.js +222 -0
- package/scripts/test-redis-storage.ts +490 -0
- package/scripts/test-rlm-basic.sh +122 -0
- package/scripts/test-rlm-comprehensive.sh +260 -0
- package/scripts/test-rlm-e2e.sh +268 -0
- package/scripts/test-rlm-simple.js +90 -0
- package/scripts/test-rlm.js +110 -0
- package/scripts/test-session-handoff.sh +165 -0
- package/scripts/test-shell-integration.sh +275 -0
- package/scripts/testing/ab-test-runner.ts +508 -0
- package/scripts/testing/collect-metrics.ts +457 -0
- package/scripts/testing/quick-effectiveness-demo.js +187 -0
- package/scripts/testing/real-performance-test.js +422 -0
- package/scripts/testing/run-effectiveness-tests.sh +176 -0
- package/scripts/testing/scripts/testing/ab-test-runner.js +363 -0
- package/scripts/testing/scripts/testing/collect-metrics.js +292 -0
- package/scripts/testing/simple-effectiveness-test.js +310 -0
- package/scripts/testing/src/core/context/context-bridge.js +253 -0
- package/scripts/testing/src/core/context/frame-manager.js +746 -0
- package/scripts/testing/src/core/context/shared-context-layer.js +437 -0
- package/scripts/testing/src/core/database/database-adapter.js +54 -0
- package/scripts/testing/src/core/errors/index.js +291 -0
- package/scripts/testing/src/core/errors/recovery.js +268 -0
- package/scripts/testing/src/core/monitoring/logger.js +145 -0
- package/scripts/testing/src/core/retrieval/context-retriever.js +516 -0
- package/scripts/testing/src/core/session/index.js +1 -0
- package/scripts/testing/src/core/session/session-manager.js +323 -0
- package/scripts/testing/src/core/trace/cli-trace-wrapper.js +140 -0
- package/scripts/testing/src/core/trace/db-trace-wrapper.js +251 -0
- package/scripts/testing/src/core/trace/debug-trace.js +398 -0
- package/scripts/testing/src/core/trace/index.js +120 -0
- package/scripts/testing/src/core/trace/linear-api-wrapper.js +204 -0
- package/scripts/update-linear-status.js +268 -0
- package/scripts/update-linear-tasks-fixed.js +284 -0
- package/templates/claude-hooks/hooks.json +5 -0
- package/templates/claude-hooks/on-clear.js +56 -0
- package/templates/claude-hooks/on-startup.js +56 -0
- package/templates/claude-hooks/tool-use-trace.js +67 -0
- package/dist/features/tui/components/analytics-panel.js +0 -157
- package/dist/features/tui/components/analytics-panel.js.map +0 -7
- package/dist/features/tui/components/frame-visualizer.js +0 -377
- package/dist/features/tui/components/frame-visualizer.js.map +0 -7
- package/dist/features/tui/components/pr-tracker.js +0 -135
- package/dist/features/tui/components/pr-tracker.js.map +0 -7
- package/dist/features/tui/components/session-monitor.js +0 -299
- package/dist/features/tui/components/session-monitor.js.map +0 -7
- package/dist/features/tui/components/subagent-fleet.js +0 -395
- package/dist/features/tui/components/subagent-fleet.js.map +0 -7
- package/dist/features/tui/components/task-board.js +0 -1139
- package/dist/features/tui/components/task-board.js.map +0 -7
- package/dist/features/tui/index.js +0 -408
- package/dist/features/tui/index.js.map +0 -7
- package/dist/features/tui/services/data-service.js +0 -641
- package/dist/features/tui/services/data-service.js.map +0 -7
- package/dist/features/tui/services/linear-task-reader.js +0 -102
- package/dist/features/tui/services/linear-task-reader.js.map +0 -7
- package/dist/features/tui/services/websocket-client.js +0 -162
- package/dist/features/tui/services/websocket-client.js.map +0 -7
- package/dist/features/tui/terminal-compat.js +0 -220
- package/dist/features/tui/terminal-compat.js.map +0 -7
- package/dist/features/tui/types.js +0 -1
- package/dist/features/tui/types.js.map +0 -7
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# Enhanced Claude Worktree Manager with Sandbox & Chrome Support
|
|
4
|
+
# Handles multiple Claude instances with isolation and safety features
|
|
5
|
+
|
|
6
|
+
set -e
|
|
7
|
+
|
|
8
|
+
# Configuration
|
|
9
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
10
|
+
WORKTREE_SETUP_SCRIPT="${SCRIPT_DIR}/claude-worktree-setup.sh"
|
|
11
|
+
CLAUDE_CONFIG_DIR="${HOME}/.claude"
|
|
12
|
+
SANDBOX_MODE="${CLAUDE_SANDBOX:-false}"
|
|
13
|
+
CHROME_MODE="${CLAUDE_CHROME:-false}"
|
|
14
|
+
|
|
15
|
+
# Source the main worktree setup
|
|
16
|
+
source "$WORKTREE_SETUP_SCRIPT"
|
|
17
|
+
|
|
18
|
+
# Enhanced ga() function for Claude with worktree support
|
|
19
|
+
ga_claude() {
|
|
20
|
+
local branch_base="$1"
|
|
21
|
+
local task="${2:-development}"
|
|
22
|
+
local flags="${3:-}"
|
|
23
|
+
|
|
24
|
+
if [[ -z "$branch_base" ]]; then
|
|
25
|
+
echo "Usage: ga_claude <branch-name> [task] [flags]"
|
|
26
|
+
echo "Flags: --sandbox, --chrome, --both"
|
|
27
|
+
return 1
|
|
28
|
+
fi
|
|
29
|
+
|
|
30
|
+
# Parse flags
|
|
31
|
+
local use_sandbox=false
|
|
32
|
+
local use_chrome=false
|
|
33
|
+
|
|
34
|
+
case "$flags" in
|
|
35
|
+
--sandbox)
|
|
36
|
+
use_sandbox=true
|
|
37
|
+
;;
|
|
38
|
+
--chrome)
|
|
39
|
+
use_chrome=true
|
|
40
|
+
;;
|
|
41
|
+
--both)
|
|
42
|
+
use_sandbox=true
|
|
43
|
+
use_chrome=true
|
|
44
|
+
;;
|
|
45
|
+
esac
|
|
46
|
+
|
|
47
|
+
# Create the worktree
|
|
48
|
+
claude_worktree_create "$branch_base" "$task"
|
|
49
|
+
|
|
50
|
+
# Get the created worktree path
|
|
51
|
+
local timestamp=$(date +%Y%m%d-%H%M%S)
|
|
52
|
+
local branch="claude-${branch_base}-${timestamp}-${CLAUDE_INSTANCE_ID}"
|
|
53
|
+
local repo_name="$(basename "$PWD")"
|
|
54
|
+
local worktree_path="${WORKTREE_BASE_DIR}${repo_name}--${branch}"
|
|
55
|
+
|
|
56
|
+
# Create instance-specific config
|
|
57
|
+
create_instance_config "$worktree_path" "$use_sandbox" "$use_chrome"
|
|
58
|
+
|
|
59
|
+
# Launch Claude with appropriate flags
|
|
60
|
+
launch_claude_instance "$worktree_path" "$use_sandbox" "$use_chrome"
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
# Enhanced gd() function for Claude worktrees
|
|
64
|
+
gd_claude() {
|
|
65
|
+
local current_dir="$(basename "$PWD")"
|
|
66
|
+
|
|
67
|
+
if [[ "$current_dir" == *"--claude-"* ]]; then
|
|
68
|
+
if gum confirm "Remove Claude worktree and branch?"; then
|
|
69
|
+
local branch="${current_dir#*--}"
|
|
70
|
+
cd ..
|
|
71
|
+
claude_worktree_remove "$branch"
|
|
72
|
+
fi
|
|
73
|
+
else
|
|
74
|
+
echo "Not in a Claude worktree directory"
|
|
75
|
+
return 1
|
|
76
|
+
fi
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
# Create instance-specific configuration
|
|
80
|
+
create_instance_config() {
|
|
81
|
+
local worktree_path="$1"
|
|
82
|
+
local use_sandbox="$2"
|
|
83
|
+
local use_chrome="$3"
|
|
84
|
+
|
|
85
|
+
local config_file="${worktree_path}/.claude-instance.json"
|
|
86
|
+
|
|
87
|
+
cat > "$config_file" <<EOF
|
|
88
|
+
{
|
|
89
|
+
"instance_id": "${CLAUDE_INSTANCE_ID}",
|
|
90
|
+
"worktree_path": "${worktree_path}",
|
|
91
|
+
"sandbox_enabled": ${use_sandbox},
|
|
92
|
+
"chrome_enabled": ${use_chrome},
|
|
93
|
+
"created": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
|
|
94
|
+
"restrictions": {
|
|
95
|
+
"file_access": [
|
|
96
|
+
"${worktree_path}/**",
|
|
97
|
+
"${HOME}/.claude/**"
|
|
98
|
+
],
|
|
99
|
+
"network_access": ${use_sandbox},
|
|
100
|
+
"chrome_automation": ${use_chrome}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
EOF
|
|
104
|
+
|
|
105
|
+
echo "Instance config created: $config_file"
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
# Launch Claude instance with appropriate configuration
|
|
109
|
+
launch_claude_instance() {
|
|
110
|
+
local worktree_path="$1"
|
|
111
|
+
local use_sandbox="$2"
|
|
112
|
+
local use_chrome="$3"
|
|
113
|
+
|
|
114
|
+
local claude_cmd="claude"
|
|
115
|
+
local launch_args=""
|
|
116
|
+
|
|
117
|
+
# Build launch command
|
|
118
|
+
if [[ "$use_sandbox" == "true" ]]; then
|
|
119
|
+
launch_args="${launch_args} --sandbox"
|
|
120
|
+
echo "🔒 Sandbox mode enabled - file and network restrictions active"
|
|
121
|
+
fi
|
|
122
|
+
|
|
123
|
+
if [[ "$use_chrome" == "true" ]]; then
|
|
124
|
+
launch_args="${launch_args} --chrome"
|
|
125
|
+
echo "🌐 Chrome mode enabled - browser automation available"
|
|
126
|
+
fi
|
|
127
|
+
|
|
128
|
+
# Set working directory
|
|
129
|
+
cd "$worktree_path"
|
|
130
|
+
|
|
131
|
+
# Export environment variables
|
|
132
|
+
export CLAUDE_INSTANCE_ID
|
|
133
|
+
export CLAUDE_WORKTREE_PATH="$worktree_path"
|
|
134
|
+
|
|
135
|
+
echo
|
|
136
|
+
echo "Launching Claude instance:"
|
|
137
|
+
echo " Working directory: $worktree_path"
|
|
138
|
+
echo " Instance ID: $CLAUDE_INSTANCE_ID"
|
|
139
|
+
echo " Command: ${claude_cmd}${launch_args}"
|
|
140
|
+
echo
|
|
141
|
+
|
|
142
|
+
# Launch Claude (uncomment when ready to use)
|
|
143
|
+
# exec ${claude_cmd}${launch_args}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
# Monitor active Claude instances
|
|
147
|
+
claude_instance_monitor() {
|
|
148
|
+
echo "=== Active Claude Instances ==="
|
|
149
|
+
echo
|
|
150
|
+
|
|
151
|
+
local instance_count=0
|
|
152
|
+
|
|
153
|
+
git worktree list --porcelain | while IFS= read -r line; do
|
|
154
|
+
if [[ "$line" == worktree* ]]; then
|
|
155
|
+
local path="${line#worktree }"
|
|
156
|
+
local config_file="${path}/.claude-instance.json"
|
|
157
|
+
|
|
158
|
+
if [[ -f "$config_file" ]]; then
|
|
159
|
+
((instance_count++))
|
|
160
|
+
echo "Instance #${instance_count}:"
|
|
161
|
+
|
|
162
|
+
local instance_id=$(grep '"instance_id"' "$config_file" | cut -d'"' -f4)
|
|
163
|
+
local sandbox=$(grep '"sandbox_enabled"' "$config_file" | cut -d':' -f2 | tr -d ' ,')
|
|
164
|
+
local chrome=$(grep '"chrome_enabled"' "$config_file" | cut -d':' -f2 | tr -d ' ,')
|
|
165
|
+
local created=$(grep '"created"' "$config_file" | cut -d'"' -f4)
|
|
166
|
+
|
|
167
|
+
echo " ID: $instance_id"
|
|
168
|
+
echo " Path: $path"
|
|
169
|
+
echo " Sandbox: $sandbox"
|
|
170
|
+
echo " Chrome: $chrome"
|
|
171
|
+
echo " Created: $created"
|
|
172
|
+
|
|
173
|
+
# Check for activity (modified files in last hour)
|
|
174
|
+
local recent_files=$(find "$path" -type f -mmin -60 2>/dev/null | wc -l)
|
|
175
|
+
if [[ $recent_files -gt 0 ]]; then
|
|
176
|
+
echo " Status: Active (${recent_files} files modified in last hour)"
|
|
177
|
+
else
|
|
178
|
+
echo " Status: Idle"
|
|
179
|
+
fi
|
|
180
|
+
echo
|
|
181
|
+
fi
|
|
182
|
+
fi
|
|
183
|
+
done
|
|
184
|
+
|
|
185
|
+
if [[ $instance_count -eq 0 ]]; then
|
|
186
|
+
echo "No active Claude instances found"
|
|
187
|
+
else
|
|
188
|
+
echo "Total active instances: $instance_count"
|
|
189
|
+
fi
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
# Create isolated sandbox for Claude instance
|
|
193
|
+
create_claude_sandbox() {
|
|
194
|
+
local branch_base="$1"
|
|
195
|
+
local sandbox_dir="/tmp/claude-sandbox-${CLAUDE_INSTANCE_ID}"
|
|
196
|
+
|
|
197
|
+
echo "Creating isolated sandbox at: $sandbox_dir"
|
|
198
|
+
|
|
199
|
+
# Create sandbox structure
|
|
200
|
+
mkdir -p "$sandbox_dir"/{workspace,config,cache}
|
|
201
|
+
|
|
202
|
+
# Create sandbox configuration
|
|
203
|
+
cat > "$sandbox_dir/sandbox.conf" <<EOF
|
|
204
|
+
# Claude Sandbox Configuration
|
|
205
|
+
SANDBOX_ID=${CLAUDE_INSTANCE_ID}
|
|
206
|
+
WORKSPACE=${sandbox_dir}/workspace
|
|
207
|
+
CONFIG=${sandbox_dir}/config
|
|
208
|
+
CACHE=${sandbox_dir}/cache
|
|
209
|
+
NETWORK_RESTRICTED=true
|
|
210
|
+
FILE_ACCESS_RESTRICTED=true
|
|
211
|
+
ALLOWED_PATHS=(
|
|
212
|
+
"${sandbox_dir}/workspace"
|
|
213
|
+
"${HOME}/.claude/readonly"
|
|
214
|
+
)
|
|
215
|
+
EOF
|
|
216
|
+
|
|
217
|
+
# Clone repository to sandbox
|
|
218
|
+
git clone . "$sandbox_dir/workspace" --no-hardlinks
|
|
219
|
+
|
|
220
|
+
# Create worktree in sandbox
|
|
221
|
+
cd "$sandbox_dir/workspace"
|
|
222
|
+
git checkout -b "sandbox-${branch_base}-${CLAUDE_INSTANCE_ID}"
|
|
223
|
+
|
|
224
|
+
echo "Sandbox created successfully"
|
|
225
|
+
echo "To enter sandbox: cd $sandbox_dir/workspace"
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
# Cleanup sandboxes
|
|
229
|
+
cleanup_claude_sandboxes() {
|
|
230
|
+
local days="${1:-1}"
|
|
231
|
+
|
|
232
|
+
echo "Cleaning up Claude sandboxes older than ${days} days..."
|
|
233
|
+
|
|
234
|
+
find /tmp -maxdepth 1 -name "claude-sandbox-*" -type d -mtime +${days} -exec rm -rf {} \; 2>/dev/null || true
|
|
235
|
+
|
|
236
|
+
echo "Sandbox cleanup completed"
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
# Merge work from Claude worktree back to main branch
|
|
240
|
+
claude_worktree_merge() {
|
|
241
|
+
local current_branch=$(git rev-parse --abbrev-ref HEAD)
|
|
242
|
+
|
|
243
|
+
if [[ ! "$current_branch" == claude-* ]]; then
|
|
244
|
+
echo "Not in a Claude worktree branch"
|
|
245
|
+
return 1
|
|
246
|
+
fi
|
|
247
|
+
|
|
248
|
+
echo "Preparing to merge Claude work back to main branch..."
|
|
249
|
+
|
|
250
|
+
# Ensure everything is committed
|
|
251
|
+
if [[ -n $(git status --porcelain) ]]; then
|
|
252
|
+
echo "You have uncommitted changes. Please commit them first."
|
|
253
|
+
return 1
|
|
254
|
+
fi
|
|
255
|
+
|
|
256
|
+
# Interactive rebase to clean up commits
|
|
257
|
+
if gum confirm "Clean up commits before merging?"; then
|
|
258
|
+
git rebase -i origin/main || git rebase -i origin/master
|
|
259
|
+
fi
|
|
260
|
+
|
|
261
|
+
# Create PR or merge directly
|
|
262
|
+
if gum confirm "Create pull request?"; then
|
|
263
|
+
gh pr create --fill
|
|
264
|
+
else
|
|
265
|
+
# Switch to main branch
|
|
266
|
+
git checkout main || git checkout master
|
|
267
|
+
git merge "$current_branch" --no-ff
|
|
268
|
+
echo "Merged $current_branch to main"
|
|
269
|
+
|
|
270
|
+
if gum confirm "Delete the Claude worktree?"; then
|
|
271
|
+
claude_worktree_remove "$current_branch"
|
|
272
|
+
fi
|
|
273
|
+
fi
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
# Aliases for convenience
|
|
277
|
+
alias cw='claude_worktree_create'
|
|
278
|
+
alias cwl='claude_worktree_list'
|
|
279
|
+
alias cwr='claude_worktree_remove'
|
|
280
|
+
alias cwc='claude_worktree_cleanup'
|
|
281
|
+
alias cws='claude_worktree_sync'
|
|
282
|
+
alias cwm='claude_worktree_merge'
|
|
283
|
+
alias cim='claude_instance_monitor'
|
|
284
|
+
|
|
285
|
+
# Export functions for use in subshells
|
|
286
|
+
export -f ga_claude
|
|
287
|
+
export -f gd_claude
|
|
288
|
+
export -f claude_worktree_create
|
|
289
|
+
export -f claude_worktree_list
|
|
290
|
+
export -f claude_worktree_remove
|
|
291
|
+
export -f claude_worktree_cleanup
|
|
292
|
+
export -f claude_worktree_sync
|
|
293
|
+
export -f claude_worktree_merge
|
|
294
|
+
export -f claude_instance_monitor
|
|
295
|
+
export -f create_claude_sandbox
|
|
296
|
+
export -f cleanup_claude_sandboxes
|
|
297
|
+
|
|
298
|
+
# Show help if no arguments
|
|
299
|
+
if [[ "$#" -eq 0 ]]; then
|
|
300
|
+
echo "Claude Worktree Manager with Sandbox & Chrome Support"
|
|
301
|
+
echo
|
|
302
|
+
echo "Quick Start:"
|
|
303
|
+
echo " ga_claude <branch> [task] [--sandbox|--chrome|--both]"
|
|
304
|
+
echo " gd_claude - Remove current Claude worktree"
|
|
305
|
+
echo
|
|
306
|
+
echo "Commands:"
|
|
307
|
+
echo " cw <branch> [task] - Create worktree"
|
|
308
|
+
echo " cwl - List worktrees"
|
|
309
|
+
echo " cwr [branch] - Remove worktree"
|
|
310
|
+
echo " cwc [days] - Cleanup old worktrees"
|
|
311
|
+
echo " cws - Sync with main"
|
|
312
|
+
echo " cwm - Merge back to main"
|
|
313
|
+
echo " cim - Monitor instances"
|
|
314
|
+
echo
|
|
315
|
+
echo "Sandbox Commands:"
|
|
316
|
+
echo " create_claude_sandbox <branch> - Create isolated sandbox"
|
|
317
|
+
echo " cleanup_claude_sandboxes [days] - Clean old sandboxes"
|
|
318
|
+
echo
|
|
319
|
+
echo "Examples:"
|
|
320
|
+
echo " ga_claude feature-auth 'Add authentication' --sandbox"
|
|
321
|
+
echo " ga_claude ui-update 'Update UI components' --chrome"
|
|
322
|
+
echo " ga_claude complex-task 'Major refactor' --both"
|
|
323
|
+
fi
|
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# Claude Worktree Monitor & Cleanup Service
|
|
4
|
+
# Monitors active worktrees, manages resources, and prevents conflicts
|
|
5
|
+
|
|
6
|
+
set -e
|
|
7
|
+
|
|
8
|
+
# Configuration
|
|
9
|
+
MONITOR_INTERVAL="${CLAUDE_MONITOR_INTERVAL:-300}" # 5 minutes
|
|
10
|
+
LOG_DIR="${HOME}/.claude/logs"
|
|
11
|
+
LOCK_DIR=".claude-worktree-locks"
|
|
12
|
+
MAX_ACTIVE_WORKTREES="${MAX_ACTIVE_WORKTREES:-5}"
|
|
13
|
+
AUTO_CLEANUP_DAYS="${AUTO_CLEANUP_DAYS:-7}"
|
|
14
|
+
|
|
15
|
+
# Colors
|
|
16
|
+
RED='\033[0;31m'
|
|
17
|
+
GREEN='\033[0;32m'
|
|
18
|
+
YELLOW='\033[1;33m'
|
|
19
|
+
BLUE='\033[0;34m'
|
|
20
|
+
NC='\033[0m'
|
|
21
|
+
|
|
22
|
+
# Initialize logging
|
|
23
|
+
init_logging() {
|
|
24
|
+
mkdir -p "$LOG_DIR"
|
|
25
|
+
local log_file="${LOG_DIR}/monitor-$(date +%Y%m%d).log"
|
|
26
|
+
exec 1> >(tee -a "$log_file")
|
|
27
|
+
exec 2>&1
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
# Log with timestamp
|
|
31
|
+
log_message() {
|
|
32
|
+
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1"
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
# Check worktree health
|
|
36
|
+
check_worktree_health() {
|
|
37
|
+
local worktree_path="$1"
|
|
38
|
+
local branch="$2"
|
|
39
|
+
local health_status="healthy"
|
|
40
|
+
local issues=()
|
|
41
|
+
|
|
42
|
+
# Check if directory exists
|
|
43
|
+
if [[ ! -d "$worktree_path" ]]; then
|
|
44
|
+
issues+=("Directory missing")
|
|
45
|
+
health_status="critical"
|
|
46
|
+
return 1
|
|
47
|
+
fi
|
|
48
|
+
|
|
49
|
+
cd "$worktree_path" 2>/dev/null || {
|
|
50
|
+
issues+=("Cannot access directory")
|
|
51
|
+
health_status="critical"
|
|
52
|
+
return 1
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
# Check git status
|
|
56
|
+
if ! git status &>/dev/null; then
|
|
57
|
+
issues+=("Git repository corrupted")
|
|
58
|
+
health_status="critical"
|
|
59
|
+
fi
|
|
60
|
+
|
|
61
|
+
# Check for merge conflicts
|
|
62
|
+
if git diff --name-only --diff-filter=U | grep -q .; then
|
|
63
|
+
issues+=("Has merge conflicts")
|
|
64
|
+
health_status="warning"
|
|
65
|
+
fi
|
|
66
|
+
|
|
67
|
+
# Check disk usage
|
|
68
|
+
local disk_usage=$(du -sh . 2>/dev/null | cut -f1)
|
|
69
|
+
local disk_usage_mb=$(du -sm . 2>/dev/null | cut -f1)
|
|
70
|
+
if [[ $disk_usage_mb -gt 1000 ]]; then
|
|
71
|
+
issues+=("High disk usage: ${disk_usage}")
|
|
72
|
+
health_status="warning"
|
|
73
|
+
fi
|
|
74
|
+
|
|
75
|
+
# Check for stale lock files
|
|
76
|
+
local lock_file="${LOCK_DIR}/${branch}.lock"
|
|
77
|
+
if [[ -f "$lock_file" ]]; then
|
|
78
|
+
local lock_age_hours=$(( ($(date +%s) - $(stat -f %m "$lock_file" 2>/dev/null || stat -c %Y "$lock_file" 2>/dev/null)) / 3600 ))
|
|
79
|
+
if [[ $lock_age_hours -gt 24 ]]; then
|
|
80
|
+
issues+=("Stale lock file (${lock_age_hours}h old)")
|
|
81
|
+
health_status="warning"
|
|
82
|
+
fi
|
|
83
|
+
fi
|
|
84
|
+
|
|
85
|
+
# Return health report
|
|
86
|
+
if [[ ${#issues[@]} -gt 0 ]]; then
|
|
87
|
+
echo -e "${YELLOW}Health: ${health_status}${NC}"
|
|
88
|
+
for issue in "${issues[@]}"; do
|
|
89
|
+
echo " - $issue"
|
|
90
|
+
done
|
|
91
|
+
else
|
|
92
|
+
echo -e "${GREEN}Health: healthy${NC}"
|
|
93
|
+
fi
|
|
94
|
+
|
|
95
|
+
cd - > /dev/null
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
# Monitor active worktrees
|
|
99
|
+
monitor_worktrees() {
|
|
100
|
+
log_message "Starting worktree monitoring cycle"
|
|
101
|
+
|
|
102
|
+
local active_count=0
|
|
103
|
+
local total_disk_usage=0
|
|
104
|
+
local worktree_data=()
|
|
105
|
+
|
|
106
|
+
echo -e "${BLUE}=== Claude Worktree Status ===${NC}"
|
|
107
|
+
echo "Time: $(date '+%Y-%m-%d %H:%M:%S')"
|
|
108
|
+
echo
|
|
109
|
+
|
|
110
|
+
# Collect worktree information
|
|
111
|
+
git worktree list --porcelain | while IFS= read -r line; do
|
|
112
|
+
if [[ "$line" == worktree* ]]; then
|
|
113
|
+
local path="${line#worktree }"
|
|
114
|
+
local dirname="$(basename "$path")"
|
|
115
|
+
|
|
116
|
+
# Check if this is a Claude worktree
|
|
117
|
+
if [[ "$dirname" == *"--claude-"* ]]; then
|
|
118
|
+
((active_count++))
|
|
119
|
+
local branch="${dirname#*--}"
|
|
120
|
+
|
|
121
|
+
echo -e "${YELLOW}Worktree ${active_count}: ${dirname}${NC}"
|
|
122
|
+
echo " Path: $path"
|
|
123
|
+
|
|
124
|
+
# Check health
|
|
125
|
+
check_worktree_health "$path" "$branch"
|
|
126
|
+
|
|
127
|
+
# Check activity
|
|
128
|
+
if [[ -d "$path" ]]; then
|
|
129
|
+
local last_modified=$(find "$path" -type f -name "*.ts" -o -name "*.tsx" -o -name "*.js" -o -name "*.jsx" 2>/dev/null | xargs stat -f %m 2>/dev/null | sort -n | tail -1)
|
|
130
|
+
if [[ -n "$last_modified" ]]; then
|
|
131
|
+
local age_minutes=$(( ($(date +%s) - $last_modified) / 60 ))
|
|
132
|
+
if [[ $age_minutes -lt 60 ]]; then
|
|
133
|
+
echo -e " Activity: ${GREEN}Active (${age_minutes}m ago)${NC}"
|
|
134
|
+
elif [[ $age_minutes -lt 1440 ]]; then
|
|
135
|
+
echo -e " Activity: ${YELLOW}Idle ($(( age_minutes / 60 ))h ago)${NC}"
|
|
136
|
+
else
|
|
137
|
+
echo -e " Activity: ${RED}Stale ($(( age_minutes / 1440 ))d ago)${NC}"
|
|
138
|
+
fi
|
|
139
|
+
fi
|
|
140
|
+
|
|
141
|
+
# Disk usage
|
|
142
|
+
local disk_mb=$(du -sm "$path" 2>/dev/null | cut -f1)
|
|
143
|
+
total_disk_usage=$((total_disk_usage + disk_mb))
|
|
144
|
+
echo " Disk usage: ${disk_mb}MB"
|
|
145
|
+
fi
|
|
146
|
+
echo
|
|
147
|
+
fi
|
|
148
|
+
fi
|
|
149
|
+
done
|
|
150
|
+
|
|
151
|
+
# Summary
|
|
152
|
+
echo -e "${BLUE}=== Summary ===${NC}"
|
|
153
|
+
echo "Active worktrees: $active_count / $MAX_ACTIVE_WORKTREES"
|
|
154
|
+
echo "Total disk usage: ${total_disk_usage}MB"
|
|
155
|
+
|
|
156
|
+
# Warnings
|
|
157
|
+
if [[ $active_count -ge $MAX_ACTIVE_WORKTREES ]]; then
|
|
158
|
+
echo -e "${RED}WARNING: Maximum worktree limit reached!${NC}"
|
|
159
|
+
echo "Consider running: ./claude-worktree-cleanup.sh"
|
|
160
|
+
fi
|
|
161
|
+
|
|
162
|
+
if [[ $total_disk_usage -gt 5000 ]]; then
|
|
163
|
+
echo -e "${YELLOW}WARNING: High total disk usage (${total_disk_usage}MB)${NC}"
|
|
164
|
+
fi
|
|
165
|
+
|
|
166
|
+
log_message "Monitoring cycle completed: ${active_count} active worktrees, ${total_disk_usage}MB total"
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
# Auto-cleanup old worktrees
|
|
170
|
+
auto_cleanup() {
|
|
171
|
+
log_message "Running auto-cleanup for worktrees older than ${AUTO_CLEANUP_DAYS} days"
|
|
172
|
+
|
|
173
|
+
local cleaned_count=0
|
|
174
|
+
|
|
175
|
+
git worktree list --porcelain | while IFS= read -r line; do
|
|
176
|
+
if [[ "$line" == worktree* ]]; then
|
|
177
|
+
local path="${line#worktree }"
|
|
178
|
+
local dirname="$(basename "$path")"
|
|
179
|
+
|
|
180
|
+
if [[ "$dirname" == *"--claude-"* ]]; then
|
|
181
|
+
local branch="${dirname#*--}"
|
|
182
|
+
local lock_file="${LOCK_DIR}/${branch}.lock"
|
|
183
|
+
|
|
184
|
+
# Check age
|
|
185
|
+
if [[ -f "$lock_file" ]]; then
|
|
186
|
+
local created=$(grep '"created"' "$lock_file" | cut -d'"' -f4)
|
|
187
|
+
local created_timestamp=$(date -d "$created" +%s 2>/dev/null || date -j -f "%Y-%m-%dT%H:%M:%SZ" "$created" +%s 2>/dev/null)
|
|
188
|
+
local current_timestamp=$(date +%s)
|
|
189
|
+
local age_days=$(( (current_timestamp - created_timestamp) / 86400 ))
|
|
190
|
+
|
|
191
|
+
if [[ $age_days -gt $AUTO_CLEANUP_DAYS ]]; then
|
|
192
|
+
# Check if idle
|
|
193
|
+
local last_modified=$(find "$path" -type f -newer "$lock_file" 2>/dev/null | head -1)
|
|
194
|
+
if [[ -z "$last_modified" ]]; then
|
|
195
|
+
log_message "Auto-removing old idle worktree: $dirname (${age_days} days old)"
|
|
196
|
+
git worktree remove "$path" --force 2>/dev/null && ((cleaned_count++))
|
|
197
|
+
rm -f "$lock_file"
|
|
198
|
+
fi
|
|
199
|
+
fi
|
|
200
|
+
fi
|
|
201
|
+
fi
|
|
202
|
+
fi
|
|
203
|
+
done
|
|
204
|
+
|
|
205
|
+
if [[ $cleaned_count -gt 0 ]]; then
|
|
206
|
+
log_message "Auto-cleanup completed: removed ${cleaned_count} old worktrees"
|
|
207
|
+
fi
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
# Conflict detection
|
|
211
|
+
detect_conflicts() {
|
|
212
|
+
local conflicts=()
|
|
213
|
+
local branches=()
|
|
214
|
+
|
|
215
|
+
# Collect all Claude branches
|
|
216
|
+
git worktree list --porcelain | while IFS= read -r line; do
|
|
217
|
+
if [[ "$line" == branch* ]] && [[ "$line" == *"claude-"* ]]; then
|
|
218
|
+
branches+=("${line#branch refs/heads/}")
|
|
219
|
+
fi
|
|
220
|
+
done
|
|
221
|
+
|
|
222
|
+
# Check for potential conflicts
|
|
223
|
+
for ((i=0; i<${#branches[@]}; i++)); do
|
|
224
|
+
for ((j=i+1; j<${#branches[@]}; j++)); do
|
|
225
|
+
local branch1="${branches[i]}"
|
|
226
|
+
local branch2="${branches[j]}"
|
|
227
|
+
|
|
228
|
+
# Check if branches modify same files
|
|
229
|
+
local common_files=$(comm -12 \
|
|
230
|
+
<(git diff --name-only "origin/main...$branch1" 2>/dev/null | sort) \
|
|
231
|
+
<(git diff --name-only "origin/main...$branch2" 2>/dev/null | sort))
|
|
232
|
+
|
|
233
|
+
if [[ -n "$common_files" ]]; then
|
|
234
|
+
conflicts+=("${branch1} ↔ ${branch2}: $(echo "$common_files" | wc -l) common files")
|
|
235
|
+
fi
|
|
236
|
+
done
|
|
237
|
+
done
|
|
238
|
+
|
|
239
|
+
if [[ ${#conflicts[@]} -gt 0 ]]; then
|
|
240
|
+
echo -e "${RED}=== Potential Conflicts Detected ===${NC}"
|
|
241
|
+
for conflict in "${conflicts[@]}"; do
|
|
242
|
+
echo " - $conflict"
|
|
243
|
+
done
|
|
244
|
+
echo
|
|
245
|
+
fi
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
# Resource usage report
|
|
249
|
+
resource_report() {
|
|
250
|
+
echo -e "${BLUE}=== Resource Usage Report ===${NC}"
|
|
251
|
+
echo "Generated: $(date '+%Y-%m-%d %H:%M:%S')"
|
|
252
|
+
echo
|
|
253
|
+
|
|
254
|
+
# CPU usage by git processes
|
|
255
|
+
local git_cpu=$(ps aux | grep '[g]it' | awk '{sum+=$3} END {print sum}')
|
|
256
|
+
echo "Git processes CPU usage: ${git_cpu:-0}%"
|
|
257
|
+
|
|
258
|
+
# Memory usage
|
|
259
|
+
local git_mem=$(ps aux | grep '[g]it' | awk '{sum+=$4} END {print sum}')
|
|
260
|
+
echo "Git processes memory usage: ${git_mem:-0}%"
|
|
261
|
+
|
|
262
|
+
# Disk I/O (if iostat available)
|
|
263
|
+
if command -v iostat &>/dev/null; then
|
|
264
|
+
echo "Disk I/O:"
|
|
265
|
+
iostat -d 1 2 | tail -n +4 | head -2
|
|
266
|
+
fi
|
|
267
|
+
|
|
268
|
+
# Network connections (git remote operations)
|
|
269
|
+
local git_connections=$(netstat -an 2>/dev/null | grep -c ':22\|:443' || echo "0")
|
|
270
|
+
echo "Active git network connections: $git_connections"
|
|
271
|
+
echo
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
# Daemon mode
|
|
275
|
+
run_daemon() {
|
|
276
|
+
log_message "Starting Claude Worktree Monitor daemon (PID: $$)"
|
|
277
|
+
|
|
278
|
+
# Create PID file
|
|
279
|
+
echo $$ > "${HOME}/.claude/monitor.pid"
|
|
280
|
+
|
|
281
|
+
# Trap signals for clean shutdown
|
|
282
|
+
trap 'log_message "Daemon shutting down"; rm -f "${HOME}/.claude/monitor.pid"; exit 0' SIGTERM SIGINT
|
|
283
|
+
|
|
284
|
+
while true; do
|
|
285
|
+
monitor_worktrees
|
|
286
|
+
detect_conflicts
|
|
287
|
+
resource_report
|
|
288
|
+
|
|
289
|
+
# Run auto-cleanup once per day
|
|
290
|
+
if [[ $(date +%H:%M) == "03:00" ]]; then
|
|
291
|
+
auto_cleanup
|
|
292
|
+
fi
|
|
293
|
+
|
|
294
|
+
sleep "$MONITOR_INTERVAL"
|
|
295
|
+
done
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
# Stop daemon
|
|
299
|
+
stop_daemon() {
|
|
300
|
+
if [[ -f "${HOME}/.claude/monitor.pid" ]]; then
|
|
301
|
+
local pid=$(cat "${HOME}/.claude/monitor.pid")
|
|
302
|
+
if kill -0 "$pid" 2>/dev/null; then
|
|
303
|
+
kill "$pid"
|
|
304
|
+
echo "Monitor daemon stopped (PID: $pid)"
|
|
305
|
+
else
|
|
306
|
+
echo "Monitor daemon not running"
|
|
307
|
+
fi
|
|
308
|
+
rm -f "${HOME}/.claude/monitor.pid"
|
|
309
|
+
else
|
|
310
|
+
echo "No monitor daemon found"
|
|
311
|
+
fi
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
# Main command handler
|
|
315
|
+
main() {
|
|
316
|
+
local command="${1:-monitor}"
|
|
317
|
+
|
|
318
|
+
case "$command" in
|
|
319
|
+
monitor)
|
|
320
|
+
monitor_worktrees
|
|
321
|
+
detect_conflicts
|
|
322
|
+
;;
|
|
323
|
+
daemon|start)
|
|
324
|
+
if [[ -f "${HOME}/.claude/monitor.pid" ]] && kill -0 "$(cat "${HOME}/.claude/monitor.pid")" 2>/dev/null; then
|
|
325
|
+
echo "Monitor daemon already running (PID: $(cat "${HOME}/.claude/monitor.pid"))"
|
|
326
|
+
else
|
|
327
|
+
init_logging
|
|
328
|
+
run_daemon &
|
|
329
|
+
echo "Monitor daemon started (PID: $!)"
|
|
330
|
+
fi
|
|
331
|
+
;;
|
|
332
|
+
stop)
|
|
333
|
+
stop_daemon
|
|
334
|
+
;;
|
|
335
|
+
status)
|
|
336
|
+
if [[ -f "${HOME}/.claude/monitor.pid" ]] && kill -0 "$(cat "${HOME}/.claude/monitor.pid")" 2>/dev/null; then
|
|
337
|
+
echo "Monitor daemon running (PID: $(cat "${HOME}/.claude/monitor.pid"))"
|
|
338
|
+
else
|
|
339
|
+
echo "Monitor daemon not running"
|
|
340
|
+
fi
|
|
341
|
+
;;
|
|
342
|
+
cleanup)
|
|
343
|
+
auto_cleanup
|
|
344
|
+
;;
|
|
345
|
+
report)
|
|
346
|
+
resource_report
|
|
347
|
+
;;
|
|
348
|
+
conflicts)
|
|
349
|
+
detect_conflicts
|
|
350
|
+
;;
|
|
351
|
+
*)
|
|
352
|
+
echo "Claude Worktree Monitor"
|
|
353
|
+
echo
|
|
354
|
+
echo "Usage: $0 [command]"
|
|
355
|
+
echo
|
|
356
|
+
echo "Commands:"
|
|
357
|
+
echo " monitor - Run monitoring check once (default)"
|
|
358
|
+
echo " daemon - Start monitoring daemon"
|
|
359
|
+
echo " stop - Stop monitoring daemon"
|
|
360
|
+
echo " status - Check daemon status"
|
|
361
|
+
echo " cleanup - Run auto-cleanup"
|
|
362
|
+
echo " report - Generate resource report"
|
|
363
|
+
echo " conflicts - Detect potential conflicts"
|
|
364
|
+
;;
|
|
365
|
+
esac
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
# Run if executed directly
|
|
369
|
+
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
|
370
|
+
main "$@"
|
|
371
|
+
fi
|