@stackmemoryai/stackmemory 0.3.7 → 0.3.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (190) hide show
  1. package/dist/agents/core/agent-task-manager.js +5 -5
  2. package/dist/agents/core/agent-task-manager.js.map +2 -2
  3. package/dist/agents/verifiers/base-verifier.js +2 -2
  4. package/dist/agents/verifiers/base-verifier.js.map +2 -2
  5. package/dist/cli/claude-sm.js +0 -11
  6. package/dist/cli/claude-sm.js.map +2 -2
  7. package/dist/cli/codex-sm.js +0 -11
  8. package/dist/cli/codex-sm.js.map +2 -2
  9. package/dist/cli/commands/chromadb.js +64 -34
  10. package/dist/cli/commands/chromadb.js.map +2 -2
  11. package/dist/cli/commands/clear.js +9 -13
  12. package/dist/cli/commands/clear.js.map +2 -2
  13. package/dist/cli/commands/config.js +43 -33
  14. package/dist/cli/commands/config.js.map +2 -2
  15. package/dist/cli/commands/context.js.map +2 -2
  16. package/dist/cli/commands/dashboard.js +41 -13
  17. package/dist/cli/commands/dashboard.js.map +2 -2
  18. package/dist/cli/commands/gc.js +69 -20
  19. package/dist/cli/commands/gc.js.map +2 -2
  20. package/dist/cli/commands/handoff.js.map +2 -2
  21. package/dist/cli/commands/infinite-storage.js +60 -19
  22. package/dist/cli/commands/infinite-storage.js.map +2 -2
  23. package/dist/cli/commands/linear-create.js +36 -8
  24. package/dist/cli/commands/linear-create.js.map +2 -2
  25. package/dist/cli/commands/linear-list.js +33 -10
  26. package/dist/cli/commands/linear-list.js.map +2 -2
  27. package/dist/cli/commands/linear-migrate.js +17 -4
  28. package/dist/cli/commands/linear-migrate.js.map +2 -2
  29. package/dist/cli/commands/linear-test.js +14 -6
  30. package/dist/cli/commands/linear-test.js.map +2 -2
  31. package/dist/cli/commands/linear-unified.js +123 -35
  32. package/dist/cli/commands/linear-unified.js.map +2 -2
  33. package/dist/cli/commands/linear.js.map +2 -2
  34. package/dist/cli/commands/monitor.js.map +2 -2
  35. package/dist/cli/commands/onboard.js +35 -8
  36. package/dist/cli/commands/onboard.js.map +2 -2
  37. package/dist/cli/commands/quality.js +2 -7
  38. package/dist/cli/commands/quality.js.map +2 -2
  39. package/dist/cli/commands/session.js +23 -6
  40. package/dist/cli/commands/session.js.map +2 -2
  41. package/dist/cli/commands/skills.js +72 -27
  42. package/dist/cli/commands/skills.js.map +2 -2
  43. package/dist/cli/commands/storage.js +108 -38
  44. package/dist/cli/commands/storage.js.map +2 -2
  45. package/dist/cli/commands/tui.js.map +2 -2
  46. package/dist/cli/commands/webhook.js +57 -18
  47. package/dist/cli/commands/webhook.js.map +2 -2
  48. package/dist/cli/commands/workflow.js +8 -15
  49. package/dist/cli/commands/workflow.js.map +2 -2
  50. package/dist/cli/commands/worktree.js +34 -13
  51. package/dist/cli/commands/worktree.js.map +2 -2
  52. package/dist/cli/index.js +0 -11
  53. package/dist/cli/index.js.map +2 -2
  54. package/dist/core/config/types.js.map +1 -1
  55. package/dist/core/context/auto-context.js +10 -6
  56. package/dist/core/context/auto-context.js.map +2 -2
  57. package/dist/core/context/context-bridge.js.map +2 -2
  58. package/dist/core/context/frame-database.js +13 -3
  59. package/dist/core/context/frame-database.js.map +2 -2
  60. package/dist/core/context/frame-digest.js +7 -5
  61. package/dist/core/context/frame-digest.js.map +2 -2
  62. package/dist/core/context/frame-manager.js.map +2 -2
  63. package/dist/core/context/frame-stack.js +16 -5
  64. package/dist/core/context/frame-stack.js.map +2 -2
  65. package/dist/core/context/incremental-gc.js +10 -3
  66. package/dist/core/context/incremental-gc.js.map +2 -2
  67. package/dist/core/context/index.js.map +1 -1
  68. package/dist/core/context/permission-manager.js.map +2 -2
  69. package/dist/core/context/refactored-frame-manager.js +12 -3
  70. package/dist/core/context/refactored-frame-manager.js.map +2 -2
  71. package/dist/core/context/shared-context-layer.js +4 -2
  72. package/dist/core/context/shared-context-layer.js.map +2 -2
  73. package/dist/core/database/batch-operations.js +112 -86
  74. package/dist/core/database/batch-operations.js.map +2 -2
  75. package/dist/core/database/query-cache.js +19 -9
  76. package/dist/core/database/query-cache.js.map +2 -2
  77. package/dist/core/database/sqlite-adapter.js +1 -1
  78. package/dist/core/database/sqlite-adapter.js.map +2 -2
  79. package/dist/core/digest/enhanced-hybrid-digest.js +8 -2
  80. package/dist/core/digest/enhanced-hybrid-digest.js.map +2 -2
  81. package/dist/core/errors/recovery.js +9 -2
  82. package/dist/core/errors/recovery.js.map +2 -2
  83. package/dist/core/frame/workflow-templates-stub.js.map +1 -1
  84. package/dist/core/frame/workflow-templates.js +40 -1
  85. package/dist/core/frame/workflow-templates.js.map +2 -2
  86. package/dist/core/monitoring/logger.js +6 -1
  87. package/dist/core/monitoring/logger.js.map +2 -2
  88. package/dist/core/monitoring/metrics.js.map +2 -2
  89. package/dist/core/monitoring/progress-tracker.js.map +2 -2
  90. package/dist/core/performance/context-cache.js.map +2 -2
  91. package/dist/core/performance/lazy-context-loader.js +24 -20
  92. package/dist/core/performance/lazy-context-loader.js.map +2 -2
  93. package/dist/core/performance/optimized-frame-context.js +27 -12
  94. package/dist/core/performance/optimized-frame-context.js.map +2 -2
  95. package/dist/core/performance/performance-benchmark.js +10 -6
  96. package/dist/core/performance/performance-benchmark.js.map +2 -2
  97. package/dist/core/performance/performance-profiler.js +51 -14
  98. package/dist/core/performance/performance-profiler.js.map +2 -2
  99. package/dist/core/performance/streaming-jsonl-parser.js +5 -1
  100. package/dist/core/performance/streaming-jsonl-parser.js.map +2 -2
  101. package/dist/core/projects/project-manager.js +14 -20
  102. package/dist/core/projects/project-manager.js.map +2 -2
  103. package/dist/core/retrieval/context-retriever.js.map +1 -1
  104. package/dist/core/retrieval/llm-context-retrieval.js.map +2 -2
  105. package/dist/core/session/clear-survival-stub.js +5 -1
  106. package/dist/core/session/clear-survival-stub.js.map +2 -2
  107. package/dist/core/session/clear-survival.js +35 -0
  108. package/dist/core/session/clear-survival.js.map +2 -2
  109. package/dist/core/session/index.js.map +1 -1
  110. package/dist/core/session/session-manager.js.map +2 -2
  111. package/dist/core/storage/chromadb-adapter.js +6 -2
  112. package/dist/core/storage/chromadb-adapter.js.map +2 -2
  113. package/dist/core/storage/chromadb-simple.js +17 -5
  114. package/dist/core/storage/chromadb-simple.js.map +2 -2
  115. package/dist/core/storage/infinite-storage.js +109 -46
  116. package/dist/core/storage/infinite-storage.js.map +2 -2
  117. package/dist/core/storage/railway-optimized-storage.js +48 -22
  118. package/dist/core/storage/railway-optimized-storage.js.map +2 -2
  119. package/dist/core/storage/remote-storage.js +41 -23
  120. package/dist/core/storage/remote-storage.js.map +2 -2
  121. package/dist/core/trace/cli-trace-wrapper.js +9 -2
  122. package/dist/core/trace/cli-trace-wrapper.js.map +2 -2
  123. package/dist/core/trace/db-trace-wrapper.js +96 -68
  124. package/dist/core/trace/db-trace-wrapper.js.map +2 -2
  125. package/dist/core/trace/debug-trace.js +25 -8
  126. package/dist/core/trace/debug-trace.js.map +2 -2
  127. package/dist/core/trace/index.js +6 -2
  128. package/dist/core/trace/index.js.map +2 -2
  129. package/dist/core/trace/linear-api-wrapper.js +10 -5
  130. package/dist/core/trace/linear-api-wrapper.js.map +2 -2
  131. package/dist/core/trace/trace-demo.js +14 -10
  132. package/dist/core/trace/trace-demo.js.map +2 -2
  133. package/dist/core/trace/trace-detector.js +9 -2
  134. package/dist/core/trace/trace-detector.js.map +2 -2
  135. package/dist/core/trace/types.js.map +1 -1
  136. package/dist/core/utils/compression.js.map +1 -1
  137. package/dist/core/utils/update-checker.js.map +1 -1
  138. package/dist/core/worktree/worktree-manager.js +18 -7
  139. package/dist/core/worktree/worktree-manager.js.map +2 -2
  140. package/dist/features/analytics/core/analytics-service.js.map +2 -2
  141. package/dist/features/analytics/queries/metrics-queries.js +1 -1
  142. package/dist/features/analytics/queries/metrics-queries.js.map +2 -2
  143. package/dist/features/tasks/pebbles-task-store.js.map +1 -1
  144. package/dist/features/tui/components/analytics-panel.js +36 -15
  145. package/dist/features/tui/components/analytics-panel.js.map +2 -2
  146. package/dist/features/tui/components/pr-tracker.js +19 -7
  147. package/dist/features/tui/components/pr-tracker.js.map +2 -2
  148. package/dist/features/tui/components/session-monitor.js +22 -9
  149. package/dist/features/tui/components/session-monitor.js.map +2 -2
  150. package/dist/features/tui/components/subagent-fleet.js +20 -13
  151. package/dist/features/tui/components/subagent-fleet.js.map +2 -2
  152. package/dist/features/tui/components/task-board.js +26 -10
  153. package/dist/features/tui/components/task-board.js.map +2 -2
  154. package/dist/features/tui/index.js.map +2 -2
  155. package/dist/features/tui/services/data-service.js +6 -2
  156. package/dist/features/tui/services/data-service.js.map +2 -2
  157. package/dist/features/tui/services/linear-task-reader.js +3 -1
  158. package/dist/features/tui/services/linear-task-reader.js.map +2 -2
  159. package/dist/features/tui/services/websocket-client.js +3 -1
  160. package/dist/features/tui/services/websocket-client.js.map +2 -2
  161. package/dist/features/tui/terminal-compat.js +6 -2
  162. package/dist/features/tui/terminal-compat.js.map +2 -2
  163. package/dist/features/web/client/stores/task-store.js.map +2 -2
  164. package/dist/features/web/server/index.js +18 -10
  165. package/dist/features/web/server/index.js.map +2 -2
  166. package/dist/integrations/linear/sync-service.js +12 -13
  167. package/dist/integrations/linear/sync-service.js.map +2 -2
  168. package/dist/integrations/linear/sync.js +174 -12
  169. package/dist/integrations/linear/sync.js.map +2 -2
  170. package/dist/integrations/linear/unified-sync.js +1 -1
  171. package/dist/integrations/linear/unified-sync.js.map +1 -1
  172. package/dist/integrations/linear/webhook-server.js +15 -16
  173. package/dist/integrations/linear/webhook-server.js.map +2 -2
  174. package/dist/mcp/stackmemory-mcp-server.js +0 -11
  175. package/dist/mcp/stackmemory-mcp-server.js.map +2 -2
  176. package/dist/servers/production/auth-middleware.js.map +2 -2
  177. package/dist/servers/railway/index.js.map +2 -2
  178. package/dist/services/config-service.js +6 -7
  179. package/dist/services/config-service.js.map +2 -2
  180. package/dist/services/context-service.js +11 -12
  181. package/dist/services/context-service.js.map +2 -2
  182. package/dist/skills/claude-skills.js +4 -2
  183. package/dist/skills/claude-skills.js.map +2 -2
  184. package/dist/skills/dashboard-launcher.js.map +2 -2
  185. package/dist/skills/repo-ingestion-skill.js.map +2 -2
  186. package/dist/utils/env.js +46 -0
  187. package/dist/utils/env.js.map +7 -0
  188. package/dist/utils/logger.js +0 -11
  189. package/dist/utils/logger.js.map +2 -2
  190. package/package.json +1 -1
@@ -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// 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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",
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\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 =\n tier.tier === 'hot' ? '\uD83D\uDD25' : tier.tier === 'warm' ? '\u2601\uFE0F' : '\u2744\uFE0F';\n const color =\n tier.tier === 'hot'\n ? chalk.red\n : tier.tier === 'warm'\n ? chalk.yellow\n : chalk.cyan;\n\n console.log(`\\n${icon} ${color(tier.tier.toUpperCase())} Tier:`);\n console.log(` Traces: ${chalk.white(tier.count)}`);\n console.log(\n ` Original Size: ${chalk.white(formatBytes(tier.total_original || 0))}`\n );\n console.log(\n ` Compressed Size: ${chalk.white(formatBytes(tier.total_compressed || 0))}`\n );\n console.log(\n ` Compression Ratio: ${chalk.green((tier.avg_compression * 100).toFixed(1) + '%')}`\n );\n console.log(\n ` Avg Access Count: ${chalk.white(tier.avg_access?.toFixed(1) || '0')}`\n );\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(\n ` ${age.age_group.padEnd(10)} ${bar} ${percent}% (${age.count})`\n );\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(\n ` Total Size: ${chalk.white(formatBytes(stats.totalSize))}`\n );\n console.log(\n ` Compressed Size: ${chalk.white(formatBytes(stats.compressedSize))}`\n );\n\n const compressionRatio = (\n (1 - stats.compressedSize / stats.totalSize) *\n 100\n ).toFixed(1);\n console.log(\n ` Overall Compression: ${chalk.green(compressionRatio + '%')}`\n );\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(\n ` Redis (Hot): ${chalk.green('$0.00')} (included with Railway)`\n );\n console.log(\n ` Railway Buckets (Warm): ${chalk.yellow(costEstimate.railway)}`\n );\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\n .prepare(\n `\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 `\n )\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(\n ` ${time} - ${m.trace_id.substring(0, 8)}... \u2192 ${m.tier} (score: ${m.score.toFixed(2)})`\n );\n }\n }\n }\n\n db.close();\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\n .prepare(\n `\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 `\n )\n .all(Date.now()) as any[];\n\n const toMigrate = {\n hotToWarm: candidates.filter(\n (c: any) => c.tier === 'hot' && c.age_hours > 24\n ),\n warmToCold: candidates.filter(\n (c: any) => 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(\n chalk.red(\n `\\n\uD83D\uDD25 \u2192 \u2601\uFE0F Hot to Warm: ${toMigrate.hotToWarm.length} traces`\n )\n );\n for (const t of toMigrate.hotToWarm.slice(0, 5)) {\n console.log(\n ` \u2022 ${t.trace_id.substring(0, 8)}... (${t.age_hours.toFixed(0)}h old, score: ${t.score.toFixed(2)})`\n );\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(\n chalk.yellow(\n `\\n\u2601\uFE0F \u2192 \u2744\uFE0F Warm to Cold: ${toMigrate.warmToCold.length} traces`\n )\n );\n for (const t of toMigrate.warmToCold.slice(0, 5)) {\n const ageDays = Math.floor(t.age_hours / 24);\n console.log(\n ` \u2022 ${t.trace_id.substring(0, 8)}... (${ageDays}d old, score: ${t.score.toFixed(2)})`\n );\n }\n if (toMigrate.warmToCold.length > 5) {\n console.log(` ... and ${toMigrate.warmToCold.length - 5} more`);\n }\n }\n\n if (\n toMigrate.hotToWarm.length === 0 &&\n toMigrate.warmToCold.length === 0\n ) {\n console.log(chalk.green('\u2713 No traces need migration'));\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(\n ` Hot \u2192 Warm: ${chalk.yellow(results.hotToWarm)} traces`\n );\n console.log(\n ` Warm \u2192 Cold: ${chalk.cyan(results.warmToCold)} traces`\n );\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 } 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\n .prepare(\n `\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 `\n )\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(\n ` Space to free: ${chalk.yellow(formatBytes(toRemove.size || 0))}`\n );\n console.log(` Criteria: > ${options.days} days old with 0 access`);\n } else {\n const removed = await storage.cleanup();\n spinner.succeed(`Cleanup completed - removed ${removed} traces`);\n }\n\n db.close();\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(\n ` Tools: ${trace.tools?.length || trace.toolSummary?.count || 0}`\n );\n\n const metadata = trace.metadata;\n if (metadata) {\n console.log(chalk.blue('\\n\uD83D\uDCCB Metadata:'));\n console.log(\n ` Start: ${new Date(metadata.startTime).toLocaleString()}`\n );\n console.log(\n ` Duration: ${formatDuration(metadata.endTime - metadata.startTime)}`\n );\n console.log(\n ` Files: ${metadata.filesModified?.length || metadata.filesModified || 0}`\n );\n console.log(\n ` Errors: ${metadata.errorsEncountered?.length || metadata.errorsCount || 0}`\n );\n }\n\n // Show storage location\n const location = db\n .prepare(\n 'SELECT tier, location, access_count FROM storage_tiers WHERE trace_id = ?'\n )\n .get(traceId) as any;\n\n if (location) {\n const tierIcon =\n location.tier === 'hot'\n ? '\uD83D\uDD25'\n : location.tier === 'warm'\n ? '\u2601\uFE0F'\n : '\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 } 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(\n ` URL: ${process.env['REDIS_URL'] ? chalk.green('Configured') : chalk.yellow('Not configured')}`\n );\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(\n ` Endpoint: ${process.env['RAILWAY_BUCKET_ENDPOINT'] || 'Not configured'}`\n );\n console.log(\n ` Bucket: ${process.env['RAILWAY_BUCKET_NAME'] || 'stackmemory-warm'}`\n );\n console.log(\n ` Access Key: ${process.env['RAILWAY_BUCKET_ACCESS_KEY'] ? chalk.green('Set') : chalk.yellow('Not set')}`\n );\n console.log(` Retention: 30 days`);\n\n console.log(chalk.cyan('\\n\u2744\uFE0F Cold Tier (GCS):'));\n console.log(\n ` Project: ${process.env['GCP_PROJECT_ID'] || 'Not configured'}`\n );\n console.log(\n ` Bucket: ${process.env['GCS_BUCKET'] || 'stackmemory-cold'}`\n );\n console.log(\n ` Key File: ${process.env['GCP_KEY_FILE'] ? chalk.green('Set') : chalk.yellow('Not set')}`\n );\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): {\n railway: string;\n gcs: string;\n total: string;\n} {\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}\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/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// 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;",
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\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}\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;AAEA,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
  }
@@ -1,7 +1,7 @@
1
1
  import { Command } from "commander";
2
2
  import chalk from "chalk";
3
3
  import { LinearWebhookServer } from "../../integrations/linear/webhook-server.js";
4
- import { Logger } from "../../utils/logger.js";
4
+ import { logger } from "../../core/monitoring/logger.js";
5
5
  import ngrok from "ngrok";
6
6
  function getEnv(key, defaultValue) {
7
7
  const value = process.env[key];
@@ -18,9 +18,10 @@ function webhookCommand() {
18
18
  const command = new Command("webhook");
19
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");
20
20
  command.command("start").description("Start the Linear webhook server").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("--background", "Run in background (daemon mode)").action(async (options) => {
21
- const logger = new Logger("WebhookCLI");
22
21
  try {
23
- console.log(chalk.cyan.bold("\n\u{1F4E1} Starting Linear Webhook Server...\n"));
22
+ console.log(
23
+ chalk.cyan.bold("\n\u{1F4E1} Starting Linear Webhook Server...\n")
24
+ );
24
25
  const server = new LinearWebhookServer({
25
26
  port: parseInt(options.port),
26
27
  host: options.host,
@@ -36,20 +37,42 @@ function webhookCommand() {
36
37
  });
37
38
  console.log(chalk.green("\u2713") + chalk.bold(" Ngrok Tunnel Created"));
38
39
  console.log(chalk.cyan(" Public URL: ") + url);
39
- console.log(chalk.cyan(" Webhook URL: ") + url + "/webhook/linear");
40
- console.log(chalk.yellow("\n\u26A0 Add this webhook URL to your Linear settings:\n"));
41
- console.log(chalk.white(` 1. Go to Linear Settings \u2192 API \u2192 Webhooks`));
40
+ console.log(
41
+ chalk.cyan(" Webhook URL: ") + url + "/webhook/linear"
42
+ );
43
+ console.log(
44
+ chalk.yellow(
45
+ "\n\u26A0 Add this webhook URL to your Linear settings:\n"
46
+ )
47
+ );
48
+ console.log(
49
+ chalk.white(` 1. Go to Linear Settings \u2192 API \u2192 Webhooks`)
50
+ );
42
51
  console.log(chalk.white(` 2. Click "New webhook"`));
43
52
  console.log(chalk.white(` 3. Set URL to: ${url}/webhook/linear`));
44
- console.log(chalk.white(` 4. Select events: Issues (all), Comments (optional)`));
45
- console.log(chalk.white(` 5. Copy the webhook secret to LINEAR_WEBHOOK_SECRET env var
46
- `));
53
+ console.log(
54
+ chalk.white(
55
+ ` 4. Select events: Issues (all), Comments (optional)`
56
+ )
57
+ );
58
+ console.log(
59
+ chalk.white(
60
+ ` 5. Copy the webhook secret to LINEAR_WEBHOOK_SECRET env var
61
+ `
62
+ )
63
+ );
47
64
  } catch (error) {
48
65
  logger.warn("Failed to create ngrok tunnel:", error.message);
49
- console.log(chalk.yellow(" \u26A0 Ngrok tunnel failed, running locally only"));
66
+ console.log(
67
+ chalk.yellow(" \u26A0 Ngrok tunnel failed, running locally only")
68
+ );
50
69
  }
51
70
  } else {
52
- console.log(chalk.yellow("\n\u{1F4A1} Tip: Use --ngrok flag to create a public webhook URL"));
71
+ console.log(
72
+ chalk.yellow(
73
+ "\n\u{1F4A1} Tip: Use --ngrok flag to create a public webhook URL"
74
+ )
75
+ );
53
76
  }
54
77
  if (options.background) {
55
78
  console.log(chalk.dim("\nRunning in background mode..."));
@@ -59,13 +82,20 @@ function webhookCommand() {
59
82
  }
60
83
  } catch (error) {
61
84
  logger.error("Failed to start webhook server:", error);
62
- console.error(chalk.red("\u2717 Failed to start webhook server:"), error.message);
85
+ console.error(
86
+ chalk.red("\u2717 Failed to start webhook server:"),
87
+ error.message
88
+ );
63
89
  process.exit(1);
64
90
  }
65
91
  });
66
92
  command.command("stop").description("Stop the webhook server").action(async () => {
67
93
  console.log(chalk.yellow("Stopping webhook server..."));
68
- console.log(chalk.dim("(This would stop a background webhook server if implemented)"));
94
+ console.log(
95
+ chalk.dim(
96
+ "(This would stop a background webhook server if implemented)"
97
+ )
98
+ );
69
99
  });
70
100
  command.command("status").description("Check webhook server status").action(async () => {
71
101
  try {
@@ -75,18 +105,25 @@ function webhookCommand() {
75
105
  console.log(chalk.green("\u2713") + chalk.bold(" Webhook Server Status"));
76
106
  console.log(chalk.cyan(" Status: ") + health.status);
77
107
  console.log(chalk.cyan(" Queue: ") + health.queue + " events");
78
- console.log(chalk.cyan(" Processing: ") + (health.processing ? "Yes" : "No"));
108
+ console.log(
109
+ chalk.cyan(" Processing: ") + (health.processing ? "Yes" : "No")
110
+ );
79
111
  console.log(chalk.cyan(" Timestamp: ") + health.timestamp);
80
112
  } else {
81
113
  console.log(chalk.red("\u2717 Webhook server not responding"));
82
114
  }
83
115
  } catch (error) {
84
116
  console.log(chalk.red("\u2717 Webhook server not running"));
85
- console.log(chalk.dim(' Run "stackmemory webhook start" to start the server'));
117
+ console.log(
118
+ chalk.dim(' Run "stackmemory webhook start" to start the server')
119
+ );
86
120
  }
87
121
  });
88
- command.command("test").description("Send a test webhook to verify configuration").option("--url <url>", "Webhook URL to test", "http://localhost:3456/webhook/linear").action(async (options) => {
89
- const logger = new Logger("WebhookTest");
122
+ command.command("test").description("Send a test webhook to verify configuration").option(
123
+ "--url <url>",
124
+ "Webhook URL to test",
125
+ "http://localhost:3456/webhook/linear"
126
+ ).action(async (options) => {
90
127
  try {
91
128
  console.log(chalk.cyan("\u{1F9EA} Testing webhook endpoint..."));
92
129
  const testPayload = {
@@ -123,7 +160,9 @@ function webhookCommand() {
123
160
  if (response.ok) {
124
161
  const result = await response.json();
125
162
  console.log(chalk.green("\u2713") + " Webhook test successful");
126
- console.log(chalk.cyan(" Response: ") + JSON.stringify(result, null, 2));
163
+ console.log(
164
+ chalk.cyan(" Response: ") + JSON.stringify(result, null, 2)
165
+ );
127
166
  } else {
128
167
  console.log(chalk.red("\u2717 Webhook test failed"));
129
168
  console.log(chalk.red(" Status: ") + response.status);
@@ -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// 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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",
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 '../../core/monitoring/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\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 \n\n try {\n console.log(\n chalk.cyan.bold('\\n\uD83D\uDCE1 Starting Linear Webhook Server...\\n')\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(\n chalk.cyan(' Webhook URL: ') + url + '/webhook/linear'\n );\n console.log(\n chalk.yellow(\n '\\n\u26A0 Add this webhook URL to your Linear settings:\\n'\n )\n );\n console.log(\n chalk.white(` 1. Go to Linear Settings \u2192 API \u2192 Webhooks`)\n );\n console.log(chalk.white(` 2. Click \"New webhook\"`));\n console.log(chalk.white(` 3. Set URL to: ${url}/webhook/linear`));\n console.log(\n chalk.white(\n ` 4. Select events: Issues (all), Comments (optional)`\n )\n );\n console.log(\n chalk.white(\n ` 5. Copy the webhook secret to LINEAR_WEBHOOK_SECRET env var\\n`\n )\n );\n } catch (error: any) {\n logger.warn('Failed to create ngrok tunnel:', error.message);\n console.log(\n chalk.yellow(' \u26A0 Ngrok tunnel failed, running locally only')\n );\n }\n } else {\n console.log(\n chalk.yellow(\n '\\n\uD83D\uDCA1 Tip: Use --ngrok flag to create a public webhook URL'\n )\n );\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(\n chalk.red('\u2717 Failed to start webhook server:'),\n error.message\n );\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(\n chalk.dim(\n '(This would stop a background webhook server if implemented)'\n )\n );\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(\n chalk.cyan(' Processing: ') + (health.processing ? 'Yes' : 'No')\n );\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(\n chalk.dim(' Run \"stackmemory webhook start\" to start the server')\n );\n }\n });\n\n command\n .command('test')\n .description('Send a test webhook to verify configuration')\n .option(\n '--url <url>',\n 'Webhook URL to test',\n 'http://localhost:3456/webhook/linear'\n )\n .action(async (options) => {\n \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(\n chalk.cyan(' Response: ') + JSON.stringify(result, null, 2)\n );\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}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -4,19 +4,8 @@ import * as path from "path";
4
4
  import Database from "better-sqlite3";
5
5
  import { existsSync } from "fs";
6
6
  import { FrameManager } from "../../core/context/frame-manager.js";
7
- import { workflowTemplates } from "../../core/frame/workflow-templates-stub.js";
7
+ import { workflowTemplates } from "../../core/frame/workflow-templates.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
- }
20
9
  function createWorkflowCommand() {
21
10
  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) => {
22
11
  try {
@@ -63,7 +52,9 @@ ${key}:`));
63
52
  console.log(` ... and ${template.phases.length - 3} more`);
64
53
  }
65
54
  });
66
- console.log(chalk.gray("\nStart a workflow: stackmemory workflow --start <name>"));
55
+ console.log(
56
+ chalk.gray("\nStart a workflow: stackmemory workflow --start <name>")
57
+ );
67
58
  }
68
59
  async function startWorkflow(workflowName, dbPath) {
69
60
  const template = workflowTemplates[workflowName];
@@ -107,12 +98,14 @@ async function startWorkflow(workflowName, dbPath) {
107
98
  async function showWorkflowStatus(dbPath) {
108
99
  const db = new Database(dbPath);
109
100
  try {
110
- const workflows = db.prepare(`
101
+ const workflows = db.prepare(
102
+ `
111
103
  SELECT * FROM frames
112
104
  WHERE type = 'workflow'
113
105
  AND state = 'active'
114
106
  ORDER BY created_at DESC
115
- `).all();
107
+ `
108
+ ).all();
116
109
  if (workflows.length === 0) {
117
110
  console.log(chalk.yellow("No active workflows"));
118
111
  return;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/cli/commands/workflow.ts"],
4
- "sourcesContent": ["/**\n * Workflow command for StackMemory\n * Manages workflow templates and execution\n */\n\nimport { Command } from 'commander';\nimport chalk from 'chalk';\nimport * as path from 'path';\nimport Database from 'better-sqlite3';\nimport { existsSync } from 'fs';\nimport { FrameManager } from '../../core/context/frame-manager.js';\nimport { workflowTemplates } from '../../core/frame/workflow-templates-stub.js';\nimport { sessionManager } from '../../core/session/session-manager.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 createWorkflowCommand(): Command {\n const cmd = new Command('workflow')\n .description('Manage structured workflow templates')\n .option('-l, --list', 'List available workflow templates')\n .option('-s, --start <template>', 'Start a new workflow from template')\n .option('--status', 'Show status of active workflow')\n .action(async (options) => {\n try {\n const projectRoot = process.cwd();\n const dbPath = path.join(projectRoot, '.stackmemory', 'context.db');\n \n // Check if StackMemory is initialized\n if (!existsSync(dbPath)) {\n console.error(chalk.red('\u2717 StackMemory not initialized'));\n console.log(chalk.yellow('Run: stackmemory init'));\n if (process.env['NODE_ENV'] !== 'test') {\n process.exit(1);\n }\n return;\n }\n \n if (options.list) {\n await listWorkflows();\n } else if (options.start) {\n await startWorkflow(options.start, dbPath);\n } else if (options.status) {\n await showWorkflowStatus(dbPath);\n } else {\n // Default: list workflows\n await listWorkflows();\n }\n } catch (error: unknown) {\n console.error(chalk.red('Error: ' + (error as Error).message));\n if (process.env['NODE_ENV'] !== 'test') {\n process.exit(1);\n }\n }\n });\n \n return cmd;\n}\n\nasync function listWorkflows(): Promise<void> {\n console.log(chalk.bold('\\n\uD83D\uDCCB Available Workflows'));\n console.log('\u2500'.repeat(40));\n \n Object.entries(workflowTemplates).forEach(([key, template]) => {\n console.log(chalk.cyan(`\\n${key}:`));\n console.log(` ${template.description}`);\n console.log(chalk.gray(` Phases: ${template.phases.length}`));\n \n // Show first few phases\n template.phases.slice(0, 3).forEach((phase) => {\n console.log(` \u2022 ${phase.name}`);\n });\n if (template.phases.length > 3) {\n console.log(` ... and ${template.phases.length - 3} more`);\n }\n });\n \n console.log(chalk.gray('\\nStart a workflow: stackmemory workflow --start <name>'));\n}\n\nasync function startWorkflow(workflowName: string, dbPath: string): Promise<void> {\n const template = workflowTemplates[workflowName as keyof typeof workflowTemplates];\n \n if (!template) {\n console.error(chalk.red(`Unknown workflow: ${workflowName}`));\n console.log(chalk.yellow('Use --list to see available workflows'));\n if (process.env['NODE_ENV'] !== 'test') {\n process.exit(1);\n }\n return;\n }\n \n const db = new Database(dbPath);\n \n try {\n // Initialize session\n await sessionManager.initialize();\n const session = await sessionManager.getOrCreateSession({\n projectPath: process.cwd(),\n });\n \n const frameManager = new FrameManager(db, session.projectId);\n \n // Create root frame for workflow\n const workflowId = await frameManager.createFrame({\n type: 'workflow',\n name: `${template.name} Workflow`,\n metadata: {\n workflow: workflowName,\n phases: template.phases.map((p: any) => p.name),\n currentPhase: 0,\n startTime: Date.now(),\n }\n });\n \n console.log(chalk.green(`\u2713 Started ${workflowName} workflow`));\n console.log(chalk.cyan(`Workflow ID: ${workflowId}`));\n console.log('\\nPhases:');\n \n template.phases.forEach((phase, index) => {\n const marker = index === 0 ? '\u2192' : ' ';\n console.log(`${marker} ${index + 1}. ${phase.name}`);\n });\n \n console.log(chalk.gray('\\nTrack progress: stackmemory workflow --status'));\n } finally {\n db.close();\n }\n}\n\nasync function showWorkflowStatus(dbPath: string): Promise<void> {\n const db = new Database(dbPath);\n \n try {\n // Get active workflow frames\n const workflows = db.prepare(`\n SELECT * FROM frames \n WHERE type = 'workflow' \n AND state = 'active'\n ORDER BY created_at DESC\n `).all() as any[];\n \n if (workflows.length === 0) {\n console.log(chalk.yellow('No active workflows'));\n return;\n }\n \n console.log(chalk.bold('\\n\uD83D\uDD04 Active Workflows'));\n console.log('\u2500'.repeat(40));\n \n workflows.forEach((workflow) => {\n const metadata = workflow.metadata ? JSON.parse(workflow.metadata) : {};\n const elapsed = Date.now() - workflow.created_at;\n const minutes = Math.floor(elapsed / 60000);\n \n console.log(chalk.cyan(`\\n${workflow.name}`));\n console.log(` ID: ${workflow.frame_id}`);\n console.log(` Duration: ${minutes} minutes`);\n \n if (metadata.phases) {\n const current = metadata.currentPhase || 0;\n console.log(` Phase: ${current + 1}/${metadata.phases.length}`);\n console.log(` Current: ${metadata.phases[current]}`);\n }\n });\n } finally {\n db.close();\n }\n}\n\nexport default createWorkflowCommand;"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * Workflow command for StackMemory\n * Manages workflow templates and execution\n */\n\nimport { Command } from 'commander';\nimport chalk from 'chalk';\nimport * as path from 'path';\nimport Database from 'better-sqlite3';\nimport { existsSync } from 'fs';\nimport { FrameManager } from '../../core/context/frame-manager.js';\nimport { workflowTemplates } from '../../core/frame/workflow-templates.js';\nimport { sessionManager } from '../../core/session/session-manager.js';\nimport { getEnv, getOptionalEnv } from '../../utils/env.js';\n\nexport function createWorkflowCommand(): Command {\n const cmd = new Command('workflow')\n .description('Manage structured workflow templates')\n .option('-l, --list', 'List available workflow templates')\n .option('-s, --start <template>', 'Start a new workflow from template')\n .option('--status', 'Show status of active workflow')\n .action(async (options) => {\n try {\n const projectRoot = process.cwd();\n const dbPath = path.join(projectRoot, '.stackmemory', 'context.db');\n\n // Check if StackMemory is initialized\n if (!existsSync(dbPath)) {\n console.error(chalk.red('\u2717 StackMemory not initialized'));\n console.log(chalk.yellow('Run: stackmemory init'));\n if (process.env['NODE_ENV'] !== 'test') {\n process.exit(1);\n }\n return;\n }\n\n if (options.list) {\n await listWorkflows();\n } else if (options.start) {\n await startWorkflow(options.start, dbPath);\n } else if (options.status) {\n await showWorkflowStatus(dbPath);\n } else {\n // Default: list workflows\n await listWorkflows();\n }\n } catch (error: unknown) {\n console.error(chalk.red('Error: ' + (error as Error).message));\n if (process.env['NODE_ENV'] !== 'test') {\n process.exit(1);\n }\n }\n });\n\n return cmd;\n}\n\nasync function listWorkflows(): Promise<void> {\n console.log(chalk.bold('\\n\uD83D\uDCCB Available Workflows'));\n console.log('\u2500'.repeat(40));\n\n Object.entries(workflowTemplates).forEach(([key, template]) => {\n console.log(chalk.cyan(`\\n${key}:`));\n console.log(` ${template.description}`);\n console.log(chalk.gray(` Phases: ${template.phases.length}`));\n\n // Show first few phases\n template.phases.slice(0, 3).forEach((phase) => {\n console.log(` \u2022 ${phase.name}`);\n });\n if (template.phases.length > 3) {\n console.log(` ... and ${template.phases.length - 3} more`);\n }\n });\n\n console.log(\n chalk.gray('\\nStart a workflow: stackmemory workflow --start <name>')\n );\n}\n\nasync function startWorkflow(\n workflowName: string,\n dbPath: string\n): Promise<void> {\n const template =\n workflowTemplates[workflowName as keyof typeof workflowTemplates];\n\n if (!template) {\n console.error(chalk.red(`Unknown workflow: ${workflowName}`));\n console.log(chalk.yellow('Use --list to see available workflows'));\n if (process.env['NODE_ENV'] !== 'test') {\n process.exit(1);\n }\n return;\n }\n\n const db = new Database(dbPath);\n\n try {\n // Initialize session\n await sessionManager.initialize();\n const session = await sessionManager.getOrCreateSession({\n projectPath: process.cwd(),\n });\n\n const frameManager = new FrameManager(db, session.projectId);\n\n // Create root frame for workflow\n const workflowId = await frameManager.createFrame({\n type: 'workflow',\n name: `${template.name} Workflow`,\n metadata: {\n workflow: workflowName,\n phases: template.phases.map((p: any) => p.name),\n currentPhase: 0,\n startTime: Date.now(),\n },\n });\n\n console.log(chalk.green(`\u2713 Started ${workflowName} workflow`));\n console.log(chalk.cyan(`Workflow ID: ${workflowId}`));\n console.log('\\nPhases:');\n\n template.phases.forEach((phase, index) => {\n const marker = index === 0 ? '\u2192' : ' ';\n console.log(`${marker} ${index + 1}. ${phase.name}`);\n });\n\n console.log(chalk.gray('\\nTrack progress: stackmemory workflow --status'));\n } finally {\n db.close();\n }\n}\n\nasync function showWorkflowStatus(dbPath: string): Promise<void> {\n const db = new Database(dbPath);\n\n try {\n // Get active workflow frames\n const workflows = db\n .prepare(\n `\n SELECT * FROM frames \n WHERE type = 'workflow' \n AND state = 'active'\n ORDER BY created_at DESC\n `\n )\n .all() as any[];\n\n if (workflows.length === 0) {\n console.log(chalk.yellow('No active workflows'));\n return;\n }\n\n console.log(chalk.bold('\\n\uD83D\uDD04 Active Workflows'));\n console.log('\u2500'.repeat(40));\n\n workflows.forEach((workflow) => {\n const metadata = workflow.metadata ? JSON.parse(workflow.metadata) : {};\n const elapsed = Date.now() - workflow.created_at;\n const minutes = Math.floor(elapsed / 60000);\n\n console.log(chalk.cyan(`\\n${workflow.name}`));\n console.log(` ID: ${workflow.frame_id}`);\n console.log(` Duration: ${minutes} minutes`);\n\n if (metadata.phases) {\n const current = metadata.currentPhase || 0;\n console.log(` Phase: ${current + 1}/${metadata.phases.length}`);\n console.log(` Current: ${metadata.phases[current]}`);\n }\n });\n } finally {\n db.close();\n }\n}\n\nexport default createWorkflowCommand;\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -9,7 +9,11 @@ import Database from "better-sqlite3";
9
9
  import { execSync } from "child_process";
10
10
  function registerWorktreeCommands(program) {
11
11
  const worktree = program.command("worktree").alias("wt").description("Manage StackMemory across git worktrees");
12
- worktree.command("enable").description("Enable worktree support").option("--isolate", "Isolate contexts between worktrees (default: true)", true).option("--auto-detect", "Auto-detect worktrees (default: true)", true).option("--sync-interval <minutes>", "Context sync interval", "15").action(async (options) => {
12
+ worktree.command("enable").description("Enable worktree support").option(
13
+ "--isolate",
14
+ "Isolate contexts between worktrees (default: true)",
15
+ true
16
+ ).option("--auto-detect", "Auto-detect worktrees (default: true)", true).option("--sync-interval <minutes>", "Context sync interval", "15").action(async (options) => {
13
17
  const manager = WorktreeManager.getInstance();
14
18
  manager.saveConfig({
15
19
  enabled: true,
@@ -54,9 +58,7 @@ Detected ${worktrees.length} worktree(s):`));
54
58
  if (existsSync(context.dbPath)) {
55
59
  contextStatus = "\u2713 Active";
56
60
  const db = new Database(context.dbPath);
57
- const lastEvent = db.prepare(
58
- "SELECT MAX(created_at) as last FROM events"
59
- ).get();
61
+ const lastEvent = db.prepare("SELECT MAX(created_at) as last FROM events").get();
60
62
  if (lastEvent?.last) {
61
63
  const date = new Date(lastEvent.last);
62
64
  lastActivity = date.toLocaleDateString();
@@ -82,21 +84,27 @@ Detected ${worktrees.length} worktree(s):`));
82
84
  console.log(chalk.gray("\n\u2713 Worktree support is enabled"));
83
85
  const config = manager.getConfig();
84
86
  if (config.isolateContexts) {
85
- console.log(chalk.gray(" - Contexts are isolated between worktrees"));
87
+ console.log(
88
+ chalk.gray(" - Contexts are isolated between worktrees")
89
+ );
86
90
  }
87
91
  if (config.autoDetect) {
88
92
  console.log(chalk.gray(" - Auto-detection is enabled"));
89
93
  }
90
94
  } else {
91
95
  console.log(chalk.gray("\n\u25CB Worktree support is disabled"));
92
- console.log(chalk.gray(' Run "stackmemory worktree enable" to activate'));
96
+ console.log(
97
+ chalk.gray(' Run "stackmemory worktree enable" to activate')
98
+ );
93
99
  }
94
100
  });
95
101
  worktree.command("status").description("Show status of current worktree").action(async () => {
96
102
  const manager = WorktreeManager.getInstance();
97
103
  const currentPath = process.cwd();
98
104
  const worktrees = manager.detectWorktrees(currentPath);
99
- const current = worktrees.find((w) => currentPath.startsWith(w.path));
105
+ const current = worktrees.find(
106
+ (w) => currentPath.startsWith(w.path)
107
+ );
100
108
  if (!current) {
101
109
  console.log(chalk.yellow("Not in a git worktree"));
102
110
  return;
@@ -104,7 +112,10 @@ Detected ${worktrees.length} worktree(s):`));
104
112
  console.log(chalk.cyan("Current Worktree:\n"));
105
113
  console.log(chalk.gray(" Branch:"), current.branch || "detached");
106
114
  console.log(chalk.gray(" Path:"), current.path);
107
- console.log(chalk.gray(" Type:"), current.isMainWorktree ? "Main" : "Branch");
115
+ console.log(
116
+ chalk.gray(" Type:"),
117
+ current.isMainWorktree ? "Main" : "Branch"
118
+ );
108
119
  console.log(chalk.gray(" Commit:"), current.commit.substring(0, 8));
109
120
  if (manager.isEnabled()) {
110
121
  try {
@@ -112,12 +123,14 @@ Detected ${worktrees.length} worktree(s):`));
112
123
  console.log(chalk.gray(" Context Path:"), context.contextPath);
113
124
  if (existsSync(context.dbPath)) {
114
125
  const db = new Database(context.dbPath);
115
- const stats = db.prepare(`
126
+ const stats = db.prepare(
127
+ `
116
128
  SELECT
117
129
  (SELECT COUNT(*) FROM frames) as frames,
118
130
  (SELECT COUNT(*) FROM events) as events,
119
131
  (SELECT COUNT(*) FROM contexts) as contexts
120
- `).get();
132
+ `
133
+ ).get();
121
134
  console.log(chalk.cyan("\nContext Statistics:"));
122
135
  console.log(chalk.gray(" Frames:"), stats.frames);
123
136
  console.log(chalk.gray(" Events:"), stats.events);
@@ -128,7 +141,10 @@ Detected ${worktrees.length} worktree(s):`));
128
141
  console.log(chalk.gray(' Run "stackmemory init" to initialize'));
129
142
  }
130
143
  } catch (error) {
131
- console.log(chalk.red("\nError accessing context:"), error.message);
144
+ console.log(
145
+ chalk.red("\nError accessing context:"),
146
+ error.message
147
+ );
132
148
  }
133
149
  } else {
134
150
  console.log(chalk.gray("\nWorktree support is disabled"));
@@ -149,7 +165,9 @@ Detected ${worktrees.length} worktree(s):`));
149
165
  console.log(chalk.green(`\u2713 Created worktree at ${worktreePath}`));
150
166
  if (manager.isEnabled()) {
151
167
  const context = manager.getWorktreeContext(worktreePath);
152
- console.log(chalk.green(`\u2713 Created isolated context at ${context.contextPath}`));
168
+ console.log(
169
+ chalk.green(`\u2713 Created isolated context at ${context.contextPath}`)
170
+ );
153
171
  if (options.init) {
154
172
  const db = new Database(context.dbPath);
155
173
  new FrameManager(db, project.id);
@@ -164,7 +182,10 @@ Detected ${worktrees.length} worktree(s):`));
164
182
  }
165
183
  console.log(chalk.gray(" # Start working in isolated context"));
166
184
  } catch (error) {
167
- console.error(chalk.red("Failed to create worktree:"), error.message);
185
+ console.error(
186
+ chalk.red("Failed to create worktree:"),
187
+ error.message
188
+ );
168
189
  process.exit(1);
169
190
  }
170
191
  });