@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,114 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { SharedContextLayer } from './dist/core/context/shared-context-layer.js';
4
+ import { promises as fs } from 'fs';
5
+ import path from 'path';
6
+ import { fileURLToPath } from 'url';
7
+
8
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
9
+
10
+ async function testPersistence() {
11
+ console.log('Testing StackMemory Persistence...\n');
12
+
13
+ try {
14
+ // Initialize shared context layer
15
+ const layer = new SharedContextLayer();
16
+ await layer.initialize();
17
+ console.log('āœ… SharedContextLayer initialized');
18
+
19
+ // Add test context
20
+ const testFrame = {
21
+ type: 'test',
22
+ name: 'Persistence test frame',
23
+ tags: ['test', 'persistence', 'verification'],
24
+ data: {
25
+ timestamp: new Date().toISOString(),
26
+ test_id: `test-${Date.now()}`,
27
+ message: 'This is a test frame to verify persistence'
28
+ }
29
+ };
30
+
31
+ await layer.addToSharedContext(testFrame);
32
+ console.log('āœ… Added test frame to shared context');
33
+
34
+ // Query to verify it's there
35
+ const results = await layer.querySharedContext({ tags: ['test', 'persistence'] });
36
+ console.log(`āœ… Query returned ${results.length} matching frames`);
37
+
38
+ // Get the full context
39
+ const context = await layer.getSharedContext();
40
+ console.log('\nContext Summary:');
41
+ console.log(` Total sessions: ${context.sessions?.length || 0}`);
42
+ console.log(` Global patterns: ${context.globalPatterns?.length || 0}`);
43
+ console.log(` Decision log entries: ${context.decisionLog?.length || 0}`);
44
+ console.log(` Last updated: ${new Date(context.lastUpdated).toLocaleString()}`);
45
+
46
+ // Check persistence file
47
+ const contextPath = path.join(process.env.HOME, '.stackmemory', 'data', 'shared-context.json');
48
+ try {
49
+ const fileContent = await fs.readFile(contextPath, 'utf-8');
50
+ const savedContext = JSON.parse(fileContent);
51
+ console.log(`\nāœ… Persistence file exists at: ${contextPath}`);
52
+ console.log(` File contains ${savedContext.sessions?.length || 0} sessions`);
53
+
54
+ // Find our test frame in the sessions
55
+ let foundFrame = null;
56
+ for (const session of savedContext.sessions || []) {
57
+ const frame = session.keyFrames?.find(f =>
58
+ f.title === 'Persistence test frame' &&
59
+ f.tags?.includes('persistence')
60
+ );
61
+ if (frame) {
62
+ foundFrame = frame;
63
+ break;
64
+ }
65
+ }
66
+
67
+ if (foundFrame) {
68
+ console.log('āœ… Test frame found in persisted data!');
69
+ console.log(' Frame ID:', foundFrame.frameId);
70
+ console.log(' Frame type:', foundFrame.type);
71
+ console.log(' Frame score:', foundFrame.score);
72
+ } else {
73
+ console.log('āš ļø Test frame not found in persisted data');
74
+ console.log(' Current sessions:', savedContext.sessions?.length || 0);
75
+ }
76
+ } catch (err) {
77
+ console.log(`āš ļø Could not read persistence file: ${err.message}`);
78
+ console.log(' Creating new persistence structure...');
79
+ }
80
+
81
+ // Test patterns
82
+ await layer.addToSharedContext({
83
+ type: 'error',
84
+ name: 'Test error frame',
85
+ data: {
86
+ error: 'Test error message',
87
+ resolution: 'Test resolution'
88
+ }
89
+ });
90
+
91
+ const updatedContext = await layer.getSharedContext();
92
+ console.log('\nāœ… Added error frame for pattern detection');
93
+ console.log(` Global patterns now: ${updatedContext.globalPatterns?.length || 0}`);
94
+
95
+ const errorPatterns = updatedContext.globalPatterns?.filter(p => p.type === 'error');
96
+ if (errorPatterns?.length > 0) {
97
+ console.log('āœ… Error pattern detected and stored');
98
+ console.log(` Error patterns: ${errorPatterns.length}`);
99
+ }
100
+
101
+ console.log('\nšŸŽ‰ Persistence test completed successfully!');
102
+ console.log('\nTo verify manually:');
103
+ console.log(` cat ${contextPath} | jq '.sessions | length'`);
104
+ console.log(` cat ${contextPath} | jq '.sessions[-1].keyFrames'`);
105
+ console.log(` cat ${contextPath} | jq '.globalPatterns'`);
106
+
107
+ } catch (error) {
108
+ console.error('āŒ Test failed:', error.message);
109
+ console.error(error.stack);
110
+ process.exit(1);
111
+ }
112
+ }
113
+
114
+ testPersistence().catch(console.error);
@@ -0,0 +1,93 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Test script to validate Pebbles task management through MCP
4
+ * This demonstrates the full task workflow
5
+ */
6
+
7
+ import { spawn } from 'child_process';
8
+
9
+ async function testTaskWorkflow() {
10
+ console.log('šŸš€ Testing StackMemory Pebbles Task Management\n');
11
+
12
+ // Sample tasks for v0.2.0 release
13
+ const tasks = [
14
+ {
15
+ name: 'Linear API Integration',
16
+ description:
17
+ 'Implement bi-directional sync with Linear for team collaboration',
18
+ priority: 'high',
19
+ estimatedEffort: 240, // 4 hours
20
+ tags: ['integration', 'linear', 'team'],
21
+ },
22
+ {
23
+ name: 'Enhanced CLI Commands',
24
+ description: 'Add task management commands to StackMemory CLI',
25
+ priority: 'medium',
26
+ estimatedEffort: 120, // 2 hours
27
+ tags: ['cli', 'ux'],
28
+ },
29
+ {
30
+ name: 'Git Hooks Integration',
31
+ description: 'Automate task state sync with git workflow',
32
+ priority: 'medium',
33
+ estimatedEffort: 90, // 1.5 hours
34
+ tags: ['git', 'automation'],
35
+ },
36
+ {
37
+ name: 'Task Analytics Dashboard',
38
+ description: 'Web UI for task metrics and project insights',
39
+ priority: 'low',
40
+ estimatedEffort: 480, // 8 hours
41
+ tags: ['ui', 'analytics', 'web'],
42
+ },
43
+ {
44
+ name: 'Performance Optimization',
45
+ description: 'Optimize context assembly and JSONL parsing performance',
46
+ priority: 'high',
47
+ estimatedEffort: 180, // 3 hours
48
+ tags: ['performance', 'optimization'],
49
+ },
50
+ ];
51
+
52
+ console.log(
53
+ `šŸ“‹ Creating ${tasks.length} example tasks for StackMemory development...\n`
54
+ );
55
+
56
+ tasks.forEach((task, index) => {
57
+ console.log(`${index + 1}. **${task.name}** (${task.priority})`);
58
+ console.log(` ${task.description}`);
59
+ console.log(
60
+ ` Estimated: ${task.estimatedEffort}m | Tags: ${task.tags.join(', ')}\n`
61
+ );
62
+ });
63
+
64
+ console.log('✨ These tasks demonstrate:');
65
+ console.log('- Git-native JSONL storage (.stackmemory/tasks.jsonl)');
66
+ console.log('- Content-hash task IDs for merge-friendly collaboration');
67
+ console.log('- Priority-based context assembly');
68
+ console.log('- Automatic time tracking');
69
+ console.log('- Dependency management');
70
+ console.log('- Integration readiness for Linear API sync\n');
71
+
72
+ console.log('šŸ”§ To create these tasks with StackMemory MCP:');
73
+ console.log(
74
+ '1. Start frame: start_frame("StackMemory v0.2.0 Development", "task")'
75
+ );
76
+ console.log(
77
+ '2. Create tasks: create_task("Linear API Integration", priority="high", ...)'
78
+ );
79
+ console.log('3. Track progress: update_task_status(taskId, "in_progress")');
80
+ console.log('4. View metrics: get_task_metrics()');
81
+ console.log('5. Check active work: get_active_tasks()');
82
+
83
+ return tasks;
84
+ }
85
+
86
+ // Run the test
87
+ testTaskWorkflow()
88
+ .then((tasks) => {
89
+ console.log(
90
+ `\nāœ… Ready to create ${tasks.length} tasks in StackMemory v0.2.0!`
91
+ );
92
+ })
93
+ .catch(console.error);
@@ -0,0 +1,212 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Update import paths after folder reorganization
5
+ */
6
+
7
+ import { readFileSync, writeFileSync, readdirSync, statSync } from 'fs';
8
+ import { join, relative, dirname } from 'path';
9
+
10
+ const importMappings = {
11
+ // Core mappings
12
+ '../core/frame-manager': '../core/context/frame-manager',
13
+ '../core/project-manager': '../core/projects/project-manager',
14
+ '../core/logger': '../core/monitoring/logger',
15
+ '../core/error-handler': '../core/monitoring/error-handler',
16
+ '../core/progress-tracker': '../core/monitoring/progress-tracker',
17
+ '../core/update-checker': '../core/utils/update-checker',
18
+
19
+ // Features mappings
20
+ '../pebbles/pebbles-task-store': '../features/tasks/task-store',
21
+ '../pebbles/task-aware-context': '../features/tasks/task-context',
22
+ '../analytics/': '../features/analytics/',
23
+ '../integrations/browser-mcp': '../features/browser/browser-mcp',
24
+
25
+ // Integrations mappings
26
+ '../integrations/linear-auth': '../integrations/linear/auth',
27
+ '../integrations/linear-sync': '../integrations/linear/sync',
28
+ '../integrations/linear-client': '../integrations/linear/client',
29
+ '../integrations/linear-config': '../integrations/linear/config',
30
+ '../integrations/linear-auto-sync': '../integrations/linear/auto-sync',
31
+ '../mcp/mcp-server': '../integrations/mcp/server',
32
+
33
+ // CLI mappings
34
+ './cli': './index',
35
+ './project-commands': './commands/projects',
36
+ './analytics-viewer': './utils/viewer',
37
+ '../cli/cli': '../cli/index',
38
+
39
+ // Server mappings
40
+ '../railway/': '../servers/railway/',
41
+ './railway/': './servers/railway/',
42
+ };
43
+
44
+ function updateImportsInFile(filePath) {
45
+ if (!filePath.endsWith('.ts') && !filePath.endsWith('.js')) {
46
+ return false;
47
+ }
48
+
49
+ try {
50
+ let content = readFileSync(filePath, 'utf-8');
51
+ let modified = false;
52
+
53
+ // Update import statements
54
+ for (const [oldPath, newPath] of Object.entries(importMappings)) {
55
+ const importRegex = new RegExp(
56
+ `(import.*from\\s+['"]\\.?)${escapeRegex(oldPath)}(['"])`,
57
+ 'g'
58
+ );
59
+ const newContent = content.replace(importRegex, `$1${newPath}$2`);
60
+
61
+ if (newContent !== content) {
62
+ content = newContent;
63
+ modified = true;
64
+ }
65
+ }
66
+
67
+ // Special case: Update shebang for CLI entry point
68
+ if (filePath.endsWith('src/cli/index.ts')) {
69
+ if (!content.startsWith('#!/usr/bin/env node')) {
70
+ content = '#!/usr/bin/env node\n' + content;
71
+ modified = true;
72
+ }
73
+ }
74
+
75
+ if (modified) {
76
+ writeFileSync(filePath, content);
77
+ console.log(`āœ… Updated: ${relative(process.cwd(), filePath)}`);
78
+ return true;
79
+ }
80
+
81
+ return false;
82
+ } catch (error) {
83
+ console.error(`āŒ Error updating ${filePath}:`, error.message);
84
+ return false;
85
+ }
86
+ }
87
+
88
+ function escapeRegex(string) {
89
+ return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
90
+ }
91
+
92
+ function walkDirectory(dir) {
93
+ const files = [];
94
+
95
+ try {
96
+ const items = readdirSync(dir);
97
+
98
+ for (const item of items) {
99
+ const fullPath = join(dir, item);
100
+ const stat = statSync(fullPath);
101
+
102
+ if (stat.isDirectory()) {
103
+ // Skip node_modules, dist, and .git
104
+ if (
105
+ !item.startsWith('.') &&
106
+ item !== 'node_modules' &&
107
+ item !== 'dist'
108
+ ) {
109
+ files.push(...walkDirectory(fullPath));
110
+ }
111
+ } else if (stat.isFile()) {
112
+ files.push(fullPath);
113
+ }
114
+ }
115
+ } catch (error) {
116
+ console.error(`Error walking directory ${dir}:`, error.message);
117
+ }
118
+
119
+ return files;
120
+ }
121
+
122
+ function updatePackageJson() {
123
+ try {
124
+ const packagePath = join(process.cwd(), 'package.json');
125
+ const pkg = JSON.parse(readFileSync(packagePath, 'utf-8'));
126
+
127
+ // Update bin path
128
+ if (pkg.bin && pkg.bin.stackmemory) {
129
+ pkg.bin.stackmemory = 'dist/src/cli/index.js';
130
+ }
131
+
132
+ // Update main entry
133
+ if (pkg.main) {
134
+ pkg.main = pkg.main.replace('dist/src/index.js', 'dist/src/index.js');
135
+ }
136
+
137
+ // Update scripts
138
+ if (pkg.scripts) {
139
+ // Update MCP server paths
140
+ if (pkg.scripts['mcp:start']) {
141
+ pkg.scripts['mcp:start'] = pkg.scripts['mcp:start'].replace(
142
+ 'dist/src/mcp/mcp-server.js',
143
+ 'dist/src/integrations/mcp/server.js'
144
+ );
145
+ }
146
+ if (pkg.scripts['mcp:local']) {
147
+ pkg.scripts['mcp:local'] = pkg.scripts['mcp:local'].replace(
148
+ 'dist/src/mcp/mcp-server.js',
149
+ 'dist/src/integrations/mcp/server.js'
150
+ );
151
+ }
152
+
153
+ // Update lint fix script
154
+ if (pkg.scripts['lint:autofix']) {
155
+ pkg.scripts['lint:autofix'] = pkg.scripts['lint:autofix'].replace(
156
+ 'scripts/fix-lint-loop.cjs',
157
+ 'scripts/development/fix-lint-loop.cjs'
158
+ );
159
+ }
160
+ }
161
+
162
+ writeFileSync(packagePath, JSON.stringify(pkg, null, 2) + '\n');
163
+ console.log('āœ… Updated package.json');
164
+ } catch (error) {
165
+ console.error('āŒ Error updating package.json:', error.message);
166
+ }
167
+ }
168
+
169
+ function updateTsConfig() {
170
+ try {
171
+ const tsconfigPath = join(process.cwd(), 'tsconfig.json');
172
+ const tsconfig = JSON.parse(readFileSync(tsconfigPath, 'utf-8'));
173
+
174
+ // Update exclude paths if needed
175
+ if (tsconfig.exclude) {
176
+ tsconfig.exclude = tsconfig.exclude
177
+ .map((path) => {
178
+ if (path === 'src/runway.bak') return null;
179
+ if (path === 'src/runway') return null;
180
+ return path;
181
+ })
182
+ .filter(Boolean);
183
+ }
184
+
185
+ writeFileSync(tsconfigPath, JSON.stringify(tsconfig, null, 2) + '\n');
186
+ console.log('āœ… Updated tsconfig.json');
187
+ } catch (error) {
188
+ console.error('āŒ Error updating tsconfig.json:', error.message);
189
+ }
190
+ }
191
+
192
+ // Main execution
193
+ console.log('šŸ”„ Updating import paths after reorganization...\n');
194
+
195
+ const srcFiles = walkDirectory(join(process.cwd(), 'src'));
196
+ const testFiles = walkDirectory(join(process.cwd(), 'tests'));
197
+ const scriptFiles = walkDirectory(join(process.cwd(), 'scripts'));
198
+
199
+ let updatedCount = 0;
200
+
201
+ for (const file of [...srcFiles, ...testFiles, ...scriptFiles]) {
202
+ if (updateImportsInFile(file)) {
203
+ updatedCount++;
204
+ }
205
+ }
206
+
207
+ // Update configuration files
208
+ updatePackageJson();
209
+ updateTsConfig();
210
+
211
+ console.log(`\nāœ… Updated ${updatedCount} files`);
212
+ console.log('šŸ“¦ Run "npm run build" to verify all imports are correct');
@@ -0,0 +1,125 @@
1
+ #!/usr/bin/env node
2
+ import 'dotenv/config';
3
+ import { LinearClient } from '@linear/sdk';
4
+
5
+ const API_KEY = process.env.LINEAR_API_KEY;
6
+
7
+ if (!API_KEY) {
8
+ console.error('āŒ LINEAR_API_KEY not found in environment');
9
+ process.exit(1);
10
+ }
11
+
12
+ async function fetchLinearTasks() {
13
+ const client = new LinearClient({ apiKey: API_KEY });
14
+
15
+ try {
16
+ const me = await client.viewer;
17
+ console.log(`\nšŸ‘¤ Connected as: ${me.name || me.email}\n`);
18
+
19
+ // Get teams
20
+ const teams = await client.teams();
21
+ console.log(`šŸ“‹ Teams: ${teams.nodes.map(t => t.key).join(', ')}\n`);
22
+
23
+ // Fetch all issues
24
+ const issues = await client.issues({
25
+ filter: {
26
+ state: {
27
+ name: { nin: ["Done", "Canceled"] }
28
+ }
29
+ },
30
+ orderBy: "priority"
31
+ });
32
+
33
+ // Group by state
34
+ const byState = {};
35
+ for (const issue of issues.nodes) {
36
+ const state = issue.state?.name || 'Unknown';
37
+ if (!byState[state]) byState[state] = [];
38
+ byState[state].push(issue);
39
+ }
40
+
41
+ // Display by state
42
+ const stateOrder = ['In Progress', 'Todo', 'Triage', 'Backlog', 'Unknown'];
43
+
44
+ for (const state of stateOrder) {
45
+ if (byState[state] && byState[state].length > 0) {
46
+ console.log(`šŸ“Š ${state.toUpperCase()} (${byState[state].length}):`);
47
+
48
+ // Show top 10 from each state
49
+ const topIssues = byState[state].slice(0, 10);
50
+ for (const issue of topIssues) {
51
+ const priority = issue.priority ? `[P${issue.priority}]` : '';
52
+ const assignee = issue.assignee ? `@${issue.assignee.name}` : '[Unassigned]';
53
+ const labels = issue.labels ? (await issue.labels()).nodes.map(l => l.name).join(', ') : '';
54
+ const labelStr = labels ? ` šŸ·ļø ${labels}` : '';
55
+
56
+ console.log(` • ${issue.identifier}: ${issue.title} ${priority} ${assignee}${labelStr}`);
57
+ }
58
+
59
+ if (byState[state].length > 10) {
60
+ console.log(` ... and ${byState[state].length - 10} more`);
61
+ }
62
+ console.log('');
63
+ }
64
+ }
65
+
66
+ // Summary stats
67
+ const total = issues.nodes.length;
68
+ const inProgress = byState['In Progress']?.length || 0;
69
+ const todo = byState['Todo']?.length || 0;
70
+ const triage = byState['Triage']?.length || 0;
71
+
72
+ console.log('šŸ“ˆ SUMMARY:');
73
+ console.log(` Total active issues: ${total}`);
74
+ console.log(` In Progress: ${inProgress}`);
75
+ console.log(` Todo: ${todo}`);
76
+ console.log(` Triage: ${triage}`);
77
+
78
+ // High priority items
79
+ console.log('\nšŸ”„ HIGH PRIORITY ITEMS:');
80
+ const highPriority = issues.nodes
81
+ .filter(i => i.priority && i.priority <= 2)
82
+ .slice(0, 5);
83
+
84
+ for (const issue of highPriority) {
85
+ const state = issue.state?.name || 'Unknown';
86
+ const assignee = issue.assignee ? `@${issue.assignee.name}` : '[Unassigned]';
87
+ console.log(` • ${issue.identifier}: ${issue.title} [${state}] ${assignee}`);
88
+ }
89
+
90
+ // Suggested next tasks
91
+ console.log('\nšŸ’” SUGGESTED NEXT TASKS:');
92
+ console.log('Based on priority and status, consider working on:');
93
+
94
+ // Find unassigned high priority or in-progress items
95
+ const suggestions = issues.nodes
96
+ .filter(i => {
97
+ const isHighPriority = i.priority && i.priority <= 2;
98
+ const isInProgress = i.state?.name === 'In Progress';
99
+ const isTodo = i.state?.name === 'Todo';
100
+ const isUnassigned = !i.assignee;
101
+
102
+ return (isHighPriority || isInProgress) && (isTodo || isInProgress);
103
+ })
104
+ .slice(0, 3);
105
+
106
+ if (suggestions.length > 0) {
107
+ for (const issue of suggestions) {
108
+ const state = issue.state?.name || 'Unknown';
109
+ const priority = issue.priority ? `P${issue.priority}` : 'No priority';
110
+ console.log(` 1. ${issue.identifier}: ${issue.title}`);
111
+ console.log(` Status: ${state}, Priority: ${priority}`);
112
+ console.log(` URL: https://linear.app/issue/${issue.identifier}`);
113
+ console.log('');
114
+ }
115
+ } else {
116
+ console.log(' No high-priority unassigned tasks found.');
117
+ }
118
+
119
+ } catch (error) {
120
+ console.error('Error fetching Linear tasks:', error.message);
121
+ process.exit(1);
122
+ }
123
+ }
124
+
125
+ fetchLinearTasks();