@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.
Files changed (213) hide show
  1. package/README.md +48 -2
  2. package/dist/cli/commands/skills.js +15 -2
  3. package/dist/cli/commands/skills.js.map +2 -2
  4. package/dist/cli/index.js +113 -834
  5. package/dist/cli/index.js.map +3 -3
  6. package/dist/core/context/dual-stack-manager.js +1 -1
  7. package/dist/core/context/dual-stack-manager.js.map +1 -1
  8. package/dist/core/context/frame-manager.js +3 -0
  9. package/dist/core/context/frame-manager.js.map +2 -2
  10. package/dist/integrations/claude-code/subagent-client.js +106 -3
  11. package/dist/integrations/claude-code/subagent-client.js.map +2 -2
  12. package/dist/servers/railway/config.js +51 -0
  13. package/dist/servers/railway/config.js.map +7 -0
  14. package/dist/servers/railway/index-enhanced.js +156 -0
  15. package/dist/servers/railway/index-enhanced.js.map +7 -0
  16. package/dist/servers/railway/minimal.js +48 -3
  17. package/dist/servers/railway/minimal.js.map +2 -2
  18. package/dist/servers/railway/storage-test.js +455 -0
  19. package/dist/servers/railway/storage-test.js.map +7 -0
  20. package/dist/skills/claude-skills.js +13 -12
  21. package/dist/skills/claude-skills.js.map +2 -2
  22. package/dist/skills/recursive-agent-orchestrator.js +27 -18
  23. package/dist/skills/recursive-agent-orchestrator.js.map +2 -2
  24. package/dist/skills/unified-rlm-orchestrator.js.map +2 -2
  25. package/package.json +6 -18
  26. package/scripts/README-TESTING.md +186 -0
  27. package/scripts/analyze-cli-security.js +288 -0
  28. package/scripts/archive/add-phase-tasks-to-linear.js +163 -0
  29. package/scripts/archive/analyze-linear-duplicates.js +214 -0
  30. package/scripts/archive/analyze-remaining-duplicates.js +230 -0
  31. package/scripts/archive/analyze-sta-duplicates.js +292 -0
  32. package/scripts/archive/analyze-sta-graphql.js +399 -0
  33. package/scripts/archive/cancel-duplicate-tasks.ts +246 -0
  34. package/scripts/archive/check-all-duplicates.ts +419 -0
  35. package/scripts/archive/clean-duplicate-tasks.js +114 -0
  36. package/scripts/archive/cleanup-duplicate-tasks.ts +286 -0
  37. package/scripts/archive/create-phase-tasks.js +387 -0
  38. package/scripts/archive/delete-linear-duplicates.js +182 -0
  39. package/scripts/archive/delete-remaining-duplicates.js +158 -0
  40. package/scripts/archive/delete-sta-duplicates.js +201 -0
  41. package/scripts/archive/delete-sta-oauth.js +201 -0
  42. package/scripts/archive/export-sta-tasks.js +62 -0
  43. package/scripts/archive/install-auto-sync.js +266 -0
  44. package/scripts/archive/install-chromadb-hooks.sh +133 -0
  45. package/scripts/archive/install-enhanced-clear-hooks.sh +431 -0
  46. package/scripts/archive/install-post-task-hooks.sh +289 -0
  47. package/scripts/archive/install-stackmemory-hooks.sh +420 -0
  48. package/scripts/archive/merge-linear-duplicates-safe.ts +362 -0
  49. package/scripts/archive/merge-linear-duplicates.ts +180 -0
  50. package/scripts/archive/remove-sta-tasks.js +70 -0
  51. package/scripts/archive/setup-background-sync.sh +168 -0
  52. package/scripts/archive/setup-claude-auto-triggers.sh +181 -0
  53. package/scripts/archive/setup-claude-autostart.sh +305 -0
  54. package/scripts/archive/setup-git-hooks.sh +25 -0
  55. package/scripts/archive/setup-linear-oauth.sh +46 -0
  56. package/scripts/archive/setup-mcp.sh +113 -0
  57. package/scripts/archive/setup-railway-deployment.sh +81 -0
  58. package/scripts/auto-handoff.sh +262 -0
  59. package/scripts/background-sync-manager.js +416 -0
  60. package/scripts/benchmark-performance.ts +57 -0
  61. package/scripts/check-redis.ts +48 -0
  62. package/scripts/chromadb-auto-loader.sh +128 -0
  63. package/scripts/chromadb-context-loader.js +479 -0
  64. package/scripts/claude-chromadb-hook.js +460 -0
  65. package/scripts/claude-code-wrapper.sh +66 -0
  66. package/scripts/claude-linear-skill.js +455 -0
  67. package/scripts/claude-pre-commit.sh +302 -0
  68. package/scripts/claude-sm-autostart.js +532 -0
  69. package/scripts/claude-sm-setup.sh +367 -0
  70. package/scripts/claude-with-chromadb.sh +69 -0
  71. package/scripts/claude-worktree-manager.sh +323 -0
  72. package/scripts/claude-worktree-monitor.sh +371 -0
  73. package/scripts/claude-worktree-setup.sh +327 -0
  74. package/scripts/clean-linear-backlog.js +273 -0
  75. package/scripts/cleanup-old-sessions.sh +57 -0
  76. package/scripts/codex-wrapper.sh +88 -0
  77. package/scripts/create-sandbox.sh +269 -0
  78. package/scripts/debug-linear-update.js +174 -0
  79. package/scripts/delete-linear-tasks.js +167 -0
  80. package/scripts/deploy.sh +89 -0
  81. package/scripts/deployment/railway.sh +352 -0
  82. package/scripts/deployment/test-deployment.js +194 -0
  83. package/scripts/detect-and-rehydrate.js +162 -0
  84. package/scripts/detect-and-rehydrate.mjs +165 -0
  85. package/scripts/development/create-demo-tasks.js +143 -0
  86. package/scripts/development/debug-frame-test.js +16 -0
  87. package/scripts/development/demo-auto-sync.js +128 -0
  88. package/scripts/development/fix-all-imports.js +213 -0
  89. package/scripts/development/fix-imports.js +229 -0
  90. package/scripts/development/fix-lint-loop.cjs +103 -0
  91. package/scripts/development/fix-project-id.ts +161 -0
  92. package/scripts/development/fix-strict-mode-issues.ts +291 -0
  93. package/scripts/development/reorganize-structure.sh +228 -0
  94. package/scripts/development/test-persistence-direct.js +148 -0
  95. package/scripts/development/test-persistence.js +114 -0
  96. package/scripts/development/test-tasks.js +93 -0
  97. package/scripts/development/update-imports.js +212 -0
  98. package/scripts/fetch-linear-status.js +125 -0
  99. package/scripts/git-hooks/README.md +310 -0
  100. package/scripts/git-hooks/branch-context-manager.sh +342 -0
  101. package/scripts/git-hooks/post-checkout-stackmemory.sh +63 -0
  102. package/scripts/git-hooks/post-commit-stackmemory.sh +305 -0
  103. package/scripts/git-hooks/pre-commit-stackmemory.sh +275 -0
  104. package/scripts/hooks/cleanup-shell.sh +130 -0
  105. package/scripts/hooks/task-complete.sh +114 -0
  106. package/scripts/initialize.ts +129 -0
  107. package/scripts/install-claude-hooks-auto.js +104 -0
  108. package/scripts/install-claude-hooks.sh +133 -0
  109. package/scripts/install-global.sh +296 -0
  110. package/scripts/install.sh +235 -0
  111. package/scripts/linear-auto-sync.js +262 -0
  112. package/scripts/linear-auto-sync.sh +161 -0
  113. package/scripts/linear-sync-daemon.js +150 -0
  114. package/scripts/linear-task-review.js +237 -0
  115. package/scripts/list-linear-tasks.ts +178 -0
  116. package/scripts/mcp-proxy.js +66 -0
  117. package/scripts/opencode-wrapper.sh +85 -0
  118. package/scripts/publish-local.js +74 -0
  119. package/scripts/query-chromadb.ts +201 -0
  120. package/scripts/railway-env-setup.sh +39 -0
  121. package/scripts/reconcile-local-tasks.js +170 -0
  122. package/scripts/recreate-frames-db.js +89 -0
  123. package/scripts/setup/claude-integration.js +138 -0
  124. package/scripts/setup/configure-alias.js +125 -0
  125. package/scripts/setup/configure-codex-alias.js +161 -0
  126. package/scripts/setup/configure-opencode-alias.js +175 -0
  127. package/scripts/setup-claude-integration.js +204 -0
  128. package/scripts/setup-claude-integration.sh +183 -0
  129. package/scripts/setup.sh +31 -0
  130. package/scripts/show-linear-summary.ts +172 -0
  131. package/scripts/stackmemory-auto-handoff.sh +231 -0
  132. package/scripts/stackmemory-daemon.sh +40 -0
  133. package/scripts/start-linear-sync-daemon.sh +141 -0
  134. package/scripts/start-temporal-paradox.sh +214 -0
  135. package/scripts/status.ts +159 -0
  136. package/scripts/sync-and-clean-tasks.js +258 -0
  137. package/scripts/sync-frames-from-railway.js +228 -0
  138. package/scripts/sync-linear-graphql.js +303 -0
  139. package/scripts/sync-linear-tasks.js +186 -0
  140. package/scripts/test-auto-triggers.sh +57 -0
  141. package/scripts/test-browser-mcp.js +74 -0
  142. package/scripts/test-chromadb-full.js +115 -0
  143. package/scripts/test-chromadb-hooks.sh +28 -0
  144. package/scripts/test-chromadb-sync.ts +245 -0
  145. package/scripts/test-cli-security.js +293 -0
  146. package/scripts/test-hooks-persistence.sh +220 -0
  147. package/scripts/test-installation-scenarios.sh +359 -0
  148. package/scripts/test-installation.sh +224 -0
  149. package/scripts/test-mcp.js +163 -0
  150. package/scripts/test-pre-publish-quick.sh +75 -0
  151. package/scripts/test-quality-gates.sh +263 -0
  152. package/scripts/test-railway-db.js +222 -0
  153. package/scripts/test-redis-storage.ts +490 -0
  154. package/scripts/test-rlm-basic.sh +122 -0
  155. package/scripts/test-rlm-comprehensive.sh +260 -0
  156. package/scripts/test-rlm-e2e.sh +268 -0
  157. package/scripts/test-rlm-simple.js +90 -0
  158. package/scripts/test-rlm.js +110 -0
  159. package/scripts/test-session-handoff.sh +165 -0
  160. package/scripts/test-shell-integration.sh +275 -0
  161. package/scripts/testing/ab-test-runner.ts +508 -0
  162. package/scripts/testing/collect-metrics.ts +457 -0
  163. package/scripts/testing/quick-effectiveness-demo.js +187 -0
  164. package/scripts/testing/real-performance-test.js +422 -0
  165. package/scripts/testing/run-effectiveness-tests.sh +176 -0
  166. package/scripts/testing/scripts/testing/ab-test-runner.js +363 -0
  167. package/scripts/testing/scripts/testing/collect-metrics.js +292 -0
  168. package/scripts/testing/simple-effectiveness-test.js +310 -0
  169. package/scripts/testing/src/core/context/context-bridge.js +253 -0
  170. package/scripts/testing/src/core/context/frame-manager.js +746 -0
  171. package/scripts/testing/src/core/context/shared-context-layer.js +437 -0
  172. package/scripts/testing/src/core/database/database-adapter.js +54 -0
  173. package/scripts/testing/src/core/errors/index.js +291 -0
  174. package/scripts/testing/src/core/errors/recovery.js +268 -0
  175. package/scripts/testing/src/core/monitoring/logger.js +145 -0
  176. package/scripts/testing/src/core/retrieval/context-retriever.js +516 -0
  177. package/scripts/testing/src/core/session/index.js +1 -0
  178. package/scripts/testing/src/core/session/session-manager.js +323 -0
  179. package/scripts/testing/src/core/trace/cli-trace-wrapper.js +140 -0
  180. package/scripts/testing/src/core/trace/db-trace-wrapper.js +251 -0
  181. package/scripts/testing/src/core/trace/debug-trace.js +398 -0
  182. package/scripts/testing/src/core/trace/index.js +120 -0
  183. package/scripts/testing/src/core/trace/linear-api-wrapper.js +204 -0
  184. package/scripts/update-linear-status.js +268 -0
  185. package/scripts/update-linear-tasks-fixed.js +284 -0
  186. package/templates/claude-hooks/hooks.json +5 -0
  187. package/templates/claude-hooks/on-clear.js +56 -0
  188. package/templates/claude-hooks/on-startup.js +56 -0
  189. package/templates/claude-hooks/tool-use-trace.js +67 -0
  190. package/dist/features/tui/components/analytics-panel.js +0 -157
  191. package/dist/features/tui/components/analytics-panel.js.map +0 -7
  192. package/dist/features/tui/components/frame-visualizer.js +0 -377
  193. package/dist/features/tui/components/frame-visualizer.js.map +0 -7
  194. package/dist/features/tui/components/pr-tracker.js +0 -135
  195. package/dist/features/tui/components/pr-tracker.js.map +0 -7
  196. package/dist/features/tui/components/session-monitor.js +0 -299
  197. package/dist/features/tui/components/session-monitor.js.map +0 -7
  198. package/dist/features/tui/components/subagent-fleet.js +0 -395
  199. package/dist/features/tui/components/subagent-fleet.js.map +0 -7
  200. package/dist/features/tui/components/task-board.js +0 -1139
  201. package/dist/features/tui/components/task-board.js.map +0 -7
  202. package/dist/features/tui/index.js +0 -408
  203. package/dist/features/tui/index.js.map +0 -7
  204. package/dist/features/tui/services/data-service.js +0 -641
  205. package/dist/features/tui/services/data-service.js.map +0 -7
  206. package/dist/features/tui/services/linear-task-reader.js +0 -102
  207. package/dist/features/tui/services/linear-task-reader.js.map +0 -7
  208. package/dist/features/tui/services/websocket-client.js +0 -162
  209. package/dist/features/tui/services/websocket-client.js.map +0 -7
  210. package/dist/features/tui/terminal-compat.js +0 -220
  211. package/dist/features/tui/terminal-compat.js.map +0 -7
  212. package/dist/features/tui/types.js +0 -1
  213. package/dist/features/tui/types.js.map +0 -7
@@ -0,0 +1,284 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Update Linear task status based on actual implementation status - FIXED version
5
+ */
6
+
7
+ import 'dotenv/config';
8
+
9
+ const API_KEY = process.env.LINEAR_OAUTH_TOKEN || process.env.LINEAR_API_KEY;
10
+ if (!API_KEY) {
11
+ console.error('❌ LINEAR_OAUTH_TOKEN or LINEAR_API_KEY environment variable not set');
12
+ console.log('Please set LINEAR_OAUTH_TOKEN or LINEAR_API_KEY in your .env file or export it in your shell');
13
+ process.exit(1);
14
+ }
15
+
16
+ // Tasks that should be marked as DONE based on commits and documentation
17
+ const COMPLETED_TASKS = {
18
+ // Phase 1: Core Runtime - COMPLETE
19
+ 'STA-279': 'Implement LLM-Driven Context Retrieval',
20
+
21
+ // Phase 2: Intelligence Layer - COMPLETE
22
+ 'STA-280': 'Complete Hybrid Digest Generation (60/40)',
23
+ 'STA-281': 'Implement Smart Trace Detection and Bundling',
24
+ 'STA-282': 'Implement Configurable Tool Scoring System',
25
+
26
+ // Phase 3: Collaboration - COMPLETE
27
+ 'STA-283': 'Implement Dual Stack Architecture',
28
+ 'STA-284': 'Build Frame Handoff Mechanism',
29
+ 'STA-271': '[STA-99] Phase 3: Dual Stack Architecture',
30
+ 'STA-275': '[STA-100] Phase 3: Frame Handoff Mechanism',
31
+ 'STA-285': 'Implement Merge Conflict Resolution',
32
+ 'STA-286': 'Build Team Analytics',
33
+
34
+ // Additional completed features
35
+ 'STA-276': '[STA-91] Finalize Session Persistence Design',
36
+ 'STA-277': '[STA-90] Complete Linear MCP Integration Documentation',
37
+ 'STA-155': '[STA-89] Complete Context Frame Manager Tests',
38
+ };
39
+
40
+ // Tasks in progress
41
+ const IN_PROGRESS_TASKS = {
42
+ 'STA-287': 'Implement Remote Infinite Storage System',
43
+ 'STA-288': 'Build Incremental Garbage Collection',
44
+ };
45
+
46
+ // Tasks to cancel (duplicates or no longer needed)
47
+ const CANCEL_TASKS = {
48
+ 'STA-272': 'Engineering x Marketing Team',
49
+ 'STA-273': 'Engineering x Operations Team',
50
+ 'STA-274': 'Engineering x Success Team',
51
+ 'STA-268': 'Task Analytics Dashboard',
52
+ 'STA-264': 'Complete Documentation TODOs',
53
+ };
54
+
55
+ async function getWorkflowStates() {
56
+ const query = `
57
+ query GetStates {
58
+ workflowStates {
59
+ nodes {
60
+ id
61
+ name
62
+ type
63
+ team {
64
+ key
65
+ }
66
+ }
67
+ }
68
+ }
69
+ `;
70
+
71
+ const response = await fetch('https://api.linear.app/graphql', {
72
+ method: 'POST',
73
+ headers: {
74
+ 'Authorization': `Bearer ${API_KEY}`,
75
+ 'Content-Type': 'application/json'
76
+ },
77
+ body: JSON.stringify({ query })
78
+ });
79
+
80
+ const result = await response.json();
81
+ const states = result.data?.workflowStates?.nodes || [];
82
+
83
+ // Find STA team states
84
+ const staStates = states.filter(s => s.team?.key === 'STA');
85
+
86
+ return {
87
+ done: staStates.find(s => s.type === 'completed')?.id,
88
+ inProgress: staStates.find(s => s.type === 'started' && s.name === 'In Progress')?.id,
89
+ canceled: staStates.find(s => s.type === 'canceled' && s.name === 'Canceled')?.id
90
+ };
91
+ }
92
+
93
+ async function getTaskByIdentifier(identifier) {
94
+ const query = `
95
+ query GetIssue {
96
+ issue(id: "${identifier}") {
97
+ id
98
+ identifier
99
+ title
100
+ state {
101
+ name
102
+ type
103
+ }
104
+ }
105
+ }
106
+ `;
107
+
108
+ const response = await fetch('https://api.linear.app/graphql', {
109
+ method: 'POST',
110
+ headers: {
111
+ 'Authorization': `Bearer ${API_KEY}`,
112
+ 'Content-Type': 'application/json'
113
+ },
114
+ body: JSON.stringify({ query })
115
+ });
116
+
117
+ const result = await response.json();
118
+ return result.data?.issue;
119
+ }
120
+
121
+ async function updateTaskStatus(taskId, stateId) {
122
+ const mutation = `
123
+ mutation UpdateIssue($issueId: String!, $stateId: String!) {
124
+ issueUpdate(
125
+ id: $issueId,
126
+ input: {
127
+ stateId: $stateId
128
+ }
129
+ ) {
130
+ success
131
+ issue {
132
+ identifier
133
+ state {
134
+ name
135
+ }
136
+ }
137
+ }
138
+ }
139
+ `;
140
+
141
+ const response = await fetch('https://api.linear.app/graphql', {
142
+ method: 'POST',
143
+ headers: {
144
+ 'Authorization': `Bearer ${API_KEY}`,
145
+ 'Content-Type': 'application/json'
146
+ },
147
+ body: JSON.stringify({
148
+ query: mutation,
149
+ variables: {
150
+ issueId: taskId,
151
+ stateId: stateId
152
+ }
153
+ })
154
+ });
155
+
156
+ return response.json();
157
+ }
158
+
159
+ async function updateLinearTasks() {
160
+ console.log('📊 Updating Linear task states based on actual implementation...\n');
161
+
162
+ // Get state IDs
163
+ const states = await getWorkflowStates();
164
+
165
+ if (!states.done || !states.inProgress) {
166
+ console.error('❌ Could not find required workflow states');
167
+ console.log('Available states:', states);
168
+ return;
169
+ }
170
+
171
+ console.log('Found states:', {
172
+ done: states.done,
173
+ inProgress: states.inProgress,
174
+ canceled: states.canceled
175
+ });
176
+
177
+ let updated = 0;
178
+ let skipped = 0;
179
+ let failed = 0;
180
+
181
+ // Update completed tasks
182
+ console.log('\n✅ Marking completed tasks as Done:\n');
183
+ for (const [identifier, title] of Object.entries(COMPLETED_TASKS)) {
184
+ const task = await getTaskByIdentifier(identifier);
185
+ if (!task) {
186
+ console.log(` ⚠️ ${identifier} not found`);
187
+ failed++;
188
+ continue;
189
+ }
190
+
191
+ if (task.state.type === 'completed') {
192
+ console.log(` ✓ ${identifier} already Done`);
193
+ skipped++;
194
+ continue;
195
+ }
196
+
197
+ const result = await updateTaskStatus(task.id, states.done);
198
+ if (result.data?.issueUpdate?.success) {
199
+ console.log(` ✅ ${identifier}: ${title.substring(0, 40)}... → Done`);
200
+ updated++;
201
+ } else {
202
+ console.log(` ❌ ${identifier}: Failed to update`, result.errors);
203
+ failed++;
204
+ }
205
+
206
+ // Small delay to avoid rate limits
207
+ await new Promise(r => setTimeout(r, 500));
208
+ }
209
+
210
+ // Update in-progress tasks
211
+ console.log('\n🔄 Marking in-progress tasks:\n');
212
+ for (const [identifier, title] of Object.entries(IN_PROGRESS_TASKS)) {
213
+ const task = await getTaskByIdentifier(identifier);
214
+ if (!task) {
215
+ console.log(` ⚠️ ${identifier} not found`);
216
+ failed++;
217
+ continue;
218
+ }
219
+
220
+ if (task.state.type === 'started') {
221
+ console.log(` ✓ ${identifier} already In Progress`);
222
+ skipped++;
223
+ continue;
224
+ }
225
+
226
+ const result = await updateTaskStatus(task.id, states.inProgress);
227
+ if (result.data?.issueUpdate?.success) {
228
+ console.log(` 🔄 ${identifier}: ${title.substring(0, 40)}... → In Progress`);
229
+ updated++;
230
+ } else {
231
+ console.log(` ❌ ${identifier}: Failed to update`);
232
+ failed++;
233
+ }
234
+
235
+ await new Promise(r => setTimeout(r, 500));
236
+ }
237
+
238
+ // Cancel obsolete tasks
239
+ if (states.canceled) {
240
+ console.log('\n❌ Canceling obsolete tasks:\n');
241
+ for (const [identifier, title] of Object.entries(CANCEL_TASKS)) {
242
+ const task = await getTaskByIdentifier(identifier);
243
+ if (!task) {
244
+ console.log(` ⚠️ ${identifier} not found`);
245
+ failed++;
246
+ continue;
247
+ }
248
+
249
+ if (task.state.type === 'canceled') {
250
+ console.log(` ✓ ${identifier} already Canceled`);
251
+ skipped++;
252
+ continue;
253
+ }
254
+
255
+ const result = await updateTaskStatus(task.id, states.canceled);
256
+ if (result.data?.issueUpdate?.success) {
257
+ console.log(` ❌ ${identifier}: ${title.substring(0, 40)}... → Canceled`);
258
+ updated++;
259
+ } else {
260
+ console.log(` ❌ ${identifier}: Failed to update`);
261
+ failed++;
262
+ }
263
+
264
+ await new Promise(r => setTimeout(r, 500));
265
+ }
266
+ }
267
+
268
+ // Summary
269
+ console.log('\n' + '='.repeat(60));
270
+ console.log('📊 UPDATE SUMMARY');
271
+ console.log('='.repeat(60));
272
+ console.log(`✅ Successfully updated: ${updated} tasks`);
273
+ console.log(`⏭️ Skipped (already correct): ${skipped} tasks`);
274
+ console.log(`❌ Failed: ${failed} tasks`);
275
+ console.log('\nLinear backlog now reflects actual implementation status.');
276
+ console.log('\nRemaining backlog: ~20 tasks (from 188 originally)');
277
+ }
278
+
279
+ // Run if called directly
280
+ if (import.meta.url === `file://${process.argv[1]}`) {
281
+ updateLinearTasks().catch(console.error);
282
+ }
283
+
284
+ export { updateLinearTasks };
@@ -0,0 +1,5 @@
1
+ {
2
+ "tool-use-approval": "~/.claude/hooks/tool-use-trace.js",
3
+ "on-startup": "~/.claude/hooks/on-startup.js",
4
+ "on-clear": "~/.claude/hooks/on-clear.js"
5
+ }
@@ -0,0 +1,56 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Claude Code Clear Hook - Save context before clearing
5
+ */
6
+
7
+ import { execSync, spawn } from 'child_process';
8
+ import { existsSync, readFileSync, writeFileSync } from 'fs';
9
+ import { join } from 'path';
10
+ import { homedir } from 'os';
11
+
12
+ const traceDir = join(homedir(), '.stackmemory', 'traces');
13
+ const sessionFile = join(traceDir, 'current-session.json');
14
+
15
+ let sessionData = null;
16
+ if (existsSync(sessionFile)) {
17
+ try {
18
+ sessionData = JSON.parse(readFileSync(sessionFile, 'utf8'));
19
+ } catch (err) {
20
+ // Ignore parse errors
21
+ }
22
+ }
23
+
24
+ // Log session clear
25
+ const clearData = {
26
+ action: 'session_clear',
27
+ timestamp: new Date().toISOString(),
28
+ sessionId: sessionData?.sessionId || 'unknown',
29
+ workingDirectory: process.cwd(),
30
+ clearReason: process.env.CLAUDE_CLEAR_REASON || 'user_initiated'
31
+ };
32
+
33
+ // Save to StackMemory if available
34
+ const stackmemoryPath = join(homedir(), '.stackmemory', 'bin', 'stackmemory');
35
+ if (existsSync(stackmemoryPath)) {
36
+ try {
37
+ spawn(stackmemoryPath, ['context', 'save', '--json', JSON.stringify({
38
+ message: 'Claude Code session cleared - context preserved',
39
+ metadata: clearData
40
+ })], { detached: true, stdio: 'ignore' });
41
+ } catch (err) {
42
+ // Silent fail
43
+ }
44
+ }
45
+
46
+ // Write clear log
47
+ const clearLogFile = join(traceDir, `clear-${new Date().toISOString().split('T')[0]}.jsonl`);
48
+ const logEntry = JSON.stringify(clearData) + '\n';
49
+
50
+ try {
51
+ require('fs').appendFileSync(clearLogFile, logEntry);
52
+ } catch (err) {
53
+ // Silent fail
54
+ }
55
+
56
+ console.log('📚 Context saved before clear');
@@ -0,0 +1,56 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Claude Code Startup Hook - Initialize StackMemory tracing
5
+ */
6
+
7
+ import { execSync, spawn } from 'child_process';
8
+ import { existsSync, mkdirSync, writeFileSync } from 'fs';
9
+ import { join } from 'path';
10
+ import { homedir } from 'os';
11
+
12
+ const traceDir = join(homedir(), '.stackmemory', 'traces');
13
+ const sessionFile = join(traceDir, 'current-session.json');
14
+
15
+ // Ensure trace directory exists
16
+ if (!existsSync(traceDir)) {
17
+ mkdirSync(traceDir, { recursive: true });
18
+ }
19
+
20
+ // Create session trace record
21
+ const sessionData = {
22
+ sessionId: process.env.CLAUDE_INSTANCE_ID || `session-${Date.now()}`,
23
+ startTime: new Date().toISOString(),
24
+ workingDirectory: process.cwd(),
25
+ gitBranch: null,
26
+ gitRepo: null
27
+ };
28
+
29
+ // Get Git info if available
30
+ try {
31
+ sessionData.gitRepo = execSync('git remote get-url origin', { encoding: 'utf8' }).trim();
32
+ sessionData.gitBranch = execSync('git rev-parse --abbrev-ref HEAD', { encoding: 'utf8' }).trim();
33
+ } catch (err) {
34
+ // Not in a git repo
35
+ }
36
+
37
+ writeFileSync(sessionFile, JSON.stringify(sessionData, null, 2));
38
+
39
+ // Initialize StackMemory if available and not already initialized
40
+ const stackmemoryPath = join(homedir(), '.stackmemory', 'bin', 'stackmemory');
41
+ if (existsSync(stackmemoryPath)) {
42
+ try {
43
+ // Try to init or get status (will fail silently if already initialized)
44
+ spawn(stackmemoryPath, ['init'], { detached: true, stdio: 'ignore' });
45
+
46
+ // Log session start
47
+ spawn(stackmemoryPath, ['context', 'save', '--json', JSON.stringify({
48
+ message: 'Claude Code session started',
49
+ metadata: sessionData
50
+ })], { detached: true, stdio: 'ignore' });
51
+ } catch (err) {
52
+ // Silent fail
53
+ }
54
+ }
55
+
56
+ console.log(`🔍 StackMemory tracing enabled - Session: ${sessionData.sessionId}`);
@@ -0,0 +1,67 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Claude Code Tool Use Tracing Hook
5
+ * Captures all tool usage for StackMemory trace logging
6
+ */
7
+
8
+ import { writeFileSync, appendFileSync, existsSync, mkdirSync } from 'fs';
9
+ import { join } from 'path';
10
+ import { homedir } from 'os';
11
+
12
+ // Setup trace directory
13
+ const traceDir = join(homedir(), '.stackmemory', 'traces');
14
+ if (!existsSync(traceDir)) {
15
+ mkdirSync(traceDir, { recursive: true });
16
+ }
17
+
18
+ const traceFile = join(traceDir, `claude-tools-${new Date().toISOString().split('T')[0]}.jsonl`);
19
+
20
+ function logToolUse(data) {
21
+ const entry = {
22
+ timestamp: new Date().toISOString(),
23
+ type: 'tool_use',
24
+ sessionId: process.env.CLAUDE_INSTANCE_ID || 'unknown',
25
+ workingDir: process.cwd(),
26
+ ...data
27
+ };
28
+
29
+ const logLine = JSON.stringify(entry) + '\n';
30
+ appendFileSync(traceFile, logLine);
31
+
32
+ // Also try to log to StackMemory if available
33
+ try {
34
+ const { spawn } = require('child_process');
35
+ const stackmemoryPath = join(homedir(), '.stackmemory', 'bin', 'stackmemory');
36
+ if (existsSync(stackmemoryPath)) {
37
+ spawn(stackmemoryPath, ['context', 'save', '--json', JSON.stringify({
38
+ message: `Tool used: ${data.tool}`,
39
+ metadata: entry
40
+ })], { detached: true, stdio: 'ignore' });
41
+ }
42
+ } catch (err) {
43
+ // Silent fail
44
+ }
45
+ }
46
+
47
+ // Read the tool use data from stdin
48
+ let input = '';
49
+ process.stdin.setEncoding('utf8');
50
+ process.stdin.on('data', chunk => input += chunk);
51
+ process.stdin.on('end', () => {
52
+ try {
53
+ const toolUse = JSON.parse(input);
54
+
55
+ logToolUse({
56
+ tool: toolUse.function?.name || toolUse.tool_name || 'unknown',
57
+ parameters: toolUse.function?.arguments || toolUse.parameters || {},
58
+ requestId: toolUse.id || 'unknown'
59
+ });
60
+
61
+ // Always approve the tool use
62
+ process.stdout.write('approved');
63
+ } catch (err) {
64
+ // If parsing fails, approve anyway
65
+ process.stdout.write('approved');
66
+ }
67
+ });
@@ -1,157 +0,0 @@
1
- import { EventEmitter } from "events";
2
- class AnalyticsPanel extends EventEmitter {
3
- line;
4
- // contrib.line type
5
- currentMetric = "tokens";
6
- data = null;
7
- constructor(line) {
8
- super();
9
- this.line = line;
10
- this.initializeUI();
11
- }
12
- initializeUI() {
13
- this.line.screen.key(["m"], () => {
14
- this.cycleMetric();
15
- });
16
- this.showTokenUsage();
17
- }
18
- cycleMetric() {
19
- const metrics = [
20
- "tokens",
21
- "velocity",
22
- "quality",
23
- "performance"
24
- ];
25
- const currentIndex = metrics.indexOf(this.currentMetric);
26
- this.currentMetric = metrics[(currentIndex + 1) % metrics.length];
27
- switch (this.currentMetric) {
28
- case "tokens":
29
- this.showTokenUsage();
30
- break;
31
- case "velocity":
32
- this.showVelocity();
33
- break;
34
- case "quality":
35
- this.showQuality();
36
- break;
37
- case "performance":
38
- this.showPerformance();
39
- break;
40
- }
41
- }
42
- showTokenUsage() {
43
- if (!this.data) return;
44
- const data = [
45
- {
46
- title: "Token Usage",
47
- x: this.data.tokens.labels.map((_, i) => i.toString()),
48
- y: this.data.tokens.values,
49
- style: { line: "yellow" }
50
- }
51
- ];
52
- this.line.setData(data);
53
- if (typeof this.line.setLabel === "function") {
54
- this.line.setLabel(" \u{1F4C8} Analytics - Token Usage [m] cycle ");
55
- }
56
- this.line.screen.render();
57
- }
58
- showVelocity() {
59
- if (!this.data) return;
60
- const data = [
61
- {
62
- title: "Task Velocity",
63
- x: this.data.tasks.velocity.map((_, i) => `Sprint ${i + 1}`),
64
- y: this.data.tasks.velocity,
65
- style: { line: "green" }
66
- }
67
- ];
68
- this.line.setData(data);
69
- if (typeof this.line.setLabel === "function") {
70
- this.line.setLabel(" \u{1F4C8} Analytics - Task Velocity [m] cycle ");
71
- }
72
- this.line.screen.render();
73
- }
74
- showQuality() {
75
- if (!this.data) return;
76
- const data = [
77
- {
78
- title: "Tests Passed",
79
- x: ["1", "2", "3", "4", "5"],
80
- y: [
81
- this.data.quality.testsPassed,
82
- this.data.quality.testsPassed,
83
- this.data.quality.testsPassed,
84
- this.data.quality.testsPassed,
85
- this.data.quality.testsPassed
86
- ],
87
- style: { line: "green" }
88
- },
89
- {
90
- title: "Coverage %",
91
- x: ["1", "2", "3", "4", "5"],
92
- y: [
93
- this.data.quality.coverage,
94
- this.data.quality.coverage,
95
- this.data.quality.coverage,
96
- this.data.quality.coverage,
97
- this.data.quality.coverage
98
- ],
99
- style: { line: "blue" }
100
- }
101
- ];
102
- this.line.setData(data);
103
- if (typeof this.line.setLabel === "function") {
104
- this.line.setLabel(" \u{1F4C8} Analytics - Code Quality [m] cycle ");
105
- }
106
- this.line.screen.render();
107
- }
108
- showPerformance() {
109
- if (!this.data) return;
110
- const data = [
111
- {
112
- title: "Response Time (ms)",
113
- x: this.data.performance.avgResponseTime.map((_, i) => i.toString()),
114
- y: this.data.performance.avgResponseTime,
115
- style: { line: "cyan" }
116
- },
117
- {
118
- title: "Error Rate (%)",
119
- x: this.data.performance.errorRate.map((_, i) => i.toString()),
120
- y: this.data.performance.errorRate.map((r) => r * 100),
121
- style: { line: "red" }
122
- }
123
- ];
124
- this.line.setData(data);
125
- if (typeof this.line.setLabel === "function") {
126
- this.line.setLabel(" \u{1F4C8} Analytics - Performance [m] cycle ");
127
- }
128
- this.line.screen.render();
129
- }
130
- update(data) {
131
- this.data = data;
132
- switch (this.currentMetric) {
133
- case "tokens":
134
- this.showTokenUsage();
135
- break;
136
- case "velocity":
137
- this.showVelocity();
138
- break;
139
- case "quality":
140
- this.showQuality();
141
- break;
142
- case "performance":
143
- this.showPerformance();
144
- break;
145
- }
146
- }
147
- focus() {
148
- this.emit("focused");
149
- }
150
- hasFocus() {
151
- return false;
152
- }
153
- }
154
- export {
155
- AnalyticsPanel
156
- };
157
- //# sourceMappingURL=analytics-panel.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../src/features/tui/components/analytics-panel.ts"],
4
- "sourcesContent": ["/**\n * Analytics Panel Component\n * Real-time charts and metrics visualization\n */\n\nimport contrib from 'blessed-contrib';\nimport { EventEmitter } from 'events';\nimport type { AnalyticsData } from '../types.js';\n\nexport class AnalyticsPanel extends EventEmitter {\n private line: any; // contrib.line type\n private currentMetric: 'tokens' | 'velocity' | 'quality' | 'performance' =\n 'tokens';\n private data: AnalyticsData | null = null;\n\n constructor(line: any) {\n super();\n this.line = line;\n this.initializeUI();\n }\n\n private initializeUI(): void {\n // Cycle through metrics\n this.line.screen.key(['m'], () => {\n this.cycleMetric();\n });\n\n // Set initial display\n this.showTokenUsage();\n }\n\n private cycleMetric(): void {\n const metrics: Array<typeof this.currentMetric> = [\n 'tokens',\n 'velocity',\n 'quality',\n 'performance',\n ];\n const currentIndex = metrics.indexOf(this.currentMetric);\n this.currentMetric = metrics[(currentIndex + 1) % metrics.length];\n\n switch (this.currentMetric) {\n case 'tokens':\n this.showTokenUsage();\n break;\n case 'velocity':\n this.showVelocity();\n break;\n case 'quality':\n this.showQuality();\n break;\n case 'performance':\n this.showPerformance();\n break;\n }\n }\n\n private showTokenUsage(): void {\n if (!this.data) return;\n\n const data = [\n {\n title: 'Token Usage',\n x: this.data.tokens.labels.map((_, i) => i.toString()),\n y: this.data.tokens.values,\n style: { line: 'yellow' },\n },\n ];\n\n this.line.setData(data);\n if (typeof this.line.setLabel === 'function') {\n this.line.setLabel(' \uD83D\uDCC8 Analytics - Token Usage [m] cycle ');\n }\n this.line.screen.render();\n }\n\n private showVelocity(): void {\n if (!this.data) return;\n\n const data = [\n {\n title: 'Task Velocity',\n x: this.data.tasks.velocity.map((_, i) => `Sprint ${i + 1}`),\n y: this.data.tasks.velocity,\n style: { line: 'green' },\n },\n ];\n\n this.line.setData(data);\n if (typeof this.line.setLabel === 'function') {\n this.line.setLabel(' \uD83D\uDCC8 Analytics - Task Velocity [m] cycle ');\n }\n this.line.screen.render();\n }\n\n private showQuality(): void {\n if (!this.data) return;\n\n const data = [\n {\n title: 'Tests Passed',\n x: ['1', '2', '3', '4', '5'],\n y: [\n this.data.quality.testsPassed,\n this.data.quality.testsPassed,\n this.data.quality.testsPassed,\n this.data.quality.testsPassed,\n this.data.quality.testsPassed,\n ],\n style: { line: 'green' },\n },\n {\n title: 'Coverage %',\n x: ['1', '2', '3', '4', '5'],\n y: [\n this.data.quality.coverage,\n this.data.quality.coverage,\n this.data.quality.coverage,\n this.data.quality.coverage,\n this.data.quality.coverage,\n ],\n style: { line: 'blue' },\n },\n ];\n\n this.line.setData(data);\n if (typeof this.line.setLabel === 'function') {\n this.line.setLabel(' \uD83D\uDCC8 Analytics - Code Quality [m] cycle ');\n }\n this.line.screen.render();\n }\n\n private showPerformance(): void {\n if (!this.data) return;\n\n const data = [\n {\n title: 'Response Time (ms)',\n x: this.data.performance.avgResponseTime.map((_, i) => i.toString()),\n y: this.data.performance.avgResponseTime,\n style: { line: 'cyan' },\n },\n {\n title: 'Error Rate (%)',\n x: this.data.performance.errorRate.map((_, i) => i.toString()),\n y: this.data.performance.errorRate.map((r: any) => r * 100),\n style: { line: 'red' },\n },\n ];\n\n this.line.setData(data);\n if (typeof this.line.setLabel === 'function') {\n this.line.setLabel(' \uD83D\uDCC8 Analytics - Performance [m] cycle ');\n }\n this.line.screen.render();\n }\n\n public update(data: AnalyticsData): void {\n this.data = data;\n\n // Refresh current view\n switch (this.currentMetric) {\n case 'tokens':\n this.showTokenUsage();\n break;\n case 'velocity':\n this.showVelocity();\n break;\n case 'quality':\n this.showQuality();\n break;\n case 'performance':\n this.showPerformance();\n break;\n }\n }\n\n public focus(): void {\n // Line chart doesn't have traditional focus\n this.emit('focused');\n }\n\n public hasFocus(): boolean {\n return false; // Line charts don't take focus\n }\n}\n"],
5
- "mappings": "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",
6
- "names": []
7
- }