@stackmemoryai/stackmemory 0.3.6 → 0.3.7

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/dist/agents/verifiers/base-verifier.js.map +2 -2
  2. package/dist/agents/verifiers/formatter-verifier.js.map +2 -2
  3. package/dist/agents/verifiers/llm-judge.js.map +2 -2
  4. package/dist/cli/claude-sm.js +24 -13
  5. package/dist/cli/claude-sm.js.map +2 -2
  6. package/dist/cli/codex-sm.js +24 -13
  7. package/dist/cli/codex-sm.js.map +2 -2
  8. package/dist/cli/commands/agent.js.map +2 -2
  9. package/dist/cli/commands/chromadb.js +217 -32
  10. package/dist/cli/commands/chromadb.js.map +2 -2
  11. package/dist/cli/commands/clear.js +12 -1
  12. package/dist/cli/commands/clear.js.map +2 -2
  13. package/dist/cli/commands/context.js +13 -2
  14. package/dist/cli/commands/context.js.map +2 -2
  15. package/dist/cli/commands/dashboard.js.map +2 -2
  16. package/dist/cli/commands/gc.js +202 -0
  17. package/dist/cli/commands/gc.js.map +7 -0
  18. package/dist/cli/commands/handoff.js +12 -1
  19. package/dist/cli/commands/handoff.js.map +2 -2
  20. package/dist/cli/commands/infinite-storage.js +32 -21
  21. package/dist/cli/commands/infinite-storage.js.map +2 -2
  22. package/dist/cli/commands/linear-create.js +13 -2
  23. package/dist/cli/commands/linear-create.js.map +2 -2
  24. package/dist/cli/commands/linear-list.js +12 -1
  25. package/dist/cli/commands/linear-list.js.map +2 -2
  26. package/dist/cli/commands/linear-migrate.js +12 -1
  27. package/dist/cli/commands/linear-migrate.js.map +2 -2
  28. package/dist/cli/commands/linear-test.js +12 -1
  29. package/dist/cli/commands/linear-test.js.map +2 -2
  30. package/dist/cli/commands/linear-unified.js +262 -0
  31. package/dist/cli/commands/linear-unified.js.map +7 -0
  32. package/dist/cli/commands/linear.js +17 -6
  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.map +2 -2
  36. package/dist/cli/commands/quality.js.map +2 -2
  37. package/dist/cli/commands/search.js.map +2 -2
  38. package/dist/cli/commands/session.js.map +2 -2
  39. package/dist/cli/commands/skills.js +12 -1
  40. package/dist/cli/commands/skills.js.map +2 -2
  41. package/dist/cli/commands/storage.js +18 -7
  42. package/dist/cli/commands/storage.js.map +2 -2
  43. package/dist/cli/commands/tasks.js.map +2 -2
  44. package/dist/cli/commands/tui.js +13 -2
  45. package/dist/cli/commands/tui.js.map +2 -2
  46. package/dist/cli/commands/webhook.js +14 -3
  47. package/dist/cli/commands/webhook.js.map +2 -2
  48. package/dist/cli/commands/workflow.js +14 -3
  49. package/dist/cli/commands/workflow.js.map +2 -2
  50. package/dist/cli/commands/worktree.js.map +2 -2
  51. package/dist/cli/index.js +18 -5
  52. package/dist/cli/index.js.map +2 -2
  53. package/dist/core/config/config-manager.js.map +2 -2
  54. package/dist/core/context/auto-context.js.map +2 -2
  55. package/dist/core/context/compaction-handler.js.map +2 -2
  56. package/dist/core/context/context-bridge.js.map +2 -2
  57. package/dist/core/context/dual-stack-manager.js.map +2 -2
  58. package/dist/core/context/frame-database.js.map +2 -2
  59. package/dist/core/context/frame-digest.js.map +2 -2
  60. package/dist/core/context/frame-handoff-manager.js.map +2 -2
  61. package/dist/core/context/frame-manager.js +12 -1
  62. package/dist/core/context/frame-manager.js.map +2 -2
  63. package/dist/core/context/frame-stack.js.map +2 -2
  64. package/dist/core/context/incremental-gc.js +279 -0
  65. package/dist/core/context/incremental-gc.js.map +7 -0
  66. package/dist/core/context/permission-manager.js +12 -1
  67. package/dist/core/context/permission-manager.js.map +2 -2
  68. package/dist/core/context/refactored-frame-manager.js.map +2 -2
  69. package/dist/core/context/shared-context-layer.js +12 -1
  70. package/dist/core/context/shared-context-layer.js.map +2 -2
  71. package/dist/core/context/stack-merge-resolver.js.map +2 -2
  72. package/dist/core/context/validation.js.map +2 -2
  73. package/dist/core/database/batch-operations.js.map +2 -2
  74. package/dist/core/database/connection-pool.js.map +2 -2
  75. package/dist/core/database/migration-manager.js.map +2 -2
  76. package/dist/core/database/paradedb-adapter.js.map +2 -2
  77. package/dist/core/database/query-cache.js.map +2 -2
  78. package/dist/core/database/query-router.js.map +2 -2
  79. package/dist/core/database/sqlite-adapter.js.map +2 -2
  80. package/dist/core/digest/enhanced-hybrid-digest.js.map +2 -2
  81. package/dist/core/errors/recovery.js.map +2 -2
  82. package/dist/core/merge/resolution-engine.js.map +2 -2
  83. package/dist/core/monitoring/error-handler.js.map +2 -2
  84. package/dist/core/monitoring/logger.js +14 -3
  85. package/dist/core/monitoring/logger.js.map +2 -2
  86. package/dist/core/monitoring/metrics.js +13 -2
  87. package/dist/core/monitoring/metrics.js.map +2 -2
  88. package/dist/core/monitoring/progress-tracker.js +12 -1
  89. package/dist/core/monitoring/progress-tracker.js.map +2 -2
  90. package/dist/core/monitoring/session-monitor.js.map +2 -2
  91. package/dist/core/performance/context-cache.js.map +2 -2
  92. package/dist/core/performance/lazy-context-loader.js.map +2 -2
  93. package/dist/core/performance/monitor.js.map +2 -2
  94. package/dist/core/performance/optimized-frame-context.js.map +2 -2
  95. package/dist/core/performance/performance-benchmark.js.map +2 -2
  96. package/dist/core/performance/performance-profiler.js +12 -1
  97. package/dist/core/performance/performance-profiler.js.map +2 -2
  98. package/dist/core/performance/streaming-jsonl-parser.js.map +2 -2
  99. package/dist/core/persistence/postgres-adapter.js.map +2 -2
  100. package/dist/core/projects/project-manager.js.map +2 -2
  101. package/dist/core/retrieval/context-retriever.js.map +2 -2
  102. package/dist/core/retrieval/graph-retrieval.js.map +2 -2
  103. package/dist/core/retrieval/llm-context-retrieval.js.map +2 -2
  104. package/dist/core/retrieval/retrieval-benchmarks.js.map +2 -2
  105. package/dist/core/retrieval/summary-generator.js.map +2 -2
  106. package/dist/core/session/clear-survival.js.map +2 -2
  107. package/dist/core/session/handoff-generator.js.map +2 -2
  108. package/dist/core/session/session-manager.js +16 -5
  109. package/dist/core/session/session-manager.js.map +2 -2
  110. package/dist/core/skills/skill-storage.js +13 -2
  111. package/dist/core/skills/skill-storage.js.map +2 -2
  112. package/dist/core/storage/chromadb-adapter.js.map +2 -2
  113. package/dist/core/storage/chromadb-simple.js.map +2 -2
  114. package/dist/core/storage/infinite-storage.js.map +2 -2
  115. package/dist/core/storage/railway-optimized-storage.js +19 -8
  116. package/dist/core/storage/railway-optimized-storage.js.map +2 -2
  117. package/dist/core/storage/remote-storage.js +12 -1
  118. package/dist/core/storage/remote-storage.js.map +2 -2
  119. package/dist/core/trace/cli-trace-wrapper.js +16 -5
  120. package/dist/core/trace/cli-trace-wrapper.js.map +2 -2
  121. package/dist/core/trace/db-trace-wrapper.js.map +2 -2
  122. package/dist/core/trace/debug-trace.js +21 -10
  123. package/dist/core/trace/debug-trace.js.map +2 -2
  124. package/dist/core/trace/index.js +46 -35
  125. package/dist/core/trace/index.js.map +2 -2
  126. package/dist/core/trace/trace-demo.js +12 -1
  127. package/dist/core/trace/trace-demo.js.map +2 -2
  128. package/dist/core/trace/trace-detector.js.map +2 -2
  129. package/dist/core/trace/trace-store.js.map +2 -2
  130. package/dist/core/utils/update-checker.js.map +2 -2
  131. package/dist/core/worktree/worktree-manager.js.map +2 -2
  132. package/dist/features/analytics/api/analytics-api.js.map +2 -2
  133. package/dist/features/analytics/core/analytics-service.js +12 -1
  134. package/dist/features/analytics/core/analytics-service.js.map +2 -2
  135. package/dist/features/analytics/queries/metrics-queries.js.map +2 -2
  136. package/dist/features/tasks/pebbles-task-store.js.map +2 -2
  137. package/dist/features/tui/components/analytics-panel.js.map +2 -2
  138. package/dist/features/tui/components/pr-tracker.js.map +2 -2
  139. package/dist/features/tui/components/session-monitor.js.map +2 -2
  140. package/dist/features/tui/components/subagent-fleet.js.map +2 -2
  141. package/dist/features/tui/components/task-board.js +650 -2
  142. package/dist/features/tui/components/task-board.js.map +2 -2
  143. package/dist/features/tui/index.js +16 -5
  144. package/dist/features/tui/index.js.map +2 -2
  145. package/dist/features/tui/services/data-service.js +25 -14
  146. package/dist/features/tui/services/data-service.js.map +2 -2
  147. package/dist/features/tui/services/linear-task-reader.js.map +2 -2
  148. package/dist/features/tui/services/websocket-client.js +13 -2
  149. package/dist/features/tui/services/websocket-client.js.map +2 -2
  150. package/dist/features/tui/terminal-compat.js +27 -16
  151. package/dist/features/tui/terminal-compat.js.map +2 -2
  152. package/dist/features/web/client/stores/task-store.js.map +2 -2
  153. package/dist/features/web/server/index.js +13 -2
  154. package/dist/features/web/server/index.js.map +2 -2
  155. package/dist/integrations/claude-code/enhanced-pre-clear-hooks.js.map +2 -2
  156. package/dist/integrations/claude-code/lifecycle-hooks.js.map +2 -2
  157. package/dist/integrations/claude-code/post-task-hooks.js.map +2 -2
  158. package/dist/integrations/linear/auth.js +17 -6
  159. package/dist/integrations/linear/auth.js.map +2 -2
  160. package/dist/integrations/linear/auto-sync.js.map +2 -2
  161. package/dist/integrations/linear/client.js.map +2 -2
  162. package/dist/integrations/linear/config.js.map +2 -2
  163. package/dist/integrations/linear/migration.js.map +2 -2
  164. package/dist/integrations/linear/oauth-server.js +13 -2
  165. package/dist/integrations/linear/oauth-server.js.map +2 -2
  166. package/dist/integrations/linear/rest-client.js.map +2 -2
  167. package/dist/integrations/linear/sync-enhanced.js +202 -0
  168. package/dist/integrations/linear/sync-enhanced.js.map +7 -0
  169. package/dist/integrations/linear/sync-manager.js.map +2 -2
  170. package/dist/integrations/linear/sync-service.js +12 -1
  171. package/dist/integrations/linear/sync-service.js.map +2 -2
  172. package/dist/integrations/linear/sync.js +34 -3
  173. package/dist/integrations/linear/sync.js.map +2 -2
  174. package/dist/integrations/linear/unified-sync.js +560 -0
  175. package/dist/integrations/linear/unified-sync.js.map +7 -0
  176. package/dist/integrations/linear/webhook-handler.js +12 -1
  177. package/dist/integrations/linear/webhook-handler.js.map +2 -2
  178. package/dist/integrations/linear/webhook-server.js +14 -3
  179. package/dist/integrations/linear/webhook-server.js.map +2 -2
  180. package/dist/integrations/linear/webhook.js +12 -1
  181. package/dist/integrations/linear/webhook.js.map +2 -2
  182. package/dist/integrations/mcp/handlers/context-handlers.js.map +2 -2
  183. package/dist/integrations/mcp/handlers/linear-handlers.js.map +2 -2
  184. package/dist/integrations/mcp/handlers/skill-handlers.js +13 -2
  185. package/dist/integrations/mcp/handlers/skill-handlers.js.map +2 -2
  186. package/dist/integrations/mcp/handlers/task-handlers.js.map +2 -2
  187. package/dist/integrations/mcp/handlers/trace-handlers.js.map +2 -2
  188. package/dist/integrations/mcp/middleware/tool-scoring.js.map +2 -2
  189. package/dist/integrations/mcp/refactored-server.js +15 -4
  190. package/dist/integrations/mcp/refactored-server.js.map +2 -2
  191. package/dist/integrations/mcp/server.js +12 -1
  192. package/dist/integrations/mcp/server.js.map +2 -2
  193. package/dist/integrations/mcp/tool-definitions.js.map +2 -2
  194. package/dist/integrations/pg-aiguide/embedding-provider.js +13 -2
  195. package/dist/integrations/pg-aiguide/embedding-provider.js.map +2 -2
  196. package/dist/integrations/pg-aiguide/semantic-search.js.map +2 -2
  197. package/dist/mcp/stackmemory-mcp-server.js +12 -1
  198. package/dist/mcp/stackmemory-mcp-server.js.map +2 -2
  199. package/dist/middleware/exponential-rate-limiter.js.map +2 -2
  200. package/dist/servers/production/auth-middleware.js +13 -2
  201. package/dist/servers/production/auth-middleware.js.map +2 -2
  202. package/dist/servers/railway/index.js +22 -11
  203. package/dist/servers/railway/index.js.map +2 -2
  204. package/dist/services/config-service.js.map +2 -2
  205. package/dist/services/context-service.js.map +2 -2
  206. package/dist/skills/claude-skills.js +105 -2
  207. package/dist/skills/claude-skills.js.map +2 -2
  208. package/dist/skills/dashboard-launcher.js.map +2 -2
  209. package/dist/skills/repo-ingestion-skill.js +561 -0
  210. package/dist/skills/repo-ingestion-skill.js.map +7 -0
  211. package/dist/utils/logger.js +12 -1
  212. package/dist/utils/logger.js.map +2 -2
  213. package/package.json +5 -1
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/cli/commands/skills.ts"],
4
- "sourcesContent": ["#!/usr/bin/env node\n/**\n * Claude Skills CLI Commands\n * Integrates Claude skills into the stackmemory CLI\n */\n\nimport { Command } from 'commander';\nimport chalk from 'chalk';\nimport ora from 'ora';\nimport { ClaudeSkillsManager, type SkillContext } from '../../skills/claude-skills.js';\nimport { DualStackManager } from '../../core/context/dual-stack-manager.js';\nimport { FrameHandoffManager } from '../../core/context/frame-handoff-manager.js';\nimport { ContextRetriever } from '../../core/retrieval/context-retriever.js';\nimport { SQLiteAdapter } from '../../core/database/sqlite-adapter.js';\nimport { ConfigManager } from '../../core/config/config-manager.js';\nimport * as path from 'path';\nimport * as os from 'os';\n\nasync function initializeSkillContext(): Promise<SkillContext> {\n const config = ConfigManager.getInstance();\n const projectId = config.get('project.id');\n const userId = config.get('user.id') || process.env.USER || 'default';\n \n const dbPath = path.join(\n os.homedir(),\n '.stackmemory',\n 'data',\n projectId,\n 'stackmemory.db'\n );\n\n const database = new SQLiteAdapter(projectId, { dbPath });\n await database.connect();\n\n const dualStackManager = new DualStackManager(database, projectId, userId);\n const handoffManager = new FrameHandoffManager(dualStackManager);\n const contextRetriever = new ContextRetriever(database);\n\n return {\n projectId,\n userId,\n dualStackManager,\n handoffManager,\n contextRetriever,\n database,\n };\n}\n\nexport function createSkillsCommand(): Command {\n const skillsCmd = new Command('skills')\n .description('Execute Claude skills for enhanced workflow');\n\n // Handoff skill command\n skillsCmd\n .command('handoff <targetUser> <message>')\n .description('Streamline frame handoffs between team members')\n .option('-p, --priority <level>', 'Set priority (low, medium, high, critical)', 'medium')\n .option('-f, --frames <frames...>', 'Specific frames to handoff')\n .option('--no-auto-detect', 'Disable auto-detection of frames')\n .action(async (targetUser, message, options) => {\n const spinner = ora('Initiating handoff...').start();\n \n try {\n const context = await initializeSkillContext();\n const skillsManager = new ClaudeSkillsManager(context);\n \n const result = await skillsManager.executeSkill('handoff', [targetUser, message], {\n priority: options.priority,\n frames: options.frames,\n autoDetect: options.autoDetect !== false,\n });\n\n spinner.stop();\n\n if (result.success) {\n console.log(chalk.green('\u2713'), result.message);\n if (result.data) {\n console.log(chalk.cyan('\\nHandoff Details:'));\n console.log(` ID: ${result.data.handoffId}`);\n console.log(` Frames: ${result.data.frameCount}`);\n console.log(` Priority: ${result.data.priority}`);\n if (result.data.actionItems?.length > 0) {\n console.log(chalk.yellow('\\n Action Items:'));\n result.data.actionItems.forEach(item => {\n console.log(` \u2022 ${item}`);\n });\n }\n }\n } else {\n console.log(chalk.red('\u2717'), result.message);\n }\n\n await context.database.disconnect();\n } catch (error) {\n spinner.stop();\n console.error(chalk.red('Error:'), error.message);\n process.exit(1);\n }\n });\n\n // Checkpoint skill commands\n const checkpointCmd = skillsCmd.command('checkpoint')\n .description('Create and manage recovery points');\n\n checkpointCmd\n .command('create <description>')\n .description('Create a new checkpoint')\n .option('--files <files...>', 'Include specific files in checkpoint')\n .option('--auto-detect-risky', 'Auto-detect risky operations')\n .action(async (description, options) => {\n const spinner = ora('Creating checkpoint...').start();\n \n try {\n const context = await initializeSkillContext();\n const skillsManager = new ClaudeSkillsManager(context);\n \n const result = await skillsManager.executeSkill('checkpoint', ['create', description], {\n includeFiles: options.files,\n autoDetectRisky: options.autoDetectRisky,\n });\n\n spinner.stop();\n\n if (result.success) {\n console.log(chalk.green('\u2713'), result.message);\n if (result.data) {\n console.log(chalk.cyan('\\nCheckpoint Info:'));\n console.log(` ID: ${result.data.checkpointId}`);\n console.log(` Time: ${result.data.timestamp}`);\n console.log(` Frames: ${result.data.frameCount}`);\n }\n } else {\n console.log(chalk.red('\u2717'), result.message);\n }\n\n await context.database.disconnect();\n } catch (error) {\n spinner.stop();\n console.error(chalk.red('Error:'), error.message);\n process.exit(1);\n }\n });\n\n checkpointCmd\n .command('restore <checkpointId>')\n .description('Restore from a checkpoint')\n .action(async (checkpointId) => {\n const spinner = ora('Restoring checkpoint...').start();\n \n try {\n const context = await initializeSkillContext();\n const skillsManager = new ClaudeSkillsManager(context);\n \n const result = await skillsManager.executeSkill('checkpoint', ['restore', checkpointId]);\n\n spinner.stop();\n\n if (result.success) {\n console.log(chalk.green('\u2713'), result.message);\n if (result.data) {\n console.log(chalk.cyan('\\nRestored:'));\n console.log(` Frames: ${result.data.frameCount}`);\n console.log(` Files: ${result.data.filesRestored}`);\n }\n } else {\n console.log(chalk.red('\u2717'), result.message);\n }\n\n await context.database.disconnect();\n } catch (error) {\n spinner.stop();\n console.error(chalk.red('Error:'), error.message);\n process.exit(1);\n }\n });\n\n checkpointCmd\n .command('list')\n .description('List available checkpoints')\n .option('-l, --limit <number>', 'Limit number of results', '10')\n .option('-s, --since <date>', 'Show checkpoints since date')\n .action(async (options) => {\n const spinner = ora('Loading checkpoints...').start();\n \n try {\n const context = await initializeSkillContext();\n const skillsManager = new ClaudeSkillsManager(context);\n \n const result = await skillsManager.executeSkill('checkpoint', ['list'], {\n limit: parseInt(options.limit),\n since: options.since ? new Date(options.since) : undefined,\n });\n\n spinner.stop();\n\n if (result.success) {\n console.log(chalk.cyan('Available Checkpoints:\\n'));\n if (result.data && result.data.length > 0) {\n result.data.forEach((cp: any) => {\n const riskIndicator = cp.risky ? chalk.yellow(' [RISKY]') : '';\n console.log(`${chalk.bold(cp.id)}${riskIndicator}`);\n console.log(` ${cp.description}`);\n console.log(chalk.gray(` ${cp.timestamp} (${cp.frameCount} frames)\\n`));\n });\n } else {\n console.log(chalk.gray('No checkpoints found'));\n }\n } else {\n console.log(chalk.red('\u2717'), result.message);\n }\n\n await context.database.disconnect();\n } catch (error) {\n spinner.stop();\n console.error(chalk.red('Error:'), error.message);\n process.exit(1);\n }\n });\n\n checkpointCmd\n .command('diff <checkpoint1> <checkpoint2>')\n .description('Show differences between two checkpoints')\n .action(async (checkpoint1, checkpoint2) => {\n const spinner = ora('Comparing checkpoints...').start();\n \n try {\n const context = await initializeSkillContext();\n const skillsManager = new ClaudeSkillsManager(context);\n \n const result = await skillsManager.executeSkill('checkpoint', ['diff', checkpoint1, checkpoint2]);\n\n spinner.stop();\n\n if (result.success) {\n console.log(chalk.cyan('Checkpoint Diff:\\n'));\n if (result.data) {\n console.log(` Time difference: ${result.data.timeDiff}`);\n console.log(` Frame difference: ${result.data.framesDiff}`);\n console.log(` New frames: ${result.data.newFrames}`);\n console.log(` Removed frames: ${result.data.removedFrames}`);\n console.log(` Modified frames: ${result.data.modifiedFrames}`);\n }\n } else {\n console.log(chalk.red('\u2717'), result.message);\n }\n\n await context.database.disconnect();\n } catch (error) {\n spinner.stop();\n console.error(chalk.red('Error:'), error.message);\n process.exit(1);\n }\n });\n\n // Context Archaeologist skill command\n skillsCmd\n .command('dig <query>')\n .description('Deep historical context retrieval')\n .option('-d, --depth <depth>', 'Search depth (e.g., 30days, 6months, all)', '30days')\n .option('--patterns', 'Extract patterns from results')\n .option('--decisions', 'Extract key decisions')\n .option('--timeline', 'Generate activity timeline')\n .action(async (query, options) => {\n const spinner = ora('Digging through context...').start();\n \n try {\n const context = await initializeSkillContext();\n const skillsManager = new ClaudeSkillsManager(context);\n \n const result = await skillsManager.executeSkill('dig', [query], {\n depth: options.depth,\n patterns: options.patterns,\n decisions: options.decisions,\n timeline: options.timeline,\n });\n\n spinner.stop();\n\n if (result.success) {\n console.log(chalk.green('\u2713'), result.message);\n \n if (result.data) {\n console.log(chalk.cyan(`\\nSearched ${result.data.timeRange.from} to ${result.data.timeRange.to}`));\n \n if (result.data.summary) {\n console.log('\\n' + result.data.summary);\n } else {\n // Display top results\n if (result.data.topResults?.length > 0) {\n console.log(chalk.cyan('\\nTop Results:'));\n result.data.topResults.forEach((r: any) => {\n console.log(` ${chalk.yellow(`[${r.score.toFixed(2)}]`)} ${r.summary}`);\n });\n }\n\n // Display patterns if found\n if (result.data.patterns?.length > 0) {\n console.log(chalk.cyan('\\nDetected Patterns:'));\n result.data.patterns.forEach((p: any) => {\n console.log(` ${p.name}: ${p.count} occurrences`);\n });\n }\n\n // Display decisions if found\n if (result.data.decisions?.length > 0) {\n console.log(chalk.cyan('\\nKey Decisions:'));\n result.data.decisions.slice(0, 5).forEach((d: any) => {\n console.log(` ${chalk.gray(new Date(d.timestamp).toLocaleDateString())}: ${d.decision}`);\n });\n }\n\n // Display timeline if generated\n if (result.data.timeline?.length > 0) {\n console.log(chalk.cyan('\\nActivity Timeline:'));\n result.data.timeline.slice(0, 5).forEach((t: any) => {\n console.log(` ${t.date}: ${t.itemCount} activities`);\n });\n }\n }\n }\n } else {\n console.log(chalk.red('\u2717'), result.message);\n }\n\n await context.database.disconnect();\n } catch (error) {\n spinner.stop();\n console.error(chalk.red('Error:'), error.message);\n process.exit(1);\n }\n });\n\n // Help command for skills\n skillsCmd\n .command('help [skill]')\n .description('Show help for a specific skill')\n .action(async (skill) => {\n const context = await initializeSkillContext();\n const skillsManager = new ClaudeSkillsManager(context);\n \n if (skill) {\n console.log(skillsManager.getSkillHelp(skill));\n } else {\n console.log(chalk.cyan('Available Claude Skills:\\n'));\n console.log(' handoff - Streamline frame handoffs between team members');\n console.log(' checkpoint - Create and manage recovery points');\n console.log(' dig - Deep historical context retrieval\\n');\n console.log('Use \"stackmemory skills help <skill>\" for detailed help on each skill');\n }\n \n await context.database.disconnect();\n });\n\n return skillsCmd;\n}"],
5
- "mappings": "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",
4
+ "sourcesContent": ["#!/usr/bin/env node\n/**\n * Claude Skills CLI Commands\n * Integrates Claude skills into the stackmemory CLI\n */\n\nimport { Command } from 'commander';\nimport chalk from 'chalk';\nimport ora from 'ora';\nimport { ClaudeSkillsManager, type SkillContext } from '../../skills/claude-skills.js';\nimport { DualStackManager } from '../../core/context/dual-stack-manager.js';\nimport { FrameHandoffManager } from '../../core/context/frame-handoff-manager.js';\nimport { ContextRetriever } from '../../core/retrieval/context-retriever.js';\nimport { SQLiteAdapter } from '../../core/database/sqlite-adapter.js';\nimport { ConfigManager } from '../../core/config/config-manager.js';\nimport * as path from 'path';\nimport * as os from 'os';\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\nasync function initializeSkillContext(): Promise<SkillContext> {\n const config = ConfigManager.getInstance();\n const projectId = config.get('project.id');\n const userId = config.get('user.id') || process.env['USER'] || 'default';\n \n const dbPath = path.join(\n os.homedir(),\n '.stackmemory',\n 'data',\n projectId,\n 'stackmemory.db'\n );\n\n const database = new SQLiteAdapter(projectId, { dbPath });\n await database.connect();\n\n const dualStackManager = new DualStackManager(database, projectId, userId);\n const handoffManager = new FrameHandoffManager(dualStackManager);\n const contextRetriever = new ContextRetriever(database);\n\n return {\n projectId,\n userId,\n dualStackManager,\n handoffManager,\n contextRetriever,\n database,\n };\n}\n\nexport function createSkillsCommand(): Command {\n const skillsCmd = new Command('skills')\n .description('Execute Claude skills for enhanced workflow');\n\n // Handoff skill command\n skillsCmd\n .command('handoff <targetUser> <message>')\n .description('Streamline frame handoffs between team members')\n .option('-p, --priority <level>', 'Set priority (low, medium, high, critical)', 'medium')\n .option('-f, --frames <frames...>', 'Specific frames to handoff')\n .option('--no-auto-detect', 'Disable auto-detection of frames')\n .action(async (targetUser, message, options) => {\n const spinner = ora('Initiating handoff...').start();\n \n try {\n const context = await initializeSkillContext();\n const skillsManager = new ClaudeSkillsManager(context);\n \n const result = await skillsManager.executeSkill('handoff', [targetUser, message], {\n priority: options.priority,\n frames: options.frames,\n autoDetect: options.autoDetect !== false,\n });\n\n spinner.stop();\n\n if (result.success) {\n console.log(chalk.green('\u2713'), result.message);\n if (result.data) {\n console.log(chalk.cyan('\\nHandoff Details:'));\n console.log(` ID: ${result.data.handoffId}`);\n console.log(` Frames: ${result.data.frameCount}`);\n console.log(` Priority: ${result.data.priority}`);\n if (result.data.actionItems?.length > 0) {\n console.log(chalk.yellow('\\n Action Items:'));\n result.data.actionItems.forEach(item => {\n console.log(` \u2022 ${item}`);\n });\n }\n }\n } else {\n console.log(chalk.red('\u2717'), result.message);\n }\n\n await context.database.disconnect();\n } catch (error: unknown) {\n spinner.stop();\n console.error(chalk.red('Error:'), error.message);\n process.exit(1);\n }\n });\n\n // Checkpoint skill commands\n const checkpointCmd = skillsCmd.command('checkpoint')\n .description('Create and manage recovery points');\n\n checkpointCmd\n .command('create <description>')\n .description('Create a new checkpoint')\n .option('--files <files...>', 'Include specific files in checkpoint')\n .option('--auto-detect-risky', 'Auto-detect risky operations')\n .action(async (description, options) => {\n const spinner = ora('Creating checkpoint...').start();\n \n try {\n const context = await initializeSkillContext();\n const skillsManager = new ClaudeSkillsManager(context);\n \n const result = await skillsManager.executeSkill('checkpoint', ['create', description], {\n includeFiles: options.files,\n autoDetectRisky: options.autoDetectRisky,\n });\n\n spinner.stop();\n\n if (result.success) {\n console.log(chalk.green('\u2713'), result.message);\n if (result.data) {\n console.log(chalk.cyan('\\nCheckpoint Info:'));\n console.log(` ID: ${result.data.checkpointId}`);\n console.log(` Time: ${result.data.timestamp}`);\n console.log(` Frames: ${result.data.frameCount}`);\n }\n } else {\n console.log(chalk.red('\u2717'), result.message);\n }\n\n await context.database.disconnect();\n } catch (error: unknown) {\n spinner.stop();\n console.error(chalk.red('Error:'), error.message);\n process.exit(1);\n }\n });\n\n checkpointCmd\n .command('restore <checkpointId>')\n .description('Restore from a checkpoint')\n .action(async (checkpointId) => {\n const spinner = ora('Restoring checkpoint...').start();\n \n try {\n const context = await initializeSkillContext();\n const skillsManager = new ClaudeSkillsManager(context);\n \n const result = await skillsManager.executeSkill('checkpoint', ['restore', checkpointId]);\n\n spinner.stop();\n\n if (result.success) {\n console.log(chalk.green('\u2713'), result.message);\n if (result.data) {\n console.log(chalk.cyan('\\nRestored:'));\n console.log(` Frames: ${result.data.frameCount}`);\n console.log(` Files: ${result.data.filesRestored}`);\n }\n } else {\n console.log(chalk.red('\u2717'), result.message);\n }\n\n await context.database.disconnect();\n } catch (error: unknown) {\n spinner.stop();\n console.error(chalk.red('Error:'), error.message);\n process.exit(1);\n }\n });\n\n checkpointCmd\n .command('list')\n .description('List available checkpoints')\n .option('-l, --limit <number>', 'Limit number of results', '10')\n .option('-s, --since <date>', 'Show checkpoints since date')\n .action(async (options) => {\n const spinner = ora('Loading checkpoints...').start();\n \n try {\n const context = await initializeSkillContext();\n const skillsManager = new ClaudeSkillsManager(context);\n \n const result = await skillsManager.executeSkill('checkpoint', ['list'], {\n limit: parseInt(options.limit),\n since: options.since ? new Date(options.since) : undefined,\n });\n\n spinner.stop();\n\n if (result.success) {\n console.log(chalk.cyan('Available Checkpoints:\\n'));\n if (result.data && result.data.length > 0) {\n result.data.forEach((cp: any) => {\n const riskIndicator = cp.risky ? chalk.yellow(' [RISKY]') : '';\n console.log(`${chalk.bold(cp.id)}${riskIndicator}`);\n console.log(` ${cp.description}`);\n console.log(chalk.gray(` ${cp.timestamp} (${cp.frameCount} frames)\\n`));\n });\n } else {\n console.log(chalk.gray('No checkpoints found'));\n }\n } else {\n console.log(chalk.red('\u2717'), result.message);\n }\n\n await context.database.disconnect();\n } catch (error: unknown) {\n spinner.stop();\n console.error(chalk.red('Error:'), error.message);\n process.exit(1);\n }\n });\n\n checkpointCmd\n .command('diff <checkpoint1> <checkpoint2>')\n .description('Show differences between two checkpoints')\n .action(async (checkpoint1, checkpoint2) => {\n const spinner = ora('Comparing checkpoints...').start();\n \n try {\n const context = await initializeSkillContext();\n const skillsManager = new ClaudeSkillsManager(context);\n \n const result = await skillsManager.executeSkill('checkpoint', ['diff', checkpoint1, checkpoint2]);\n\n spinner.stop();\n\n if (result.success) {\n console.log(chalk.cyan('Checkpoint Diff:\\n'));\n if (result.data) {\n console.log(` Time difference: ${result.data.timeDiff}`);\n console.log(` Frame difference: ${result.data.framesDiff}`);\n console.log(` New frames: ${result.data.newFrames}`);\n console.log(` Removed frames: ${result.data.removedFrames}`);\n console.log(` Modified frames: ${result.data.modifiedFrames}`);\n }\n } else {\n console.log(chalk.red('\u2717'), result.message);\n }\n\n await context.database.disconnect();\n } catch (error: unknown) {\n spinner.stop();\n console.error(chalk.red('Error:'), error.message);\n process.exit(1);\n }\n });\n\n // Context Archaeologist skill command\n skillsCmd\n .command('dig <query>')\n .description('Deep historical context retrieval')\n .option('-d, --depth <depth>', 'Search depth (e.g., 30days, 6months, all)', '30days')\n .option('--patterns', 'Extract patterns from results')\n .option('--decisions', 'Extract key decisions')\n .option('--timeline', 'Generate activity timeline')\n .action(async (query, options) => {\n const spinner = ora('Digging through context...').start();\n \n try {\n const context = await initializeSkillContext();\n const skillsManager = new ClaudeSkillsManager(context);\n \n const result = await skillsManager.executeSkill('dig', [query], {\n depth: options.depth,\n patterns: options.patterns,\n decisions: options.decisions,\n timeline: options.timeline,\n });\n\n spinner.stop();\n\n if (result.success) {\n console.log(chalk.green('\u2713'), result.message);\n \n if (result.data) {\n console.log(chalk.cyan(`\\nSearched ${result.data.timeRange.from} to ${result.data.timeRange.to}`));\n \n if (result.data.summary) {\n console.log('\\n' + result.data.summary);\n } else {\n // Display top results\n if (result.data.topResults?.length > 0) {\n console.log(chalk.cyan('\\nTop Results:'));\n result.data.topResults.forEach((r: any) => {\n console.log(` ${chalk.yellow(`[${r.score.toFixed(2)}]`)} ${r.summary}`);\n });\n }\n\n // Display patterns if found\n if (result.data.patterns?.length > 0) {\n console.log(chalk.cyan('\\nDetected Patterns:'));\n result.data.patterns.forEach((p: any) => {\n console.log(` ${p.name}: ${p.count} occurrences`);\n });\n }\n\n // Display decisions if found\n if (result.data.decisions?.length > 0) {\n console.log(chalk.cyan('\\nKey Decisions:'));\n result.data.decisions.slice(0, 5).forEach((d: any) => {\n console.log(` ${chalk.gray(new Date(d.timestamp).toLocaleDateString())}: ${d.decision}`);\n });\n }\n\n // Display timeline if generated\n if (result.data.timeline?.length > 0) {\n console.log(chalk.cyan('\\nActivity Timeline:'));\n result.data.timeline.slice(0, 5).forEach((t: any) => {\n console.log(` ${t.date}: ${t.itemCount} activities`);\n });\n }\n }\n }\n } else {\n console.log(chalk.red('\u2717'), result.message);\n }\n\n await context.database.disconnect();\n } catch (error: unknown) {\n spinner.stop();\n console.error(chalk.red('Error:'), error.message);\n process.exit(1);\n }\n });\n\n // Help command for skills\n skillsCmd\n .command('help [skill]')\n .description('Show help for a specific skill')\n .action(async (skill) => {\n const context = await initializeSkillContext();\n const skillsManager = new ClaudeSkillsManager(context);\n \n if (skill) {\n console.log(skillsManager.getSkillHelp(skill));\n } else {\n console.log(chalk.cyan('Available Claude Skills:\\n'));\n console.log(' handoff - Streamline frame handoffs between team members');\n console.log(' checkpoint - Create and manage recovery points');\n console.log(' dig - Deep historical context retrieval\\n');\n console.log('Use \"stackmemory skills help <skill>\" for detailed help on each skill');\n }\n \n await context.database.disconnect();\n });\n\n return skillsCmd;\n}"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -7,6 +7,17 @@ import { existsSync } from "fs";
7
7
  import { RailwayOptimizedStorage } from "../../core/storage/railway-optimized-storage.js";
8
8
  import { ConfigManager } from "../../core/config/config-manager.js";
9
9
  import { formatBytes, formatDuration } from "../../utils/formatting.js";
10
+ function getEnv(key, defaultValue) {
11
+ const value = process.env[key];
12
+ if (value === void 0) {
13
+ if (defaultValue !== void 0) return defaultValue;
14
+ throw new Error(`Environment variable ${key} is required`);
15
+ }
16
+ return value;
17
+ }
18
+ function getOptionalEnv(key) {
19
+ return process.env[key];
20
+ }
10
21
  function createStorageCommand() {
11
22
  const storage = new Command("storage").description(
12
23
  "Manage 3-tier storage system (Redis/Railway/GCS)"
@@ -234,18 +245,18 @@ ${icon} ${color(tier.tier.toUpperCase())} Tier:`);
234
245
  console.log(chalk.blue("\n\u2699\uFE0F Storage Configuration:"));
235
246
  console.log(chalk.gray("\u2501".repeat(50)));
236
247
  console.log(chalk.red("\n\u{1F525} Hot Tier (Redis):"));
237
- console.log(` URL: ${process.env.REDIS_URL ? chalk.green("Configured") : chalk.yellow("Not configured")}`);
248
+ console.log(` URL: ${process.env["REDIS_URL"] ? chalk.green("Configured") : chalk.yellow("Not configured")}`);
238
249
  console.log(` TTL: 24 hours`);
239
250
  console.log(` Max Memory: 100MB`);
240
251
  console.log(chalk.yellow("\n\u2601\uFE0F Warm Tier (Railway Buckets):"));
241
- console.log(` Endpoint: ${process.env.RAILWAY_BUCKET_ENDPOINT || "Not configured"}`);
242
- console.log(` Bucket: ${process.env.RAILWAY_BUCKET_NAME || "stackmemory-warm"}`);
243
- console.log(` Access Key: ${process.env.RAILWAY_BUCKET_ACCESS_KEY ? chalk.green("Set") : chalk.yellow("Not set")}`);
252
+ console.log(` Endpoint: ${process.env["RAILWAY_BUCKET_ENDPOINT"] || "Not configured"}`);
253
+ console.log(` Bucket: ${process.env["RAILWAY_BUCKET_NAME"] || "stackmemory-warm"}`);
254
+ console.log(` Access Key: ${process.env["RAILWAY_BUCKET_ACCESS_KEY"] ? chalk.green("Set") : chalk.yellow("Not set")}`);
244
255
  console.log(` Retention: 30 days`);
245
256
  console.log(chalk.cyan("\n\u2744\uFE0F Cold Tier (GCS):"));
246
- console.log(` Project: ${process.env.GCP_PROJECT_ID || "Not configured"}`);
247
- console.log(` Bucket: ${process.env.GCS_BUCKET || "stackmemory-cold"}`);
248
- console.log(` Key File: ${process.env.GCP_KEY_FILE ? chalk.green("Set") : chalk.yellow("Not set")}`);
257
+ console.log(` Project: ${process.env["GCP_PROJECT_ID"] || "Not configured"}`);
258
+ console.log(` Bucket: ${process.env["GCS_BUCKET"] || "stackmemory-cold"}`);
259
+ console.log(` Key File: ${process.env["GCP_KEY_FILE"] ? chalk.green("Set") : chalk.yellow("Not set")}`);
249
260
  console.log(` Storage Class: Coldline`);
250
261
  console.log(` Retention: Infinite`);
251
262
  console.log(chalk.blue("\n\u{1F4CA} Migration Thresholds:"));
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/cli/commands/storage.ts"],
4
- "sourcesContent": ["/**\n * Storage management commands for StackMemory\n */\n\nimport { Command } from 'commander';\nimport chalk from 'chalk';\nimport ora from 'ora';\nimport Database from 'better-sqlite3';\nimport { join } from 'path';\nimport { existsSync } from 'fs';\nimport { RailwayOptimizedStorage } from '../../core/storage/railway-optimized-storage.js';\nimport { ConfigManager } from '../../core/config/config-manager.js';\nimport { formatBytes, formatDuration } from '../../utils/formatting.js';\n\nexport function createStorageCommand(): Command {\n const storage = new Command('storage').description(\n 'Manage 3-tier storage system (Redis/Railway/GCS)'\n );\n\n storage\n .command('status')\n .description('Show storage tier statistics')\n .option('-v, --verbose', 'Show detailed statistics')\n .action(async (options) => {\n const spinner = ora('Loading storage statistics...').start();\n \n try {\n const dbPath = join(process.cwd(), '.stackmemory', 'context.db');\n if (!existsSync(dbPath)) {\n spinner.fail('StackMemory not initialized in this directory');\n process.exit(1);\n }\n \n const db = new Database(dbPath);\n const configManager = new ConfigManager();\n const storage = new RailwayOptimizedStorage(db, configManager);\n \n const stats = storage.getStorageStats();\n spinner.succeed('Storage statistics loaded');\n \n console.log(chalk.blue('\\n\uD83D\uDCCA Storage Tier Distribution:'));\n console.log(chalk.gray('\u2501'.repeat(50)));\n \n // Tier statistics\n for (const tier of stats.byTier) {\n const icon = tier.tier === 'hot' ? '\uD83D\uDD25' : tier.tier === 'warm' ? '\u2601\uFE0F' : '\u2744\uFE0F';\n const color = tier.tier === 'hot' ? chalk.red : tier.tier === 'warm' ? chalk.yellow : chalk.cyan;\n \n console.log(`\\n${icon} ${color(tier.tier.toUpperCase())} Tier:`);\n console.log(` Traces: ${chalk.white(tier.count)}`);\n console.log(` Original Size: ${chalk.white(formatBytes(tier.total_original || 0))}`);\n console.log(` Compressed Size: ${chalk.white(formatBytes(tier.total_compressed || 0))}`);\n console.log(` Compression Ratio: ${chalk.green((tier.avg_compression * 100).toFixed(1) + '%')}`);\n console.log(` Avg Access Count: ${chalk.white(tier.avg_access?.toFixed(1) || '0')}`);\n }\n \n // Age distribution\n console.log(chalk.blue('\\n\uD83D\uDCC5 Age Distribution:'));\n console.log(chalk.gray('\u2501'.repeat(50)));\n for (const age of stats.byAge) {\n const percent = (age.count / stats.totalTraces * 100).toFixed(1);\n const bar = '\u2588'.repeat(Math.floor(percent / 2));\n console.log(` ${age.age_group.padEnd(10)} ${bar} ${percent}% (${age.count})`);\n }\n \n // Summary\n console.log(chalk.blue('\\n\uD83D\uDCC8 Summary:'));\n console.log(chalk.gray('\u2501'.repeat(50)));\n console.log(` Total Traces: ${chalk.white(stats.totalTraces)}`);\n console.log(` Total Size: ${chalk.white(formatBytes(stats.totalSize))}`);\n console.log(` Compressed Size: ${chalk.white(formatBytes(stats.compressedSize))}`);\n \n const compressionRatio = ((1 - stats.compressedSize / stats.totalSize) * 100).toFixed(1);\n console.log(` Overall Compression: ${chalk.green(compressionRatio + '%')}`);\n \n // Cost estimation\n const costEstimate = calculateStorageCost(stats);\n console.log(chalk.blue('\\n\uD83D\uDCB0 Estimated Monthly Cost:'));\n console.log(chalk.gray('\u2501'.repeat(50)));\n console.log(` Redis (Hot): ${chalk.green('$0.00')} (included with Railway)`);\n console.log(` Railway Buckets (Warm): ${chalk.yellow(costEstimate.railway)}`);\n console.log(` GCS Coldline (Cold): ${chalk.cyan(costEstimate.gcs)}`);\n console.log(` Total: ${chalk.white(costEstimate.total)}`);\n \n if (options.verbose) {\n // Show recent migrations\n const recentMigrations = db.prepare(`\n SELECT trace_id, tier, migrated_at, score\n FROM storage_tiers\n WHERE migrated_at > ?\n ORDER BY migrated_at DESC\n LIMIT 10\n `).all(Date.now() - 24 * 60 * 60 * 1000) as any[];\n \n if (recentMigrations.length > 0) {\n console.log(chalk.blue('\\n\uD83D\uDD04 Recent Migrations (last 24h):'));\n console.log(chalk.gray('\u2501'.repeat(50)));\n for (const m of recentMigrations) {\n const time = new Date(m.migrated_at).toLocaleTimeString();\n console.log(` ${time} - ${m.trace_id.substring(0, 8)}... \u2192 ${m.tier} (score: ${m.score.toFixed(2)})`);\n }\n }\n }\n \n db.close();\n \n } catch (error) {\n spinner.fail('Failed to load storage statistics');\n console.error(error);\n process.exit(1);\n }\n });\n\n storage\n .command('migrate')\n .description('Migrate traces between storage tiers')\n .option('--dry-run', 'Show what would be migrated without doing it')\n .option('--force', 'Force migration regardless of age')\n .action(async (options) => {\n const spinner = ora('Checking for traces to migrate...').start();\n \n try {\n const dbPath = join(process.cwd(), '.stackmemory', 'context.db');\n const db = new Database(dbPath);\n const configManager = new ConfigManager();\n const storage = new RailwayOptimizedStorage(db, configManager);\n \n if (options.dryRun) {\n // Analyze what would be migrated\n const candidates = db.prepare(`\n SELECT trace_id, tier, created_at, score,\n (? - created_at) / 3600000 as age_hours\n FROM storage_tiers\n WHERE tier != 'cold'\n ORDER BY created_at ASC\n `).all(Date.now()) as any[];\n \n const toMigrate = {\n hotToWarm: candidates.filter((c: any) => \n c.tier === 'hot' && c.age_hours > 24\n ),\n warmToCold: candidates.filter((c: any) => \n c.tier === 'warm' && c.age_hours > 720\n ),\n };\n \n spinner.info('Dry run - no changes will be made');\n \n console.log(chalk.blue('\\n\uD83D\uDD04 Migration Plan:'));\n console.log(chalk.gray('\u2501'.repeat(50)));\n \n if (toMigrate.hotToWarm.length > 0) {\n console.log(chalk.red(`\\n\uD83D\uDD25 \u2192 \u2601\uFE0F Hot to Warm: ${toMigrate.hotToWarm.length} traces`));\n for (const t of toMigrate.hotToWarm.slice(0, 5)) {\n console.log(` \u2022 ${t.trace_id.substring(0, 8)}... (${t.age_hours.toFixed(0)}h old, score: ${t.score.toFixed(2)})`);\n }\n if (toMigrate.hotToWarm.length > 5) {\n console.log(` ... and ${toMigrate.hotToWarm.length - 5} more`);\n }\n }\n \n if (toMigrate.warmToCold.length > 0) {\n console.log(chalk.yellow(`\\n\u2601\uFE0F \u2192 \u2744\uFE0F Warm to Cold: ${toMigrate.warmToCold.length} traces`));\n for (const t of toMigrate.warmToCold.slice(0, 5)) {\n const ageDays = Math.floor(t.age_hours / 24);\n console.log(` \u2022 ${t.trace_id.substring(0, 8)}... (${ageDays}d old, score: ${t.score.toFixed(2)})`);\n }\n if (toMigrate.warmToCold.length > 5) {\n console.log(` ... and ${toMigrate.warmToCold.length - 5} more`);\n }\n }\n \n if (toMigrate.hotToWarm.length === 0 && toMigrate.warmToCold.length === 0) {\n console.log(chalk.green('\u2713 No traces need migration'));\n }\n \n } else {\n // Perform actual migration\n spinner.text = 'Migrating traces between tiers...';\n const results = await storage.migrateTiers();\n \n spinner.succeed('Migration completed');\n \n console.log(chalk.blue('\\n\u2705 Migration Results:'));\n console.log(chalk.gray('\u2501'.repeat(50)));\n console.log(` Hot \u2192 Warm: ${chalk.yellow(results.hotToWarm)} traces`);\n console.log(` Warm \u2192 Cold: ${chalk.cyan(results.warmToCold)} traces`);\n \n if (results.errors.length > 0) {\n console.log(chalk.red(`\\n\u274C Errors (${results.errors.length}):`));\n for (const error of results.errors.slice(0, 5)) {\n console.log(` \u2022 ${error}`);\n }\n }\n }\n \n db.close();\n \n } catch (error) {\n spinner.fail('Migration failed');\n console.error(error);\n process.exit(1);\n }\n });\n\n storage\n .command('cleanup')\n .description('Clean up old traces from cold storage')\n .option('--days <number>', 'Remove traces older than N days', parseInt, 90)\n .option('--dry-run', 'Show what would be removed without doing it')\n .action(async (options) => {\n const spinner = ora('Analyzing storage for cleanup...').start();\n \n try {\n const dbPath = join(process.cwd(), '.stackmemory', 'context.db');\n const db = new Database(dbPath);\n const configManager = new ConfigManager();\n const storage = new RailwayOptimizedStorage(db, configManager);\n \n const cutoff = Date.now() - (options.days * 24 * 60 * 60 * 1000);\n \n if (options.dryRun) {\n const toRemove = db.prepare(`\n SELECT COUNT(*) as count, SUM(compressed_size) as size\n FROM storage_tiers\n WHERE tier = 'cold' AND created_at < ? AND access_count = 0\n `).get(cutoff) as any;\n \n spinner.info('Dry run - no traces will be removed');\n \n console.log(chalk.blue('\\n\uD83E\uDDF9 Cleanup Analysis:'));\n console.log(chalk.gray('\u2501'.repeat(50)));\n console.log(` Traces to remove: ${chalk.red(toRemove.count || 0)}`);\n console.log(` Space to free: ${chalk.yellow(formatBytes(toRemove.size || 0))}`);\n console.log(` Criteria: > ${options.days} days old with 0 access`);\n \n } else {\n const removed = await storage.cleanup();\n spinner.succeed(`Cleanup completed - removed ${removed} traces`);\n }\n \n db.close();\n \n } catch (error) {\n spinner.fail('Cleanup failed');\n console.error(error);\n process.exit(1);\n }\n });\n\n storage\n .command('retrieve <traceId>')\n .description('Retrieve a trace from any storage tier')\n .action(async (traceId) => {\n const spinner = ora(`Retrieving trace ${traceId}...`).start();\n \n try {\n const dbPath = join(process.cwd(), '.stackmemory', 'context.db');\n const db = new Database(dbPath);\n const configManager = new ConfigManager();\n const storage = new RailwayOptimizedStorage(db, configManager);\n \n const trace = await storage.retrieveTrace(traceId);\n \n if (!trace) {\n spinner.fail(`Trace ${traceId} not found`);\n process.exit(1);\n }\n \n spinner.succeed('Trace retrieved');\n \n console.log(chalk.blue('\\n\uD83D\uDCE6 Trace Details:'));\n console.log(chalk.gray('\u2501'.repeat(50)));\n console.log(` ID: ${chalk.cyan(trace.id)}`);\n console.log(` Type: ${chalk.yellow(trace.type)}`);\n console.log(` Score: ${chalk.green(trace.score.toFixed(3))}`);\n console.log(` Summary: ${trace.summary}`);\n console.log(` Tools: ${trace.tools?.length || trace.toolSummary?.count || 0}`);\n \n const metadata = trace.metadata;\n if (metadata) {\n console.log(chalk.blue('\\n\uD83D\uDCCB Metadata:'));\n console.log(` Start: ${new Date(metadata.startTime).toLocaleString()}`);\n console.log(` Duration: ${formatDuration(metadata.endTime - metadata.startTime)}`);\n console.log(` Files: ${metadata.filesModified?.length || metadata.filesModified || 0}`);\n console.log(` Errors: ${metadata.errorsEncountered?.length || metadata.errorsCount || 0}`);\n }\n \n // Show storage location\n const location = db.prepare(\n 'SELECT tier, location, access_count FROM storage_tiers WHERE trace_id = ?'\n ).get(traceId) as any;\n \n if (location) {\n const tierIcon = location.tier === 'hot' ? '\uD83D\uDD25' : \n location.tier === 'warm' ? '\u2601\uFE0F' : '\u2744\uFE0F';\n console.log(chalk.blue('\\n\uD83D\uDCBE Storage:'));\n console.log(` Tier: ${tierIcon} ${location.tier}`);\n console.log(` Access Count: ${location.access_count}`);\n }\n \n db.close();\n \n } catch (error) {\n spinner.fail('Failed to retrieve trace');\n console.error(error);\n process.exit(1);\n }\n });\n\n storage\n .command('config')\n .description('Show storage configuration')\n .action(async () => {\n console.log(chalk.blue('\\n\u2699\uFE0F Storage Configuration:'));\n console.log(chalk.gray('\u2501'.repeat(50)));\n \n console.log(chalk.red('\\n\uD83D\uDD25 Hot Tier (Redis):'));\n console.log(` URL: ${process.env.REDIS_URL ? chalk.green('Configured') : chalk.yellow('Not configured')}`);\n console.log(` TTL: 24 hours`);\n console.log(` Max Memory: 100MB`);\n \n console.log(chalk.yellow('\\n\u2601\uFE0F Warm Tier (Railway Buckets):'));\n console.log(` Endpoint: ${process.env.RAILWAY_BUCKET_ENDPOINT || 'Not configured'}`);\n console.log(` Bucket: ${process.env.RAILWAY_BUCKET_NAME || 'stackmemory-warm'}`);\n console.log(` Access Key: ${process.env.RAILWAY_BUCKET_ACCESS_KEY ? chalk.green('Set') : chalk.yellow('Not set')}`);\n console.log(` Retention: 30 days`);\n \n console.log(chalk.cyan('\\n\u2744\uFE0F Cold Tier (GCS):'));\n console.log(` Project: ${process.env.GCP_PROJECT_ID || 'Not configured'}`);\n console.log(` Bucket: ${process.env.GCS_BUCKET || 'stackmemory-cold'}`);\n console.log(` Key File: ${process.env.GCP_KEY_FILE ? chalk.green('Set') : chalk.yellow('Not set')}`);\n console.log(` Storage Class: Coldline`);\n console.log(` Retention: Infinite`);\n \n console.log(chalk.blue('\\n\uD83D\uDCCA Migration Thresholds:'));\n console.log(` Hot \u2192 Warm: After 24 hours`);\n console.log(` Warm \u2192 Cold: After 30 days`);\n console.log(` Low Score Migration: < 0.4 score`);\n });\n\n return storage;\n}\n\n/**\n * Calculate storage cost estimates\n */\nfunction calculateStorageCost(stats: any): { railway: string; gcs: string; total: string } {\n // Find warm and cold tier sizes\n const warmTier = stats.byTier.find((t: any) => t.tier === 'warm');\n const coldTier = stats.byTier.find((t: any) => t.tier === 'cold');\n \n const warmGB = (warmTier?.total_compressed || 0) / (1024 * 1024 * 1024);\n const coldGB = (coldTier?.total_compressed || 0) / (1024 * 1024 * 1024);\n \n // Railway Buckets: ~$0.02/GB (estimate)\n const railwayCost = warmGB * 0.02;\n \n // GCS Coldline: $0.004/GB\n const gcsCost = coldGB * 0.004;\n \n const totalCost = railwayCost + gcsCost;\n \n return {\n railway: `$${railwayCost.toFixed(2)}`,\n gcs: `$${gcsCost.toFixed(2)}`,\n total: `$${totalCost.toFixed(2)}`,\n };\n}"],
5
- "mappings": "AAIA,SAAS,eAAe;AACxB,OAAO,WAAW;AAClB,OAAO,SAAS;AAChB,OAAO,cAAc;AACrB,SAAS,YAAY;AACrB,SAAS,kBAAkB;AAC3B,SAAS,+BAA+B;AACxC,SAAS,qBAAqB;AAC9B,SAAS,aAAa,sBAAsB;AAErC,SAAS,uBAAgC;AAC9C,QAAM,UAAU,IAAI,QAAQ,SAAS,EAAE;AAAA,IACrC;AAAA,EACF;AAEA,UACG,QAAQ,QAAQ,EAChB,YAAY,8BAA8B,EAC1C,OAAO,iBAAiB,0BAA0B,EAClD,OAAO,OAAO,YAAY;AACzB,UAAM,UAAU,IAAI,+BAA+B,EAAE,MAAM;AAE3D,QAAI;AACF,YAAM,SAAS,KAAK,QAAQ,IAAI,GAAG,gBAAgB,YAAY;AAC/D,UAAI,CAAC,WAAW,MAAM,GAAG;AACvB,gBAAQ,KAAK,+CAA+C;AAC5D,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAEA,YAAM,KAAK,IAAI,SAAS,MAAM;AAC9B,YAAM,gBAAgB,IAAI,cAAc;AACxC,YAAMA,WAAU,IAAI,wBAAwB,IAAI,aAAa;AAE7D,YAAM,QAAQA,SAAQ,gBAAgB;AACtC,cAAQ,QAAQ,2BAA2B;AAE3C,cAAQ,IAAI,MAAM,KAAK,wCAAiC,CAAC;AACzD,cAAQ,IAAI,MAAM,KAAK,SAAI,OAAO,EAAE,CAAC,CAAC;AAGtC,iBAAW,QAAQ,MAAM,QAAQ;AAC/B,cAAM,OAAO,KAAK,SAAS,QAAQ,cAAO,KAAK,SAAS,SAAS,iBAAO;AACxE,cAAM,QAAQ,KAAK,SAAS,QAAQ,MAAM,MAAM,KAAK,SAAS,SAAS,MAAM,SAAS,MAAM;AAE5F,gBAAQ,IAAI;AAAA,EAAK,IAAI,IAAI,MAAM,KAAK,KAAK,YAAY,CAAC,CAAC,QAAQ;AAC/D,gBAAQ,IAAI,aAAa,MAAM,MAAM,KAAK,KAAK,CAAC,EAAE;AAClD,gBAAQ,IAAI,oBAAoB,MAAM,MAAM,YAAY,KAAK,kBAAkB,CAAC,CAAC,CAAC,EAAE;AACpF,gBAAQ,IAAI,sBAAsB,MAAM,MAAM,YAAY,KAAK,oBAAoB,CAAC,CAAC,CAAC,EAAE;AACxF,gBAAQ,IAAI,wBAAwB,MAAM,OAAO,KAAK,kBAAkB,KAAK,QAAQ,CAAC,IAAI,GAAG,CAAC,EAAE;AAChG,gBAAQ,IAAI,uBAAuB,MAAM,MAAM,KAAK,YAAY,QAAQ,CAAC,KAAK,GAAG,CAAC,EAAE;AAAA,MACtF;AAGA,cAAQ,IAAI,MAAM,KAAK,+BAAwB,CAAC;AAChD,cAAQ,IAAI,MAAM,KAAK,SAAI,OAAO,EAAE,CAAC,CAAC;AACtC,iBAAW,OAAO,MAAM,OAAO;AAC7B,cAAM,WAAW,IAAI,QAAQ,MAAM,cAAc,KAAK,QAAQ,CAAC;AAC/D,cAAM,MAAM,SAAI,OAAO,KAAK,MAAM,UAAU,CAAC,CAAC;AAC9C,gBAAQ,IAAI,KAAK,IAAI,UAAU,OAAO,EAAE,CAAC,IAAI,GAAG,IAAI,OAAO,MAAM,IAAI,KAAK,GAAG;AAAA,MAC/E;AAGA,cAAQ,IAAI,MAAM,KAAK,sBAAe,CAAC;AACvC,cAAQ,IAAI,MAAM,KAAK,SAAI,OAAO,EAAE,CAAC,CAAC;AACtC,cAAQ,IAAI,mBAAmB,MAAM,MAAM,MAAM,WAAW,CAAC,EAAE;AAC/D,cAAQ,IAAI,iBAAiB,MAAM,MAAM,YAAY,MAAM,SAAS,CAAC,CAAC,EAAE;AACxE,cAAQ,IAAI,sBAAsB,MAAM,MAAM,YAAY,MAAM,cAAc,CAAC,CAAC,EAAE;AAElF,YAAM,qBAAqB,IAAI,MAAM,iBAAiB,MAAM,aAAa,KAAK,QAAQ,CAAC;AACvF,cAAQ,IAAI,0BAA0B,MAAM,MAAM,mBAAmB,GAAG,CAAC,EAAE;AAG3E,YAAM,eAAe,qBAAqB,KAAK;AAC/C,cAAQ,IAAI,MAAM,KAAK,qCAA8B,CAAC;AACtD,cAAQ,IAAI,MAAM,KAAK,SAAI,OAAO,EAAE,CAAC,CAAC;AACtC,cAAQ,IAAI,kBAAkB,MAAM,MAAM,OAAO,CAAC,0BAA0B;AAC5E,cAAQ,IAAI,6BAA6B,MAAM,OAAO,aAAa,OAAO,CAAC,EAAE;AAC7E,cAAQ,IAAI,0BAA0B,MAAM,KAAK,aAAa,GAAG,CAAC,EAAE;AACpE,cAAQ,IAAI,YAAY,MAAM,MAAM,aAAa,KAAK,CAAC,EAAE;AAEzD,UAAI,QAAQ,SAAS;AAEnB,cAAM,mBAAmB,GAAG,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,WAMnC,EAAE,IAAI,KAAK,IAAI,IAAI,KAAK,KAAK,KAAK,GAAI;AAEvC,YAAI,iBAAiB,SAAS,GAAG;AAC/B,kBAAQ,IAAI,MAAM,KAAK,2CAAoC,CAAC;AAC5D,kBAAQ,IAAI,MAAM,KAAK,SAAI,OAAO,EAAE,CAAC,CAAC;AACtC,qBAAW,KAAK,kBAAkB;AAChC,kBAAM,OAAO,IAAI,KAAK,EAAE,WAAW,EAAE,mBAAmB;AACxD,oBAAQ,IAAI,KAAK,IAAI,MAAM,EAAE,SAAS,UAAU,GAAG,CAAC,CAAC,cAAS,EAAE,IAAI,YAAY,EAAE,MAAM,QAAQ,CAAC,CAAC,GAAG;AAAA,UACvG;AAAA,QACF;AAAA,MACF;AAEA,SAAG,MAAM;AAAA,IAEX,SAAS,OAAO;AACd,cAAQ,KAAK,mCAAmC;AAChD,cAAQ,MAAM,KAAK;AACnB,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,CAAC;AAEH,UACG,QAAQ,SAAS,EACjB,YAAY,sCAAsC,EAClD,OAAO,aAAa,8CAA8C,EAClE,OAAO,WAAW,mCAAmC,EACrD,OAAO,OAAO,YAAY;AACzB,UAAM,UAAU,IAAI,mCAAmC,EAAE,MAAM;AAE/D,QAAI;AACF,YAAM,SAAS,KAAK,QAAQ,IAAI,GAAG,gBAAgB,YAAY;AAC/D,YAAM,KAAK,IAAI,SAAS,MAAM;AAC9B,YAAM,gBAAgB,IAAI,cAAc;AACxC,YAAMA,WAAU,IAAI,wBAAwB,IAAI,aAAa;AAE7D,UAAI,QAAQ,QAAQ;AAElB,cAAM,aAAa,GAAG,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,WAM7B,EAAE,IAAI,KAAK,IAAI,CAAC;AAEjB,cAAM,YAAY;AAAA,UAChB,WAAW,WAAW;AAAA,YAAO,CAAC,MAC5B,EAAE,SAAS,SAAS,EAAE,YAAY;AAAA,UACpC;AAAA,UACA,YAAY,WAAW;AAAA,YAAO,CAAC,MAC7B,EAAE,SAAS,UAAU,EAAE,YAAY;AAAA,UACrC;AAAA,QACF;AAEA,gBAAQ,KAAK,mCAAmC;AAEhD,gBAAQ,IAAI,MAAM,KAAK,6BAAsB,CAAC;AAC9C,gBAAQ,IAAI,MAAM,KAAK,SAAI,OAAO,EAAE,CAAC,CAAC;AAEtC,YAAI,UAAU,UAAU,SAAS,GAAG;AAClC,kBAAQ,IAAI,MAAM,IAAI;AAAA,8CAA2B,UAAU,UAAU,MAAM,SAAS,CAAC;AACrF,qBAAW,KAAK,UAAU,UAAU,MAAM,GAAG,CAAC,GAAG;AAC/C,oBAAQ,IAAI,YAAO,EAAE,SAAS,UAAU,GAAG,CAAC,CAAC,QAAQ,EAAE,UAAU,QAAQ,CAAC,CAAC,iBAAiB,EAAE,MAAM,QAAQ,CAAC,CAAC,GAAG;AAAA,UACnH;AACA,cAAI,UAAU,UAAU,SAAS,GAAG;AAClC,oBAAQ,IAAI,aAAa,UAAU,UAAU,SAAS,CAAC,OAAO;AAAA,UAChE;AAAA,QACF;AAEA,YAAI,UAAU,WAAW,SAAS,GAAG;AACnC,kBAAQ,IAAI,MAAM,OAAO;AAAA,mDAA6B,UAAU,WAAW,MAAM,SAAS,CAAC;AAC3F,qBAAW,KAAK,UAAU,WAAW,MAAM,GAAG,CAAC,GAAG;AAChD,kBAAM,UAAU,KAAK,MAAM,EAAE,YAAY,EAAE;AAC3C,oBAAQ,IAAI,YAAO,EAAE,SAAS,UAAU,GAAG,CAAC,CAAC,QAAQ,OAAO,iBAAiB,EAAE,MAAM,QAAQ,CAAC,CAAC,GAAG;AAAA,UACpG;AACA,cAAI,UAAU,WAAW,SAAS,GAAG;AACnC,oBAAQ,IAAI,aAAa,UAAU,WAAW,SAAS,CAAC,OAAO;AAAA,UACjE;AAAA,QACF;AAEA,YAAI,UAAU,UAAU,WAAW,KAAK,UAAU,WAAW,WAAW,GAAG;AACzE,kBAAQ,IAAI,MAAM,MAAM,iCAA4B,CAAC;AAAA,QACvD;AAAA,MAEF,OAAO;AAEL,gBAAQ,OAAO;AACf,cAAM,UAAU,MAAMA,SAAQ,aAAa;AAE3C,gBAAQ,QAAQ,qBAAqB;AAErC,gBAAQ,IAAI,MAAM,KAAK,6BAAwB,CAAC;AAChD,gBAAQ,IAAI,MAAM,KAAK,SAAI,OAAO,EAAE,CAAC,CAAC;AACtC,gBAAQ,IAAI,sBAAiB,MAAM,OAAO,QAAQ,SAAS,CAAC,SAAS;AACrE,gBAAQ,IAAI,uBAAkB,MAAM,KAAK,QAAQ,UAAU,CAAC,SAAS;AAErE,YAAI,QAAQ,OAAO,SAAS,GAAG;AAC7B,kBAAQ,IAAI,MAAM,IAAI;AAAA,iBAAe,QAAQ,OAAO,MAAM,IAAI,CAAC;AAC/D,qBAAW,SAAS,QAAQ,OAAO,MAAM,GAAG,CAAC,GAAG;AAC9C,oBAAQ,IAAI,YAAO,KAAK,EAAE;AAAA,UAC5B;AAAA,QACF;AAAA,MACF;AAEA,SAAG,MAAM;AAAA,IAEX,SAAS,OAAO;AACd,cAAQ,KAAK,kBAAkB;AAC/B,cAAQ,MAAM,KAAK;AACnB,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,CAAC;AAEH,UACG,QAAQ,SAAS,EACjB,YAAY,uCAAuC,EACnD,OAAO,mBAAmB,mCAAmC,UAAU,EAAE,EACzE,OAAO,aAAa,6CAA6C,EACjE,OAAO,OAAO,YAAY;AACzB,UAAM,UAAU,IAAI,kCAAkC,EAAE,MAAM;AAE9D,QAAI;AACF,YAAM,SAAS,KAAK,QAAQ,IAAI,GAAG,gBAAgB,YAAY;AAC/D,YAAM,KAAK,IAAI,SAAS,MAAM;AAC9B,YAAM,gBAAgB,IAAI,cAAc;AACxC,YAAMA,WAAU,IAAI,wBAAwB,IAAI,aAAa;AAE7D,YAAM,SAAS,KAAK,IAAI,IAAK,QAAQ,OAAO,KAAK,KAAK,KAAK;AAE3D,UAAI,QAAQ,QAAQ;AAClB,cAAM,WAAW,GAAG,QAAQ;AAAA;AAAA;AAAA;AAAA,WAI3B,EAAE,IAAI,MAAM;AAEb,gBAAQ,KAAK,qCAAqC;AAElD,gBAAQ,IAAI,MAAM,KAAK,+BAAwB,CAAC;AAChD,gBAAQ,IAAI,MAAM,KAAK,SAAI,OAAO,EAAE,CAAC,CAAC;AACtC,gBAAQ,IAAI,uBAAuB,MAAM,IAAI,SAAS,SAAS,CAAC,CAAC,EAAE;AACnE,gBAAQ,IAAI,oBAAoB,MAAM,OAAO,YAAY,SAAS,QAAQ,CAAC,CAAC,CAAC,EAAE;AAC/E,gBAAQ,IAAI,iBAAiB,QAAQ,IAAI,yBAAyB;AAAA,MAEpE,OAAO;AACL,cAAM,UAAU,MAAMA,SAAQ,QAAQ;AACtC,gBAAQ,QAAQ,+BAA+B,OAAO,SAAS;AAAA,MACjE;AAEA,SAAG,MAAM;AAAA,IAEX,SAAS,OAAO;AACd,cAAQ,KAAK,gBAAgB;AAC7B,cAAQ,MAAM,KAAK;AACnB,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,CAAC;AAEH,UACG,QAAQ,oBAAoB,EAC5B,YAAY,wCAAwC,EACpD,OAAO,OAAO,YAAY;AACzB,UAAM,UAAU,IAAI,oBAAoB,OAAO,KAAK,EAAE,MAAM;AAE5D,QAAI;AACF,YAAM,SAAS,KAAK,QAAQ,IAAI,GAAG,gBAAgB,YAAY;AAC/D,YAAM,KAAK,IAAI,SAAS,MAAM;AAC9B,YAAM,gBAAgB,IAAI,cAAc;AACxC,YAAMA,WAAU,IAAI,wBAAwB,IAAI,aAAa;AAE7D,YAAM,QAAQ,MAAMA,SAAQ,cAAc,OAAO;AAEjD,UAAI,CAAC,OAAO;AACV,gBAAQ,KAAK,SAAS,OAAO,YAAY;AACzC,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAEA,cAAQ,QAAQ,iBAAiB;AAEjC,cAAQ,IAAI,MAAM,KAAK,4BAAqB,CAAC;AAC7C,cAAQ,IAAI,MAAM,KAAK,SAAI,OAAO,EAAE,CAAC,CAAC;AACtC,cAAQ,IAAI,SAAS,MAAM,KAAK,MAAM,EAAE,CAAC,EAAE;AAC3C,cAAQ,IAAI,WAAW,MAAM,OAAO,MAAM,IAAI,CAAC,EAAE;AACjD,cAAQ,IAAI,YAAY,MAAM,MAAM,MAAM,MAAM,QAAQ,CAAC,CAAC,CAAC,EAAE;AAC7D,cAAQ,IAAI,cAAc,MAAM,OAAO,EAAE;AACzC,cAAQ,IAAI,YAAY,MAAM,OAAO,UAAU,MAAM,aAAa,SAAS,CAAC,EAAE;AAE9E,YAAM,WAAW,MAAM;AACvB,UAAI,UAAU;AACZ,gBAAQ,IAAI,MAAM,KAAK,uBAAgB,CAAC;AACxC,gBAAQ,IAAI,YAAY,IAAI,KAAK,SAAS,SAAS,EAAE,eAAe,CAAC,EAAE;AACvE,gBAAQ,IAAI,eAAe,eAAe,SAAS,UAAU,SAAS,SAAS,CAAC,EAAE;AAClF,gBAAQ,IAAI,YAAY,SAAS,eAAe,UAAU,SAAS,iBAAiB,CAAC,EAAE;AACvF,gBAAQ,IAAI,aAAa,SAAS,mBAAmB,UAAU,SAAS,eAAe,CAAC,EAAE;AAAA,MAC5F;AAGA,YAAM,WAAW,GAAG;AAAA,QAClB;AAAA,MACF,EAAE,IAAI,OAAO;AAEb,UAAI,UAAU;AACZ,cAAM,WAAW,SAAS,SAAS,QAAQ,cAC3B,SAAS,SAAS,SAAS,iBAAO;AAClD,gBAAQ,IAAI,MAAM,KAAK,sBAAe,CAAC;AACvC,gBAAQ,IAAI,WAAW,QAAQ,IAAI,SAAS,IAAI,EAAE;AAClD,gBAAQ,IAAI,mBAAmB,SAAS,YAAY,EAAE;AAAA,MACxD;AAEA,SAAG,MAAM;AAAA,IAEX,SAAS,OAAO;AACd,cAAQ,KAAK,0BAA0B;AACvC,cAAQ,MAAM,KAAK;AACnB,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,CAAC;AAEH,UACG,QAAQ,QAAQ,EAChB,YAAY,4BAA4B,EACxC,OAAO,YAAY;AAClB,YAAQ,IAAI,MAAM,KAAK,wCAA8B,CAAC;AACtD,YAAQ,IAAI,MAAM,KAAK,SAAI,OAAO,EAAE,CAAC,CAAC;AAEtC,YAAQ,IAAI,MAAM,IAAI,+BAAwB,CAAC;AAC/C,YAAQ,IAAI,UAAU,QAAQ,IAAI,YAAY,MAAM,MAAM,YAAY,IAAI,MAAM,OAAO,gBAAgB,CAAC,EAAE;AAC1G,YAAQ,IAAI,iBAAiB;AAC7B,YAAQ,IAAI,qBAAqB;AAEjC,YAAQ,IAAI,MAAM,OAAO,8CAAoC,CAAC;AAC9D,YAAQ,IAAI,eAAe,QAAQ,IAAI,2BAA2B,gBAAgB,EAAE;AACpF,YAAQ,IAAI,aAAa,QAAQ,IAAI,uBAAuB,kBAAkB,EAAE;AAChF,YAAQ,IAAI,iBAAiB,QAAQ,IAAI,4BAA4B,MAAM,MAAM,KAAK,IAAI,MAAM,OAAO,SAAS,CAAC,EAAE;AACnH,YAAQ,IAAI,sBAAsB;AAElC,YAAQ,IAAI,MAAM,KAAK,kCAAwB,CAAC;AAChD,YAAQ,IAAI,cAAc,QAAQ,IAAI,kBAAkB,gBAAgB,EAAE;AAC1E,YAAQ,IAAI,aAAa,QAAQ,IAAI,cAAc,kBAAkB,EAAE;AACvE,YAAQ,IAAI,eAAe,QAAQ,IAAI,eAAe,MAAM,MAAM,KAAK,IAAI,MAAM,OAAO,SAAS,CAAC,EAAE;AACpG,YAAQ,IAAI,2BAA2B;AACvC,YAAQ,IAAI,uBAAuB;AAEnC,YAAQ,IAAI,MAAM,KAAK,mCAA4B,CAAC;AACpD,YAAQ,IAAI,mCAA8B;AAC1C,YAAQ,IAAI,mCAA8B;AAC1C,YAAQ,IAAI,oCAAoC;AAAA,EAClD,CAAC;AAEH,SAAO;AACT;AAKA,SAAS,qBAAqB,OAA6D;AAEzF,QAAM,WAAW,MAAM,OAAO,KAAK,CAAC,MAAW,EAAE,SAAS,MAAM;AAChE,QAAM,WAAW,MAAM,OAAO,KAAK,CAAC,MAAW,EAAE,SAAS,MAAM;AAEhE,QAAM,UAAU,UAAU,oBAAoB,MAAM,OAAO,OAAO;AAClE,QAAM,UAAU,UAAU,oBAAoB,MAAM,OAAO,OAAO;AAGlE,QAAM,cAAc,SAAS;AAG7B,QAAM,UAAU,SAAS;AAEzB,QAAM,YAAY,cAAc;AAEhC,SAAO;AAAA,IACL,SAAS,IAAI,YAAY,QAAQ,CAAC,CAAC;AAAA,IACnC,KAAK,IAAI,QAAQ,QAAQ,CAAC,CAAC;AAAA,IAC3B,OAAO,IAAI,UAAU,QAAQ,CAAC,CAAC;AAAA,EACjC;AACF;",
4
+ "sourcesContent": ["/**\n * Storage management commands for StackMemory\n */\n\nimport { Command } from 'commander';\nimport chalk from 'chalk';\nimport ora from 'ora';\nimport Database from 'better-sqlite3';\nimport { join } from 'path';\nimport { existsSync } from 'fs';\nimport { RailwayOptimizedStorage } from '../../core/storage/railway-optimized-storage.js';\nimport { ConfigManager } from '../../core/config/config-manager.js';\nimport { formatBytes, formatDuration } from '../../utils/formatting.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 createStorageCommand(): Command {\n const storage = new Command('storage').description(\n 'Manage 3-tier storage system (Redis/Railway/GCS)'\n );\n\n storage\n .command('status')\n .description('Show storage tier statistics')\n .option('-v, --verbose', 'Show detailed statistics')\n .action(async (options) => {\n const spinner = ora('Loading storage statistics...').start();\n \n try {\n const dbPath = join(process.cwd(), '.stackmemory', 'context.db');\n if (!existsSync(dbPath)) {\n spinner.fail('StackMemory not initialized in this directory');\n process.exit(1);\n }\n \n const db = new Database(dbPath);\n const configManager = new ConfigManager();\n const storage = new RailwayOptimizedStorage(db, configManager);\n \n const stats = storage.getStorageStats();\n spinner.succeed('Storage statistics loaded');\n \n console.log(chalk.blue('\\n\uD83D\uDCCA Storage Tier Distribution:'));\n console.log(chalk.gray('\u2501'.repeat(50)));\n \n // Tier statistics\n for (const tier of stats.byTier) {\n const icon = tier.tier === 'hot' ? '\uD83D\uDD25' : tier.tier === 'warm' ? '\u2601\uFE0F' : '\u2744\uFE0F';\n const color = tier.tier === 'hot' ? chalk.red : tier.tier === 'warm' ? chalk.yellow : chalk.cyan;\n \n console.log(`\\n${icon} ${color(tier.tier.toUpperCase())} Tier:`);\n console.log(` Traces: ${chalk.white(tier.count)}`);\n console.log(` Original Size: ${chalk.white(formatBytes(tier.total_original || 0))}`);\n console.log(` Compressed Size: ${chalk.white(formatBytes(tier.total_compressed || 0))}`);\n console.log(` Compression Ratio: ${chalk.green((tier.avg_compression * 100).toFixed(1) + '%')}`);\n console.log(` Avg Access Count: ${chalk.white(tier.avg_access?.toFixed(1) || '0')}`);\n }\n \n // Age distribution\n console.log(chalk.blue('\\n\uD83D\uDCC5 Age Distribution:'));\n console.log(chalk.gray('\u2501'.repeat(50)));\n for (const age of stats.byAge) {\n const percent = (age.count / stats.totalTraces * 100).toFixed(1);\n const bar = '\u2588'.repeat(Math.floor(percent / 2));\n console.log(` ${age.age_group.padEnd(10)} ${bar} ${percent}% (${age.count})`);\n }\n \n // Summary\n console.log(chalk.blue('\\n\uD83D\uDCC8 Summary:'));\n console.log(chalk.gray('\u2501'.repeat(50)));\n console.log(` Total Traces: ${chalk.white(stats.totalTraces)}`);\n console.log(` Total Size: ${chalk.white(formatBytes(stats.totalSize))}`);\n console.log(` Compressed Size: ${chalk.white(formatBytes(stats.compressedSize))}`);\n \n const compressionRatio = ((1 - stats.compressedSize / stats.totalSize) * 100).toFixed(1);\n console.log(` Overall Compression: ${chalk.green(compressionRatio + '%')}`);\n \n // Cost estimation\n const costEstimate = calculateStorageCost(stats);\n console.log(chalk.blue('\\n\uD83D\uDCB0 Estimated Monthly Cost:'));\n console.log(chalk.gray('\u2501'.repeat(50)));\n console.log(` Redis (Hot): ${chalk.green('$0.00')} (included with Railway)`);\n console.log(` Railway Buckets (Warm): ${chalk.yellow(costEstimate.railway)}`);\n console.log(` GCS Coldline (Cold): ${chalk.cyan(costEstimate.gcs)}`);\n console.log(` Total: ${chalk.white(costEstimate.total)}`);\n \n if (options.verbose) {\n // Show recent migrations\n const recentMigrations = db.prepare(`\n SELECT trace_id, tier, migrated_at, score\n FROM storage_tiers\n WHERE migrated_at > ?\n ORDER BY migrated_at DESC\n LIMIT 10\n `).all(Date.now() - 24 * 60 * 60 * 1000) as any[];\n \n if (recentMigrations.length > 0) {\n console.log(chalk.blue('\\n\uD83D\uDD04 Recent Migrations (last 24h):'));\n console.log(chalk.gray('\u2501'.repeat(50)));\n for (const m of recentMigrations) {\n const time = new Date(m.migrated_at).toLocaleTimeString();\n console.log(` ${time} - ${m.trace_id.substring(0, 8)}... \u2192 ${m.tier} (score: ${m.score.toFixed(2)})`);\n }\n }\n }\n \n db.close();\n \n } catch (error: unknown) {\n spinner.fail('Failed to load storage statistics');\n console.error(error);\n process.exit(1);\n }\n });\n\n storage\n .command('migrate')\n .description('Migrate traces between storage tiers')\n .option('--dry-run', 'Show what would be migrated without doing it')\n .option('--force', 'Force migration regardless of age')\n .action(async (options) => {\n const spinner = ora('Checking for traces to migrate...').start();\n \n try {\n const dbPath = join(process.cwd(), '.stackmemory', 'context.db');\n const db = new Database(dbPath);\n const configManager = new ConfigManager();\n const storage = new RailwayOptimizedStorage(db, configManager);\n \n if (options.dryRun) {\n // Analyze what would be migrated\n const candidates = db.prepare(`\n SELECT trace_id, tier, created_at, score,\n (? - created_at) / 3600000 as age_hours\n FROM storage_tiers\n WHERE tier != 'cold'\n ORDER BY created_at ASC\n `).all(Date.now()) as any[];\n \n const toMigrate = {\n hotToWarm: candidates.filter((c: any) => \n c.tier === 'hot' && c.age_hours > 24\n ),\n warmToCold: candidates.filter((c: any) => \n c.tier === 'warm' && c.age_hours > 720\n ),\n };\n \n spinner.info('Dry run - no changes will be made');\n \n console.log(chalk.blue('\\n\uD83D\uDD04 Migration Plan:'));\n console.log(chalk.gray('\u2501'.repeat(50)));\n \n if (toMigrate.hotToWarm.length > 0) {\n console.log(chalk.red(`\\n\uD83D\uDD25 \u2192 \u2601\uFE0F Hot to Warm: ${toMigrate.hotToWarm.length} traces`));\n for (const t of toMigrate.hotToWarm.slice(0, 5)) {\n console.log(` \u2022 ${t.trace_id.substring(0, 8)}... (${t.age_hours.toFixed(0)}h old, score: ${t.score.toFixed(2)})`);\n }\n if (toMigrate.hotToWarm.length > 5) {\n console.log(` ... and ${toMigrate.hotToWarm.length - 5} more`);\n }\n }\n \n if (toMigrate.warmToCold.length > 0) {\n console.log(chalk.yellow(`\\n\u2601\uFE0F \u2192 \u2744\uFE0F Warm to Cold: ${toMigrate.warmToCold.length} traces`));\n for (const t of toMigrate.warmToCold.slice(0, 5)) {\n const ageDays = Math.floor(t.age_hours / 24);\n console.log(` \u2022 ${t.trace_id.substring(0, 8)}... (${ageDays}d old, score: ${t.score.toFixed(2)})`);\n }\n if (toMigrate.warmToCold.length > 5) {\n console.log(` ... and ${toMigrate.warmToCold.length - 5} more`);\n }\n }\n \n if (toMigrate.hotToWarm.length === 0 && toMigrate.warmToCold.length === 0) {\n console.log(chalk.green('\u2713 No traces need migration'));\n }\n \n } else {\n // Perform actual migration\n spinner.text = 'Migrating traces between tiers...';\n const results = await storage.migrateTiers();\n \n spinner.succeed('Migration completed');\n \n console.log(chalk.blue('\\n\u2705 Migration Results:'));\n console.log(chalk.gray('\u2501'.repeat(50)));\n console.log(` Hot \u2192 Warm: ${chalk.yellow(results.hotToWarm)} traces`);\n console.log(` Warm \u2192 Cold: ${chalk.cyan(results.warmToCold)} traces`);\n \n if (results.errors.length > 0) {\n console.log(chalk.red(`\\n\u274C Errors (${results.errors.length}):`));\n for (const error of results.errors.slice(0, 5)) {\n console.log(` \u2022 ${error}`);\n }\n }\n }\n \n db.close();\n \n } catch (error: unknown) {\n spinner.fail('Migration failed');\n console.error(error);\n process.exit(1);\n }\n });\n\n storage\n .command('cleanup')\n .description('Clean up old traces from cold storage')\n .option('--days <number>', 'Remove traces older than N days', parseInt, 90)\n .option('--dry-run', 'Show what would be removed without doing it')\n .action(async (options) => {\n const spinner = ora('Analyzing storage for cleanup...').start();\n \n try {\n const dbPath = join(process.cwd(), '.stackmemory', 'context.db');\n const db = new Database(dbPath);\n const configManager = new ConfigManager();\n const storage = new RailwayOptimizedStorage(db, configManager);\n \n const cutoff = Date.now() - (options.days * 24 * 60 * 60 * 1000);\n \n if (options.dryRun) {\n const toRemove = db.prepare(`\n SELECT COUNT(*) as count, SUM(compressed_size) as size\n FROM storage_tiers\n WHERE tier = 'cold' AND created_at < ? AND access_count = 0\n `).get(cutoff) as any;\n \n spinner.info('Dry run - no traces will be removed');\n \n console.log(chalk.blue('\\n\uD83E\uDDF9 Cleanup Analysis:'));\n console.log(chalk.gray('\u2501'.repeat(50)));\n console.log(` Traces to remove: ${chalk.red(toRemove.count || 0)}`);\n console.log(` Space to free: ${chalk.yellow(formatBytes(toRemove.size || 0))}`);\n console.log(` Criteria: > ${options.days} days old with 0 access`);\n \n } else {\n const removed = await storage.cleanup();\n spinner.succeed(`Cleanup completed - removed ${removed} traces`);\n }\n \n db.close();\n \n } catch (error: unknown) {\n spinner.fail('Cleanup failed');\n console.error(error);\n process.exit(1);\n }\n });\n\n storage\n .command('retrieve <traceId>')\n .description('Retrieve a trace from any storage tier')\n .action(async (traceId) => {\n const spinner = ora(`Retrieving trace ${traceId}...`).start();\n \n try {\n const dbPath = join(process.cwd(), '.stackmemory', 'context.db');\n const db = new Database(dbPath);\n const configManager = new ConfigManager();\n const storage = new RailwayOptimizedStorage(db, configManager);\n \n const trace = await storage.retrieveTrace(traceId);\n \n if (!trace) {\n spinner.fail(`Trace ${traceId} not found`);\n process.exit(1);\n }\n \n spinner.succeed('Trace retrieved');\n \n console.log(chalk.blue('\\n\uD83D\uDCE6 Trace Details:'));\n console.log(chalk.gray('\u2501'.repeat(50)));\n console.log(` ID: ${chalk.cyan(trace.id)}`);\n console.log(` Type: ${chalk.yellow(trace.type)}`);\n console.log(` Score: ${chalk.green(trace.score.toFixed(3))}`);\n console.log(` Summary: ${trace.summary}`);\n console.log(` Tools: ${trace.tools?.length || trace.toolSummary?.count || 0}`);\n \n const metadata = trace.metadata;\n if (metadata) {\n console.log(chalk.blue('\\n\uD83D\uDCCB Metadata:'));\n console.log(` Start: ${new Date(metadata.startTime).toLocaleString()}`);\n console.log(` Duration: ${formatDuration(metadata.endTime - metadata.startTime)}`);\n console.log(` Files: ${metadata.filesModified?.length || metadata.filesModified || 0}`);\n console.log(` Errors: ${metadata.errorsEncountered?.length || metadata.errorsCount || 0}`);\n }\n \n // Show storage location\n const location = db.prepare(\n 'SELECT tier, location, access_count FROM storage_tiers WHERE trace_id = ?'\n ).get(traceId) as any;\n \n if (location) {\n const tierIcon = location.tier === 'hot' ? '\uD83D\uDD25' : \n location.tier === 'warm' ? '\u2601\uFE0F' : '\u2744\uFE0F';\n console.log(chalk.blue('\\n\uD83D\uDCBE Storage:'));\n console.log(` Tier: ${tierIcon} ${location.tier}`);\n console.log(` Access Count: ${location.access_count}`);\n }\n \n db.close();\n \n } catch (error: unknown) {\n spinner.fail('Failed to retrieve trace');\n console.error(error);\n process.exit(1);\n }\n });\n\n storage\n .command('config')\n .description('Show storage configuration')\n .action(async () => {\n console.log(chalk.blue('\\n\u2699\uFE0F Storage Configuration:'));\n console.log(chalk.gray('\u2501'.repeat(50)));\n \n console.log(chalk.red('\\n\uD83D\uDD25 Hot Tier (Redis):'));\n console.log(` URL: ${process.env['REDIS_URL'] ? chalk.green('Configured') : chalk.yellow('Not configured')}`);\n console.log(` TTL: 24 hours`);\n console.log(` Max Memory: 100MB`);\n \n console.log(chalk.yellow('\\n\u2601\uFE0F Warm Tier (Railway Buckets):'));\n console.log(` Endpoint: ${process.env['RAILWAY_BUCKET_ENDPOINT'] || 'Not configured'}`);\n console.log(` Bucket: ${process.env['RAILWAY_BUCKET_NAME'] || 'stackmemory-warm'}`);\n console.log(` Access Key: ${process.env['RAILWAY_BUCKET_ACCESS_KEY'] ? chalk.green('Set') : chalk.yellow('Not set')}`);\n console.log(` Retention: 30 days`);\n \n console.log(chalk.cyan('\\n\u2744\uFE0F Cold Tier (GCS):'));\n console.log(` Project: ${process.env['GCP_PROJECT_ID'] || 'Not configured'}`);\n console.log(` Bucket: ${process.env['GCS_BUCKET'] || 'stackmemory-cold'}`);\n console.log(` Key File: ${process.env['GCP_KEY_FILE'] ? chalk.green('Set') : chalk.yellow('Not set')}`);\n console.log(` Storage Class: Coldline`);\n console.log(` Retention: Infinite`);\n \n console.log(chalk.blue('\\n\uD83D\uDCCA Migration Thresholds:'));\n console.log(` Hot \u2192 Warm: After 24 hours`);\n console.log(` Warm \u2192 Cold: After 30 days`);\n console.log(` Low Score Migration: < 0.4 score`);\n });\n\n return storage;\n}\n\n/**\n * Calculate storage cost estimates\n */\nfunction calculateStorageCost(stats: any): { railway: string; gcs: string; total: string } {\n // Find warm and cold tier sizes\n const warmTier = stats.byTier.find((t: any) => t.tier === 'warm');\n const coldTier = stats.byTier.find((t: any) => t.tier === 'cold');\n \n const warmGB = (warmTier?.total_compressed || 0) / (1024 * 1024 * 1024);\n const coldGB = (coldTier?.total_compressed || 0) / (1024 * 1024 * 1024);\n \n // Railway Buckets: ~$0.02/GB (estimate)\n const railwayCost = warmGB * 0.02;\n \n // GCS Coldline: $0.004/GB\n const gcsCost = coldGB * 0.004;\n \n const totalCost = railwayCost + gcsCost;\n \n return {\n railway: `$${railwayCost.toFixed(2)}`,\n gcs: `$${gcsCost.toFixed(2)}`,\n total: `$${totalCost.toFixed(2)}`,\n };\n}"],
5
+ "mappings": "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",
6
6
  "names": ["storage"]
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/cli/commands/tasks.ts"],
4
- "sourcesContent": ["/**\n * Enhanced Task Commands for StackMemory CLI\n * Provides task management directly from command line\n */\n\nimport { Command } from 'commander';\nimport Database from 'better-sqlite3';\nimport { join } from 'path';\nimport { existsSync } from 'fs';\nimport {\n PebblesTaskStore,\n TaskPriority,\n TaskStatus,\n} from '../../features/tasks/pebbles-task-store.js';\nimport { logger } from '../../core/monitoring/logger.js';\n\nfunction getTaskStore(projectRoot: string): PebblesTaskStore | null {\n const dbPath = join(projectRoot, '.stackmemory', 'context.db');\n if (!existsSync(dbPath)) {\n console.log(\n '\u274C StackMemory not initialized. Run \"stackmemory init\" first.'\n );\n return null;\n }\n const db = new Database(dbPath);\n return new PebblesTaskStore(projectRoot, db);\n}\n\nexport function createTaskCommands(): Command {\n const tasks = new Command('tasks')\n .alias('task')\n .description('Manage tasks from command line');\n\n // List tasks\n tasks\n .command('list')\n .alias('ls')\n .description('List tasks')\n .option(\n '-s, --status <status>',\n 'Filter by status (pending, in_progress, completed, blocked)'\n )\n .option(\n '-p, --priority <priority>',\n 'Filter by priority (urgent, high, medium, low)'\n )\n .option('-q, --query <text>', 'Search in title/description')\n .option('-l, --limit <n>', 'Limit results', '20')\n .option('-a, --all', 'Include completed tasks')\n .action(async (options) => {\n const projectRoot = process.cwd();\n const taskStore = getTaskStore(projectRoot);\n if (!taskStore) return;\n\n try {\n // Get all tasks from DB\n const db = new Database(\n join(projectRoot, '.stackmemory', 'context.db')\n );\n let query = 'SELECT * FROM task_cache WHERE 1=1';\n const params: any[] = [];\n\n if (!options.all && !options.status) {\n query += \" AND status NOT IN ('completed', 'cancelled')\";\n }\n\n if (options.status) {\n query += ' AND status = ?';\n params.push(options.status);\n }\n\n if (options.priority) {\n query += ' AND priority = ?';\n params.push(options.priority);\n }\n\n if (options.query) {\n query += ' AND (title LIKE ? OR description LIKE ?)';\n params.push(`%${options.query}%`, `%${options.query}%`);\n }\n\n query += ' ORDER BY priority ASC, created_at DESC LIMIT ?';\n params.push(parseInt(options.limit));\n\n const rows = db.prepare(query).all(...params) as any[];\n db.close();\n\n if (rows.length === 0) {\n console.log('\uD83D\uDCDD No tasks found');\n return;\n }\n\n console.log(`\\n\uD83D\uDCCB Tasks (${rows.length})\\n`);\n\n const priorityIcon: Record<string, string> = {\n urgent: '\uD83D\uDD34',\n high: '\uD83D\uDFE0',\n medium: '\uD83D\uDFE1',\n low: '\uD83D\uDFE2',\n };\n const statusIcon: Record<string, string> = {\n pending: '\u23F3',\n in_progress: '\uD83D\uDD04',\n completed: '\u2705',\n blocked: '\uD83D\uDEAB',\n cancelled: '\u274C',\n };\n\n rows.forEach((row, i) => {\n const pIcon = priorityIcon[row.priority] || '\u26AA';\n const sIcon = statusIcon[row.status] || '\u26AA';\n const id = row.id.slice(0, 10);\n console.log(`${sIcon} ${pIcon} [${id}] ${row.title}`);\n if (row.description) {\n const desc = row.description.split('\\n')[0].slice(0, 60);\n console.log(\n ` ${desc}${row.description.length > 60 ? '...' : ''}`\n );\n }\n });\n console.log('');\n } catch (error) {\n console.error('\u274C Failed to list tasks:', (error as Error).message);\n }\n });\n\n // Add task\n tasks\n .command('add <title>')\n .description('Add a new task')\n .option('-d, --description <text>', 'Task description')\n .option(\n '-p, --priority <priority>',\n 'Priority (urgent, high, medium, low)',\n 'medium'\n )\n .option('-t, --tags <tags>', 'Comma-separated tags')\n .action(async (title, options) => {\n const projectRoot = process.cwd();\n const taskStore = getTaskStore(projectRoot);\n if (!taskStore) return;\n\n try {\n const taskId = taskStore.createTask({\n title,\n description: options.description,\n priority: options.priority as TaskPriority,\n frameId: 'cli',\n tags: options.tags\n ? options.tags.split(',').map((t: string) => t.trim())\n : [],\n });\n\n console.log(`\u2705 Created task: ${taskId.slice(0, 10)}`);\n console.log(` Title: ${title}`);\n console.log(` Priority: ${options.priority}`);\n } catch (error) {\n console.error('\u274C Failed to add task:', (error as Error).message);\n }\n });\n\n // Start task (set to in_progress)\n tasks\n .command('start <taskId>')\n .description('Start working on a task')\n .action(async (taskId) => {\n const projectRoot = process.cwd();\n const taskStore = getTaskStore(projectRoot);\n if (!taskStore) return;\n\n try {\n // Find task by partial ID\n const task = findTaskByPartialId(projectRoot, taskId);\n if (!task) {\n console.log(`\u274C Task not found: ${taskId}`);\n return;\n }\n\n taskStore.updateTaskStatus(task.id, 'in_progress', 'Started from CLI');\n console.log(`\uD83D\uDD04 Started: ${task.title}`);\n } catch (error) {\n console.error('\u274C Failed to start task:', (error as Error).message);\n }\n });\n\n // Complete task\n tasks\n .command('done <taskId>')\n .alias('complete')\n .description('Mark task as completed')\n .action(async (taskId) => {\n const projectRoot = process.cwd();\n const taskStore = getTaskStore(projectRoot);\n if (!taskStore) return;\n\n try {\n const task = findTaskByPartialId(projectRoot, taskId);\n if (!task) {\n console.log(`\u274C Task not found: ${taskId}`);\n return;\n }\n\n taskStore.updateTaskStatus(task.id, 'completed', 'Completed from CLI');\n console.log(`\u2705 Completed: ${task.title}`);\n } catch (error) {\n console.error('\u274C Failed to complete task:', (error as Error).message);\n }\n });\n\n // Show task details\n tasks\n .command('show <taskId>')\n .description('Show task details')\n .action(async (taskId) => {\n const projectRoot = process.cwd();\n\n try {\n const task = findTaskByPartialId(projectRoot, taskId);\n if (!task) {\n console.log(`\u274C Task not found: ${taskId}`);\n return;\n }\n\n console.log(`\\n\uD83D\uDCCB Task Details\\n`);\n console.log(`ID: ${task.id}`);\n console.log(`Title: ${task.title}`);\n console.log(`Status: ${task.status}`);\n console.log(`Priority: ${task.priority}`);\n console.log(\n `Created: ${new Date(task.created_at * 1000).toLocaleString()}`\n );\n if (task.completed_at) {\n console.log(\n `Completed: ${new Date(task.completed_at * 1000).toLocaleString()}`\n );\n }\n if (task.description) {\n console.log(`\\nDescription:\\n${task.description}`);\n }\n const tags = JSON.parse(task.tags || '[]');\n if (tags.length > 0) {\n console.log(`\\nTags: ${tags.join(', ')}`);\n }\n console.log('');\n } catch (error) {\n console.error('\u274C Failed to show task:', (error as Error).message);\n }\n });\n\n return tasks;\n}\n\nfunction findTaskByPartialId(\n projectRoot: string,\n partialId: string\n): any | null {\n const dbPath = join(projectRoot, '.stackmemory', 'context.db');\n if (!existsSync(dbPath)) return null;\n\n const db = new Database(dbPath);\n\n // Try exact match first, then partial\n let row = db.prepare('SELECT * FROM task_cache WHERE id = ?').get(partialId);\n\n if (!row) {\n row = db\n .prepare('SELECT * FROM task_cache WHERE id LIKE ?')\n .get(`${partialId}%`);\n }\n\n // Also try matching Linear identifier in title\n if (!row && partialId.match(/^ENG-\\d+$/i)) {\n row = db\n .prepare('SELECT * FROM task_cache WHERE title LIKE ?')\n .get(`%[${partialId.toUpperCase()}]%`);\n }\n\n db.close();\n return row || null;\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * Enhanced Task Commands for StackMemory CLI\n * Provides task management directly from command line\n */\n\nimport { Command } from 'commander';\nimport Database from 'better-sqlite3';\nimport { join } from 'path';\nimport { existsSync } from 'fs';\nimport {\n PebblesTaskStore,\n TaskPriority,\n TaskStatus,\n} from '../../features/tasks/pebbles-task-store.js';\nimport { logger } from '../../core/monitoring/logger.js';\n\nfunction getTaskStore(projectRoot: string): PebblesTaskStore | null {\n const dbPath = join(projectRoot, '.stackmemory', 'context.db');\n if (!existsSync(dbPath)) {\n console.log(\n '\u274C StackMemory not initialized. Run \"stackmemory init\" first.'\n );\n return null;\n }\n const db = new Database(dbPath);\n return new PebblesTaskStore(projectRoot, db);\n}\n\nexport function createTaskCommands(): Command {\n const tasks = new Command('tasks')\n .alias('task')\n .description('Manage tasks from command line');\n\n // List tasks\n tasks\n .command('list')\n .alias('ls')\n .description('List tasks')\n .option(\n '-s, --status <status>',\n 'Filter by status (pending, in_progress, completed, blocked)'\n )\n .option(\n '-p, --priority <priority>',\n 'Filter by priority (urgent, high, medium, low)'\n )\n .option('-q, --query <text>', 'Search in title/description')\n .option('-l, --limit <n>', 'Limit results', '20')\n .option('-a, --all', 'Include completed tasks')\n .action(async (options) => {\n const projectRoot = process.cwd();\n const taskStore = getTaskStore(projectRoot);\n if (!taskStore) return;\n\n try {\n // Get all tasks from DB\n const db = new Database(\n join(projectRoot, '.stackmemory', 'context.db')\n );\n let query = 'SELECT * FROM task_cache WHERE 1=1';\n const params: any[] = [];\n\n if (!options.all && !options.status) {\n query += \" AND status NOT IN ('completed', 'cancelled')\";\n }\n\n if (options.status) {\n query += ' AND status = ?';\n params.push(options.status);\n }\n\n if (options.priority) {\n query += ' AND priority = ?';\n params.push(options.priority);\n }\n\n if (options.query) {\n query += ' AND (title LIKE ? OR description LIKE ?)';\n params.push(`%${options.query}%`, `%${options.query}%`);\n }\n\n query += ' ORDER BY priority ASC, created_at DESC LIMIT ?';\n params.push(parseInt(options.limit));\n\n const rows = db.prepare(query).all(...params) as any[];\n db.close();\n\n if (rows.length === 0) {\n console.log('\uD83D\uDCDD No tasks found');\n return;\n }\n\n console.log(`\\n\uD83D\uDCCB Tasks (${rows.length})\\n`);\n\n const priorityIcon: Record<string, string> = {\n urgent: '\uD83D\uDD34',\n high: '\uD83D\uDFE0',\n medium: '\uD83D\uDFE1',\n low: '\uD83D\uDFE2',\n };\n const statusIcon: Record<string, string> = {\n pending: '\u23F3',\n in_progress: '\uD83D\uDD04',\n completed: '\u2705',\n blocked: '\uD83D\uDEAB',\n cancelled: '\u274C',\n };\n\n rows.forEach((row, i) => {\n const pIcon = priorityIcon[row.priority] || '\u26AA';\n const sIcon = statusIcon[row.status] || '\u26AA';\n const id = row.id.slice(0, 10);\n console.log(`${sIcon} ${pIcon} [${id}] ${row.title}`);\n if (row.description) {\n const desc = row.description.split('\\n')[0].slice(0, 60);\n console.log(\n ` ${desc}${row.description.length > 60 ? '...' : ''}`\n );\n }\n });\n console.log('');\n } catch (error: unknown) {\n console.error('\u274C Failed to list tasks:', (error as Error).message);\n }\n });\n\n // Add task\n tasks\n .command('add <title>')\n .description('Add a new task')\n .option('-d, --description <text>', 'Task description')\n .option(\n '-p, --priority <priority>',\n 'Priority (urgent, high, medium, low)',\n 'medium'\n )\n .option('-t, --tags <tags>', 'Comma-separated tags')\n .action(async (title, options) => {\n const projectRoot = process.cwd();\n const taskStore = getTaskStore(projectRoot);\n if (!taskStore) return;\n\n try {\n const taskId = taskStore.createTask({\n title,\n description: options.description,\n priority: options.priority as TaskPriority,\n frameId: 'cli',\n tags: options.tags\n ? options.tags.split(',').map((t: string) => t.trim())\n : [],\n });\n\n console.log(`\u2705 Created task: ${taskId.slice(0, 10)}`);\n console.log(` Title: ${title}`);\n console.log(` Priority: ${options.priority}`);\n } catch (error: unknown) {\n console.error('\u274C Failed to add task:', (error as Error).message);\n }\n });\n\n // Start task (set to in_progress)\n tasks\n .command('start <taskId>')\n .description('Start working on a task')\n .action(async (taskId) => {\n const projectRoot = process.cwd();\n const taskStore = getTaskStore(projectRoot);\n if (!taskStore) return;\n\n try {\n // Find task by partial ID\n const task = findTaskByPartialId(projectRoot, taskId);\n if (!task) {\n console.log(`\u274C Task not found: ${taskId}`);\n return;\n }\n\n taskStore.updateTaskStatus(task.id, 'in_progress', 'Started from CLI');\n console.log(`\uD83D\uDD04 Started: ${task.title}`);\n } catch (error: unknown) {\n console.error('\u274C Failed to start task:', (error as Error).message);\n }\n });\n\n // Complete task\n tasks\n .command('done <taskId>')\n .alias('complete')\n .description('Mark task as completed')\n .action(async (taskId) => {\n const projectRoot = process.cwd();\n const taskStore = getTaskStore(projectRoot);\n if (!taskStore) return;\n\n try {\n const task = findTaskByPartialId(projectRoot, taskId);\n if (!task) {\n console.log(`\u274C Task not found: ${taskId}`);\n return;\n }\n\n taskStore.updateTaskStatus(task.id, 'completed', 'Completed from CLI');\n console.log(`\u2705 Completed: ${task.title}`);\n } catch (error: unknown) {\n console.error('\u274C Failed to complete task:', (error as Error).message);\n }\n });\n\n // Show task details\n tasks\n .command('show <taskId>')\n .description('Show task details')\n .action(async (taskId) => {\n const projectRoot = process.cwd();\n\n try {\n const task = findTaskByPartialId(projectRoot, taskId);\n if (!task) {\n console.log(`\u274C Task not found: ${taskId}`);\n return;\n }\n\n console.log(`\\n\uD83D\uDCCB Task Details\\n`);\n console.log(`ID: ${task.id}`);\n console.log(`Title: ${task.title}`);\n console.log(`Status: ${task.status}`);\n console.log(`Priority: ${task.priority}`);\n console.log(\n `Created: ${new Date(task.created_at * 1000).toLocaleString()}`\n );\n if (task.completed_at) {\n console.log(\n `Completed: ${new Date(task.completed_at * 1000).toLocaleString()}`\n );\n }\n if (task.description) {\n console.log(`\\nDescription:\\n${task.description}`);\n }\n const tags = JSON.parse(task.tags || '[]');\n if (tags.length > 0) {\n console.log(`\\nTags: ${tags.join(', ')}`);\n }\n console.log('');\n } catch (error: unknown) {\n console.error('\u274C Failed to show task:', (error as Error).message);\n }\n });\n\n return tasks;\n}\n\nfunction findTaskByPartialId(\n projectRoot: string,\n partialId: string\n): any | null {\n const dbPath = join(projectRoot, '.stackmemory', 'context.db');\n if (!existsSync(dbPath)) return null;\n\n const db = new Database(dbPath);\n\n // Try exact match first, then partial\n let row = db.prepare('SELECT * FROM task_cache WHERE id = ?').get(partialId);\n\n if (!row) {\n row = db\n .prepare('SELECT * FROM task_cache WHERE id LIKE ?')\n .get(`${partialId}%`);\n }\n\n // Also try matching Linear identifier in title\n if (!row && partialId.match(/^ENG-\\d+$/i)) {\n row = db\n .prepare('SELECT * FROM task_cache WHERE title LIKE ?')\n .get(`%[${partialId.toUpperCase()}]%`);\n }\n\n db.close();\n return row || null;\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -3,6 +3,17 @@ import { spawn } from "child_process";
3
3
  import { fileURLToPath } from "url";
4
4
  import { dirname, join } from "path";
5
5
  import chalk from "chalk";
6
+ function getEnv(key, defaultValue) {
7
+ const value = process.env[key];
8
+ if (value === void 0) {
9
+ if (defaultValue !== void 0) return defaultValue;
10
+ throw new Error(`Environment variable ${key} is required`);
11
+ }
12
+ return value;
13
+ }
14
+ function getOptionalEnv(key) {
15
+ return process.env[key];
16
+ }
6
17
  const __filename = fileURLToPath(import.meta.url);
7
18
  const __dirname = dirname(__filename);
8
19
  const tuiCommand = {
@@ -28,7 +39,7 @@ const tuiCommand = {
28
39
  },
29
40
  handler: async (argv) => {
30
41
  console.log(chalk.cyan("\u{1F680} Launching StackMemory TUI Dashboard..."));
31
- process.env.STACKMEMORY_WS_URL = argv.wsUrl;
42
+ process.env["STACKMEMORY_WS_URL"] = argv.wsUrl;
32
43
  const scriptPath = join(__dirname, "../../../scripts/start-tui.sh");
33
44
  const args = [];
34
45
  if (argv.server) {
@@ -56,7 +67,7 @@ const tuiCommand = {
56
67
  if (require.main === module) {
57
68
  tuiCommand.handler({
58
69
  server: process.argv.includes("--server"),
59
- wsUrl: process.env.STACKMEMORY_WS_URL || "ws://localhost:8080",
70
+ wsUrl: process.env["STACKMEMORY_WS_URL"] || "ws://localhost:8080",
60
71
  refresh: 2e3
61
72
  });
62
73
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/cli/commands/tui.ts"],
4
- "sourcesContent": ["#!/usr/bin/env node\n/**\n * TUI Command - Launch interactive monitoring dashboard\n */\n\nimport { spawn } from 'child_process';\nimport { fileURLToPath } from 'url';\nimport { dirname, join } from 'path';\nimport chalk from 'chalk';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\nexport const tuiCommand = {\n command: 'tui',\n describe: 'Launch interactive TUI monitoring dashboard',\n builder: (yargs: any) => {\n return yargs\n .option('server', {\n alias: 's',\n type: 'boolean',\n description: 'Start WebSocket server for real-time updates',\n default: false\n })\n .option('ws-url', {\n alias: 'w',\n type: 'string',\n description: 'WebSocket server URL',\n default: 'ws://localhost:8080'\n })\n .option('refresh', {\n alias: 'r',\n type: 'number',\n description: 'Auto-refresh interval in milliseconds',\n default: 2000\n });\n },\n handler: async (argv: any) => {\n console.log(chalk.cyan('\uD83D\uDE80 Launching StackMemory TUI Dashboard...'));\n \n // Set environment variables\n process.env.STACKMEMORY_WS_URL = argv.wsUrl;\n \n // Get script path\n const scriptPath = join(__dirname, '../../../scripts/start-tui.sh');\n \n // Prepare arguments\n const args = [];\n if (argv.server) {\n args.push('--with-server');\n }\n \n // Launch TUI\n const tui = spawn('bash', [scriptPath, ...args], {\n stdio: 'inherit',\n env: {\n ...process.env,\n STACKMEMORY_WS_URL: argv.wsUrl\n }\n });\n \n tui.on('error', (error) => {\n console.error(chalk.red('Failed to launch TUI:'), error);\n process.exit(1);\n });\n \n tui.on('exit', (code) => {\n if (code !== 0) {\n console.error(chalk.red(`TUI exited with code ${code}`));\n process.exit(code || 1);\n }\n });\n }\n};\n\n// Direct execution support\nif (require.main === module) {\n tuiCommand.handler({\n server: process.argv.includes('--server'),\n wsUrl: process.env.STACKMEMORY_WS_URL || 'ws://localhost:8080',\n refresh: 2000\n });\n}"],
5
- "mappings": ";AAKA,SAAS,aAAa;AACtB,SAAS,qBAAqB;AAC9B,SAAS,SAAS,YAAY;AAC9B,OAAO,WAAW;AAElB,MAAM,aAAa,cAAc,YAAY,GAAG;AAChD,MAAM,YAAY,QAAQ,UAAU;AAE7B,MAAM,aAAa;AAAA,EACxB,SAAS;AAAA,EACT,UAAU;AAAA,EACV,SAAS,CAAC,UAAe;AACvB,WAAO,MACJ,OAAO,UAAU;AAAA,MAChB,OAAO;AAAA,MACP,MAAM;AAAA,MACN,aAAa;AAAA,MACb,SAAS;AAAA,IACX,CAAC,EACA,OAAO,UAAU;AAAA,MAChB,OAAO;AAAA,MACP,MAAM;AAAA,MACN,aAAa;AAAA,MACb,SAAS;AAAA,IACX,CAAC,EACA,OAAO,WAAW;AAAA,MACjB,OAAO;AAAA,MACP,MAAM;AAAA,MACN,aAAa;AAAA,MACb,SAAS;AAAA,IACX,CAAC;AAAA,EACL;AAAA,EACA,SAAS,OAAO,SAAc;AAC5B,YAAQ,IAAI,MAAM,KAAK,kDAA2C,CAAC;AAGnE,YAAQ,IAAI,qBAAqB,KAAK;AAGtC,UAAM,aAAa,KAAK,WAAW,+BAA+B;AAGlE,UAAM,OAAO,CAAC;AACd,QAAI,KAAK,QAAQ;AACf,WAAK,KAAK,eAAe;AAAA,IAC3B;AAGA,UAAM,MAAM,MAAM,QAAQ,CAAC,YAAY,GAAG,IAAI,GAAG;AAAA,MAC/C,OAAO;AAAA,MACP,KAAK;AAAA,QACH,GAAG,QAAQ;AAAA,QACX,oBAAoB,KAAK;AAAA,MAC3B;AAAA,IACF,CAAC;AAED,QAAI,GAAG,SAAS,CAAC,UAAU;AACzB,cAAQ,MAAM,MAAM,IAAI,uBAAuB,GAAG,KAAK;AACvD,cAAQ,KAAK,CAAC;AAAA,IAChB,CAAC;AAED,QAAI,GAAG,QAAQ,CAAC,SAAS;AACvB,UAAI,SAAS,GAAG;AACd,gBAAQ,MAAM,MAAM,IAAI,wBAAwB,IAAI,EAAE,CAAC;AACvD,gBAAQ,KAAK,QAAQ,CAAC;AAAA,MACxB;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAGA,IAAI,QAAQ,SAAS,QAAQ;AAC3B,aAAW,QAAQ;AAAA,IACjB,QAAQ,QAAQ,KAAK,SAAS,UAAU;AAAA,IACxC,OAAO,QAAQ,IAAI,sBAAsB;AAAA,IACzC,SAAS;AAAA,EACX,CAAC;AACH;",
4
+ "sourcesContent": ["#!/usr/bin/env node\n/**\n * TUI Command - Launch interactive monitoring dashboard\n */\n\nimport { spawn } from 'child_process';\nimport { fileURLToPath } from 'url';\nimport { dirname, join } from 'path';\nimport chalk from 'chalk';\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\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\nexport const tuiCommand = {\n command: 'tui',\n describe: 'Launch interactive TUI monitoring dashboard',\n builder: (yargs: any) => {\n return yargs\n .option('server', {\n alias: 's',\n type: 'boolean',\n description: 'Start WebSocket server for real-time updates',\n default: false\n })\n .option('ws-url', {\n alias: 'w',\n type: 'string',\n description: 'WebSocket server URL',\n default: 'ws://localhost:8080'\n })\n .option('refresh', {\n alias: 'r',\n type: 'number',\n description: 'Auto-refresh interval in milliseconds',\n default: 2000\n });\n },\n handler: async (argv: any) => {\n console.log(chalk.cyan('\uD83D\uDE80 Launching StackMemory TUI Dashboard...'));\n \n // Set environment variables\n process.env['STACKMEMORY_WS_URL'] = argv.wsUrl;\n \n // Get script path\n const scriptPath = join(__dirname, '../../../scripts/start-tui.sh');\n \n // Prepare arguments\n const args = [];\n if (argv.server) {\n args.push('--with-server');\n }\n \n // Launch TUI\n const tui = spawn('bash', [scriptPath, ...args], {\n stdio: 'inherit',\n env: {\n ...process.env,\n STACKMEMORY_WS_URL: argv.wsUrl\n }\n });\n \n tui.on('error', (error) => {\n console.error(chalk.red('Failed to launch TUI:'), error);\n process.exit(1);\n });\n \n tui.on('exit', (code) => {\n if (code !== 0) {\n console.error(chalk.red(`TUI exited with code ${code}`));\n process.exit(code || 1);\n }\n });\n }\n};\n\n// Direct execution support\nif (require.main === module) {\n tuiCommand.handler({\n server: process.argv.includes('--server'),\n wsUrl: process.env['STACKMEMORY_WS_URL'] || 'ws://localhost:8080',\n refresh: 2000\n });\n}"],
5
+ "mappings": ";AAKA,SAAS,aAAa;AACtB,SAAS,qBAAqB;AAC9B,SAAS,SAAS,YAAY;AAC9B,OAAO,WAAW;AAElB,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;AAGA,MAAM,aAAa,cAAc,YAAY,GAAG;AAChD,MAAM,YAAY,QAAQ,UAAU;AAE7B,MAAM,aAAa;AAAA,EACxB,SAAS;AAAA,EACT,UAAU;AAAA,EACV,SAAS,CAAC,UAAe;AACvB,WAAO,MACJ,OAAO,UAAU;AAAA,MAChB,OAAO;AAAA,MACP,MAAM;AAAA,MACN,aAAa;AAAA,MACb,SAAS;AAAA,IACX,CAAC,EACA,OAAO,UAAU;AAAA,MAChB,OAAO;AAAA,MACP,MAAM;AAAA,MACN,aAAa;AAAA,MACb,SAAS;AAAA,IACX,CAAC,EACA,OAAO,WAAW;AAAA,MACjB,OAAO;AAAA,MACP,MAAM;AAAA,MACN,aAAa;AAAA,MACb,SAAS;AAAA,IACX,CAAC;AAAA,EACL;AAAA,EACA,SAAS,OAAO,SAAc;AAC5B,YAAQ,IAAI,MAAM,KAAK,kDAA2C,CAAC;AAGnE,YAAQ,IAAI,oBAAoB,IAAI,KAAK;AAGzC,UAAM,aAAa,KAAK,WAAW,+BAA+B;AAGlE,UAAM,OAAO,CAAC;AACd,QAAI,KAAK,QAAQ;AACf,WAAK,KAAK,eAAe;AAAA,IAC3B;AAGA,UAAM,MAAM,MAAM,QAAQ,CAAC,YAAY,GAAG,IAAI,GAAG;AAAA,MAC/C,OAAO;AAAA,MACP,KAAK;AAAA,QACH,GAAG,QAAQ;AAAA,QACX,oBAAoB,KAAK;AAAA,MAC3B;AAAA,IACF,CAAC;AAED,QAAI,GAAG,SAAS,CAAC,UAAU;AACzB,cAAQ,MAAM,MAAM,IAAI,uBAAuB,GAAG,KAAK;AACvD,cAAQ,KAAK,CAAC;AAAA,IAChB,CAAC;AAED,QAAI,GAAG,QAAQ,CAAC,SAAS;AACvB,UAAI,SAAS,GAAG;AACd,gBAAQ,MAAM,MAAM,IAAI,wBAAwB,IAAI,EAAE,CAAC;AACvD,gBAAQ,KAAK,QAAQ,CAAC;AAAA,MACxB;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAGA,IAAI,QAAQ,SAAS,QAAQ;AAC3B,aAAW,QAAQ;AAAA,IACjB,QAAQ,QAAQ,KAAK,SAAS,UAAU;AAAA,IACxC,OAAO,QAAQ,IAAI,oBAAoB,KAAK;AAAA,IAC5C,SAAS;AAAA,EACX,CAAC;AACH;",
6
6
  "names": []
7
7
  }
@@ -3,6 +3,17 @@ import chalk from "chalk";
3
3
  import { LinearWebhookServer } from "../../integrations/linear/webhook-server.js";
4
4
  import { Logger } from "../../utils/logger.js";
5
5
  import ngrok from "ngrok";
6
+ function getEnv(key, defaultValue) {
7
+ const value = process.env[key];
8
+ if (value === void 0) {
9
+ if (defaultValue !== void 0) return defaultValue;
10
+ throw new Error(`Environment variable ${key} is required`);
11
+ }
12
+ return value;
13
+ }
14
+ function getOptionalEnv(key) {
15
+ return process.env[key];
16
+ }
6
17
  function webhookCommand() {
7
18
  const command = new Command("webhook");
8
19
  command.description("Manage webhook servers for real-time sync").option("-p, --port <port>", "Port to run webhook server on", "3456").option("-h, --host <host>", "Host to bind to", "localhost").option("--ngrok", "Create ngrok tunnel for public webhook URL").option("--secret <secret>", "Webhook secret for signature validation");
@@ -13,15 +24,15 @@ function webhookCommand() {
13
24
  const server = new LinearWebhookServer({
14
25
  port: parseInt(options.port),
15
26
  host: options.host,
16
- webhookSecret: process.env.LINEAR_WEBHOOK_SECRET
27
+ webhookSecret: process.env["LINEAR_WEBHOOK_SECRET"]
17
28
  });
18
29
  await server.start();
19
30
  if (options.ngrok) {
20
31
  try {
21
32
  const url = await ngrok.connect({
22
33
  addr: options.port,
23
- subdomain: process.env.NGROK_SUBDOMAIN,
24
- authtoken: process.env.NGROK_AUTH_TOKEN
34
+ subdomain: process.env["NGROK_SUBDOMAIN"],
35
+ authtoken: process.env["NGROK_AUTH_TOKEN"]
25
36
  });
26
37
  console.log(chalk.green("\u2713") + chalk.bold(" Ngrok Tunnel Created"));
27
38
  console.log(chalk.cyan(" Public URL: ") + url);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/cli/commands/webhook.ts"],
4
- "sourcesContent": ["import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { LinearWebhookServer } from '../../integrations/linear/webhook-server.js';\nimport { ConfigService } from '../../services/config-service.js';\nimport { Logger } from '../../utils/logger.js';\nimport ngrok from 'ngrok';\n\nexport function webhookCommand(): Command {\n const command = new Command('webhook');\n \n command\n .description('Manage webhook servers for real-time sync')\n .option('-p, --port <port>', 'Port to run webhook server on', '3456')\n .option('-h, --host <host>', 'Host to bind to', 'localhost')\n .option('--ngrok', 'Create ngrok tunnel for public webhook URL')\n .option('--secret <secret>', 'Webhook secret for signature validation');\n\n command\n .command('start')\n .description('Start the Linear webhook server')\n .option('-p, --port <port>', 'Port to run webhook server on', '3456')\n .option('-h, --host <host>', 'Host to bind to', 'localhost')\n .option('--ngrok', 'Create ngrok tunnel for public webhook URL')\n .option('--background', 'Run in background (daemon mode)')\n .action(async (options) => {\n const logger = new Logger('WebhookCLI');\n \n try {\n console.log(chalk.cyan.bold('\\n\uD83D\uDCE1 Starting Linear Webhook Server...\\n'));\n \n const server = new LinearWebhookServer({\n port: parseInt(options.port),\n host: options.host,\n webhookSecret: process.env.LINEAR_WEBHOOK_SECRET,\n });\n\n await server.start();\n\n if (options.ngrok) {\n try {\n const url = await ngrok.connect({\n addr: options.port,\n subdomain: process.env.NGROK_SUBDOMAIN,\n authtoken: process.env.NGROK_AUTH_TOKEN,\n });\n \n console.log(chalk.green('\u2713') + chalk.bold(' Ngrok Tunnel Created'));\n console.log(chalk.cyan(' Public URL: ') + url);\n console.log(chalk.cyan(' Webhook URL: ') + url + '/webhook/linear');\n console.log(chalk.yellow('\\n\u26A0 Add this webhook URL to your Linear settings:\\n'));\n console.log(chalk.white(` 1. Go to Linear Settings \u2192 API \u2192 Webhooks`));\n console.log(chalk.white(` 2. Click \"New webhook\"`));\n console.log(chalk.white(` 3. Set URL to: ${url}/webhook/linear`));\n console.log(chalk.white(` 4. Select events: Issues (all), Comments (optional)`));\n console.log(chalk.white(` 5. Copy the webhook secret to LINEAR_WEBHOOK_SECRET env var\\n`));\n } catch (error: any) {\n logger.warn('Failed to create ngrok tunnel:', error.message);\n console.log(chalk.yellow(' \u26A0 Ngrok tunnel failed, running locally only'));\n }\n } else {\n console.log(chalk.yellow('\\n\uD83D\uDCA1 Tip: Use --ngrok flag to create a public webhook URL'));\n }\n\n if (options.background) {\n console.log(chalk.dim('\\nRunning in background mode...'));\n process.exit(0);\n } else {\n console.log(chalk.dim('\\nPress Ctrl+C to stop the server\\n'));\n }\n } catch (error: any) {\n logger.error('Failed to start webhook server:', error);\n console.error(chalk.red('\u2717 Failed to start webhook server:'), error.message);\n process.exit(1);\n }\n });\n\n command\n .command('stop')\n .description('Stop the webhook server')\n .action(async () => {\n console.log(chalk.yellow('Stopping webhook server...'));\n console.log(chalk.dim('(This would stop a background webhook server if implemented)'));\n });\n\n command\n .command('status')\n .description('Check webhook server status')\n .action(async () => {\n try {\n const response = await fetch('http://localhost:3456/health');\n if (response.ok) {\n const health = await response.json() as any;\n console.log(chalk.green('\u2713') + chalk.bold(' Webhook Server Status'));\n console.log(chalk.cyan(' Status: ') + health.status);\n console.log(chalk.cyan(' Queue: ') + health.queue + ' events');\n console.log(chalk.cyan(' Processing: ') + (health.processing ? 'Yes' : 'No'));\n console.log(chalk.cyan(' Timestamp: ') + health.timestamp);\n } else {\n console.log(chalk.red('\u2717 Webhook server not responding'));\n }\n } catch (error) {\n console.log(chalk.red('\u2717 Webhook server not running'));\n console.log(chalk.dim(' Run \"stackmemory webhook start\" to start the server'));\n }\n });\n\n command\n .command('test')\n .description('Send a test webhook to verify configuration')\n .option('--url <url>', 'Webhook URL to test', 'http://localhost:3456/webhook/linear')\n .action(async (options) => {\n const logger = new Logger('WebhookTest');\n \n try {\n console.log(chalk.cyan('\uD83E\uDDEA Testing webhook endpoint...'));\n \n const testPayload = {\n action: 'create',\n type: 'Issue',\n data: {\n id: 'test-' + Date.now(),\n identifier: 'TEST-1',\n title: 'Test webhook issue',\n description: 'This is a test webhook event',\n state: {\n id: 'state-1',\n name: 'Todo',\n type: 'unstarted',\n },\n team: {\n id: 'team-1',\n key: 'TEST',\n name: 'Test Team',\n },\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n url: 'https://linear.app/test/issue/TEST-1',\n },\n createdAt: new Date().toISOString(),\n };\n\n const response = await fetch(options.url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(testPayload),\n });\n\n if (response.ok) {\n const result = await response.json();\n console.log(chalk.green('\u2713') + ' Webhook test successful');\n console.log(chalk.cyan(' Response: ') + JSON.stringify(result, null, 2));\n } else {\n console.log(chalk.red('\u2717 Webhook test failed'));\n console.log(chalk.red(' Status: ') + response.status);\n console.log(chalk.red(' Response: ') + await response.text());\n }\n } catch (error: any) {\n logger.error('Webhook test failed:', error);\n console.error(chalk.red('\u2717 Webhook test failed:'), error.message);\n }\n });\n\n return command;\n}"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { LinearWebhookServer } from '../../integrations/linear/webhook-server.js';\nimport { ConfigService } from '../../services/config-service.js';\nimport { Logger } from '../../utils/logger.js';\nimport ngrok from 'ngrok';\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 webhookCommand(): Command {\n const command = new Command('webhook');\n \n command\n .description('Manage webhook servers for real-time sync')\n .option('-p, --port <port>', 'Port to run webhook server on', '3456')\n .option('-h, --host <host>', 'Host to bind to', 'localhost')\n .option('--ngrok', 'Create ngrok tunnel for public webhook URL')\n .option('--secret <secret>', 'Webhook secret for signature validation');\n\n command\n .command('start')\n .description('Start the Linear webhook server')\n .option('-p, --port <port>', 'Port to run webhook server on', '3456')\n .option('-h, --host <host>', 'Host to bind to', 'localhost')\n .option('--ngrok', 'Create ngrok tunnel for public webhook URL')\n .option('--background', 'Run in background (daemon mode)')\n .action(async (options) => {\n const logger = new Logger('WebhookCLI');\n \n try {\n console.log(chalk.cyan.bold('\\n\uD83D\uDCE1 Starting Linear Webhook Server...\\n'));\n \n const server = new LinearWebhookServer({\n port: parseInt(options.port),\n host: options.host,\n webhookSecret: process.env['LINEAR_WEBHOOK_SECRET'],\n });\n\n await server.start();\n\n if (options.ngrok) {\n try {\n const url = await ngrok.connect({\n addr: options.port,\n subdomain: process.env['NGROK_SUBDOMAIN'],\n authtoken: process.env['NGROK_AUTH_TOKEN'],\n });\n \n console.log(chalk.green('\u2713') + chalk.bold(' Ngrok Tunnel Created'));\n console.log(chalk.cyan(' Public URL: ') + url);\n console.log(chalk.cyan(' Webhook URL: ') + url + '/webhook/linear');\n console.log(chalk.yellow('\\n\u26A0 Add this webhook URL to your Linear settings:\\n'));\n console.log(chalk.white(` 1. Go to Linear Settings \u2192 API \u2192 Webhooks`));\n console.log(chalk.white(` 2. Click \"New webhook\"`));\n console.log(chalk.white(` 3. Set URL to: ${url}/webhook/linear`));\n console.log(chalk.white(` 4. Select events: Issues (all), Comments (optional)`));\n console.log(chalk.white(` 5. Copy the webhook secret to LINEAR_WEBHOOK_SECRET env var\\n`));\n } catch (error: any) {\n logger.warn('Failed to create ngrok tunnel:', error.message);\n console.log(chalk.yellow(' \u26A0 Ngrok tunnel failed, running locally only'));\n }\n } else {\n console.log(chalk.yellow('\\n\uD83D\uDCA1 Tip: Use --ngrok flag to create a public webhook URL'));\n }\n\n if (options.background) {\n console.log(chalk.dim('\\nRunning in background mode...'));\n process.exit(0);\n } else {\n console.log(chalk.dim('\\nPress Ctrl+C to stop the server\\n'));\n }\n } catch (error: any) {\n logger.error('Failed to start webhook server:', error);\n console.error(chalk.red('\u2717 Failed to start webhook server:'), error.message);\n process.exit(1);\n }\n });\n\n command\n .command('stop')\n .description('Stop the webhook server')\n .action(async () => {\n console.log(chalk.yellow('Stopping webhook server...'));\n console.log(chalk.dim('(This would stop a background webhook server if implemented)'));\n });\n\n command\n .command('status')\n .description('Check webhook server status')\n .action(async () => {\n try {\n const response = await fetch('http://localhost:3456/health');\n if (response.ok) {\n const health = await response.json() as any;\n console.log(chalk.green('\u2713') + chalk.bold(' Webhook Server Status'));\n console.log(chalk.cyan(' Status: ') + health.status);\n console.log(chalk.cyan(' Queue: ') + health.queue + ' events');\n console.log(chalk.cyan(' Processing: ') + (health.processing ? 'Yes' : 'No'));\n console.log(chalk.cyan(' Timestamp: ') + health.timestamp);\n } else {\n console.log(chalk.red('\u2717 Webhook server not responding'));\n }\n } catch (error: unknown) {\n console.log(chalk.red('\u2717 Webhook server not running'));\n console.log(chalk.dim(' Run \"stackmemory webhook start\" to start the server'));\n }\n });\n\n command\n .command('test')\n .description('Send a test webhook to verify configuration')\n .option('--url <url>', 'Webhook URL to test', 'http://localhost:3456/webhook/linear')\n .action(async (options) => {\n const logger = new Logger('WebhookTest');\n \n try {\n console.log(chalk.cyan('\uD83E\uDDEA Testing webhook endpoint...'));\n \n const testPayload = {\n action: 'create',\n type: 'Issue',\n data: {\n id: 'test-' + Date.now(),\n identifier: 'TEST-1',\n title: 'Test webhook issue',\n description: 'This is a test webhook event',\n state: {\n id: 'state-1',\n name: 'Todo',\n type: 'unstarted',\n },\n team: {\n id: 'team-1',\n key: 'TEST',\n name: 'Test Team',\n },\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n url: 'https://linear.app/test/issue/TEST-1',\n },\n createdAt: new Date().toISOString(),\n };\n\n const response = await fetch(options.url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(testPayload),\n });\n\n if (response.ok) {\n const result = await response.json();\n console.log(chalk.green('\u2713') + ' Webhook test successful');\n console.log(chalk.cyan(' Response: ') + JSON.stringify(result, null, 2));\n } else {\n console.log(chalk.red('\u2717 Webhook test failed'));\n console.log(chalk.red(' Status: ') + response.status);\n console.log(chalk.red(' Response: ') + await response.text());\n }\n } catch (error: any) {\n logger.error('Webhook test failed:', error);\n console.error(chalk.red('\u2717 Webhook test failed:'), error.message);\n }\n });\n\n return command;\n}"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -6,6 +6,17 @@ import { existsSync } from "fs";
6
6
  import { FrameManager } from "../../core/context/frame-manager.js";
7
7
  import { workflowTemplates } from "../../core/frame/workflow-templates-stub.js";
8
8
  import { sessionManager } from "../../core/session/session-manager.js";
9
+ function getEnv(key, defaultValue) {
10
+ const value = process.env[key];
11
+ if (value === void 0) {
12
+ if (defaultValue !== void 0) return defaultValue;
13
+ throw new Error(`Environment variable ${key} is required`);
14
+ }
15
+ return value;
16
+ }
17
+ function getOptionalEnv(key) {
18
+ return process.env[key];
19
+ }
9
20
  function createWorkflowCommand() {
10
21
  const cmd = new Command("workflow").description("Manage structured workflow templates").option("-l, --list", "List available workflow templates").option("-s, --start <template>", "Start a new workflow from template").option("--status", "Show status of active workflow").action(async (options) => {
11
22
  try {
@@ -14,7 +25,7 @@ function createWorkflowCommand() {
14
25
  if (!existsSync(dbPath)) {
15
26
  console.error(chalk.red("\u2717 StackMemory not initialized"));
16
27
  console.log(chalk.yellow("Run: stackmemory init"));
17
- if (process.env.NODE_ENV !== "test") {
28
+ if (process.env["NODE_ENV"] !== "test") {
18
29
  process.exit(1);
19
30
  }
20
31
  return;
@@ -30,7 +41,7 @@ function createWorkflowCommand() {
30
41
  }
31
42
  } catch (error) {
32
43
  console.error(chalk.red("Error: " + error.message));
33
- if (process.env.NODE_ENV !== "test") {
44
+ if (process.env["NODE_ENV"] !== "test") {
34
45
  process.exit(1);
35
46
  }
36
47
  }
@@ -59,7 +70,7 @@ async function startWorkflow(workflowName, dbPath) {
59
70
  if (!template) {
60
71
  console.error(chalk.red(`Unknown workflow: ${workflowName}`));
61
72
  console.log(chalk.yellow("Use --list to see available workflows"));
62
- if (process.env.NODE_ENV !== "test") {
73
+ if (process.env["NODE_ENV"] !== "test") {
63
74
  process.exit(1);
64
75
  }
65
76
  return;