@stackmemoryai/stackmemory 0.3.17 → 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.
Files changed (212) hide show
  1. package/dist/cli/commands/skills.js +15 -2
  2. package/dist/cli/commands/skills.js.map +2 -2
  3. package/dist/cli/index.js +113 -834
  4. package/dist/cli/index.js.map +3 -3
  5. package/dist/core/context/dual-stack-manager.js +1 -1
  6. package/dist/core/context/dual-stack-manager.js.map +1 -1
  7. package/dist/core/context/frame-manager.js +3 -0
  8. package/dist/core/context/frame-manager.js.map +2 -2
  9. package/dist/integrations/claude-code/subagent-client.js +106 -3
  10. package/dist/integrations/claude-code/subagent-client.js.map +2 -2
  11. package/dist/servers/railway/config.js +51 -0
  12. package/dist/servers/railway/config.js.map +7 -0
  13. package/dist/servers/railway/index-enhanced.js +156 -0
  14. package/dist/servers/railway/index-enhanced.js.map +7 -0
  15. package/dist/servers/railway/minimal.js +48 -3
  16. package/dist/servers/railway/minimal.js.map +2 -2
  17. package/dist/servers/railway/storage-test.js +455 -0
  18. package/dist/servers/railway/storage-test.js.map +7 -0
  19. package/dist/skills/claude-skills.js +13 -12
  20. package/dist/skills/claude-skills.js.map +2 -2
  21. package/dist/skills/recursive-agent-orchestrator.js +27 -18
  22. package/dist/skills/recursive-agent-orchestrator.js.map +2 -2
  23. package/dist/skills/unified-rlm-orchestrator.js.map +2 -2
  24. package/package.json +6 -18
  25. package/scripts/README-TESTING.md +186 -0
  26. package/scripts/analyze-cli-security.js +288 -0
  27. package/scripts/archive/add-phase-tasks-to-linear.js +163 -0
  28. package/scripts/archive/analyze-linear-duplicates.js +214 -0
  29. package/scripts/archive/analyze-remaining-duplicates.js +230 -0
  30. package/scripts/archive/analyze-sta-duplicates.js +292 -0
  31. package/scripts/archive/analyze-sta-graphql.js +399 -0
  32. package/scripts/archive/cancel-duplicate-tasks.ts +246 -0
  33. package/scripts/archive/check-all-duplicates.ts +419 -0
  34. package/scripts/archive/clean-duplicate-tasks.js +114 -0
  35. package/scripts/archive/cleanup-duplicate-tasks.ts +286 -0
  36. package/scripts/archive/create-phase-tasks.js +387 -0
  37. package/scripts/archive/delete-linear-duplicates.js +182 -0
  38. package/scripts/archive/delete-remaining-duplicates.js +158 -0
  39. package/scripts/archive/delete-sta-duplicates.js +201 -0
  40. package/scripts/archive/delete-sta-oauth.js +201 -0
  41. package/scripts/archive/export-sta-tasks.js +62 -0
  42. package/scripts/archive/install-auto-sync.js +266 -0
  43. package/scripts/archive/install-chromadb-hooks.sh +133 -0
  44. package/scripts/archive/install-enhanced-clear-hooks.sh +431 -0
  45. package/scripts/archive/install-post-task-hooks.sh +289 -0
  46. package/scripts/archive/install-stackmemory-hooks.sh +420 -0
  47. package/scripts/archive/merge-linear-duplicates-safe.ts +362 -0
  48. package/scripts/archive/merge-linear-duplicates.ts +180 -0
  49. package/scripts/archive/remove-sta-tasks.js +70 -0
  50. package/scripts/archive/setup-background-sync.sh +168 -0
  51. package/scripts/archive/setup-claude-auto-triggers.sh +181 -0
  52. package/scripts/archive/setup-claude-autostart.sh +305 -0
  53. package/scripts/archive/setup-git-hooks.sh +25 -0
  54. package/scripts/archive/setup-linear-oauth.sh +46 -0
  55. package/scripts/archive/setup-mcp.sh +113 -0
  56. package/scripts/archive/setup-railway-deployment.sh +81 -0
  57. package/scripts/auto-handoff.sh +262 -0
  58. package/scripts/background-sync-manager.js +416 -0
  59. package/scripts/benchmark-performance.ts +57 -0
  60. package/scripts/check-redis.ts +48 -0
  61. package/scripts/chromadb-auto-loader.sh +128 -0
  62. package/scripts/chromadb-context-loader.js +479 -0
  63. package/scripts/claude-chromadb-hook.js +460 -0
  64. package/scripts/claude-code-wrapper.sh +66 -0
  65. package/scripts/claude-linear-skill.js +455 -0
  66. package/scripts/claude-pre-commit.sh +302 -0
  67. package/scripts/claude-sm-autostart.js +532 -0
  68. package/scripts/claude-sm-setup.sh +367 -0
  69. package/scripts/claude-with-chromadb.sh +69 -0
  70. package/scripts/claude-worktree-manager.sh +323 -0
  71. package/scripts/claude-worktree-monitor.sh +371 -0
  72. package/scripts/claude-worktree-setup.sh +327 -0
  73. package/scripts/clean-linear-backlog.js +273 -0
  74. package/scripts/cleanup-old-sessions.sh +57 -0
  75. package/scripts/codex-wrapper.sh +88 -0
  76. package/scripts/create-sandbox.sh +269 -0
  77. package/scripts/debug-linear-update.js +174 -0
  78. package/scripts/delete-linear-tasks.js +167 -0
  79. package/scripts/deploy.sh +89 -0
  80. package/scripts/deployment/railway.sh +352 -0
  81. package/scripts/deployment/test-deployment.js +194 -0
  82. package/scripts/detect-and-rehydrate.js +162 -0
  83. package/scripts/detect-and-rehydrate.mjs +165 -0
  84. package/scripts/development/create-demo-tasks.js +143 -0
  85. package/scripts/development/debug-frame-test.js +16 -0
  86. package/scripts/development/demo-auto-sync.js +128 -0
  87. package/scripts/development/fix-all-imports.js +213 -0
  88. package/scripts/development/fix-imports.js +229 -0
  89. package/scripts/development/fix-lint-loop.cjs +103 -0
  90. package/scripts/development/fix-project-id.ts +161 -0
  91. package/scripts/development/fix-strict-mode-issues.ts +291 -0
  92. package/scripts/development/reorganize-structure.sh +228 -0
  93. package/scripts/development/test-persistence-direct.js +148 -0
  94. package/scripts/development/test-persistence.js +114 -0
  95. package/scripts/development/test-tasks.js +93 -0
  96. package/scripts/development/update-imports.js +212 -0
  97. package/scripts/fetch-linear-status.js +125 -0
  98. package/scripts/git-hooks/README.md +310 -0
  99. package/scripts/git-hooks/branch-context-manager.sh +342 -0
  100. package/scripts/git-hooks/post-checkout-stackmemory.sh +63 -0
  101. package/scripts/git-hooks/post-commit-stackmemory.sh +305 -0
  102. package/scripts/git-hooks/pre-commit-stackmemory.sh +275 -0
  103. package/scripts/hooks/cleanup-shell.sh +130 -0
  104. package/scripts/hooks/task-complete.sh +114 -0
  105. package/scripts/initialize.ts +129 -0
  106. package/scripts/install-claude-hooks-auto.js +104 -0
  107. package/scripts/install-claude-hooks.sh +133 -0
  108. package/scripts/install-global.sh +296 -0
  109. package/scripts/install.sh +235 -0
  110. package/scripts/linear-auto-sync.js +262 -0
  111. package/scripts/linear-auto-sync.sh +161 -0
  112. package/scripts/linear-sync-daemon.js +150 -0
  113. package/scripts/linear-task-review.js +237 -0
  114. package/scripts/list-linear-tasks.ts +178 -0
  115. package/scripts/mcp-proxy.js +66 -0
  116. package/scripts/opencode-wrapper.sh +85 -0
  117. package/scripts/publish-local.js +74 -0
  118. package/scripts/query-chromadb.ts +201 -0
  119. package/scripts/railway-env-setup.sh +39 -0
  120. package/scripts/reconcile-local-tasks.js +170 -0
  121. package/scripts/recreate-frames-db.js +89 -0
  122. package/scripts/setup/claude-integration.js +138 -0
  123. package/scripts/setup/configure-alias.js +125 -0
  124. package/scripts/setup/configure-codex-alias.js +161 -0
  125. package/scripts/setup/configure-opencode-alias.js +175 -0
  126. package/scripts/setup-claude-integration.js +204 -0
  127. package/scripts/setup-claude-integration.sh +183 -0
  128. package/scripts/setup.sh +31 -0
  129. package/scripts/show-linear-summary.ts +172 -0
  130. package/scripts/stackmemory-auto-handoff.sh +231 -0
  131. package/scripts/stackmemory-daemon.sh +40 -0
  132. package/scripts/start-linear-sync-daemon.sh +141 -0
  133. package/scripts/start-temporal-paradox.sh +214 -0
  134. package/scripts/status.ts +159 -0
  135. package/scripts/sync-and-clean-tasks.js +258 -0
  136. package/scripts/sync-frames-from-railway.js +228 -0
  137. package/scripts/sync-linear-graphql.js +303 -0
  138. package/scripts/sync-linear-tasks.js +186 -0
  139. package/scripts/test-auto-triggers.sh +57 -0
  140. package/scripts/test-browser-mcp.js +74 -0
  141. package/scripts/test-chromadb-full.js +115 -0
  142. package/scripts/test-chromadb-hooks.sh +28 -0
  143. package/scripts/test-chromadb-sync.ts +245 -0
  144. package/scripts/test-cli-security.js +293 -0
  145. package/scripts/test-hooks-persistence.sh +220 -0
  146. package/scripts/test-installation-scenarios.sh +359 -0
  147. package/scripts/test-installation.sh +224 -0
  148. package/scripts/test-mcp.js +163 -0
  149. package/scripts/test-pre-publish-quick.sh +75 -0
  150. package/scripts/test-quality-gates.sh +263 -0
  151. package/scripts/test-railway-db.js +222 -0
  152. package/scripts/test-redis-storage.ts +490 -0
  153. package/scripts/test-rlm-basic.sh +122 -0
  154. package/scripts/test-rlm-comprehensive.sh +260 -0
  155. package/scripts/test-rlm-e2e.sh +268 -0
  156. package/scripts/test-rlm-simple.js +90 -0
  157. package/scripts/test-rlm.js +110 -0
  158. package/scripts/test-session-handoff.sh +165 -0
  159. package/scripts/test-shell-integration.sh +275 -0
  160. package/scripts/testing/ab-test-runner.ts +508 -0
  161. package/scripts/testing/collect-metrics.ts +457 -0
  162. package/scripts/testing/quick-effectiveness-demo.js +187 -0
  163. package/scripts/testing/real-performance-test.js +422 -0
  164. package/scripts/testing/run-effectiveness-tests.sh +176 -0
  165. package/scripts/testing/scripts/testing/ab-test-runner.js +363 -0
  166. package/scripts/testing/scripts/testing/collect-metrics.js +292 -0
  167. package/scripts/testing/simple-effectiveness-test.js +310 -0
  168. package/scripts/testing/src/core/context/context-bridge.js +253 -0
  169. package/scripts/testing/src/core/context/frame-manager.js +746 -0
  170. package/scripts/testing/src/core/context/shared-context-layer.js +437 -0
  171. package/scripts/testing/src/core/database/database-adapter.js +54 -0
  172. package/scripts/testing/src/core/errors/index.js +291 -0
  173. package/scripts/testing/src/core/errors/recovery.js +268 -0
  174. package/scripts/testing/src/core/monitoring/logger.js +145 -0
  175. package/scripts/testing/src/core/retrieval/context-retriever.js +516 -0
  176. package/scripts/testing/src/core/session/index.js +1 -0
  177. package/scripts/testing/src/core/session/session-manager.js +323 -0
  178. package/scripts/testing/src/core/trace/cli-trace-wrapper.js +140 -0
  179. package/scripts/testing/src/core/trace/db-trace-wrapper.js +251 -0
  180. package/scripts/testing/src/core/trace/debug-trace.js +398 -0
  181. package/scripts/testing/src/core/trace/index.js +120 -0
  182. package/scripts/testing/src/core/trace/linear-api-wrapper.js +204 -0
  183. package/scripts/update-linear-status.js +268 -0
  184. package/scripts/update-linear-tasks-fixed.js +284 -0
  185. package/templates/claude-hooks/hooks.json +5 -0
  186. package/templates/claude-hooks/on-clear.js +56 -0
  187. package/templates/claude-hooks/on-startup.js +56 -0
  188. package/templates/claude-hooks/tool-use-trace.js +67 -0
  189. package/dist/features/tui/components/analytics-panel.js +0 -157
  190. package/dist/features/tui/components/analytics-panel.js.map +0 -7
  191. package/dist/features/tui/components/frame-visualizer.js +0 -377
  192. package/dist/features/tui/components/frame-visualizer.js.map +0 -7
  193. package/dist/features/tui/components/pr-tracker.js +0 -135
  194. package/dist/features/tui/components/pr-tracker.js.map +0 -7
  195. package/dist/features/tui/components/session-monitor.js +0 -299
  196. package/dist/features/tui/components/session-monitor.js.map +0 -7
  197. package/dist/features/tui/components/subagent-fleet.js +0 -395
  198. package/dist/features/tui/components/subagent-fleet.js.map +0 -7
  199. package/dist/features/tui/components/task-board.js +0 -1139
  200. package/dist/features/tui/components/task-board.js.map +0 -7
  201. package/dist/features/tui/index.js +0 -408
  202. package/dist/features/tui/index.js.map +0 -7
  203. package/dist/features/tui/services/data-service.js +0 -641
  204. package/dist/features/tui/services/data-service.js.map +0 -7
  205. package/dist/features/tui/services/linear-task-reader.js +0 -102
  206. package/dist/features/tui/services/linear-task-reader.js.map +0 -7
  207. package/dist/features/tui/services/websocket-client.js +0 -162
  208. package/dist/features/tui/services/websocket-client.js.map +0 -7
  209. package/dist/features/tui/terminal-compat.js +0 -220
  210. package/dist/features/tui/terminal-compat.js.map +0 -7
  211. package/dist/features/tui/types.js +0 -1
  212. 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