@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,201 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Delete duplicate STA tasks from Linear using OAuth token
5
+ */
6
+
7
+ import 'dotenv/config';
8
+ import fs from 'fs';
9
+ import readline from 'readline';
10
+
11
+ // Load OAuth token from environment
12
+ const API_KEY = process.env.LINEAR_OAUTH_TOKEN || process.env.LINEAR_API_KEY;
13
+ if (!API_KEY) {
14
+ console.error('āŒ LINEAR_OAUTH_TOKEN or LINEAR_API_KEY environment variable not set');
15
+ console.log('Please set LINEAR_OAUTH_TOKEN or LINEAR_API_KEY in your .env file or export it in your shell');
16
+ process.exit(1);
17
+ }
18
+ const BATCH_SIZE = 10;
19
+ const DELAY_BETWEEN_BATCHES = 3000;
20
+
21
+ const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));
22
+
23
+ async function deleteSTATasks() {
24
+ try {
25
+ // Load deletion list
26
+ const deleteFile = `sta-deletion-list-${new Date().toISOString().split('T')[0]}.json`;
27
+ if (!fs.existsSync(deleteFile)) {
28
+ console.error(`āŒ Deletion list not found: ${deleteFile}`);
29
+ console.log('Run analyze-sta-graphql.js first to generate the list.');
30
+ process.exit(1);
31
+ }
32
+
33
+ const deleteList = JSON.parse(fs.readFileSync(deleteFile, 'utf8'));
34
+
35
+ console.log('šŸ“‹ STA TASK DELETION SUMMARY (Using OAuth Token)');
36
+ console.log('=' .repeat(60));
37
+ console.log(`\n Total workspace tasks: ${deleteList.summary.totalWorkspace}`);
38
+ console.log(` Current STA tasks: ${deleteList.summary.totalSTA}`);
39
+ console.log(` Tasks to delete: ${deleteList.summary.toDelete}`);
40
+ console.log(` Workspace after deletion: ${deleteList.summary.remainingTotal}`);
41
+ console.log(`\n šŸŽÆ Capacity to be freed: ${deleteList.summary.capacityFreed} task slots\n`);
42
+
43
+ // Show breakdown
44
+ console.log('šŸ“ Tasks to delete by category:');
45
+ Object.entries(deleteList.categories).forEach(([category, tasks]) => {
46
+ if (tasks.length > 0) {
47
+ console.log(` • ${category}: ${tasks.length} tasks`);
48
+ }
49
+ });
50
+
51
+ // Safety confirmation
52
+ console.log('\nāš ļø WARNING: This will permanently delete ' + deleteList.summary.toDelete + ' tasks from Linear!');
53
+ console.log('This action cannot be undone. Make sure you have reviewed the list.\n');
54
+ console.log('Type "DELETE STA TASKS" to confirm, or press Ctrl+C to cancel:\n');
55
+
56
+ const rl = readline.createInterface({
57
+ input: process.stdin,
58
+ output: process.stdout
59
+ });
60
+
61
+ const confirmation = await new Promise(resolve => {
62
+ rl.question('Confirmation: ', resolve);
63
+ });
64
+ rl.close();
65
+
66
+ if (confirmation !== 'DELETE STA TASKS') {
67
+ console.log('āŒ Deletion cancelled');
68
+ process.exit(0);
69
+ }
70
+
71
+ console.log('\nšŸ—‘ļø Starting deletion process with OAuth token...');
72
+ console.log(`Will delete in batches of ${BATCH_SIZE} with ${DELAY_BETWEEN_BATCHES/1000}s delay\n`);
73
+
74
+ let deleted = 0;
75
+ let failed = 0;
76
+ let alreadyDeleted = 0;
77
+ const results = [];
78
+ const errors = [];
79
+
80
+ // Process in batches
81
+ for (let i = 0; i < deleteList.tasks.length; i += BATCH_SIZE) {
82
+ const batch = deleteList.tasks.slice(i, i + BATCH_SIZE);
83
+ console.log(`\nšŸ“¦ Batch ${Math.floor(i/BATCH_SIZE) + 1}/${Math.ceil(deleteList.tasks.length/BATCH_SIZE)}`);
84
+
85
+ for (const task of batch) {
86
+ try {
87
+ process.stdout.write(` Deleting ${task.identifier}: ${task.title.substring(0, 40)}... `);
88
+
89
+ const deleteQuery = `
90
+ mutation DeleteIssue($id: String!) {
91
+ issueDelete(id: $id) {
92
+ success
93
+ }
94
+ }
95
+ `;
96
+
97
+ const response = await fetch('https://api.linear.app/graphql', {
98
+ method: 'POST',
99
+ headers: {
100
+ 'Authorization': `Bearer ${API_KEY}`,
101
+ 'Content-Type': 'application/json'
102
+ },
103
+ body: JSON.stringify({
104
+ query: deleteQuery,
105
+ variables: { id: task.id }
106
+ })
107
+ });
108
+
109
+ const result = await response.json();
110
+
111
+ if (result.data?.issueDelete?.success) {
112
+ console.log('āœ…');
113
+ deleted++;
114
+ results.push({ ...task, status: 'deleted' });
115
+ } else if (result.errors?.[0]?.message?.includes('not found')) {
116
+ console.log('āš ļø (already gone)');
117
+ alreadyDeleted++;
118
+ results.push({ ...task, status: 'already_deleted' });
119
+ } else {
120
+ const error = result.errors?.[0]?.message || 'Unknown error';
121
+ console.log(`āŒ (${error})`);
122
+ failed++;
123
+ errors.push({ ...task, error });
124
+ results.push({ ...task, status: 'failed', error });
125
+ }
126
+
127
+ } catch (error) {
128
+ console.log(`āŒ (${error.message})`);
129
+ failed++;
130
+ errors.push({ ...task, error: error.message });
131
+ results.push({ ...task, status: 'error', error: error.message });
132
+
133
+ // If rate limited, wait longer
134
+ if (error.message?.includes('rate') || error.message?.includes('429')) {
135
+ console.log('ā³ Rate limited. Waiting 30 seconds...');
136
+ await delay(30000);
137
+ }
138
+ }
139
+ }
140
+
141
+ // Progress update
142
+ const total = deleted + alreadyDeleted + failed;
143
+ const percent = Math.round((total / deleteList.tasks.length) * 100);
144
+ console.log(`\nšŸ“Š Progress: ${total}/${deleteList.tasks.length} (${percent}%)`);
145
+ console.log(` āœ… Deleted: ${deleted} | āš ļø Already gone: ${alreadyDeleted} | āŒ Failed: ${failed}`);
146
+
147
+ // Delay before next batch
148
+ if (i + BATCH_SIZE < deleteList.tasks.length) {
149
+ console.log(`ā³ Waiting ${DELAY_BETWEEN_BATCHES/1000}s before next batch...`);
150
+ await delay(DELAY_BETWEEN_BATCHES);
151
+ }
152
+ }
153
+
154
+ // Save results
155
+ const resultsFile = `sta-deletion-results-oauth-${new Date().toISOString().split('T')[0]}.json`;
156
+ fs.writeFileSync(resultsFile, JSON.stringify({
157
+ summary: {
158
+ attempted: deleteList.tasks.length,
159
+ deleted,
160
+ alreadyDeleted,
161
+ failed,
162
+ success_rate: Math.round(((deleted + alreadyDeleted) / deleteList.tasks.length) * 100)
163
+ },
164
+ results,
165
+ errors: errors.length > 0 ? errors : undefined,
166
+ timestamp: new Date().toISOString()
167
+ }, null, 2));
168
+
169
+ // Final report
170
+ console.log('\n' + '='.repeat(60));
171
+ console.log('šŸ“Š DELETION COMPLETE');
172
+ console.log('='.repeat(60));
173
+ console.log(`\nāœ… Successfully deleted: ${deleted} tasks`);
174
+ console.log(`āš ļø Already deleted: ${alreadyDeleted} tasks`);
175
+ console.log(`āŒ Failed: ${failed} tasks`);
176
+ console.log(`šŸ“ˆ Success rate: ${Math.round(((deleted + alreadyDeleted) / deleteList.tasks.length) * 100)}%`);
177
+ console.log(`\nšŸ’¾ Results saved to: ${resultsFile}`);
178
+
179
+ const totalFreed = deleted + alreadyDeleted;
180
+ if (totalFreed > 0) {
181
+ console.log(`\nšŸŽ‰ Freed up ${totalFreed} task slots in your Linear workspace!`);
182
+ console.log('\nYour workspace now has capacity for new tasks.');
183
+ console.log('The backlog has been cleaned of duplicates and similar tasks.');
184
+ }
185
+
186
+ if (failed > 0) {
187
+ console.log(`\nāš ļø ${failed} tasks could not be deleted. Check ${resultsFile} for details.`);
188
+ }
189
+
190
+ } catch (error) {
191
+ console.error('\nšŸ’„ Script failed:', error.message);
192
+ process.exit(1);
193
+ }
194
+ }
195
+
196
+ // Run if called directly
197
+ if (import.meta.url === `file://${process.argv[1]}`) {
198
+ deleteSTATasks().catch(console.error);
199
+ }
200
+
201
+ export { deleteSTATasks };
@@ -0,0 +1,62 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Export STA- tasks to JSON for manual import
5
+ */
6
+
7
+ import { LinearRestClient } from '../dist/integrations/linear/rest-client.js';
8
+ import fs from 'fs';
9
+
10
+ async function exportSTATasks() {
11
+ try {
12
+ console.log('šŸ”„ Exporting STA- tasks...');
13
+
14
+ const client = new LinearRestClient(process.env.LINEAR_API_KEY);
15
+ const allTasks = await client.getAllTasks(true);
16
+
17
+ // Filter STA- tasks
18
+ const staTasks = allTasks.filter(task => task.identifier.startsWith('STA-'));
19
+
20
+ // Export data
21
+ const exportData = {
22
+ exported: new Date().toISOString(),
23
+ source: 'LiftCL-Stackmemoryai',
24
+ taskCount: staTasks.length,
25
+ tasks: staTasks.map(task => ({
26
+ identifier: task.identifier,
27
+ title: task.title,
28
+ description: task.description || '',
29
+ state: task.state.name,
30
+ priority: task.priority || 0,
31
+ assignee: task.assignee?.name || null,
32
+ estimate: task.estimate || null,
33
+ createdAt: task.createdAt,
34
+ updatedAt: task.updatedAt,
35
+ url: task.url
36
+ }))
37
+ };
38
+
39
+ // Write to file
40
+ const filename = `sta-tasks-export-${new Date().toISOString().split('T')[0]}.json`;
41
+ fs.writeFileSync(filename, JSON.stringify(exportData, null, 2));
42
+
43
+ console.log(`āœ… Exported ${staTasks.length} STA- tasks to ${filename}`);
44
+ console.log('šŸ“‹ Summary by state:');
45
+
46
+ const stateCounts = {};
47
+ staTasks.forEach(task => {
48
+ const state = task.state.type;
49
+ stateCounts[state] = (stateCounts[state] || 0) + 1;
50
+ });
51
+
52
+ Object.entries(stateCounts).forEach(([state, count]) => {
53
+ console.log(` ${state}: ${count}`);
54
+ });
55
+
56
+ } catch (error) {
57
+ console.error('āŒ Export failed:', error.message);
58
+ process.exit(1);
59
+ }
60
+ }
61
+
62
+ exportSTATasks();
@@ -0,0 +1,266 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Install StackMemory Linear Auto-Sync as a system service
4
+ */
5
+
6
+ import { execSync } from 'child_process';
7
+ import { writeFileSync, existsSync, mkdirSync } from 'fs';
8
+ import { join, dirname } from 'path';
9
+ import { fileURLToPath } from 'url';
10
+ import os from 'os';
11
+
12
+ const __filename = fileURLToPath(import.meta.url);
13
+ const __dirname = dirname(__filename);
14
+ const projectRoot = join(__dirname, '..');
15
+
16
+ function detectPlatform() {
17
+ const platform = os.platform();
18
+ if (platform === 'darwin') return 'macos';
19
+ if (platform === 'linux') return 'linux';
20
+ if (platform === 'win32') return 'windows';
21
+ throw new Error(`Unsupported platform: ${platform}`);
22
+ }
23
+
24
+ function installMacOS() {
25
+ const homeDir = os.homedir();
26
+ const launchAgentDir = join(homeDir, 'Library', 'LaunchAgents');
27
+
28
+ if (!existsSync(launchAgentDir)) {
29
+ mkdirSync(launchAgentDir, { recursive: true });
30
+ }
31
+
32
+ const plistPath = join(launchAgentDir, 'ai.stackmemory.linear-sync.plist');
33
+ const stackmemoryBin = join(projectRoot, 'dist', 'src', 'cli', 'cli.js');
34
+
35
+ const plistContent = `<?xml version="1.0" encoding="UTF-8"?>
36
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
37
+ <plist version="1.0">
38
+ <dict>
39
+ <key>Label</key>
40
+ <string>ai.stackmemory.linear-sync</string>
41
+
42
+ <key>ProgramArguments</key>
43
+ <array>
44
+ <string>node</string>
45
+ <string>${stackmemoryBin}</string>
46
+ <string>linear</string>
47
+ <string>auto-sync</string>
48
+ <string>--start</string>
49
+ <string>--interval</string>
50
+ <string>5</string>
51
+ </array>
52
+
53
+ <key>WorkingDirectory</key>
54
+ <string>${homeDir}</string>
55
+
56
+ <key>StandardOutPath</key>
57
+ <string>${homeDir}/.stackmemory/logs/linear-sync.log</string>
58
+
59
+ <key>StandardErrorPath</key>
60
+ <string>${homeDir}/.stackmemory/logs/linear-sync-error.log</string>
61
+
62
+ <key>RunAtLoad</key>
63
+ <true/>
64
+
65
+ <key>KeepAlive</key>
66
+ <dict>
67
+ <key>SuccessfulExit</key>
68
+ <false/>
69
+ </dict>
70
+
71
+ <key>StartInterval</key>
72
+ <integer>300</integer>
73
+
74
+ <key>EnvironmentVariables</key>
75
+ <dict>
76
+ <key>PATH</key>
77
+ <string>/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
78
+ <key>NODE_ENV</key>
79
+ <string>production</string>
80
+ </dict>
81
+ </dict>
82
+ </plist>`;
83
+
84
+ writeFileSync(plistPath, plistContent);
85
+
86
+ // Create log directory
87
+ const logDir = join(homeDir, '.stackmemory', 'logs');
88
+ if (!existsSync(logDir)) {
89
+ mkdirSync(logDir, { recursive: true });
90
+ }
91
+
92
+ try {
93
+ execSync(`launchctl load ${plistPath}`);
94
+ console.log('āœ… macOS LaunchAgent installed and started');
95
+ console.log(`šŸ“„ Configuration: ${plistPath}`);
96
+ console.log(`šŸ“ Logs: ${logDir}/linear-sync.log`);
97
+ console.log('\nšŸ’” Management commands:');
98
+ console.log(` Start: launchctl load ${plistPath}`);
99
+ console.log(` Stop: launchctl unload ${plistPath}`);
100
+ console.log(` Status: launchctl list | grep stackmemory`);
101
+ } catch (error) {
102
+ console.error('āŒ Failed to load LaunchAgent:', error.message);
103
+ console.log(`šŸ“„ Configuration saved to: ${plistPath}`);
104
+ console.log('šŸ’” To start manually: launchctl load ${plistPath}');
105
+ }
106
+ }
107
+
108
+ function installLinux() {
109
+ const serviceContent = `[Unit]
110
+ Description=StackMemory Linear Auto-Sync
111
+ After=network.target
112
+
113
+ [Service]
114
+ Type=simple
115
+ User=${os.userInfo().username}
116
+ WorkingDirectory=${os.homedir()}
117
+ ExecStart=node ${join(projectRoot, 'dist', 'src', 'cli', 'cli.js')} linear auto-sync --start --interval 5
118
+ Restart=always
119
+ RestartSec=10
120
+ StandardOutput=append:${os.homedir()}/.stackmemory/logs/linear-sync.log
121
+ StandardError=append:${os.homedir()}/.stackmemory/logs/linear-sync-error.log
122
+ Environment=NODE_ENV=production
123
+ Environment=PATH=/usr/local/bin:/usr/bin:/bin
124
+
125
+ [Install]
126
+ WantedBy=default.target`;
127
+
128
+ const serviceDir = join(os.homedir(), '.config', 'systemd', 'user');
129
+ if (!existsSync(serviceDir)) {
130
+ mkdirSync(serviceDir, { recursive: true });
131
+ }
132
+
133
+ const servicePath = join(serviceDir, 'stackmemory-linear-sync.service');
134
+ writeFileSync(servicePath, serviceContent);
135
+
136
+ // Create log directory
137
+ const logDir = join(os.homedir(), '.stackmemory', 'logs');
138
+ if (!existsSync(logDir)) {
139
+ mkdirSync(logDir, { recursive: true });
140
+ }
141
+
142
+ try {
143
+ execSync('systemctl --user daemon-reload');
144
+ execSync('systemctl --user enable stackmemory-linear-sync.service');
145
+ execSync('systemctl --user start stackmemory-linear-sync.service');
146
+
147
+ console.log('āœ… Linux systemd service installed and started');
148
+ console.log(`šŸ“„ Configuration: ${servicePath}`);
149
+ console.log(`šŸ“ Logs: ${logDir}/linear-sync.log`);
150
+ console.log('\nšŸ’” Management commands:');
151
+ console.log(' Start: systemctl --user start stackmemory-linear-sync');
152
+ console.log(' Stop: systemctl --user stop stackmemory-linear-sync');
153
+ console.log(' Status: systemctl --user status stackmemory-linear-sync');
154
+ console.log(' Logs: journalctl --user -u stackmemory-linear-sync -f');
155
+ } catch (error) {
156
+ console.error('āŒ Failed to start systemd service:', error.message);
157
+ console.log(`šŸ“„ Configuration saved to: ${servicePath}`);
158
+ console.log('šŸ’” To start manually:');
159
+ console.log(' systemctl --user daemon-reload');
160
+ console.log(' systemctl --user enable stackmemory-linear-sync');
161
+ console.log(' systemctl --user start stackmemory-linear-sync');
162
+ }
163
+ }
164
+
165
+ function installWindows() {
166
+ const taskXml = `<?xml version="1.0" encoding="UTF-16"?>
167
+ <Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
168
+ <RegistrationInfo>
169
+ <Date>2024-01-01T00:00:00</Date>
170
+ <Author>StackMemory</Author>
171
+ <Description>StackMemory Linear Auto-Sync Service</Description>
172
+ </RegistrationInfo>
173
+ <Triggers>
174
+ <CalendarTrigger>
175
+ <StartBoundary>1999-01-01T00:00:00</StartBoundary>
176
+ <Enabled>true</Enabled>
177
+ <ScheduleByDay>
178
+ <DaysInterval>1</DaysInterval>
179
+ </ScheduleByDay>
180
+ <Repetition>
181
+ <Interval>PT5M</Interval>
182
+ <StopAtDurationEnd>false</StopAtDurationEnd>
183
+ </Repetition>
184
+ </CalendarTrigger>
185
+ </Triggers>
186
+ <Settings>
187
+ <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
188
+ <DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
189
+ <StopIfGoingOnBatteries>false</StopIfGoingOnBatteries>
190
+ <AllowHardTerminate>true</AllowHardTerminate>
191
+ <StartWhenAvailable>false</StartWhenAvailable>
192
+ <RunOnlyIfNetworkAvailable>true</RunOnlyIfNetworkAvailable>
193
+ <AllowStartOnDemand>true</AllowStartOnDemand>
194
+ <Enabled>true</Enabled>
195
+ <Hidden>false</Hidden>
196
+ <RunOnlyIfIdle>false</RunOnlyIfIdle>
197
+ <WakeToRun>false</WakeToRun>
198
+ <ExecutionTimeLimit>PT0S</ExecutionTimeLimit>
199
+ <Priority>7</Priority>
200
+ </Settings>
201
+ <Actions>
202
+ <Exec>
203
+ <Command>node</Command>
204
+ <Arguments>"${join(projectRoot, 'dist', 'src', 'cli', 'cli.js').replace(/\\/g, '\\\\')}" linear auto-sync --start --interval 5</Arguments>
205
+ <WorkingDirectory>${os.homedir().replace(/\\/g, '\\\\')}</WorkingDirectory>
206
+ </Exec>
207
+ </Actions>
208
+ </Task>`;
209
+
210
+ const taskFile = join(os.tmpdir(), 'stackmemory-linear-sync.xml');
211
+ writeFileSync(taskFile, taskXml);
212
+
213
+ try {
214
+ execSync(
215
+ `schtasks /create /tn "StackMemory Linear Sync" /xml "${taskFile}"`
216
+ );
217
+ console.log('āœ… Windows Task Scheduler task created');
218
+ console.log('\nšŸ’” Management commands:');
219
+ console.log(' Start: schtasks /run /tn "StackMemory Linear Sync"');
220
+ console.log(' Stop: schtasks /end /tn "StackMemory Linear Sync"');
221
+ console.log(' Status: schtasks /query /tn "StackMemory Linear Sync"');
222
+ console.log(' Delete: schtasks /delete /tn "StackMemory Linear Sync"');
223
+ } catch (error) {
224
+ console.error('āŒ Failed to create scheduled task:', error.message);
225
+ console.log(`šŸ“„ Task XML saved to: ${taskFile}`);
226
+ console.log('šŸ’” Import manually through Task Scheduler');
227
+ }
228
+ }
229
+
230
+ function main() {
231
+ console.log('šŸ”§ Installing StackMemory Linear Auto-Sync Service\n');
232
+
233
+ const platform = detectPlatform();
234
+ console.log(`šŸ–„ļø Detected platform: ${platform}`);
235
+
236
+ // Check if StackMemory is built
237
+ const builtCli = join(projectRoot, 'dist', 'src', 'cli', 'cli.js');
238
+ if (!existsSync(builtCli)) {
239
+ console.error('āŒ StackMemory not built. Run "npm run build" first.');
240
+ process.exit(1);
241
+ }
242
+
243
+ switch (platform) {
244
+ case 'macos':
245
+ installMacOS();
246
+ break;
247
+ case 'linux':
248
+ installLinux();
249
+ break;
250
+ case 'windows':
251
+ installWindows();
252
+ break;
253
+ default:
254
+ throw new Error(`Unsupported platform: ${platform}`);
255
+ }
256
+
257
+ console.log('\nšŸŽ‰ Installation complete!');
258
+ console.log('\nšŸ“‹ Next steps:');
259
+ console.log('1. Configure Linear integration: stackmemory linear setup');
260
+ console.log('2. Authorize with Linear: stackmemory linear authorize <code>');
261
+ console.log('3. Check service status with platform commands above');
262
+ }
263
+
264
+ if (import.meta.url === `file://${process.argv[1]}`) {
265
+ main();
266
+ }
@@ -0,0 +1,133 @@
1
+ #!/bin/bash
2
+
3
+ # Install ChromaDB hooks for Claude
4
+ # This script sets up automatic context saving and loading
5
+
6
+ set -e
7
+
8
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
9
+ PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
10
+ CLAUDE_DIR="$PROJECT_ROOT/.claude"
11
+ HOOKS_DIR="$CLAUDE_DIR/hooks"
12
+ LOG_DIR="$HOME/.stackmemory/logs"
13
+
14
+ echo "šŸ”§ Installing ChromaDB hooks for Claude..."
15
+
16
+ # Create directories
17
+ mkdir -p "$HOOKS_DIR"
18
+ mkdir -p "$LOG_DIR"
19
+
20
+ # Make hooks executable
21
+ chmod +x "$HOOKS_DIR"/*.js 2>/dev/null || true
22
+
23
+ # Check for ChromaDB API key
24
+ if [ -z "$CHROMADB_API_KEY" ]; then
25
+ echo "āš ļø CHROMADB_API_KEY not found in environment"
26
+ echo " Add to .env: CHROMADB_API_KEY=your_key_here"
27
+ else
28
+ echo "āœ… ChromaDB API key found"
29
+ fi
30
+
31
+ # Test ChromaDB connection
32
+ echo "šŸ”„ Testing ChromaDB connection..."
33
+ if node -e "
34
+ const { ChromaDBAdapter } = require('$PROJECT_ROOT/dist/core/storage/chromadb-adapter.js');
35
+ const adapter = new ChromaDBAdapter({
36
+ apiKey: process.env.CHROMADB_API_KEY,
37
+ apiUrl: process.env.CHROMADB_API_URL || 'http://localhost:8000',
38
+ collectionName: 'claude_context',
39
+ userId: process.env.USER || 'default'
40
+ });
41
+ adapter.initialize().then(() => {
42
+ console.log('āœ… ChromaDB connection successful');
43
+ process.exit(0);
44
+ }).catch(err => {
45
+ console.error('āŒ ChromaDB connection failed:', err.message);
46
+ process.exit(1);
47
+ });
48
+ " 2>/dev/null; then
49
+ echo "āœ… ChromaDB is accessible"
50
+ else
51
+ echo "āš ļø ChromaDB connection failed - hooks will be installed but may not work"
52
+ fi
53
+
54
+ # Create a launcher script
55
+ cat > "$PROJECT_ROOT/claude-with-chromadb.sh" << 'EOF'
56
+ #!/bin/bash
57
+
58
+ # Launch Claude with ChromaDB hooks enabled
59
+ PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
60
+
61
+ # Load environment
62
+ if [ -f "$PROJECT_ROOT/.env" ]; then
63
+ export $(grep -v '^#' "$PROJECT_ROOT/.env" | xargs)
64
+ fi
65
+
66
+ # Run startup hook to load context
67
+ echo "Loading context from ChromaDB..."
68
+ node "$PROJECT_ROOT/.claude/hooks/on-startup.js"
69
+
70
+ # Start periodic save in background
71
+ (
72
+ while true; do
73
+ sleep 900 # 15 minutes
74
+ node "$PROJECT_ROOT/.claude/hooks/periodic-save.js" 2>/dev/null
75
+ done
76
+ ) &
77
+ PERIODIC_PID=$!
78
+
79
+ # Cleanup function
80
+ cleanup() {
81
+ echo "Saving final context..."
82
+ node "$PROJECT_ROOT/.claude/hooks/chromadb-save-hook.js" << JSON
83
+ {
84
+ "event": "session_end",
85
+ "data": {
86
+ "summary": "Claude session ended",
87
+ "duration": "$SECONDS seconds"
88
+ }
89
+ }
90
+ JSON
91
+ kill $PERIODIC_PID 2>/dev/null
92
+ exit
93
+ }
94
+
95
+ trap cleanup EXIT INT TERM
96
+
97
+ echo "✨ Claude with ChromaDB hooks is ready!"
98
+ echo " - Context loaded from last 24 hours"
99
+ echo " - Periodic saves every 15 minutes"
100
+ echo " - Linear task updates enabled"
101
+ echo ""
102
+ echo "Press Ctrl+C to exit and save context"
103
+
104
+ # Keep running
105
+ wait
106
+ EOF
107
+
108
+ chmod +x "$PROJECT_ROOT/claude-with-chromadb.sh"
109
+
110
+ # Summary
111
+ echo ""
112
+ echo "āœ… ChromaDB hooks installed successfully!"
113
+ echo ""
114
+ echo "šŸ“‹ Installed hooks:"
115
+ echo " - on-startup.js: Loads context on Claude startup"
116
+ echo " - on-code-change.js: Saves when code is modified"
117
+ echo " - on-task-complete.js: Saves and updates Linear on task completion"
118
+ echo " - periodic-save.js: Auto-saves every 15 minutes"
119
+ echo " - chromadb-save-hook.js: Core context saving logic"
120
+ echo " - linear-update-hook.js: Auto-updates Linear tasks"
121
+ echo ""
122
+ echo "šŸš€ To use:"
123
+ echo " 1. Ensure CHROMADB_API_KEY is in .env"
124
+ echo " 2. Run: ./claude-with-chromadb.sh"
125
+ echo " 3. Or hooks will activate automatically in Claude"
126
+ echo ""
127
+ echo "šŸ“Š ChromaDB will save context on:"
128
+ echo " - Session start (loads last 24h)"
129
+ echo " - Every 15 minutes"
130
+ echo " - Task completions"
131
+ echo " - Code changes"
132
+ echo " - Git commits"
133
+ echo " - Session end"