@stackmemoryai/stackmemory 0.3.7 → 0.3.8

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 (190) hide show
  1. package/dist/agents/core/agent-task-manager.js +5 -5
  2. package/dist/agents/core/agent-task-manager.js.map +2 -2
  3. package/dist/agents/verifiers/base-verifier.js +2 -2
  4. package/dist/agents/verifiers/base-verifier.js.map +2 -2
  5. package/dist/cli/claude-sm.js +0 -11
  6. package/dist/cli/claude-sm.js.map +2 -2
  7. package/dist/cli/codex-sm.js +0 -11
  8. package/dist/cli/codex-sm.js.map +2 -2
  9. package/dist/cli/commands/chromadb.js +64 -34
  10. package/dist/cli/commands/chromadb.js.map +2 -2
  11. package/dist/cli/commands/clear.js +9 -13
  12. package/dist/cli/commands/clear.js.map +2 -2
  13. package/dist/cli/commands/config.js +43 -33
  14. package/dist/cli/commands/config.js.map +2 -2
  15. package/dist/cli/commands/context.js.map +2 -2
  16. package/dist/cli/commands/dashboard.js +41 -13
  17. package/dist/cli/commands/dashboard.js.map +2 -2
  18. package/dist/cli/commands/gc.js +69 -20
  19. package/dist/cli/commands/gc.js.map +2 -2
  20. package/dist/cli/commands/handoff.js.map +2 -2
  21. package/dist/cli/commands/infinite-storage.js +60 -19
  22. package/dist/cli/commands/infinite-storage.js.map +2 -2
  23. package/dist/cli/commands/linear-create.js +36 -8
  24. package/dist/cli/commands/linear-create.js.map +2 -2
  25. package/dist/cli/commands/linear-list.js +33 -10
  26. package/dist/cli/commands/linear-list.js.map +2 -2
  27. package/dist/cli/commands/linear-migrate.js +17 -4
  28. package/dist/cli/commands/linear-migrate.js.map +2 -2
  29. package/dist/cli/commands/linear-test.js +14 -6
  30. package/dist/cli/commands/linear-test.js.map +2 -2
  31. package/dist/cli/commands/linear-unified.js +123 -35
  32. package/dist/cli/commands/linear-unified.js.map +2 -2
  33. package/dist/cli/commands/linear.js.map +2 -2
  34. package/dist/cli/commands/monitor.js.map +2 -2
  35. package/dist/cli/commands/onboard.js +35 -8
  36. package/dist/cli/commands/onboard.js.map +2 -2
  37. package/dist/cli/commands/quality.js +2 -7
  38. package/dist/cli/commands/quality.js.map +2 -2
  39. package/dist/cli/commands/session.js +23 -6
  40. package/dist/cli/commands/session.js.map +2 -2
  41. package/dist/cli/commands/skills.js +72 -27
  42. package/dist/cli/commands/skills.js.map +2 -2
  43. package/dist/cli/commands/storage.js +108 -38
  44. package/dist/cli/commands/storage.js.map +2 -2
  45. package/dist/cli/commands/tui.js.map +2 -2
  46. package/dist/cli/commands/webhook.js +57 -18
  47. package/dist/cli/commands/webhook.js.map +2 -2
  48. package/dist/cli/commands/workflow.js +8 -15
  49. package/dist/cli/commands/workflow.js.map +2 -2
  50. package/dist/cli/commands/worktree.js +34 -13
  51. package/dist/cli/commands/worktree.js.map +2 -2
  52. package/dist/cli/index.js +0 -11
  53. package/dist/cli/index.js.map +2 -2
  54. package/dist/core/config/types.js.map +1 -1
  55. package/dist/core/context/auto-context.js +10 -6
  56. package/dist/core/context/auto-context.js.map +2 -2
  57. package/dist/core/context/context-bridge.js.map +2 -2
  58. package/dist/core/context/frame-database.js +13 -3
  59. package/dist/core/context/frame-database.js.map +2 -2
  60. package/dist/core/context/frame-digest.js +7 -5
  61. package/dist/core/context/frame-digest.js.map +2 -2
  62. package/dist/core/context/frame-manager.js.map +2 -2
  63. package/dist/core/context/frame-stack.js +16 -5
  64. package/dist/core/context/frame-stack.js.map +2 -2
  65. package/dist/core/context/incremental-gc.js +10 -3
  66. package/dist/core/context/incremental-gc.js.map +2 -2
  67. package/dist/core/context/index.js.map +1 -1
  68. package/dist/core/context/permission-manager.js.map +2 -2
  69. package/dist/core/context/refactored-frame-manager.js +12 -3
  70. package/dist/core/context/refactored-frame-manager.js.map +2 -2
  71. package/dist/core/context/shared-context-layer.js +4 -2
  72. package/dist/core/context/shared-context-layer.js.map +2 -2
  73. package/dist/core/database/batch-operations.js +112 -86
  74. package/dist/core/database/batch-operations.js.map +2 -2
  75. package/dist/core/database/query-cache.js +19 -9
  76. package/dist/core/database/query-cache.js.map +2 -2
  77. package/dist/core/database/sqlite-adapter.js +1 -1
  78. package/dist/core/database/sqlite-adapter.js.map +2 -2
  79. package/dist/core/digest/enhanced-hybrid-digest.js +8 -2
  80. package/dist/core/digest/enhanced-hybrid-digest.js.map +2 -2
  81. package/dist/core/errors/recovery.js +9 -2
  82. package/dist/core/errors/recovery.js.map +2 -2
  83. package/dist/core/frame/workflow-templates-stub.js.map +1 -1
  84. package/dist/core/frame/workflow-templates.js +40 -1
  85. package/dist/core/frame/workflow-templates.js.map +2 -2
  86. package/dist/core/monitoring/logger.js +6 -1
  87. package/dist/core/monitoring/logger.js.map +2 -2
  88. package/dist/core/monitoring/metrics.js.map +2 -2
  89. package/dist/core/monitoring/progress-tracker.js.map +2 -2
  90. package/dist/core/performance/context-cache.js.map +2 -2
  91. package/dist/core/performance/lazy-context-loader.js +24 -20
  92. package/dist/core/performance/lazy-context-loader.js.map +2 -2
  93. package/dist/core/performance/optimized-frame-context.js +27 -12
  94. package/dist/core/performance/optimized-frame-context.js.map +2 -2
  95. package/dist/core/performance/performance-benchmark.js +10 -6
  96. package/dist/core/performance/performance-benchmark.js.map +2 -2
  97. package/dist/core/performance/performance-profiler.js +51 -14
  98. package/dist/core/performance/performance-profiler.js.map +2 -2
  99. package/dist/core/performance/streaming-jsonl-parser.js +5 -1
  100. package/dist/core/performance/streaming-jsonl-parser.js.map +2 -2
  101. package/dist/core/projects/project-manager.js +14 -20
  102. package/dist/core/projects/project-manager.js.map +2 -2
  103. package/dist/core/retrieval/context-retriever.js.map +1 -1
  104. package/dist/core/retrieval/llm-context-retrieval.js.map +2 -2
  105. package/dist/core/session/clear-survival-stub.js +5 -1
  106. package/dist/core/session/clear-survival-stub.js.map +2 -2
  107. package/dist/core/session/clear-survival.js +35 -0
  108. package/dist/core/session/clear-survival.js.map +2 -2
  109. package/dist/core/session/index.js.map +1 -1
  110. package/dist/core/session/session-manager.js.map +2 -2
  111. package/dist/core/storage/chromadb-adapter.js +6 -2
  112. package/dist/core/storage/chromadb-adapter.js.map +2 -2
  113. package/dist/core/storage/chromadb-simple.js +17 -5
  114. package/dist/core/storage/chromadb-simple.js.map +2 -2
  115. package/dist/core/storage/infinite-storage.js +109 -46
  116. package/dist/core/storage/infinite-storage.js.map +2 -2
  117. package/dist/core/storage/railway-optimized-storage.js +48 -22
  118. package/dist/core/storage/railway-optimized-storage.js.map +2 -2
  119. package/dist/core/storage/remote-storage.js +41 -23
  120. package/dist/core/storage/remote-storage.js.map +2 -2
  121. package/dist/core/trace/cli-trace-wrapper.js +9 -2
  122. package/dist/core/trace/cli-trace-wrapper.js.map +2 -2
  123. package/dist/core/trace/db-trace-wrapper.js +96 -68
  124. package/dist/core/trace/db-trace-wrapper.js.map +2 -2
  125. package/dist/core/trace/debug-trace.js +25 -8
  126. package/dist/core/trace/debug-trace.js.map +2 -2
  127. package/dist/core/trace/index.js +6 -2
  128. package/dist/core/trace/index.js.map +2 -2
  129. package/dist/core/trace/linear-api-wrapper.js +10 -5
  130. package/dist/core/trace/linear-api-wrapper.js.map +2 -2
  131. package/dist/core/trace/trace-demo.js +14 -10
  132. package/dist/core/trace/trace-demo.js.map +2 -2
  133. package/dist/core/trace/trace-detector.js +9 -2
  134. package/dist/core/trace/trace-detector.js.map +2 -2
  135. package/dist/core/trace/types.js.map +1 -1
  136. package/dist/core/utils/compression.js.map +1 -1
  137. package/dist/core/utils/update-checker.js.map +1 -1
  138. package/dist/core/worktree/worktree-manager.js +18 -7
  139. package/dist/core/worktree/worktree-manager.js.map +2 -2
  140. package/dist/features/analytics/core/analytics-service.js.map +2 -2
  141. package/dist/features/analytics/queries/metrics-queries.js +1 -1
  142. package/dist/features/analytics/queries/metrics-queries.js.map +2 -2
  143. package/dist/features/tasks/pebbles-task-store.js.map +1 -1
  144. package/dist/features/tui/components/analytics-panel.js +36 -15
  145. package/dist/features/tui/components/analytics-panel.js.map +2 -2
  146. package/dist/features/tui/components/pr-tracker.js +19 -7
  147. package/dist/features/tui/components/pr-tracker.js.map +2 -2
  148. package/dist/features/tui/components/session-monitor.js +22 -9
  149. package/dist/features/tui/components/session-monitor.js.map +2 -2
  150. package/dist/features/tui/components/subagent-fleet.js +20 -13
  151. package/dist/features/tui/components/subagent-fleet.js.map +2 -2
  152. package/dist/features/tui/components/task-board.js +26 -10
  153. package/dist/features/tui/components/task-board.js.map +2 -2
  154. package/dist/features/tui/index.js.map +2 -2
  155. package/dist/features/tui/services/data-service.js +6 -2
  156. package/dist/features/tui/services/data-service.js.map +2 -2
  157. package/dist/features/tui/services/linear-task-reader.js +3 -1
  158. package/dist/features/tui/services/linear-task-reader.js.map +2 -2
  159. package/dist/features/tui/services/websocket-client.js +3 -1
  160. package/dist/features/tui/services/websocket-client.js.map +2 -2
  161. package/dist/features/tui/terminal-compat.js +6 -2
  162. package/dist/features/tui/terminal-compat.js.map +2 -2
  163. package/dist/features/web/client/stores/task-store.js.map +2 -2
  164. package/dist/features/web/server/index.js +18 -10
  165. package/dist/features/web/server/index.js.map +2 -2
  166. package/dist/integrations/linear/sync-service.js +12 -13
  167. package/dist/integrations/linear/sync-service.js.map +2 -2
  168. package/dist/integrations/linear/sync.js +174 -12
  169. package/dist/integrations/linear/sync.js.map +2 -2
  170. package/dist/integrations/linear/unified-sync.js +1 -1
  171. package/dist/integrations/linear/unified-sync.js.map +1 -1
  172. package/dist/integrations/linear/webhook-server.js +15 -16
  173. package/dist/integrations/linear/webhook-server.js.map +2 -2
  174. package/dist/mcp/stackmemory-mcp-server.js +0 -11
  175. package/dist/mcp/stackmemory-mcp-server.js.map +2 -2
  176. package/dist/servers/production/auth-middleware.js.map +2 -2
  177. package/dist/servers/railway/index.js.map +2 -2
  178. package/dist/services/config-service.js +6 -7
  179. package/dist/services/config-service.js.map +2 -2
  180. package/dist/services/context-service.js +11 -12
  181. package/dist/services/context-service.js.map +2 -2
  182. package/dist/skills/claude-skills.js +4 -2
  183. package/dist/skills/claude-skills.js.map +2 -2
  184. package/dist/skills/dashboard-launcher.js.map +2 -2
  185. package/dist/skills/repo-ingestion-skill.js.map +2 -2
  186. package/dist/utils/env.js +46 -0
  187. package/dist/utils/env.js.map +7 -0
  188. package/dist/utils/logger.js +0 -11
  189. package/dist/utils/logger.js.map +2 -2
  190. package/package.json +1 -1
@@ -15,7 +15,9 @@ function createGCCommand() {
15
15
  const collector = new IncrementalGarbageCollector(frameManager);
16
16
  const stats = collector.getStats();
17
17
  spinner.stop();
18
- console.log(chalk.cyan("\n\u{1F5D1}\uFE0F Incremental Garbage Collection Status\n"));
18
+ console.log(
19
+ chalk.cyan("\n\u{1F5D1}\uFE0F Incremental Garbage Collection Status\n")
20
+ );
19
21
  const table = new Table({
20
22
  head: ["Metric", "Value"],
21
23
  colWidths: [25, 20]
@@ -26,7 +28,10 @@ function createGCCommand() {
26
28
  ["Collection Cycles", stats.cycleCount.toString()],
27
29
  ["Avg Cycle Time", `${stats.avgCycleTime.toFixed(2)}ms`],
28
30
  ["Protected Frames", stats.protectedFrames.toString()],
29
- ["Last Run", stats.lastRunTime ? new Date(stats.lastRunTime).toLocaleString() : "Never"]
31
+ [
32
+ "Last Run",
33
+ stats.lastRunTime ? new Date(stats.lastRunTime).toLocaleString() : "Never"
34
+ ]
30
35
  );
31
36
  console.log(table.toString());
32
37
  if (stats.totalFrames > 0) {
@@ -39,10 +44,15 @@ function createGCCommand() {
39
44
  } catch (error) {
40
45
  spinner.fail("Failed to get GC status");
41
46
  logger.error("GC status error", error);
42
- console.error(chalk.red(error instanceof Error ? error.message : "Unknown error"));
47
+ console.error(
48
+ chalk.red(error instanceof Error ? error.message : "Unknown error")
49
+ );
43
50
  }
44
51
  });
45
- gc.command("collect").description("Run manual garbage collection cycle").option("--dry-run", "Show what would be collected without actually collecting").action(async (options) => {
52
+ gc.command("collect").description("Run manual garbage collection cycle").option(
53
+ "--dry-run",
54
+ "Show what would be collected without actually collecting"
55
+ ).action(async (options) => {
46
56
  const spinner = ora("Running garbage collection...").start();
47
57
  try {
48
58
  const frameManager = new FrameManager();
@@ -53,7 +63,9 @@ function createGCCommand() {
53
63
  } else {
54
64
  await collector.forceCollection();
55
65
  const stats = collector.getStats();
56
- spinner.succeed(`Collection completed - collected ${stats.collectedFrames} frames`);
66
+ spinner.succeed(
67
+ `Collection completed - collected ${stats.collectedFrames} frames`
68
+ );
57
69
  console.log(chalk.green("\n\u2705 Manual collection completed"));
58
70
  console.log(` Processed: ${stats.totalFrames} frames`);
59
71
  console.log(` Collected: ${stats.collectedFrames} frames`);
@@ -62,7 +74,9 @@ function createGCCommand() {
62
74
  } catch (error) {
63
75
  spinner.fail("Collection failed");
64
76
  logger.error("GC collection error", error);
65
- console.error(chalk.red(error instanceof Error ? error.message : "Unknown error"));
77
+ console.error(
78
+ chalk.red(error instanceof Error ? error.message : "Unknown error")
79
+ );
66
80
  }
67
81
  });
68
82
  gc.command("start").description("Start incremental GC daemon").option("--interval <seconds>", "Collection interval in seconds", "60").option("--frames-per-cycle <number>", "Frames to process per cycle", "100").action(async (options) => {
@@ -89,7 +103,9 @@ function createGCCommand() {
89
103
  } catch (error) {
90
104
  spinner.fail("Failed to start GC daemon");
91
105
  logger.error("GC start error", error);
92
- console.error(chalk.red(error instanceof Error ? error.message : "Unknown error"));
106
+ console.error(
107
+ chalk.red(error instanceof Error ? error.message : "Unknown error")
108
+ );
93
109
  }
94
110
  });
95
111
  gc.command("config").description("View or update GC configuration").option("--set-interval <seconds>", "Set collection interval").option("--set-frames-per-cycle <number>", "Set frames per cycle").option("--set-max-age <days>", "Set max frame age before collection").action(async (options) => {
@@ -98,9 +114,12 @@ function createGCCommand() {
98
114
  const collector = new IncrementalGarbageCollector(frameManager);
99
115
  if (options.setInterval || options.setFramesPerCycle || options.setMaxAge) {
100
116
  const newConfig = {};
101
- if (options.setInterval) newConfig.cycleInterval = parseInt(options.setInterval) * 1e3;
102
- if (options.setFramesPerCycle) newConfig.framesPerCycle = parseInt(options.setFramesPerCycle);
103
- if (options.setMaxAge) newConfig.maxAge = parseInt(options.setMaxAge) * 24 * 60 * 60 * 1e3;
117
+ if (options.setInterval)
118
+ newConfig.cycleInterval = parseInt(options.setInterval) * 1e3;
119
+ if (options.setFramesPerCycle)
120
+ newConfig.framesPerCycle = parseInt(options.setFramesPerCycle);
121
+ if (options.setMaxAge)
122
+ newConfig.maxAge = parseInt(options.setMaxAge) * 24 * 60 * 60 * 1e3;
104
123
  collector.updateConfig(newConfig);
105
124
  console.log(chalk.green("\u2705 Configuration updated"));
106
125
  }
@@ -114,7 +133,9 @@ function createGCCommand() {
114
133
  console.log(" Old: 7-30 days");
115
134
  } catch (error) {
116
135
  logger.error("GC config error", error);
117
- console.error(chalk.red(error instanceof Error ? error.message : "Unknown error"));
136
+ console.error(
137
+ chalk.red(error instanceof Error ? error.message : "Unknown error")
138
+ );
118
139
  }
119
140
  });
120
141
  gc.command("analyze").description("Analyze frame distribution and collection opportunities").action(async () => {
@@ -168,30 +189,58 @@ function createGCCommand() {
168
189
  ["Closed Frames", analysis.closed.toString(), pct(analysis.closed)],
169
190
  ["", "", ""],
170
191
  ["Young (< 1 day)", analysis.young.toString(), pct(analysis.young)],
171
- ["Mature (1-7 days)", analysis.mature.toString(), pct(analysis.mature)],
192
+ [
193
+ "Mature (1-7 days)",
194
+ analysis.mature.toString(),
195
+ pct(analysis.mature)
196
+ ],
172
197
  ["Old (> 7 days)", analysis.old.toString(), pct(analysis.old)],
173
198
  ["", "", ""],
174
- ["With Outputs", analysis.withOutputs.toString(), pct(analysis.withOutputs)],
175
- ["Without Outputs", analysis.withoutOutputs.toString(), pct(analysis.withoutOutputs)],
199
+ [
200
+ "With Outputs",
201
+ analysis.withOutputs.toString(),
202
+ pct(analysis.withOutputs)
203
+ ],
204
+ [
205
+ "Without Outputs",
206
+ analysis.withoutOutputs.toString(),
207
+ pct(analysis.withoutOutputs)
208
+ ],
176
209
  ["", "", ""],
177
- ["Root Frames", analysis.rootFrames.toString(), pct(analysis.rootFrames)],
178
- ["Leaf Frames", analysis.leafFrames.toString(), pct(analysis.leafFrames)]
210
+ [
211
+ "Root Frames",
212
+ analysis.rootFrames.toString(),
213
+ pct(analysis.rootFrames)
214
+ ],
215
+ [
216
+ "Leaf Frames",
217
+ analysis.leafFrames.toString(),
218
+ pct(analysis.leafFrames)
219
+ ]
179
220
  );
180
221
  console.log(stateTable.toString());
181
222
  console.log(chalk.yellow("\n\u{1F4A1} Collection Recommendations:\n"));
182
223
  const candidatesForCollection = analysis.closed + analysis.withoutOutputs;
183
- console.log(`\u2022 Potential collection candidates: ${candidatesForCollection} frames`);
184
- console.log(`\u2022 Estimated space savings: ${(candidatesForCollection / analysis.total * 100).toFixed(1)}%`);
224
+ console.log(
225
+ `\u2022 Potential collection candidates: ${candidatesForCollection} frames`
226
+ );
227
+ console.log(
228
+ `\u2022 Estimated space savings: ${(candidatesForCollection / analysis.total * 100).toFixed(1)}%`
229
+ );
185
230
  if (analysis.old > 0) {
186
231
  console.log(`\u2022 ${analysis.old} old frames ready for collection`);
187
232
  }
188
233
  if (analysis.withoutOutputs > 0) {
189
- console.log(`\u2022 ${analysis.withoutOutputs} frames without outputs can be collected`);
234
+ console.log(
235
+ `\u2022 ${analysis.withoutOutputs} frames without outputs can be collected`
236
+ );
190
237
  }
191
238
  } catch (error) {
192
239
  spinner.fail("Analysis failed");
193
240
  logger.error("GC analysis error", error);
194
- console.error(chalk.red(error instanceof Error ? error.message : "Unknown error"));
241
+ console.error(
242
+ chalk.red(error instanceof Error ? error.message : "Unknown error")
243
+ );
195
244
  }
196
245
  });
197
246
  return gc;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/cli/commands/gc.ts"],
4
- "sourcesContent": ["/**\n * CLI commands for Incremental Garbage Collection management\n */\n\nimport { Command } from 'commander';\nimport chalk from 'chalk';\nimport ora from 'ora';\nimport Table from 'cli-table3';\nimport { IncrementalGarbageCollector } from '../../core/context/incremental-gc.js';\nimport { FrameManager } from '../../core/context/frame-manager.js';\nimport { Logger } from '../../core/monitoring/logger.js';\n\nconst logger = new Logger('GC-CLI');\n\nexport function createGCCommand(): Command {\n const gc = new Command('gc')\n .description('Manage incremental garbage collection system')\n .alias('garbage-collect');\n\n // Status command\n gc.command('status')\n .description('Show garbage collection statistics')\n .action(async () => {\n const spinner = ora('Getting GC status...').start();\n\n try {\n const frameManager = new FrameManager();\n const collector = new IncrementalGarbageCollector(frameManager);\n \n const stats = collector.getStats();\n spinner.stop();\n\n console.log(chalk.cyan('\\n\uD83D\uDDD1\uFE0F Incremental Garbage Collection Status\\n'));\n\n const table = new Table({\n head: ['Metric', 'Value'],\n colWidths: [25, 20],\n });\n\n table.push(\n ['Total Frames', stats.totalFrames.toString()],\n ['Collected Frames', stats.collectedFrames.toString()],\n ['Collection Cycles', stats.cycleCount.toString()],\n ['Avg Cycle Time', `${stats.avgCycleTime.toFixed(2)}ms`],\n ['Protected Frames', stats.protectedFrames.toString()],\n ['Last Run', stats.lastRunTime ? new Date(stats.lastRunTime).toLocaleString() : 'Never']\n );\n\n console.log(table.toString());\n\n // Show efficiency metrics\n if (stats.totalFrames > 0) {\n const collectionRate = ((stats.collectedFrames / stats.totalFrames) * 100).toFixed(1);\n const protectionRate = ((stats.protectedFrames / stats.totalFrames) * 100).toFixed(1);\n \n console.log('\\n\uD83D\uDCCA Collection Efficiency:');\n console.log(` Collection Rate: ${collectionRate}%`);\n console.log(` Protection Rate: ${protectionRate}%`);\n }\n\n } catch (error: unknown) {\n spinner.fail('Failed to get GC status');\n logger.error('GC status error', error);\n console.error(chalk.red(error instanceof Error ? error.message : 'Unknown error'));\n }\n });\n\n // Manual collection command \n gc.command('collect')\n .description('Run manual garbage collection cycle')\n .option('--dry-run', 'Show what would be collected without actually collecting')\n .action(async (options) => {\n const spinner = ora('Running garbage collection...').start();\n\n try {\n const frameManager = new FrameManager();\n const collector = new IncrementalGarbageCollector(frameManager);\n \n if (options.dryRun) {\n spinner.text = 'Analyzing collection candidates (dry run)...';\n // TODO: Implement dry run mode\n spinner.succeed('Dry run completed - check logs for details');\n } else {\n await collector.forceCollection();\n const stats = collector.getStats();\n \n spinner.succeed(`Collection completed - collected ${stats.collectedFrames} frames`);\n \n console.log(chalk.green('\\n\u2705 Manual collection completed'));\n console.log(` Processed: ${stats.totalFrames} frames`);\n console.log(` Collected: ${stats.collectedFrames} frames`);\n console.log(` Protected: ${stats.protectedFrames} frames`);\n }\n\n } catch (error: unknown) {\n spinner.fail('Collection failed');\n logger.error('GC collection error', error);\n console.error(chalk.red(error instanceof Error ? error.message : 'Unknown error'));\n }\n });\n\n // Start/stop daemon commands\n gc.command('start')\n .description('Start incremental GC daemon')\n .option('--interval <seconds>', 'Collection interval in seconds', '60')\n .option('--frames-per-cycle <number>', 'Frames to process per cycle', '100')\n .action(async (options) => {\n const spinner = ora('Starting GC daemon...').start();\n\n try {\n const frameManager = new FrameManager();\n const collector = new IncrementalGarbageCollector(frameManager, {\n cycleInterval: parseInt(options.interval) * 1000,\n framesPerCycle: parseInt(options.framesPerCycle)\n });\n \n collector.start();\n \n spinner.succeed('GC daemon started');\n console.log(chalk.green('\\n\uD83D\uDE80 Incremental GC daemon is running'));\n console.log(` Interval: ${options.interval}s`);\n console.log(` Frames per cycle: ${options.framesPerCycle}`);\n console.log('\\nPress Ctrl+C to stop');\n \n // Keep process alive\n process.on('SIGINT', () => {\n console.log('\\n\u23F9\uFE0F Stopping GC daemon...');\n collector.stop();\n process.exit(0);\n });\n \n // Keep the process running\n await new Promise(() => {}); // Run forever\n\n } catch (error: unknown) {\n spinner.fail('Failed to start GC daemon');\n logger.error('GC start error', error);\n console.error(chalk.red(error instanceof Error ? error.message : 'Unknown error'));\n }\n });\n\n // Configuration command\n gc.command('config')\n .description('View or update GC configuration')\n .option('--set-interval <seconds>', 'Set collection interval')\n .option('--set-frames-per-cycle <number>', 'Set frames per cycle')\n .option('--set-max-age <days>', 'Set max frame age before collection')\n .action(async (options) => {\n try {\n const frameManager = new FrameManager();\n const collector = new IncrementalGarbageCollector(frameManager);\n \n if (options.setInterval || options.setFramesPerCycle || options.setMaxAge) {\n // Update configuration\n const newConfig: any = {};\n if (options.setInterval) newConfig.cycleInterval = parseInt(options.setInterval) * 1000;\n if (options.setFramesPerCycle) newConfig.framesPerCycle = parseInt(options.setFramesPerCycle);\n if (options.setMaxAge) newConfig.maxAge = parseInt(options.setMaxAge) * 24 * 60 * 60 * 1000;\n \n collector.updateConfig(newConfig);\n console.log(chalk.green('\u2705 Configuration updated'));\n }\n\n // Show current config\n console.log(chalk.cyan('\\n\u2699\uFE0F Current GC Configuration\\n'));\n console.log('Cycle Interval: 60s');\n console.log('Frames per Cycle: 100');\n console.log('Max Age: 30 days');\n console.log('\\nGenerations:');\n console.log(' Young: < 1 day');\n console.log(' Mature: 1-7 days');\n console.log(' Old: 7-30 days');\n\n } catch (error: unknown) {\n logger.error('GC config error', error);\n console.error(chalk.red(error instanceof Error ? error.message : 'Unknown error'));\n }\n });\n\n // Analysis command\n gc.command('analyze')\n .description('Analyze frame distribution and collection opportunities')\n .action(async () => {\n const spinner = ora('Analyzing frames...').start();\n\n try {\n const frameManager = new FrameManager();\n const allFrames = await frameManager.getAllFrames();\n \n if (allFrames.length === 0) {\n spinner.succeed('No frames to analyze');\n return;\n }\n\n // Analyze frame distribution\n const now = Date.now();\n const analysis = {\n total: allFrames.length,\n active: 0,\n closed: 0,\n young: 0,\n mature: 0,\n old: 0,\n withOutputs: 0,\n withoutOutputs: 0,\n rootFrames: 0,\n leafFrames: 0\n };\n\n for (const frame of allFrames) {\n const age = now - frame.created_at;\n \n // State analysis\n if (frame.state === 'active') analysis.active++;\n else analysis.closed++;\n \n // Age analysis\n if (age < 24 * 60 * 60 * 1000) analysis.young++;\n else if (age < 7 * 24 * 60 * 60 * 1000) analysis.mature++;\n else analysis.old++;\n \n // Output analysis\n if (frame.outputs && Object.keys(frame.outputs).length > 0) {\n analysis.withOutputs++;\n } else {\n analysis.withoutOutputs++;\n }\n \n // Hierarchy analysis\n if (frame.depth === 0) analysis.rootFrames++;\n if (!allFrames.some(f => f.parent_frame_id === frame.frame_id)) {\n analysis.leafFrames++;\n }\n }\n\n spinner.stop();\n\n console.log(chalk.cyan('\\n\uD83D\uDCCA Frame Distribution Analysis\\n'));\n\n const stateTable = new Table({\n head: ['Category', 'Count', 'Percentage'],\n colWidths: [20, 10, 15],\n });\n\n const pct = (count: number) => `${((count / analysis.total) * 100).toFixed(1)}%`;\n\n stateTable.push(\n ['Active Frames', analysis.active.toString(), pct(analysis.active)],\n ['Closed Frames', analysis.closed.toString(), pct(analysis.closed)],\n ['', '', ''],\n ['Young (< 1 day)', analysis.young.toString(), pct(analysis.young)],\n ['Mature (1-7 days)', analysis.mature.toString(), pct(analysis.mature)],\n ['Old (> 7 days)', analysis.old.toString(), pct(analysis.old)],\n ['', '', ''],\n ['With Outputs', analysis.withOutputs.toString(), pct(analysis.withOutputs)],\n ['Without Outputs', analysis.withoutOutputs.toString(), pct(analysis.withoutOutputs)],\n ['', '', ''],\n ['Root Frames', analysis.rootFrames.toString(), pct(analysis.rootFrames)],\n ['Leaf Frames', analysis.leafFrames.toString(), pct(analysis.leafFrames)]\n );\n\n console.log(stateTable.toString());\n\n // Collection recommendations\n console.log(chalk.yellow('\\n\uD83D\uDCA1 Collection Recommendations:\\n'));\n const candidatesForCollection = analysis.closed + analysis.withoutOutputs;\n console.log(`\u2022 Potential collection candidates: ${candidatesForCollection} frames`);\n console.log(`\u2022 Estimated space savings: ${((candidatesForCollection / analysis.total) * 100).toFixed(1)}%`);\n \n if (analysis.old > 0) {\n console.log(`\u2022 ${analysis.old} old frames ready for collection`);\n }\n if (analysis.withoutOutputs > 0) {\n console.log(`\u2022 ${analysis.withoutOutputs} frames without outputs can be collected`);\n }\n\n } catch (error: unknown) {\n spinner.fail('Analysis failed');\n logger.error('GC analysis error', error);\n console.error(chalk.red(error instanceof Error ? error.message : 'Unknown error'));\n }\n });\n\n return gc;\n}"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * CLI commands for Incremental Garbage Collection management\n */\n\nimport { Command } from 'commander';\nimport chalk from 'chalk';\nimport ora from 'ora';\nimport Table from 'cli-table3';\nimport { IncrementalGarbageCollector } from '../../core/context/incremental-gc.js';\nimport { FrameManager } from '../../core/context/frame-manager.js';\nimport { Logger } from '../../core/monitoring/logger.js';\n\nconst logger = new Logger('GC-CLI');\n\nexport function createGCCommand(): Command {\n const gc = new Command('gc')\n .description('Manage incremental garbage collection system')\n .alias('garbage-collect');\n\n // Status command\n gc.command('status')\n .description('Show garbage collection statistics')\n .action(async () => {\n const spinner = ora('Getting GC status...').start();\n\n try {\n const frameManager = new FrameManager();\n const collector = new IncrementalGarbageCollector(frameManager);\n\n const stats = collector.getStats();\n spinner.stop();\n\n console.log(\n chalk.cyan('\\n\uD83D\uDDD1\uFE0F Incremental Garbage Collection Status\\n')\n );\n\n const table = new Table({\n head: ['Metric', 'Value'],\n colWidths: [25, 20],\n });\n\n table.push(\n ['Total Frames', stats.totalFrames.toString()],\n ['Collected Frames', stats.collectedFrames.toString()],\n ['Collection Cycles', stats.cycleCount.toString()],\n ['Avg Cycle Time', `${stats.avgCycleTime.toFixed(2)}ms`],\n ['Protected Frames', stats.protectedFrames.toString()],\n [\n 'Last Run',\n stats.lastRunTime\n ? new Date(stats.lastRunTime).toLocaleString()\n : 'Never',\n ]\n );\n\n console.log(table.toString());\n\n // Show efficiency metrics\n if (stats.totalFrames > 0) {\n const collectionRate = (\n (stats.collectedFrames / stats.totalFrames) *\n 100\n ).toFixed(1);\n const protectionRate = (\n (stats.protectedFrames / stats.totalFrames) *\n 100\n ).toFixed(1);\n\n console.log('\\n\uD83D\uDCCA Collection Efficiency:');\n console.log(` Collection Rate: ${collectionRate}%`);\n console.log(` Protection Rate: ${protectionRate}%`);\n }\n } catch (error: unknown) {\n spinner.fail('Failed to get GC status');\n logger.error('GC status error', error);\n console.error(\n chalk.red(error instanceof Error ? error.message : 'Unknown error')\n );\n }\n });\n\n // Manual collection command\n gc.command('collect')\n .description('Run manual garbage collection cycle')\n .option(\n '--dry-run',\n 'Show what would be collected without actually collecting'\n )\n .action(async (options) => {\n const spinner = ora('Running garbage collection...').start();\n\n try {\n const frameManager = new FrameManager();\n const collector = new IncrementalGarbageCollector(frameManager);\n\n if (options.dryRun) {\n spinner.text = 'Analyzing collection candidates (dry run)...';\n // TODO: Implement dry run mode\n spinner.succeed('Dry run completed - check logs for details');\n } else {\n await collector.forceCollection();\n const stats = collector.getStats();\n\n spinner.succeed(\n `Collection completed - collected ${stats.collectedFrames} frames`\n );\n\n console.log(chalk.green('\\n\u2705 Manual collection completed'));\n console.log(` Processed: ${stats.totalFrames} frames`);\n console.log(` Collected: ${stats.collectedFrames} frames`);\n console.log(` Protected: ${stats.protectedFrames} frames`);\n }\n } catch (error: unknown) {\n spinner.fail('Collection failed');\n logger.error('GC collection error', error);\n console.error(\n chalk.red(error instanceof Error ? error.message : 'Unknown error')\n );\n }\n });\n\n // Start/stop daemon commands\n gc.command('start')\n .description('Start incremental GC daemon')\n .option('--interval <seconds>', 'Collection interval in seconds', '60')\n .option('--frames-per-cycle <number>', 'Frames to process per cycle', '100')\n .action(async (options) => {\n const spinner = ora('Starting GC daemon...').start();\n\n try {\n const frameManager = new FrameManager();\n const collector = new IncrementalGarbageCollector(frameManager, {\n cycleInterval: parseInt(options.interval) * 1000,\n framesPerCycle: parseInt(options.framesPerCycle),\n });\n\n collector.start();\n\n spinner.succeed('GC daemon started');\n console.log(chalk.green('\\n\uD83D\uDE80 Incremental GC daemon is running'));\n console.log(` Interval: ${options.interval}s`);\n console.log(` Frames per cycle: ${options.framesPerCycle}`);\n console.log('\\nPress Ctrl+C to stop');\n\n // Keep process alive\n process.on('SIGINT', () => {\n console.log('\\n\u23F9\uFE0F Stopping GC daemon...');\n collector.stop();\n process.exit(0);\n });\n\n // Keep the process running\n await new Promise(() => {}); // Run forever\n } catch (error: unknown) {\n spinner.fail('Failed to start GC daemon');\n logger.error('GC start error', error);\n console.error(\n chalk.red(error instanceof Error ? error.message : 'Unknown error')\n );\n }\n });\n\n // Configuration command\n gc.command('config')\n .description('View or update GC configuration')\n .option('--set-interval <seconds>', 'Set collection interval')\n .option('--set-frames-per-cycle <number>', 'Set frames per cycle')\n .option('--set-max-age <days>', 'Set max frame age before collection')\n .action(async (options) => {\n try {\n const frameManager = new FrameManager();\n const collector = new IncrementalGarbageCollector(frameManager);\n\n if (\n options.setInterval ||\n options.setFramesPerCycle ||\n options.setMaxAge\n ) {\n // Update configuration\n const newConfig: any = {};\n if (options.setInterval)\n newConfig.cycleInterval = parseInt(options.setInterval) * 1000;\n if (options.setFramesPerCycle)\n newConfig.framesPerCycle = parseInt(options.setFramesPerCycle);\n if (options.setMaxAge)\n newConfig.maxAge =\n parseInt(options.setMaxAge) * 24 * 60 * 60 * 1000;\n\n collector.updateConfig(newConfig);\n console.log(chalk.green('\u2705 Configuration updated'));\n }\n\n // Show current config\n console.log(chalk.cyan('\\n\u2699\uFE0F Current GC Configuration\\n'));\n console.log('Cycle Interval: 60s');\n console.log('Frames per Cycle: 100');\n console.log('Max Age: 30 days');\n console.log('\\nGenerations:');\n console.log(' Young: < 1 day');\n console.log(' Mature: 1-7 days');\n console.log(' Old: 7-30 days');\n } catch (error: unknown) {\n logger.error('GC config error', error);\n console.error(\n chalk.red(error instanceof Error ? error.message : 'Unknown error')\n );\n }\n });\n\n // Analysis command\n gc.command('analyze')\n .description('Analyze frame distribution and collection opportunities')\n .action(async () => {\n const spinner = ora('Analyzing frames...').start();\n\n try {\n const frameManager = new FrameManager();\n const allFrames = await frameManager.getAllFrames();\n\n if (allFrames.length === 0) {\n spinner.succeed('No frames to analyze');\n return;\n }\n\n // Analyze frame distribution\n const now = Date.now();\n const analysis = {\n total: allFrames.length,\n active: 0,\n closed: 0,\n young: 0,\n mature: 0,\n old: 0,\n withOutputs: 0,\n withoutOutputs: 0,\n rootFrames: 0,\n leafFrames: 0,\n };\n\n for (const frame of allFrames) {\n const age = now - frame.created_at;\n\n // State analysis\n if (frame.state === 'active') analysis.active++;\n else analysis.closed++;\n\n // Age analysis\n if (age < 24 * 60 * 60 * 1000) analysis.young++;\n else if (age < 7 * 24 * 60 * 60 * 1000) analysis.mature++;\n else analysis.old++;\n\n // Output analysis\n if (frame.outputs && Object.keys(frame.outputs).length > 0) {\n analysis.withOutputs++;\n } else {\n analysis.withoutOutputs++;\n }\n\n // Hierarchy analysis\n if (frame.depth === 0) analysis.rootFrames++;\n if (!allFrames.some((f) => f.parent_frame_id === frame.frame_id)) {\n analysis.leafFrames++;\n }\n }\n\n spinner.stop();\n\n console.log(chalk.cyan('\\n\uD83D\uDCCA Frame Distribution Analysis\\n'));\n\n const stateTable = new Table({\n head: ['Category', 'Count', 'Percentage'],\n colWidths: [20, 10, 15],\n });\n\n const pct = (count: number) =>\n `${((count / analysis.total) * 100).toFixed(1)}%`;\n\n stateTable.push(\n ['Active Frames', analysis.active.toString(), pct(analysis.active)],\n ['Closed Frames', analysis.closed.toString(), pct(analysis.closed)],\n ['', '', ''],\n ['Young (< 1 day)', analysis.young.toString(), pct(analysis.young)],\n [\n 'Mature (1-7 days)',\n analysis.mature.toString(),\n pct(analysis.mature),\n ],\n ['Old (> 7 days)', analysis.old.toString(), pct(analysis.old)],\n ['', '', ''],\n [\n 'With Outputs',\n analysis.withOutputs.toString(),\n pct(analysis.withOutputs),\n ],\n [\n 'Without Outputs',\n analysis.withoutOutputs.toString(),\n pct(analysis.withoutOutputs),\n ],\n ['', '', ''],\n [\n 'Root Frames',\n analysis.rootFrames.toString(),\n pct(analysis.rootFrames),\n ],\n [\n 'Leaf Frames',\n analysis.leafFrames.toString(),\n pct(analysis.leafFrames),\n ]\n );\n\n console.log(stateTable.toString());\n\n // Collection recommendations\n console.log(chalk.yellow('\\n\uD83D\uDCA1 Collection Recommendations:\\n'));\n const candidatesForCollection =\n analysis.closed + analysis.withoutOutputs;\n console.log(\n `\u2022 Potential collection candidates: ${candidatesForCollection} frames`\n );\n console.log(\n `\u2022 Estimated space savings: ${((candidatesForCollection / analysis.total) * 100).toFixed(1)}%`\n );\n\n if (analysis.old > 0) {\n console.log(`\u2022 ${analysis.old} old frames ready for collection`);\n }\n if (analysis.withoutOutputs > 0) {\n console.log(\n `\u2022 ${analysis.withoutOutputs} frames without outputs can be collected`\n );\n }\n } catch (error: unknown) {\n spinner.fail('Analysis failed');\n logger.error('GC analysis error', error);\n console.error(\n chalk.red(error instanceof Error ? error.message : 'Unknown error')\n );\n }\n });\n\n return gc;\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/cli/commands/handoff.ts"],
4
- "sourcesContent": ["/**\n * Handoff command - Commits work and generates a prompt for the next session\n */\n\nimport { Command } from 'commander';\nimport { execSync } from 'child_process';\nimport { existsSync, readFileSync, writeFileSync } from 'fs';\nimport { join } from 'path';\nimport Database from 'better-sqlite3';\nimport { FrameManager } from '../../core/context/frame-manager.js';\nimport { PebblesTaskStore } from '../../features/tasks/pebbles-task-store.js';\nimport { logger } from '../../core/monitoring/logger.js';\n// Type-safe environment variable access\nfunction getEnv(key: string, defaultValue?: string): string {\n const value = process.env[key];\n if (value === undefined) {\n if (defaultValue !== undefined) return defaultValue;\n throw new Error(`Environment variable ${key} is required`);\n }\n return value;\n}\n\nfunction getOptionalEnv(key: string): string | undefined {\n return process.env[key];\n}\n\n\nexport function createHandoffCommand(): Command {\n const cmd = new Command('handoff');\n\n cmd.description('Session handoff for continuity between Claude sessions');\n\n // Default action - capture handoff\n cmd\n .command('capture', { isDefault: true })\n .description('Commit current work and generate a handoff prompt')\n .option('-m, --message <message>', 'Custom commit message')\n .option('--no-commit', 'Skip git commit')\n .option('--copy', 'Copy the handoff prompt to clipboard')\n .action(async (options) => {\n try {\n const projectRoot = process.cwd();\n const dbPath = join(projectRoot, '.stackmemory', 'context.db');\n\n // 1. Check git status\n let gitStatus = '';\n let hasChanges = false;\n\n try {\n gitStatus = execSync('git status --short', {\n encoding: 'utf-8',\n cwd: projectRoot,\n });\n hasChanges = gitStatus.trim().length > 0;\n } catch (err: unknown) {\n console.log('\u26A0\uFE0F Not in a git repository');\n }\n\n // 2. Commit if there are changes and not skipped\n if (hasChanges && options.commit !== false) {\n try {\n // Get current branch\n const currentBranch = execSync('git rev-parse --abbrev-ref HEAD', {\n encoding: 'utf-8',\n cwd: projectRoot,\n }).trim();\n\n // Stage all changes\n execSync('git add -A', { cwd: projectRoot });\n\n // Generate or use custom commit message\n const commitMessage =\n options.message ||\n `chore: handoff checkpoint on ${currentBranch}`;\n\n // Commit\n execSync(`git commit -m \"${commitMessage}\"`, { cwd: projectRoot });\n\n console.log(`\u2705 Committed changes: \"${commitMessage}\"`);\n console.log(` Branch: ${currentBranch}`);\n } catch (err: unknown) {\n console.error(\n '\u274C Failed to commit changes:',\n (err as Error).message\n );\n }\n } else if (!hasChanges) {\n console.log('\u2139\uFE0F No changes to commit');\n }\n\n // 3. Gather context for handoff prompt\n let contextSummary = '';\n let tasksSummary = '';\n let recentWork = '';\n\n if (existsSync(dbPath)) {\n const db = new Database(dbPath);\n\n // Get recent context\n const frameManager = new FrameManager(db, 'cli-project');\n const activeFrames = frameManager.getActiveFramePath();\n\n if (activeFrames.length > 0) {\n contextSummary = 'Active context frames:\\n';\n activeFrames.forEach((frame) => {\n contextSummary += ` - ${frame.name} [${frame.type}]\\n`;\n });\n }\n\n // Get task status\n const taskStore = new PebblesTaskStore(projectRoot, db);\n const activeTasks = taskStore.getActiveTasks();\n\n const inProgress = activeTasks.filter(\n (t: any) => t.status === 'in_progress'\n );\n const todo = activeTasks.filter((t: any) => t.status === 'pending');\n const recentlyCompleted = activeTasks\n .filter((t: any) => t.status === 'completed' && t.completed_at)\n .sort(\n (a: any, b: any) => (b.completed_at || 0) - (a.completed_at || 0)\n )\n .slice(0, 3);\n\n if (inProgress.length > 0 || todo.length > 0) {\n tasksSummary = '\\nTasks:\\n';\n\n if (inProgress.length > 0) {\n tasksSummary += 'In Progress:\\n';\n inProgress.forEach((t: any) => {\n const externalId = t.external_refs?.linear?.id;\n tasksSummary += ` - ${t.title}${externalId ? ` [${externalId}]` : ''}\\n`;\n });\n }\n\n if (todo.length > 0) {\n tasksSummary += 'TODO:\\n';\n todo.slice(0, 5).forEach((t: any) => {\n const externalId = t.external_refs?.linear?.id;\n tasksSummary += ` - ${t.title}${externalId ? ` [${externalId}]` : ''}\\n`;\n });\n if (todo.length > 5) {\n tasksSummary += ` ... and ${todo.length - 5} more\\n`;\n }\n }\n }\n\n if (recentlyCompleted.length > 0) {\n recentWork = '\\nRecently Completed:\\n';\n recentlyCompleted.forEach((t: any) => {\n recentWork += ` \u2713 ${t.title}\\n`;\n });\n }\n\n // Get recent events\n const recentEvents = db\n .prepare(\n `\n SELECT event_type as type, payload as data, datetime(ts, 'unixepoch') as time\n FROM events\n ORDER BY ts DESC\n LIMIT 5\n `\n )\n .all() as any[];\n\n if (recentEvents.length > 0) {\n recentWork += '\\nRecent Activity:\\n';\n recentEvents.forEach((event) => {\n const data = JSON.parse(event.data);\n recentWork += ` - ${event.type}: ${data.message || data.name || 'activity'}\\n`;\n });\n }\n\n db.close();\n }\n\n // 4. Get current git info\n let gitInfo = '';\n try {\n const branch = execSync('git rev-parse --abbrev-ref HEAD', {\n encoding: 'utf-8',\n cwd: projectRoot,\n }).trim();\n\n const lastCommit = execSync('git log -1 --oneline', {\n encoding: 'utf-8',\n cwd: projectRoot,\n }).trim();\n\n gitInfo = `\\nGit Status:\\n Branch: ${branch}\\n Last commit: ${lastCommit}\\n`;\n } catch (err: unknown) {\n // Ignore git errors\n }\n\n // 5. Check for any blockers or notes\n let notes = '';\n const notesPath = join(projectRoot, '.stackmemory', 'handoff.md');\n if (existsSync(notesPath)) {\n const handoffNotes = readFileSync(notesPath, 'utf-8');\n if (handoffNotes.trim()) {\n notes = `\\nNotes from previous handoff:\\n${handoffNotes}\\n`;\n }\n }\n\n // 6. Generate the handoff prompt\n const timestamp = new Date().toISOString();\n const handoffPrompt = `# Session Handoff - ${timestamp}\n\n## Project: ${projectRoot.split('/').pop()}\n\n${gitInfo}\n${contextSummary}\n${tasksSummary}\n${recentWork}\n${notes}\n\n## Continue from here:\n\n1. Run \\`stackmemory status\\` to check the current state\n2. Review any in-progress tasks above\n3. Check for any uncommitted changes with \\`git status\\`\n4. Resume work on the active context\n\n## Quick Commands:\n- \\`stackmemory context load --recent\\` - Load recent context\n- \\`stackmemory task list --state in_progress\\` - Show in-progress tasks\n- \\`stackmemory linear sync\\` - Sync with Linear if configured\n- \\`stackmemory log recent\\` - View recent activity\n\n---\nGenerated by stackmemory handoff at ${timestamp}\n`;\n\n // 7. Save handoff prompt\n const handoffPath = join(\n projectRoot,\n '.stackmemory',\n 'last-handoff.md'\n );\n writeFileSync(handoffPath, handoffPrompt);\n\n // 8. Display the prompt\n console.log('\\n' + '='.repeat(60));\n console.log(handoffPrompt);\n console.log('='.repeat(60));\n\n // 9. Copy to clipboard if requested\n if (options.copy) {\n try {\n const copyCommand =\n process.platform === 'darwin'\n ? 'pbcopy'\n : process.platform === 'win32'\n ? 'clip'\n : 'xclip -selection clipboard';\n\n execSync(copyCommand, {\n input: handoffPrompt,\n cwd: projectRoot,\n });\n\n console.log('\\n\u2705 Handoff prompt copied to clipboard!');\n } catch (err: unknown) {\n console.log('\\n\u26A0\uFE0F Could not copy to clipboard');\n }\n }\n\n console.log(`\\n\uD83D\uDCBE Handoff saved to: ${handoffPath}`);\n console.log('\uD83D\uDCCB Use this prompt when starting your next session');\n } catch (error: unknown) {\n logger.error('Handoff command failed', error as Error);\n console.error('\u274C Handoff failed:', (error as Error).message);\n process.exit(1);\n }\n });\n\n // Restore command\n cmd\n .command('restore')\n .description('Restore context from last handoff')\n .option('--no-copy', 'Do not copy prompt to clipboard')\n .action(async (options) => {\n try {\n const projectRoot = process.cwd();\n const handoffPath = join(\n projectRoot,\n '.stackmemory',\n 'last-handoff.md'\n );\n const metaPath = join(\n process.env['HOME'] || '~',\n '.stackmemory',\n 'handoffs',\n 'last-handoff-meta.json'\n );\n\n if (!existsSync(handoffPath)) {\n console.log('\u274C No handoff found in this project');\n console.log('\uD83D\uDCA1 Run \"stackmemory handoff\" to create one');\n return;\n }\n\n // Read handoff prompt\n const handoffPrompt = readFileSync(handoffPath, 'utf-8');\n\n // Display the prompt\n console.log('\\n' + '='.repeat(60));\n console.log('\uD83D\uDCCB RESTORED HANDOFF');\n console.log('='.repeat(60));\n console.log(handoffPrompt);\n console.log('='.repeat(60));\n\n // Check for metadata\n if (existsSync(metaPath)) {\n const metadata = JSON.parse(readFileSync(metaPath, 'utf-8'));\n console.log('\\n\uD83D\uDCCA Session Metadata:');\n console.log(` Timestamp: ${metadata.timestamp}`);\n console.log(` Reason: ${metadata.reason}`);\n console.log(` Duration: ${metadata.session_duration}s`);\n console.log(` Command: ${metadata.command}`);\n }\n\n // Check current git status\n try {\n const gitStatus = execSync('git status --short', {\n encoding: 'utf-8',\n }).trim();\n if (gitStatus) {\n console.log('\\n\u26A0\uFE0F Current uncommitted changes:');\n console.log(gitStatus);\n }\n } catch (err: unknown) {\n // Not a git repo\n }\n\n // Copy to clipboard unless disabled\n if (options.copy !== false) {\n try {\n const copyCommand =\n process.platform === 'darwin'\n ? 'pbcopy'\n : process.platform === 'win32'\n ? 'clip'\n : 'xclip -selection clipboard';\n\n execSync(copyCommand, {\n input: handoffPrompt,\n cwd: projectRoot,\n });\n\n console.log('\\n\u2705 Handoff prompt copied to clipboard!');\n } catch (err: unknown) {\n console.log('\\n\u26A0\uFE0F Could not copy to clipboard');\n }\n }\n\n console.log('\\n\uD83D\uDE80 Ready to continue where you left off!');\n } catch (error: unknown) {\n logger.error('Handoff restore failed', error as Error);\n console.error('\u274C Restore failed:', (error as Error).message);\n process.exit(1);\n }\n });\n\n // Auto command - enable auto-capture\n cmd\n .command('auto')\n .description('Enable auto-capture on session termination')\n .option('--command <command>', 'Command to wrap with auto-handoff')\n .action(async (options) => {\n const scriptPath = join(\n __dirname,\n '..',\n '..',\n '..',\n 'scripts',\n 'stackmemory-auto-handoff.sh'\n );\n\n if (!existsSync(scriptPath)) {\n console.error('\u274C Auto-handoff script not found');\n console.log('\uD83D\uDCE6 Please ensure StackMemory is properly installed');\n return;\n }\n\n console.log('\uD83D\uDEE1\uFE0F StackMemory Auto-Handoff');\n console.log('\u2500'.repeat(50));\n\n if (options.command) {\n // Wrap specific command\n console.log(`Wrapping command: ${options.command}`);\n execSync(`${scriptPath} ${options.command}`, {\n stdio: 'inherit',\n env: { ...process.env, AUTO_CAPTURE_ON_EXIT: 'true' },\n });\n } else {\n // Interactive mode\n console.log('To enable auto-handoff for your current session:');\n console.log('');\n console.log(' For bash/zsh:');\n console.log(` source <(${scriptPath} --shell)`);\n console.log('');\n console.log(' Or wrap a command:');\n console.log(` ${scriptPath} claude`);\n console.log(` ${scriptPath} npm run dev`);\n console.log('');\n console.log(' Add to your shell profile for permanent setup:');\n console.log(\n ` echo 'alias claude=\"${scriptPath} claude\"' >> ~/.bashrc`\n );\n }\n });\n\n return cmd;\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * Handoff command - Commits work and generates a prompt for the next session\n */\n\nimport { Command } from 'commander';\nimport { execSync } from 'child_process';\nimport { existsSync, readFileSync, writeFileSync } from 'fs';\nimport { join } from 'path';\nimport Database from 'better-sqlite3';\nimport { FrameManager } from '../../core/context/frame-manager.js';\nimport { PebblesTaskStore } from '../../features/tasks/pebbles-task-store.js';\nimport { logger } from '../../core/monitoring/logger.js';\n// Type-safe environment variable access\nfunction getEnv(key: string, defaultValue?: string): string {\n const value = process.env[key];\n if (value === undefined) {\n if (defaultValue !== undefined) return defaultValue;\n throw new Error(`Environment variable ${key} is required`);\n }\n return value;\n}\n\nfunction getOptionalEnv(key: string): string | undefined {\n return process.env[key];\n}\n\nexport function createHandoffCommand(): Command {\n const cmd = new Command('handoff');\n\n cmd.description('Session handoff for continuity between Claude sessions');\n\n // Default action - capture handoff\n cmd\n .command('capture', { isDefault: true })\n .description('Commit current work and generate a handoff prompt')\n .option('-m, --message <message>', 'Custom commit message')\n .option('--no-commit', 'Skip git commit')\n .option('--copy', 'Copy the handoff prompt to clipboard')\n .action(async (options) => {\n try {\n const projectRoot = process.cwd();\n const dbPath = join(projectRoot, '.stackmemory', 'context.db');\n\n // 1. Check git status\n let gitStatus = '';\n let hasChanges = false;\n\n try {\n gitStatus = execSync('git status --short', {\n encoding: 'utf-8',\n cwd: projectRoot,\n });\n hasChanges = gitStatus.trim().length > 0;\n } catch (err: unknown) {\n console.log('\u26A0\uFE0F Not in a git repository');\n }\n\n // 2. Commit if there are changes and not skipped\n if (hasChanges && options.commit !== false) {\n try {\n // Get current branch\n const currentBranch = execSync('git rev-parse --abbrev-ref HEAD', {\n encoding: 'utf-8',\n cwd: projectRoot,\n }).trim();\n\n // Stage all changes\n execSync('git add -A', { cwd: projectRoot });\n\n // Generate or use custom commit message\n const commitMessage =\n options.message ||\n `chore: handoff checkpoint on ${currentBranch}`;\n\n // Commit\n execSync(`git commit -m \"${commitMessage}\"`, { cwd: projectRoot });\n\n console.log(`\u2705 Committed changes: \"${commitMessage}\"`);\n console.log(` Branch: ${currentBranch}`);\n } catch (err: unknown) {\n console.error(\n '\u274C Failed to commit changes:',\n (err as Error).message\n );\n }\n } else if (!hasChanges) {\n console.log('\u2139\uFE0F No changes to commit');\n }\n\n // 3. Gather context for handoff prompt\n let contextSummary = '';\n let tasksSummary = '';\n let recentWork = '';\n\n if (existsSync(dbPath)) {\n const db = new Database(dbPath);\n\n // Get recent context\n const frameManager = new FrameManager(db, 'cli-project');\n const activeFrames = frameManager.getActiveFramePath();\n\n if (activeFrames.length > 0) {\n contextSummary = 'Active context frames:\\n';\n activeFrames.forEach((frame) => {\n contextSummary += ` - ${frame.name} [${frame.type}]\\n`;\n });\n }\n\n // Get task status\n const taskStore = new PebblesTaskStore(projectRoot, db);\n const activeTasks = taskStore.getActiveTasks();\n\n const inProgress = activeTasks.filter(\n (t: any) => t.status === 'in_progress'\n );\n const todo = activeTasks.filter((t: any) => t.status === 'pending');\n const recentlyCompleted = activeTasks\n .filter((t: any) => t.status === 'completed' && t.completed_at)\n .sort(\n (a: any, b: any) => (b.completed_at || 0) - (a.completed_at || 0)\n )\n .slice(0, 3);\n\n if (inProgress.length > 0 || todo.length > 0) {\n tasksSummary = '\\nTasks:\\n';\n\n if (inProgress.length > 0) {\n tasksSummary += 'In Progress:\\n';\n inProgress.forEach((t: any) => {\n const externalId = t.external_refs?.linear?.id;\n tasksSummary += ` - ${t.title}${externalId ? ` [${externalId}]` : ''}\\n`;\n });\n }\n\n if (todo.length > 0) {\n tasksSummary += 'TODO:\\n';\n todo.slice(0, 5).forEach((t: any) => {\n const externalId = t.external_refs?.linear?.id;\n tasksSummary += ` - ${t.title}${externalId ? ` [${externalId}]` : ''}\\n`;\n });\n if (todo.length > 5) {\n tasksSummary += ` ... and ${todo.length - 5} more\\n`;\n }\n }\n }\n\n if (recentlyCompleted.length > 0) {\n recentWork = '\\nRecently Completed:\\n';\n recentlyCompleted.forEach((t: any) => {\n recentWork += ` \u2713 ${t.title}\\n`;\n });\n }\n\n // Get recent events\n const recentEvents = db\n .prepare(\n `\n SELECT event_type as type, payload as data, datetime(ts, 'unixepoch') as time\n FROM events\n ORDER BY ts DESC\n LIMIT 5\n `\n )\n .all() as any[];\n\n if (recentEvents.length > 0) {\n recentWork += '\\nRecent Activity:\\n';\n recentEvents.forEach((event) => {\n const data = JSON.parse(event.data);\n recentWork += ` - ${event.type}: ${data.message || data.name || 'activity'}\\n`;\n });\n }\n\n db.close();\n }\n\n // 4. Get current git info\n let gitInfo = '';\n try {\n const branch = execSync('git rev-parse --abbrev-ref HEAD', {\n encoding: 'utf-8',\n cwd: projectRoot,\n }).trim();\n\n const lastCommit = execSync('git log -1 --oneline', {\n encoding: 'utf-8',\n cwd: projectRoot,\n }).trim();\n\n gitInfo = `\\nGit Status:\\n Branch: ${branch}\\n Last commit: ${lastCommit}\\n`;\n } catch (err: unknown) {\n // Ignore git errors\n }\n\n // 5. Check for any blockers or notes\n let notes = '';\n const notesPath = join(projectRoot, '.stackmemory', 'handoff.md');\n if (existsSync(notesPath)) {\n const handoffNotes = readFileSync(notesPath, 'utf-8');\n if (handoffNotes.trim()) {\n notes = `\\nNotes from previous handoff:\\n${handoffNotes}\\n`;\n }\n }\n\n // 6. Generate the handoff prompt\n const timestamp = new Date().toISOString();\n const handoffPrompt = `# Session Handoff - ${timestamp}\n\n## Project: ${projectRoot.split('/').pop()}\n\n${gitInfo}\n${contextSummary}\n${tasksSummary}\n${recentWork}\n${notes}\n\n## Continue from here:\n\n1. Run \\`stackmemory status\\` to check the current state\n2. Review any in-progress tasks above\n3. Check for any uncommitted changes with \\`git status\\`\n4. Resume work on the active context\n\n## Quick Commands:\n- \\`stackmemory context load --recent\\` - Load recent context\n- \\`stackmemory task list --state in_progress\\` - Show in-progress tasks\n- \\`stackmemory linear sync\\` - Sync with Linear if configured\n- \\`stackmemory log recent\\` - View recent activity\n\n---\nGenerated by stackmemory handoff at ${timestamp}\n`;\n\n // 7. Save handoff prompt\n const handoffPath = join(\n projectRoot,\n '.stackmemory',\n 'last-handoff.md'\n );\n writeFileSync(handoffPath, handoffPrompt);\n\n // 8. Display the prompt\n console.log('\\n' + '='.repeat(60));\n console.log(handoffPrompt);\n console.log('='.repeat(60));\n\n // 9. Copy to clipboard if requested\n if (options.copy) {\n try {\n const copyCommand =\n process.platform === 'darwin'\n ? 'pbcopy'\n : process.platform === 'win32'\n ? 'clip'\n : 'xclip -selection clipboard';\n\n execSync(copyCommand, {\n input: handoffPrompt,\n cwd: projectRoot,\n });\n\n console.log('\\n\u2705 Handoff prompt copied to clipboard!');\n } catch (err: unknown) {\n console.log('\\n\u26A0\uFE0F Could not copy to clipboard');\n }\n }\n\n console.log(`\\n\uD83D\uDCBE Handoff saved to: ${handoffPath}`);\n console.log('\uD83D\uDCCB Use this prompt when starting your next session');\n } catch (error: unknown) {\n logger.error('Handoff command failed', error as Error);\n console.error('\u274C Handoff failed:', (error as Error).message);\n process.exit(1);\n }\n });\n\n // Restore command\n cmd\n .command('restore')\n .description('Restore context from last handoff')\n .option('--no-copy', 'Do not copy prompt to clipboard')\n .action(async (options) => {\n try {\n const projectRoot = process.cwd();\n const handoffPath = join(\n projectRoot,\n '.stackmemory',\n 'last-handoff.md'\n );\n const metaPath = join(\n process.env['HOME'] || '~',\n '.stackmemory',\n 'handoffs',\n 'last-handoff-meta.json'\n );\n\n if (!existsSync(handoffPath)) {\n console.log('\u274C No handoff found in this project');\n console.log('\uD83D\uDCA1 Run \"stackmemory handoff\" to create one');\n return;\n }\n\n // Read handoff prompt\n const handoffPrompt = readFileSync(handoffPath, 'utf-8');\n\n // Display the prompt\n console.log('\\n' + '='.repeat(60));\n console.log('\uD83D\uDCCB RESTORED HANDOFF');\n console.log('='.repeat(60));\n console.log(handoffPrompt);\n console.log('='.repeat(60));\n\n // Check for metadata\n if (existsSync(metaPath)) {\n const metadata = JSON.parse(readFileSync(metaPath, 'utf-8'));\n console.log('\\n\uD83D\uDCCA Session Metadata:');\n console.log(` Timestamp: ${metadata.timestamp}`);\n console.log(` Reason: ${metadata.reason}`);\n console.log(` Duration: ${metadata.session_duration}s`);\n console.log(` Command: ${metadata.command}`);\n }\n\n // Check current git status\n try {\n const gitStatus = execSync('git status --short', {\n encoding: 'utf-8',\n }).trim();\n if (gitStatus) {\n console.log('\\n\u26A0\uFE0F Current uncommitted changes:');\n console.log(gitStatus);\n }\n } catch (err: unknown) {\n // Not a git repo\n }\n\n // Copy to clipboard unless disabled\n if (options.copy !== false) {\n try {\n const copyCommand =\n process.platform === 'darwin'\n ? 'pbcopy'\n : process.platform === 'win32'\n ? 'clip'\n : 'xclip -selection clipboard';\n\n execSync(copyCommand, {\n input: handoffPrompt,\n cwd: projectRoot,\n });\n\n console.log('\\n\u2705 Handoff prompt copied to clipboard!');\n } catch (err: unknown) {\n console.log('\\n\u26A0\uFE0F Could not copy to clipboard');\n }\n }\n\n console.log('\\n\uD83D\uDE80 Ready to continue where you left off!');\n } catch (error: unknown) {\n logger.error('Handoff restore failed', error as Error);\n console.error('\u274C Restore failed:', (error as Error).message);\n process.exit(1);\n }\n });\n\n // Auto command - enable auto-capture\n cmd\n .command('auto')\n .description('Enable auto-capture on session termination')\n .option('--command <command>', 'Command to wrap with auto-handoff')\n .action(async (options) => {\n const scriptPath = join(\n __dirname,\n '..',\n '..',\n '..',\n 'scripts',\n 'stackmemory-auto-handoff.sh'\n );\n\n if (!existsSync(scriptPath)) {\n console.error('\u274C Auto-handoff script not found');\n console.log('\uD83D\uDCE6 Please ensure StackMemory is properly installed');\n return;\n }\n\n console.log('\uD83D\uDEE1\uFE0F StackMemory Auto-Handoff');\n console.log('\u2500'.repeat(50));\n\n if (options.command) {\n // Wrap specific command\n console.log(`Wrapping command: ${options.command}`);\n execSync(`${scriptPath} ${options.command}`, {\n stdio: 'inherit',\n env: { ...process.env, AUTO_CAPTURE_ON_EXIT: 'true' },\n });\n } else {\n // Interactive mode\n console.log('To enable auto-handoff for your current session:');\n console.log('');\n console.log(' For bash/zsh:');\n console.log(` source <(${scriptPath} --shell)`);\n console.log('');\n console.log(' Or wrap a command:');\n console.log(` ${scriptPath} claude`);\n console.log(` ${scriptPath} npm run dev`);\n console.log('');\n console.log(' Add to your shell profile for permanent setup:');\n console.log(\n ` echo 'alias claude=\"${scriptPath} claude\"' >> ~/.bashrc`\n );\n }\n });\n\n return cmd;\n}\n"],
5
+ "mappings": "AAIA,SAAS,eAAe;AACxB,SAAS,gBAAgB;AACzB,SAAS,YAAY,cAAc,qBAAqB;AACxD,SAAS,YAAY;AACrB,OAAO,cAAc;AACrB,SAAS,oBAAoB;AAC7B,SAAS,wBAAwB;AACjC,SAAS,cAAc;AAEvB,SAAS,OAAO,KAAa,cAA+B;AAC1D,QAAM,QAAQ,QAAQ,IAAI,GAAG;AAC7B,MAAI,UAAU,QAAW;AACvB,QAAI,iBAAiB,OAAW,QAAO;AACvC,UAAM,IAAI,MAAM,wBAAwB,GAAG,cAAc;AAAA,EAC3D;AACA,SAAO;AACT;AAEA,SAAS,eAAe,KAAiC;AACvD,SAAO,QAAQ,IAAI,GAAG;AACxB;AAEO,SAAS,uBAAgC;AAC9C,QAAM,MAAM,IAAI,QAAQ,SAAS;AAEjC,MAAI,YAAY,wDAAwD;AAGxE,MACG,QAAQ,WAAW,EAAE,WAAW,KAAK,CAAC,EACtC,YAAY,mDAAmD,EAC/D,OAAO,2BAA2B,uBAAuB,EACzD,OAAO,eAAe,iBAAiB,EACvC,OAAO,UAAU,sCAAsC,EACvD,OAAO,OAAO,YAAY;AACzB,QAAI;AACF,YAAM,cAAc,QAAQ,IAAI;AAChC,YAAM,SAAS,KAAK,aAAa,gBAAgB,YAAY;AAG7D,UAAI,YAAY;AAChB,UAAI,aAAa;AAEjB,UAAI;AACF,oBAAY,SAAS,sBAAsB;AAAA,UACzC,UAAU;AAAA,UACV,KAAK;AAAA,QACP,CAAC;AACD,qBAAa,UAAU,KAAK,EAAE,SAAS;AAAA,MACzC,SAAS,KAAc;AACrB,gBAAQ,IAAI,uCAA6B;AAAA,MAC3C;AAGA,UAAI,cAAc,QAAQ,WAAW,OAAO;AAC1C,YAAI;AAEF,gBAAM,gBAAgB,SAAS,mCAAmC;AAAA,YAChE,UAAU;AAAA,YACV,KAAK;AAAA,UACP,CAAC,EAAE,KAAK;AAGR,mBAAS,cAAc,EAAE,KAAK,YAAY,CAAC;AAG3C,gBAAM,gBACJ,QAAQ,WACR,gCAAgC,aAAa;AAG/C,mBAAS,kBAAkB,aAAa,KAAK,EAAE,KAAK,YAAY,CAAC;AAEjE,kBAAQ,IAAI,8BAAyB,aAAa,GAAG;AACrD,kBAAQ,IAAI,cAAc,aAAa,EAAE;AAAA,QAC3C,SAAS,KAAc;AACrB,kBAAQ;AAAA,YACN;AAAA,YACC,IAAc;AAAA,UACjB;AAAA,QACF;AAAA,MACF,WAAW,CAAC,YAAY;AACtB,gBAAQ,IAAI,oCAA0B;AAAA,MACxC;AAGA,UAAI,iBAAiB;AACrB,UAAI,eAAe;AACnB,UAAI,aAAa;AAEjB,UAAI,WAAW,MAAM,GAAG;AACtB,cAAM,KAAK,IAAI,SAAS,MAAM;AAG9B,cAAM,eAAe,IAAI,aAAa,IAAI,aAAa;AACvD,cAAM,eAAe,aAAa,mBAAmB;AAErD,YAAI,aAAa,SAAS,GAAG;AAC3B,2BAAiB;AACjB,uBAAa,QAAQ,CAAC,UAAU;AAC9B,8BAAkB,OAAO,MAAM,IAAI,KAAK,MAAM,IAAI;AAAA;AAAA,UACpD,CAAC;AAAA,QACH;AAGA,cAAM,YAAY,IAAI,iBAAiB,aAAa,EAAE;AACtD,cAAM,cAAc,UAAU,eAAe;AAE7C,cAAM,aAAa,YAAY;AAAA,UAC7B,CAAC,MAAW,EAAE,WAAW;AAAA,QAC3B;AACA,cAAM,OAAO,YAAY,OAAO,CAAC,MAAW,EAAE,WAAW,SAAS;AAClE,cAAM,oBAAoB,YACvB,OAAO,CAAC,MAAW,EAAE,WAAW,eAAe,EAAE,YAAY,EAC7D;AAAA,UACC,CAAC,GAAQ,OAAY,EAAE,gBAAgB,MAAM,EAAE,gBAAgB;AAAA,QACjE,EACC,MAAM,GAAG,CAAC;AAEb,YAAI,WAAW,SAAS,KAAK,KAAK,SAAS,GAAG;AAC5C,yBAAe;AAEf,cAAI,WAAW,SAAS,GAAG;AACzB,4BAAgB;AAChB,uBAAW,QAAQ,CAAC,MAAW;AAC7B,oBAAM,aAAa,EAAE,eAAe,QAAQ;AAC5C,8BAAgB,OAAO,EAAE,KAAK,GAAG,aAAa,KAAK,UAAU,MAAM,EAAE;AAAA;AAAA,YACvE,CAAC;AAAA,UACH;AAEA,cAAI,KAAK,SAAS,GAAG;AACnB,4BAAgB;AAChB,iBAAK,MAAM,GAAG,CAAC,EAAE,QAAQ,CAAC,MAAW;AACnC,oBAAM,aAAa,EAAE,eAAe,QAAQ;AAC5C,8BAAgB,OAAO,EAAE,KAAK,GAAG,aAAa,KAAK,UAAU,MAAM,EAAE;AAAA;AAAA,YACvE,CAAC;AACD,gBAAI,KAAK,SAAS,GAAG;AACnB,8BAAgB,aAAa,KAAK,SAAS,CAAC;AAAA;AAAA,YAC9C;AAAA,UACF;AAAA,QACF;AAEA,YAAI,kBAAkB,SAAS,GAAG;AAChC,uBAAa;AACb,4BAAkB,QAAQ,CAAC,MAAW;AACpC,0BAAc,YAAO,EAAE,KAAK;AAAA;AAAA,UAC9B,CAAC;AAAA,QACH;AAGA,cAAM,eAAe,GAClB;AAAA,UACC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAMF,EACC,IAAI;AAEP,YAAI,aAAa,SAAS,GAAG;AAC3B,wBAAc;AACd,uBAAa,QAAQ,CAAC,UAAU;AAC9B,kBAAM,OAAO,KAAK,MAAM,MAAM,IAAI;AAClC,0BAAc,OAAO,MAAM,IAAI,KAAK,KAAK,WAAW,KAAK,QAAQ,UAAU;AAAA;AAAA,UAC7E,CAAC;AAAA,QACH;AAEA,WAAG,MAAM;AAAA,MACX;AAGA,UAAI,UAAU;AACd,UAAI;AACF,cAAM,SAAS,SAAS,mCAAmC;AAAA,UACzD,UAAU;AAAA,UACV,KAAK;AAAA,QACP,CAAC,EAAE,KAAK;AAER,cAAM,aAAa,SAAS,wBAAwB;AAAA,UAClD,UAAU;AAAA,UACV,KAAK;AAAA,QACP,CAAC,EAAE,KAAK;AAER,kBAAU;AAAA;AAAA,YAA4B,MAAM;AAAA,iBAAoB,UAAU;AAAA;AAAA,MAC5E,SAAS,KAAc;AAAA,MAEvB;AAGA,UAAI,QAAQ;AACZ,YAAM,YAAY,KAAK,aAAa,gBAAgB,YAAY;AAChE,UAAI,WAAW,SAAS,GAAG;AACzB,cAAM,eAAe,aAAa,WAAW,OAAO;AACpD,YAAI,aAAa,KAAK,GAAG;AACvB,kBAAQ;AAAA;AAAA,EAAmC,YAAY;AAAA;AAAA,QACzD;AAAA,MACF;AAGA,YAAM,aAAY,oBAAI,KAAK,GAAE,YAAY;AACzC,YAAM,gBAAgB,uBAAuB,SAAS;AAAA;AAAA,cAEhD,YAAY,MAAM,GAAG,EAAE,IAAI,CAAC;AAAA;AAAA,EAExC,OAAO;AAAA,EACP,cAAc;AAAA,EACd,YAAY;AAAA,EACZ,UAAU;AAAA,EACV,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sCAgB+B,SAAS;AAAA;AAIvC,YAAM,cAAc;AAAA,QAClB;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACA,oBAAc,aAAa,aAAa;AAGxC,cAAQ,IAAI,OAAO,IAAI,OAAO,EAAE,CAAC;AACjC,cAAQ,IAAI,aAAa;AACzB,cAAQ,IAAI,IAAI,OAAO,EAAE,CAAC;AAG1B,UAAI,QAAQ,MAAM;AAChB,YAAI;AACF,gBAAM,cACJ,QAAQ,aAAa,WACjB,WACA,QAAQ,aAAa,UACnB,SACA;AAER,mBAAS,aAAa;AAAA,YACpB,OAAO;AAAA,YACP,KAAK;AAAA,UACP,CAAC;AAED,kBAAQ,IAAI,8CAAyC;AAAA,QACvD,SAAS,KAAc;AACrB,kBAAQ,IAAI,6CAAmC;AAAA,QACjD;AAAA,MACF;AAEA,cAAQ,IAAI;AAAA,8BAA0B,WAAW,EAAE;AACnD,cAAQ,IAAI,2DAAoD;AAAA,IAClE,SAAS,OAAgB;AACvB,aAAO,MAAM,0BAA0B,KAAc;AACrD,cAAQ,MAAM,0BAAsB,MAAgB,OAAO;AAC3D,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,CAAC;AAGH,MACG,QAAQ,SAAS,EACjB,YAAY,mCAAmC,EAC/C,OAAO,aAAa,iCAAiC,EACrD,OAAO,OAAO,YAAY;AACzB,QAAI;AACF,YAAM,cAAc,QAAQ,IAAI;AAChC,YAAM,cAAc;AAAA,QAClB;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACA,YAAM,WAAW;AAAA,QACf,QAAQ,IAAI,MAAM,KAAK;AAAA,QACvB;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAEA,UAAI,CAAC,WAAW,WAAW,GAAG;AAC5B,gBAAQ,IAAI,yCAAoC;AAChD,gBAAQ,IAAI,mDAA4C;AACxD;AAAA,MACF;AAGA,YAAM,gBAAgB,aAAa,aAAa,OAAO;AAGvD,cAAQ,IAAI,OAAO,IAAI,OAAO,EAAE,CAAC;AACjC,cAAQ,IAAI,4BAAqB;AACjC,cAAQ,IAAI,IAAI,OAAO,EAAE,CAAC;AAC1B,cAAQ,IAAI,aAAa;AACzB,cAAQ,IAAI,IAAI,OAAO,EAAE,CAAC;AAG1B,UAAI,WAAW,QAAQ,GAAG;AACxB,cAAM,WAAW,KAAK,MAAM,aAAa,UAAU,OAAO,CAAC;AAC3D,gBAAQ,IAAI,+BAAwB;AACpC,gBAAQ,IAAI,gBAAgB,SAAS,SAAS,EAAE;AAChD,gBAAQ,IAAI,aAAa,SAAS,MAAM,EAAE;AAC1C,gBAAQ,IAAI,eAAe,SAAS,gBAAgB,GAAG;AACvD,gBAAQ,IAAI,cAAc,SAAS,OAAO,EAAE;AAAA,MAC9C;AAGA,UAAI;AACF,cAAM,YAAY,SAAS,sBAAsB;AAAA,UAC/C,UAAU;AAAA,QACZ,CAAC,EAAE,KAAK;AACR,YAAI,WAAW;AACb,kBAAQ,IAAI,8CAAoC;AAChD,kBAAQ,IAAI,SAAS;AAAA,QACvB;AAAA,MACF,SAAS,KAAc;AAAA,MAEvB;AAGA,UAAI,QAAQ,SAAS,OAAO;AAC1B,YAAI;AACF,gBAAM,cACJ,QAAQ,aAAa,WACjB,WACA,QAAQ,aAAa,UACnB,SACA;AAER,mBAAS,aAAa;AAAA,YACpB,OAAO;AAAA,YACP,KAAK;AAAA,UACP,CAAC;AAED,kBAAQ,IAAI,8CAAyC;AAAA,QACvD,SAAS,KAAc;AACrB,kBAAQ,IAAI,6CAAmC;AAAA,QACjD;AAAA,MACF;AAEA,cAAQ,IAAI,mDAA4C;AAAA,IAC1D,SAAS,OAAgB;AACvB,aAAO,MAAM,0BAA0B,KAAc;AACrD,cAAQ,MAAM,0BAAsB,MAAgB,OAAO;AAC3D,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,CAAC;AAGH,MACG,QAAQ,MAAM,EACd,YAAY,4CAA4C,EACxD,OAAO,uBAAuB,mCAAmC,EACjE,OAAO,OAAO,YAAY;AACzB,UAAM,aAAa;AAAA,MACjB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,QAAI,CAAC,WAAW,UAAU,GAAG;AAC3B,cAAQ,MAAM,sCAAiC;AAC/C,cAAQ,IAAI,2DAAoD;AAChE;AAAA,IACF;AAEA,YAAQ,IAAI,2CAA+B;AAC3C,YAAQ,IAAI,SAAI,OAAO,EAAE,CAAC;AAE1B,QAAI,QAAQ,SAAS;AAEnB,cAAQ,IAAI,qBAAqB,QAAQ,OAAO,EAAE;AAClD,eAAS,GAAG,UAAU,IAAI,QAAQ,OAAO,IAAI;AAAA,QAC3C,OAAO;AAAA,QACP,KAAK,EAAE,GAAG,QAAQ,KAAK,sBAAsB,OAAO;AAAA,MACtD,CAAC;AAAA,IACH,OAAO;AAEL,cAAQ,IAAI,kDAAkD;AAC9D,cAAQ,IAAI,EAAE;AACd,cAAQ,IAAI,iBAAiB;AAC7B,cAAQ,IAAI,gBAAgB,UAAU,WAAW;AACjD,cAAQ,IAAI,EAAE;AACd,cAAQ,IAAI,sBAAsB;AAClC,cAAQ,IAAI,OAAO,UAAU,SAAS;AACtC,cAAQ,IAAI,OAAO,UAAU,cAAc;AAC3C,cAAQ,IAAI,EAAE;AACd,cAAQ,IAAI,kDAAkD;AAC9D,cAAQ;AAAA,QACN,2BAA2B,UAAU;AAAA,MACvC;AAAA,IACF;AAAA,EACF,CAAC;AAEH,SAAO;AACT;",
6
6
  "names": []
7
7
  }
@@ -2,7 +2,9 @@ import { Command } from "commander";
2
2
  import chalk from "chalk";
3
3
  import ora from "ora";
4
4
  import Table from "cli-table3";
5
- import { InfiniteStorageSystem } from "../../core/storage/infinite-storage.js";
5
+ import {
6
+ InfiniteStorageSystem
7
+ } from "../../core/storage/infinite-storage.js";
6
8
  import { FrameManager } from "../../core/context/frame-manager.js";
7
9
  import { Logger } from "../../core/monitoring/logger.js";
8
10
  import dotenv from "dotenv";
@@ -70,12 +72,17 @@ function createInfiniteStorageCommand() {
70
72
  }
71
73
  if (updates.length > 0) {
72
74
  const fs = await import("fs");
73
- fs.appendFileSync(envPath, "\n# Infinite Storage Configuration\n" + updates.join("\n") + "\n");
75
+ fs.appendFileSync(
76
+ envPath,
77
+ "\n# Infinite Storage Configuration\n" + updates.join("\n") + "\n"
78
+ );
74
79
  }
75
80
  } catch (error) {
76
81
  spinner.fail("Failed to initialize storage");
77
82
  logger.error("Initialization error", error);
78
- console.error(chalk.red(error instanceof Error ? error.message : "Unknown error"));
83
+ console.error(
84
+ chalk.red(error instanceof Error ? error.message : "Unknown error")
85
+ );
79
86
  }
80
87
  });
81
88
  storage.command("store").description("Store current frames in infinite storage").option("--project <name>", "Project name").option("--user <id>", "User ID").action(async (options) => {
@@ -94,7 +101,9 @@ function createInfiniteStorageCommand() {
94
101
  } catch (error) {
95
102
  spinner.fail("Failed to store frames");
96
103
  logger.error("Store error", error);
97
- console.error(chalk.red(error instanceof Error ? error.message : "Unknown error"));
104
+ console.error(
105
+ chalk.red(error instanceof Error ? error.message : "Unknown error")
106
+ );
98
107
  }
99
108
  });
100
109
  storage.command("retrieve <frameId>").description("Retrieve a frame from storage").option("--user <id>", "User ID").action(async (frameId, options) => {
@@ -115,7 +124,9 @@ function createInfiniteStorageCommand() {
115
124
  } catch (error) {
116
125
  spinner.fail("Failed to retrieve frame");
117
126
  logger.error("Retrieve error", error);
118
- console.error(chalk.red(error instanceof Error ? error.message : "Unknown error"));
127
+ console.error(
128
+ chalk.red(error instanceof Error ? error.message : "Unknown error")
129
+ );
119
130
  }
120
131
  });
121
132
  storage.command("metrics").description("Show storage system metrics").action(async () => {
@@ -141,20 +152,30 @@ function createInfiniteStorageCommand() {
141
152
  console.log(table.toString());
142
153
  if (Object.keys(metrics.tierDistribution).length > 0) {
143
154
  console.log("\nTier Distribution:");
144
- for (const [tier, count] of Object.entries(metrics.tierDistribution)) {
145
- const percentage = (count / metrics.totalObjects * 100).toFixed(1);
155
+ for (const [tier, count] of Object.entries(
156
+ metrics.tierDistribution
157
+ )) {
158
+ const percentage = (count / metrics.totalObjects * 100).toFixed(
159
+ 1
160
+ );
146
161
  console.log(` ${tier}: ${count} objects (${percentage}%)`);
147
162
  }
148
163
  }
149
164
  console.log(chalk.cyan("\n\u{1F3AF} STA-287 Performance Targets:"));
150
165
  const p50Target = metrics.p50LatencyMs <= 50;
151
166
  const p99Target = metrics.p99LatencyMs <= 500;
152
- console.log(` P50 \u2264 50ms: ${p50Target ? chalk.green("\u2705 PASS") : chalk.red("\u274C FAIL")} (${metrics.p50LatencyMs}ms)`);
153
- console.log(` P99 \u2264 500ms: ${p99Target ? chalk.green("\u2705 PASS") : chalk.red("\u274C FAIL")} (${metrics.p99LatencyMs}ms)`);
167
+ console.log(
168
+ ` P50 \u2264 50ms: ${p50Target ? chalk.green("\u2705 PASS") : chalk.red("\u274C FAIL")} (${metrics.p50LatencyMs}ms)`
169
+ );
170
+ console.log(
171
+ ` P99 \u2264 500ms: ${p99Target ? chalk.green("\u2705 PASS") : chalk.red("\u274C FAIL")} (${metrics.p99LatencyMs}ms)`
172
+ );
154
173
  } catch (error) {
155
174
  spinner.fail("Failed to get metrics");
156
175
  logger.error("Metrics error", error);
157
- console.error(chalk.red(error instanceof Error ? error.message : "Unknown error"));
176
+ console.error(
177
+ chalk.red(error instanceof Error ? error.message : "Unknown error")
178
+ );
158
179
  }
159
180
  });
160
181
  storage.command("migrate").description("Manually trigger tier migration").action(async () => {
@@ -168,7 +189,9 @@ function createInfiniteStorageCommand() {
168
189
  } catch (error) {
169
190
  spinner.fail("Migration failed");
170
191
  logger.error("Migration error", error);
171
- console.error(chalk.red(error instanceof Error ? error.message : "Unknown error"));
192
+ console.error(
193
+ chalk.red(error instanceof Error ? error.message : "Unknown error")
194
+ );
172
195
  }
173
196
  });
174
197
  storage.command("status").description("Check storage system status").action(async () => {
@@ -194,26 +217,44 @@ function createInfiniteStorageCommand() {
194
217
  if (config.timeseries?.connectionString) {
195
218
  try {
196
219
  const { Pool } = await import("pg");
197
- const pool = new Pool({ connectionString: config.timeseries.connectionString });
220
+ const pool = new Pool({
221
+ connectionString: config.timeseries.connectionString
222
+ });
198
223
  await pool.query("SELECT 1");
199
224
  await pool.end();
200
- console.log("TimeSeries DB (Warm Tier): " + chalk.green("\u2705 Connected"));
225
+ console.log(
226
+ "TimeSeries DB (Warm Tier): " + chalk.green("\u2705 Connected")
227
+ );
201
228
  } catch {
202
- console.log("TimeSeries DB (Warm Tier): " + chalk.red("\u274C Not connected"));
229
+ console.log(
230
+ "TimeSeries DB (Warm Tier): " + chalk.red("\u274C Not connected")
231
+ );
203
232
  }
204
233
  } else {
205
- console.log("TimeSeries DB (Warm Tier): " + chalk.yellow("\u26A0\uFE0F Not configured"));
234
+ console.log(
235
+ "TimeSeries DB (Warm Tier): " + chalk.yellow("\u26A0\uFE0F Not configured")
236
+ );
206
237
  }
207
238
  if (config.s3?.bucket) {
208
- console.log(`S3 (Cold/Archive Tier): ${chalk.green("\u2705")} Bucket: ${config.s3.bucket}`);
239
+ console.log(
240
+ `S3 (Cold/Archive Tier): ${chalk.green("\u2705")} Bucket: ${config.s3.bucket}`
241
+ );
209
242
  } else {
210
- console.log("S3 (Cold/Archive Tier): " + chalk.yellow("\u26A0\uFE0F Not configured"));
243
+ console.log(
244
+ "S3 (Cold/Archive Tier): " + chalk.yellow("\u26A0\uFE0F Not configured")
245
+ );
211
246
  }
212
- console.log("\n" + chalk.gray("Configure missing tiers with: stackmemory infinite-storage init"));
247
+ console.log(
248
+ "\n" + chalk.gray(
249
+ "Configure missing tiers with: stackmemory infinite-storage init"
250
+ )
251
+ );
213
252
  } catch (error) {
214
253
  spinner.fail("Failed to check status");
215
254
  logger.error("Status error", error);
216
- console.error(chalk.red(error instanceof Error ? error.message : "Unknown error"));
255
+ console.error(
256
+ chalk.red(error instanceof Error ? error.message : "Unknown error")
257
+ );
217
258
  }
218
259
  });
219
260
  return storage;