@stackmemoryai/stackmemory 0.3.5 → 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 (220) 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 +251 -0
  21. package/dist/cli/commands/infinite-storage.js.map +7 -0
  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 +20 -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 +160 -0
  114. package/dist/core/storage/chromadb-simple.js.map +7 -0
  115. package/dist/core/storage/infinite-storage.js +443 -0
  116. package/dist/core/storage/infinite-storage.js.map +7 -0
  117. package/dist/core/storage/railway-optimized-storage.js +19 -8
  118. package/dist/core/storage/railway-optimized-storage.js.map +2 -2
  119. package/dist/core/storage/remote-storage.js +12 -1
  120. package/dist/core/storage/remote-storage.js.map +2 -2
  121. package/dist/core/trace/cli-trace-wrapper.js +16 -5
  122. package/dist/core/trace/cli-trace-wrapper.js.map +2 -2
  123. package/dist/core/trace/db-trace-wrapper.js.map +2 -2
  124. package/dist/core/trace/debug-trace.js +21 -10
  125. package/dist/core/trace/debug-trace.js.map +2 -2
  126. package/dist/core/trace/index.js +46 -35
  127. package/dist/core/trace/index.js.map +2 -2
  128. package/dist/core/trace/trace-demo.js +12 -1
  129. package/dist/core/trace/trace-demo.js.map +2 -2
  130. package/dist/core/trace/trace-detector.js.map +2 -2
  131. package/dist/core/trace/trace-store.js.map +2 -2
  132. package/dist/core/utils/compression.js +79 -0
  133. package/dist/core/utils/compression.js.map +7 -0
  134. package/dist/core/utils/update-checker.js.map +2 -2
  135. package/dist/core/worktree/worktree-manager.js.map +2 -2
  136. package/dist/features/analytics/api/analytics-api.js.map +2 -2
  137. package/dist/features/analytics/core/analytics-service.js +12 -1
  138. package/dist/features/analytics/core/analytics-service.js.map +2 -2
  139. package/dist/features/analytics/queries/metrics-queries.js.map +2 -2
  140. package/dist/features/tasks/pebbles-task-store.js.map +2 -2
  141. package/dist/features/tui/components/analytics-panel.js.map +2 -2
  142. package/dist/features/tui/components/pr-tracker.js.map +2 -2
  143. package/dist/features/tui/components/session-monitor.js.map +2 -2
  144. package/dist/features/tui/components/subagent-fleet.js.map +2 -2
  145. package/dist/features/tui/components/task-board.js +650 -2
  146. package/dist/features/tui/components/task-board.js.map +2 -2
  147. package/dist/features/tui/index.js +16 -5
  148. package/dist/features/tui/index.js.map +2 -2
  149. package/dist/features/tui/services/data-service.js +35 -52
  150. package/dist/features/tui/services/data-service.js.map +2 -2
  151. package/dist/features/tui/services/linear-task-reader.js +100 -0
  152. package/dist/features/tui/services/linear-task-reader.js.map +7 -0
  153. package/dist/features/tui/services/websocket-client.js +13 -2
  154. package/dist/features/tui/services/websocket-client.js.map +2 -2
  155. package/dist/features/tui/terminal-compat.js +27 -16
  156. package/dist/features/tui/terminal-compat.js.map +2 -2
  157. package/dist/features/web/client/stores/task-store.js +22 -0
  158. package/dist/features/web/client/stores/task-store.js.map +7 -0
  159. package/dist/features/web/server/index.js +182 -0
  160. package/dist/features/web/server/index.js.map +7 -0
  161. package/dist/integrations/claude-code/enhanced-pre-clear-hooks.js.map +2 -2
  162. package/dist/integrations/claude-code/lifecycle-hooks.js.map +2 -2
  163. package/dist/integrations/claude-code/post-task-hooks.js.map +2 -2
  164. package/dist/integrations/linear/auth.js +17 -6
  165. package/dist/integrations/linear/auth.js.map +2 -2
  166. package/dist/integrations/linear/auto-sync.js.map +2 -2
  167. package/dist/integrations/linear/client.js.map +2 -2
  168. package/dist/integrations/linear/config.js.map +2 -2
  169. package/dist/integrations/linear/migration.js.map +2 -2
  170. package/dist/integrations/linear/oauth-server.js +13 -2
  171. package/dist/integrations/linear/oauth-server.js.map +2 -2
  172. package/dist/integrations/linear/rest-client.js.map +2 -2
  173. package/dist/integrations/linear/sync-enhanced.js +202 -0
  174. package/dist/integrations/linear/sync-enhanced.js.map +7 -0
  175. package/dist/integrations/linear/sync-manager.js.map +2 -2
  176. package/dist/integrations/linear/sync-service.js +12 -1
  177. package/dist/integrations/linear/sync-service.js.map +2 -2
  178. package/dist/integrations/linear/sync.js +34 -3
  179. package/dist/integrations/linear/sync.js.map +2 -2
  180. package/dist/integrations/linear/unified-sync.js +560 -0
  181. package/dist/integrations/linear/unified-sync.js.map +7 -0
  182. package/dist/integrations/linear/webhook-handler.js +12 -1
  183. package/dist/integrations/linear/webhook-handler.js.map +2 -2
  184. package/dist/integrations/linear/webhook-server.js +14 -3
  185. package/dist/integrations/linear/webhook-server.js.map +2 -2
  186. package/dist/integrations/linear/webhook.js +12 -1
  187. package/dist/integrations/linear/webhook.js.map +2 -2
  188. package/dist/integrations/mcp/handlers/context-handlers.js.map +2 -2
  189. package/dist/integrations/mcp/handlers/linear-handlers.js.map +2 -2
  190. package/dist/integrations/mcp/handlers/skill-handlers.js +13 -2
  191. package/dist/integrations/mcp/handlers/skill-handlers.js.map +2 -2
  192. package/dist/integrations/mcp/handlers/task-handlers.js.map +2 -2
  193. package/dist/integrations/mcp/handlers/trace-handlers.js.map +2 -2
  194. package/dist/integrations/mcp/middleware/tool-scoring.js.map +2 -2
  195. package/dist/integrations/mcp/refactored-server.js +15 -4
  196. package/dist/integrations/mcp/refactored-server.js.map +2 -2
  197. package/dist/integrations/mcp/server.js +12 -1
  198. package/dist/integrations/mcp/server.js.map +2 -2
  199. package/dist/integrations/mcp/tool-definitions.js.map +2 -2
  200. package/dist/integrations/pg-aiguide/embedding-provider.js +13 -2
  201. package/dist/integrations/pg-aiguide/embedding-provider.js.map +2 -2
  202. package/dist/integrations/pg-aiguide/semantic-search.js.map +2 -2
  203. package/dist/mcp/stackmemory-mcp-server.js +12 -1
  204. package/dist/mcp/stackmemory-mcp-server.js.map +2 -2
  205. package/dist/middleware/exponential-rate-limiter.js.map +2 -2
  206. package/dist/servers/production/auth-middleware.js +13 -2
  207. package/dist/servers/production/auth-middleware.js.map +2 -2
  208. package/dist/servers/railway/index.js +22 -11
  209. package/dist/servers/railway/index.js.map +2 -2
  210. package/dist/services/config-service.js.map +2 -2
  211. package/dist/services/context-service.js.map +2 -2
  212. package/dist/skills/claude-skills.js +150 -1
  213. package/dist/skills/claude-skills.js.map +2 -2
  214. package/dist/skills/dashboard-launcher.js +212 -0
  215. package/dist/skills/dashboard-launcher.js.map +7 -0
  216. package/dist/skills/repo-ingestion-skill.js +561 -0
  217. package/dist/skills/repo-ingestion-skill.js.map +7 -0
  218. package/dist/utils/logger.js +12 -1
  219. package/dist/utils/logger.js.map +2 -2
  220. package/package.json +7 -1
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/features/analytics/queries/metrics-queries.ts"],
4
- "sourcesContent": ["import Database from 'better-sqlite3';\nimport {\n TaskAnalytics,\n TaskMetrics,\n TimeRange,\n AnalyticsQuery,\n} from '../types/metrics.js';\nimport {\n DatabaseError,\n SystemError,\n ErrorCode,\n createErrorHandler,\n} from '../../../core/errors/index.js';\nimport { retry } from '../../../core/errors/recovery.js';\n\nexport class MetricsQueries {\n private db: Database.Database;\n\n constructor(dbPath: string) {\n try {\n this.db = new Database(dbPath, { readonly: false });\n this.initializeTables();\n } catch (error) {\n throw new DatabaseError(\n 'Failed to initialize metrics database',\n ErrorCode.DB_CONNECTION_FAILED,\n {\n dbPath,\n operation: 'constructor',\n },\n error instanceof Error ? error : undefined\n );\n }\n }\n\n private initializeTables(): void {\n const errorHandler = createErrorHandler({\n operation: 'initializeTables',\n });\n\n try {\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS task_analytics (\n id TEXT PRIMARY KEY,\n title TEXT NOT NULL,\n state TEXT NOT NULL,\n created_at INTEGER NOT NULL,\n completed_at INTEGER,\n estimated_effort INTEGER,\n actual_effort INTEGER,\n assignee_id TEXT,\n priority TEXT DEFAULT 'medium',\n labels TEXT DEFAULT '[]',\n blocking_issues TEXT DEFAULT '[]',\n updated_at INTEGER DEFAULT (strftime('%s', 'now'))\n );\n\n CREATE INDEX IF NOT EXISTS idx_task_state ON task_analytics(state);\n CREATE INDEX IF NOT EXISTS idx_task_created ON task_analytics(created_at);\n CREATE INDEX IF NOT EXISTS idx_task_assignee ON task_analytics(assignee_id);\n `);\n } catch (error) {\n const dbError = errorHandler(error, {\n operation: 'initializeTables',\n schema: 'task_analytics',\n });\n \n throw new DatabaseError(\n 'Failed to initialize analytics tables',\n ErrorCode.DB_MIGRATION_FAILED,\n {\n operation: 'initializeTables',\n schema: 'task_analytics',\n },\n error instanceof Error ? error : undefined\n );\n }\n }\n\n getTaskMetrics(query: AnalyticsQuery = {}): TaskMetrics {\n try {\n const { timeRange, userIds, states, priorities } = query;\n\n let whereConditions: string[] = ['1=1'];\n const params: any = {};\n\n if (timeRange) {\n whereConditions.push(\n 'created_at >= @startTime AND created_at <= @endTime'\n );\n params.startTime = Math.floor(timeRange.start.getTime() / 1000);\n params.endTime = Math.floor(timeRange.end.getTime() / 1000);\n }\n\n if (userIds && userIds.length > 0) {\n whereConditions.push(\n `assignee_id IN (${userIds.map((_, i) => `@user${i}`).join(',')})`\n );\n userIds.forEach((id, i) => (params[`user${i}`] = id));\n }\n\n if (states && states.length > 0) {\n whereConditions.push(\n `state IN (${states.map((_, i) => `@state${i}`).join(',')})`\n );\n states.forEach((s, i) => (params[`state${i}`] = s));\n }\n\n if (priorities && priorities.length > 0) {\n whereConditions.push(\n `priority IN (${priorities.map((_, i) => `@priority${i}`).join(',')})`\n );\n priorities.forEach((p, i) => (params[`priority${i}`] = p));\n }\n\n const whereClause = whereConditions.join(' AND ');\n\n const metricsQuery = this.db.prepare(`\n SELECT \n COUNT(*) as total_tasks,\n SUM(CASE WHEN state = 'completed' THEN 1 ELSE 0 END) as completed_tasks,\n SUM(CASE WHEN state = 'in_progress' THEN 1 ELSE 0 END) as in_progress_tasks,\n SUM(CASE WHEN state = 'blocked' THEN 1 ELSE 0 END) as blocked_tasks,\n AVG(CASE \n WHEN state = 'completed' AND completed_at IS NOT NULL \n THEN (completed_at - created_at) * 1000\n ELSE NULL \n END) as avg_time_to_complete,\n AVG(CASE \n WHEN actual_effort IS NOT NULL AND estimated_effort IS NOT NULL AND estimated_effort > 0\n THEN (CAST(actual_effort AS REAL) / estimated_effort) * 100\n ELSE NULL\n END) as effort_accuracy,\n SUM(CASE \n WHEN json_array_length(blocking_issues) > 0 \n THEN json_array_length(blocking_issues)\n ELSE 0\n END) as blocking_issues_count\n FROM task_analytics\n WHERE ${whereClause}\n `);\n\n const result = metricsQuery.get(params) as any;\n\n const velocityQuery = this.db.prepare(`\n SELECT \n DATE(created_at, 'unixepoch') as day,\n COUNT(*) as completed_count\n FROM task_analytics\n WHERE state = 'completed' \n AND ${whereClause}\n GROUP BY day\n ORDER BY day DESC\n LIMIT 30\n `);\n\n const velocityData = velocityQuery.all(params) as any[];\n const velocityTrend = velocityData.map((v) => v.completed_count).reverse();\n\n return {\n totalTasks: result.total_tasks || 0,\n completedTasks: result.completed_tasks || 0,\n inProgressTasks: result.in_progress_tasks || 0,\n blockedTasks: result.blocked_tasks || 0,\n completionRate:\n result.total_tasks > 0\n ? (result.completed_tasks / result.total_tasks) * 100\n : 0,\n averageTimeToComplete: result.avg_time_to_complete || 0,\n effortAccuracy: result.effort_accuracy || 100,\n blockingIssuesCount: result.blocking_issues_count || 0,\n velocityTrend,\n };\n } catch (error) {\n throw new DatabaseError(\n 'Failed to get task metrics',\n ErrorCode.DB_QUERY_FAILED,\n {\n query,\n operation: 'getTaskMetrics',\n },\n error instanceof Error ? error : undefined\n );\n }\n }\n\n getRecentTasks(query: AnalyticsQuery = {}): TaskAnalytics[] {\n try {\n const { limit = 100, offset = 0 } = query;\n\n const tasksQuery = this.db.prepare(`\n SELECT \n id,\n title,\n state,\n created_at,\n completed_at,\n estimated_effort,\n actual_effort,\n assignee_id,\n priority,\n labels,\n blocking_issues\n FROM task_analytics\n ORDER BY updated_at DESC\n LIMIT ? OFFSET ?\n `);\n\n const rows = tasksQuery.all(limit, offset) as any[];\n\n return rows.map((row) => ({\n id: row.id,\n title: row.title,\n state: row.state as TaskAnalytics['state'],\n createdAt: new Date(row.created_at * 1000),\n completedAt: row.completed_at\n ? new Date(row.completed_at * 1000)\n : undefined,\n estimatedEffort: row.estimated_effort,\n actualEffort: row.actual_effort,\n assigneeId: row.assignee_id,\n priority: row.priority as TaskAnalytics['priority'],\n labels: JSON.parse(row.labels),\n blockingIssues: JSON.parse(row.blocking_issues),\n }));\n } catch (error) {\n throw new DatabaseError(\n 'Failed to get recent tasks',\n ErrorCode.DB_QUERY_FAILED,\n {\n limit: query.limit,\n offset: query.offset,\n operation: 'getRecentTasks',\n },\n error instanceof Error ? error : undefined\n );\n }\n }\n\n upsertTask(task: TaskAnalytics): void {\n try {\n const stmt = this.db.prepare(`\n INSERT INTO task_analytics (\n id, title, state, created_at, completed_at,\n estimated_effort, actual_effort, assignee_id,\n priority, labels, blocking_issues\n ) VALUES (\n @id, @title, @state, @created_at, @completed_at,\n @estimated_effort, @actual_effort, @assignee_id,\n @priority, @labels, @blocking_issues\n )\n ON CONFLICT(id) DO UPDATE SET\n title = @title,\n state = @state,\n completed_at = @completed_at,\n estimated_effort = @estimated_effort,\n actual_effort = @actual_effort,\n assignee_id = @assignee_id,\n priority = @priority,\n labels = @labels,\n blocking_issues = @blocking_issues,\n updated_at = strftime('%s', 'now')\n `);\n\n stmt.run({\n id: task.id,\n title: task.title,\n state: task.state,\n created_at: Math.floor(task.createdAt.getTime() / 1000),\n completed_at: task.completedAt\n ? Math.floor(task.completedAt.getTime() / 1000)\n : null,\n estimated_effort: task.estimatedEffort || null,\n actual_effort: task.actualEffort || null,\n assignee_id: task.assigneeId || null,\n priority: task.priority,\n labels: JSON.stringify(task.labels),\n blocking_issues: JSON.stringify(task.blockingIssues),\n });\n } catch (error) {\n throw new DatabaseError(\n `Failed to upsert task analytics: ${task.id}`,\n ErrorCode.DB_QUERY_FAILED,\n {\n taskId: task.id,\n taskState: task.state,\n operation: 'upsertTask',\n },\n error instanceof Error ? error : undefined\n );\n }\n }\n\n close(): void {\n try {\n this.db.close();\n } catch (error) {\n throw new DatabaseError(\n 'Failed to close analytics database',\n ErrorCode.DB_CONNECTION_FAILED,\n {\n operation: 'close',\n },\n error instanceof Error ? error : undefined\n );\n }\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import Database from 'better-sqlite3';\nimport {\n TaskAnalytics,\n TaskMetrics,\n TimeRange,\n AnalyticsQuery,\n} from '../types/metrics.js';\nimport {\n DatabaseError,\n SystemError,\n ErrorCode,\n createErrorHandler,\n} from '../../../core/errors/index.js';\nimport { retry } from '../../../core/errors/recovery.js';\n\nexport class MetricsQueries {\n private db: Database.Database;\n\n constructor(dbPath: string) {\n try {\n this.db = new Database(dbPath, { readonly: false });\n this.initializeTables();\n } catch (error: unknown) {\n throw new DatabaseError(\n 'Failed to initialize metrics database',\n ErrorCode.DB_CONNECTION_FAILED,\n {\n dbPath,\n operation: 'constructor',\n },\n error instanceof Error ? error : undefined\n );\n }\n }\n\n private initializeTables(): void {\n const errorHandler = createErrorHandler({\n operation: 'initializeTables',\n });\n\n try {\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS task_analytics (\n id TEXT PRIMARY KEY,\n title TEXT NOT NULL,\n state TEXT NOT NULL,\n created_at INTEGER NOT NULL,\n completed_at INTEGER,\n estimated_effort INTEGER,\n actual_effort INTEGER,\n assignee_id TEXT,\n priority TEXT DEFAULT 'medium',\n labels TEXT DEFAULT '[]',\n blocking_issues TEXT DEFAULT '[]',\n updated_at INTEGER DEFAULT (strftime('%s', 'now'))\n );\n\n CREATE INDEX IF NOT EXISTS idx_task_state ON task_analytics(state);\n CREATE INDEX IF NOT EXISTS idx_task_created ON task_analytics(created_at);\n CREATE INDEX IF NOT EXISTS idx_task_assignee ON task_analytics(assignee_id);\n `);\n } catch (error: unknown) {\n const dbError = errorHandler(error, {\n operation: 'initializeTables',\n schema: 'task_analytics',\n });\n \n throw new DatabaseError(\n 'Failed to initialize analytics tables',\n ErrorCode.DB_MIGRATION_FAILED,\n {\n operation: 'initializeTables',\n schema: 'task_analytics',\n },\n error instanceof Error ? error : undefined\n );\n }\n }\n\n getTaskMetrics(query: AnalyticsQuery = {}): TaskMetrics {\n try {\n const { timeRange, userIds, states, priorities } = query;\n\n let whereConditions: string[] = ['1=1'];\n const params: any = {};\n\n if (timeRange) {\n whereConditions.push(\n 'created_at >= @startTime AND created_at <= @endTime'\n );\n params.startTime = Math.floor(timeRange.start.getTime() / 1000);\n params.endTime = Math.floor(timeRange.end.getTime() / 1000);\n }\n\n if (userIds && userIds.length > 0) {\n whereConditions.push(\n `assignee_id IN (${userIds.map((_, i) => `@user${i}`).join(',')})`\n );\n userIds.forEach((id, i) => (params[`user${i}`] = id));\n }\n\n if (states && states.length > 0) {\n whereConditions.push(\n `state IN (${states.map((_, i) => `@state${i}`).join(',')})`\n );\n states.forEach((s, i) => (params[`state${i}`] = s));\n }\n\n if (priorities && priorities.length > 0) {\n whereConditions.push(\n `priority IN (${priorities.map((_, i) => `@priority${i}`).join(',')})`\n );\n priorities.forEach((p, i) => (params[`priority${i}`] = p));\n }\n\n const whereClause = whereConditions.join(' AND ');\n\n const metricsQuery = this.db.prepare(`\n SELECT \n COUNT(*) as total_tasks,\n SUM(CASE WHEN state = 'completed' THEN 1 ELSE 0 END) as completed_tasks,\n SUM(CASE WHEN state = 'in_progress' THEN 1 ELSE 0 END) as in_progress_tasks,\n SUM(CASE WHEN state = 'blocked' THEN 1 ELSE 0 END) as blocked_tasks,\n AVG(CASE \n WHEN state = 'completed' AND completed_at IS NOT NULL \n THEN (completed_at - created_at) * 1000\n ELSE NULL \n END) as avg_time_to_complete,\n AVG(CASE \n WHEN actual_effort IS NOT NULL AND estimated_effort IS NOT NULL AND estimated_effort > 0\n THEN (CAST(actual_effort AS REAL) / estimated_effort) * 100\n ELSE NULL\n END) as effort_accuracy,\n SUM(CASE \n WHEN json_array_length(blocking_issues) > 0 \n THEN json_array_length(blocking_issues)\n ELSE 0\n END) as blocking_issues_count\n FROM task_analytics\n WHERE ${whereClause}\n `);\n\n const result = metricsQuery.get(params) as any;\n\n const velocityQuery = this.db.prepare(`\n SELECT \n DATE(created_at, 'unixepoch') as day,\n COUNT(*) as completed_count\n FROM task_analytics\n WHERE state = 'completed' \n AND ${whereClause}\n GROUP BY day\n ORDER BY day DESC\n LIMIT 30\n `);\n\n const velocityData = velocityQuery.all(params) as any[];\n const velocityTrend = velocityData.map((v) => v.completed_count).reverse();\n\n return {\n totalTasks: result.total_tasks || 0,\n completedTasks: result.completed_tasks || 0,\n inProgressTasks: result.in_progress_tasks || 0,\n blockedTasks: result.blocked_tasks || 0,\n completionRate:\n result.total_tasks > 0\n ? (result.completed_tasks / result.total_tasks) * 100\n : 0,\n averageTimeToComplete: result.avg_time_to_complete || 0,\n effortAccuracy: result.effort_accuracy || 100,\n blockingIssuesCount: result.blocking_issues_count || 0,\n velocityTrend,\n };\n } catch (error: unknown) {\n throw new DatabaseError(\n 'Failed to get task metrics',\n ErrorCode.DB_QUERY_FAILED,\n {\n query,\n operation: 'getTaskMetrics',\n },\n error instanceof Error ? error : undefined\n );\n }\n }\n\n getRecentTasks(query: AnalyticsQuery = {}): TaskAnalytics[] {\n try {\n const { limit = 100, offset = 0 } = query;\n\n const tasksQuery = this.db.prepare(`\n SELECT \n id,\n title,\n state,\n created_at,\n completed_at,\n estimated_effort,\n actual_effort,\n assignee_id,\n priority,\n labels,\n blocking_issues\n FROM task_analytics\n ORDER BY updated_at DESC\n LIMIT ? OFFSET ?\n `);\n\n const rows = tasksQuery.all(limit, offset) as any[];\n\n return rows.map((row) => ({\n id: row.id,\n title: row.title,\n state: row.state as TaskAnalytics['state'],\n createdAt: new Date(row.created_at * 1000),\n completedAt: row.completed_at\n ? new Date(row.completed_at * 1000)\n : undefined,\n estimatedEffort: row.estimated_effort,\n actualEffort: row.actual_effort,\n assigneeId: row.assignee_id,\n priority: row.priority as TaskAnalytics['priority'],\n labels: JSON.parse(row.labels),\n blockingIssues: JSON.parse(row.blocking_issues),\n }));\n } catch (error: unknown) {\n throw new DatabaseError(\n 'Failed to get recent tasks',\n ErrorCode.DB_QUERY_FAILED,\n {\n limit: query.limit,\n offset: query.offset,\n operation: 'getRecentTasks',\n },\n error instanceof Error ? error : undefined\n );\n }\n }\n\n upsertTask(task: TaskAnalytics): void {\n try {\n const stmt = this.db.prepare(`\n INSERT INTO task_analytics (\n id, title, state, created_at, completed_at,\n estimated_effort, actual_effort, assignee_id,\n priority, labels, blocking_issues\n ) VALUES (\n @id, @title, @state, @created_at, @completed_at,\n @estimated_effort, @actual_effort, @assignee_id,\n @priority, @labels, @blocking_issues\n )\n ON CONFLICT(id) DO UPDATE SET\n title = @title,\n state = @state,\n completed_at = @completed_at,\n estimated_effort = @estimated_effort,\n actual_effort = @actual_effort,\n assignee_id = @assignee_id,\n priority = @priority,\n labels = @labels,\n blocking_issues = @blocking_issues,\n updated_at = strftime('%s', 'now')\n `);\n\n stmt.run({\n id: task.id,\n title: task.title,\n state: task.state,\n created_at: Math.floor(task.createdAt.getTime() / 1000),\n completed_at: task.completedAt\n ? Math.floor(task.completedAt.getTime() / 1000)\n : null,\n estimated_effort: task.estimatedEffort || null,\n actual_effort: task.actualEffort || null,\n assignee_id: task.assigneeId || null,\n priority: task.priority,\n labels: JSON.stringify(task.labels),\n blocking_issues: JSON.stringify(task.blockingIssues),\n });\n } catch (error: unknown) {\n throw new DatabaseError(\n `Failed to upsert task analytics: ${task.id}`,\n ErrorCode.DB_QUERY_FAILED,\n {\n taskId: task.id,\n taskState: task.state,\n operation: 'upsertTask',\n },\n error instanceof Error ? error : undefined\n );\n }\n }\n\n close(): void {\n try {\n this.db.close();\n } catch (error: unknown) {\n throw new DatabaseError(\n 'Failed to close analytics database',\n ErrorCode.DB_CONNECTION_FAILED,\n {\n operation: 'close',\n },\n error instanceof Error ? error : undefined\n );\n }\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/features/tasks/pebbles-task-store.ts"],
4
- "sourcesContent": ["/**\n * Pebbles Task Storage\n * Git-native JSONL storage with SQLite cache for tasks\n */\n\nimport Database from 'better-sqlite3';\nimport { EventEmitter } from 'events';\nimport { createHash } from 'crypto';\nimport { appendFile, existsSync, mkdirSync, readFileSync } from 'fs';\nimport { join } from 'path';\nimport { logger } from '../../core/monitoring/logger.js';\nimport {\n DatabaseError,\n TaskError,\n SystemError,\n ErrorCode,\n wrapError,\n createErrorHandler,\n} from '../../core/errors/index.js';\nimport { retry, withTimeout } from '../../core/errors/recovery.js';\nimport { StreamingJSONLParser } from '../../core/performance/streaming-jsonl-parser.js';\nimport { ContextCache } from '../../core/performance/context-cache.js';\n\nexport type TaskStatus =\n | 'pending'\n | 'in_progress'\n | 'completed'\n | 'blocked'\n | 'cancelled';\nexport type TaskPriority = 'low' | 'medium' | 'high' | 'urgent';\n\nexport interface PebblesTask {\n id: string; // Content-hash based (merge-friendly)\n type: 'task_create' | 'task_update' | 'task_complete' | 'task_block';\n timestamp: number;\n parent_id?: string; // For subtasks\n frame_id: string; // Associated call stack frame\n\n // Task data\n title: string;\n description?: string;\n status: TaskStatus;\n priority: TaskPriority;\n assignee?: string;\n\n // Tracking\n created_at: number;\n started_at?: number;\n completed_at?: number;\n estimated_effort?: number; // Minutes\n actual_effort?: number;\n\n // Relationships\n depends_on: string[]; // Task IDs\n blocks: string[]; // Task IDs this blocks\n tags: string[]; // For filtering\n\n // Integration hooks (for Linear phase)\n external_refs?: {\n linear?: { id: string; url: string };\n github?: { issue: number; url: string };\n };\n\n // Context relevance\n context_score?: number; // For intelligent assembly\n last_accessed?: number;\n}\n\nexport interface TaskMetrics {\n total_tasks: number;\n by_status: Record<TaskStatus, number>;\n by_priority: Record<TaskPriority, number>;\n completion_rate: number;\n avg_effort_accuracy: number;\n blocked_tasks: number;\n overdue_tasks: number;\n}\n\nexport class PebblesTaskStore extends EventEmitter {\n private db: Database.Database;\n private projectRoot: string;\n private tasksFile: string;\n private cacheFile: string;\n private jsonlParser: StreamingJSONLParser;\n private taskCache: ContextCache<PebblesTask>;\n\n constructor(projectRoot: string, db: Database.Database) {\n super();\n this.projectRoot = projectRoot;\n this.db = db;\n\n // Ensure .stackmemory directory exists\n const stackmemoryDir = join(projectRoot, '.stackmemory');\n if (!existsSync(stackmemoryDir)) {\n mkdirSync(stackmemoryDir, { recursive: true });\n }\n\n this.tasksFile = join(stackmemoryDir, 'tasks.jsonl');\n this.cacheFile = join(stackmemoryDir, 'cache.db');\n\n // Initialize performance optimizations\n this.jsonlParser = new StreamingJSONLParser();\n this.taskCache = new ContextCache<PebblesTask>({\n maxSize: 10 * 1024 * 1024, // 10MB for tasks\n maxItems: 1000,\n defaultTTL: 3600000, // 1 hour\n });\n\n this.initializeCache();\n // Load existing tasks from JSONL synchronously\n this.loadFromJSONLSync();\n }\n\n private initializeCache() {\n const errorHandler = createErrorHandler({\n operation: 'initializeCache',\n projectRoot: this.projectRoot,\n });\n\n try {\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS task_cache (\n id TEXT PRIMARY KEY,\n type TEXT NOT NULL,\n timestamp INTEGER NOT NULL,\n parent_id TEXT,\n frame_id TEXT NOT NULL,\n title TEXT NOT NULL,\n description TEXT,\n status TEXT NOT NULL,\n priority TEXT NOT NULL,\n assignee TEXT,\n created_at INTEGER NOT NULL,\n started_at INTEGER,\n completed_at INTEGER,\n estimated_effort INTEGER,\n actual_effort INTEGER,\n depends_on TEXT DEFAULT '[]',\n blocks TEXT DEFAULT '[]',\n tags TEXT DEFAULT '[]',\n external_refs TEXT DEFAULT '{}',\n context_score REAL DEFAULT 0.5,\n last_accessed INTEGER\n );\n \n CREATE INDEX IF NOT EXISTS idx_task_status ON task_cache(status);\n CREATE INDEX IF NOT EXISTS idx_task_priority ON task_cache(priority);\n CREATE INDEX IF NOT EXISTS idx_task_frame ON task_cache(frame_id);\n CREATE INDEX IF NOT EXISTS idx_task_timestamp ON task_cache(timestamp);\n CREATE INDEX IF NOT EXISTS idx_task_parent ON task_cache(parent_id);\n `);\n } catch (error) {\n const dbError = errorHandler(error, {\n operation: 'initializeCache',\n schema: 'task_cache',\n });\n\n throw new DatabaseError(\n 'Failed to initialize task cache schema',\n ErrorCode.DB_MIGRATION_FAILED,\n {\n projectRoot: this.projectRoot,\n cacheFile: this.cacheFile,\n operation: 'initializeCache',\n },\n error instanceof Error ? error : undefined\n );\n }\n }\n\n /**\n * Load existing tasks from JSONL into SQLite cache (optimized)\n */\n private async loadFromJSONL() {\n if (!existsSync(this.tasksFile)) return;\n\n const errorHandler = createErrorHandler({\n operation: 'loadFromJSONL',\n tasksFile: this.tasksFile,\n });\n\n try {\n let loaded = 0;\n let errors = 0;\n\n // Use streaming parser for memory efficiency\n for await (const batch of this.jsonlParser.parseStream<PebblesTask>(\n this.tasksFile,\n {\n batchSize: 100,\n filter: (obj) => obj.type && obj.id && obj.title, // Basic validation\n onProgress: (count) => {\n if (count % 500 === 0) {\n logger.debug('Loading tasks progress', { loaded: count });\n }\n },\n }\n )) {\n for (const task of batch) {\n try {\n this.upsertToCache(task);\n // Add to in-memory cache for fast access\n this.taskCache.set(task.id, task, {\n ttl: 3600000, // 1 hour cache\n });\n loaded++;\n } catch (error) {\n errors++;\n logger.warn('Failed to cache task', {\n taskId: task.id,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n }\n\n logger.info('Loaded tasks from JSONL', {\n loaded,\n errors,\n file: this.tasksFile,\n cacheStats: this.taskCache.getStats(),\n });\n } catch (error) {\n const systemError = errorHandler(error, {\n operation: 'loadFromJSONL',\n file: this.tasksFile,\n });\n\n throw new SystemError(\n 'Failed to load tasks from JSONL file',\n ErrorCode.INTERNAL_ERROR,\n {\n tasksFile: this.tasksFile,\n operation: 'loadFromJSONL',\n },\n error instanceof Error ? error : undefined\n );\n }\n }\n\n /**\n * Load existing tasks from JSONL synchronously (for constructor)\n */\n private loadFromJSONLSync() {\n if (!existsSync(this.tasksFile)) return;\n\n try {\n const content = readFileSync(this.tasksFile, 'utf-8');\n const lines = content.split('\\n').filter((line) => line.trim());\n\n let loaded = 0;\n let errors = 0;\n\n for (const line of lines) {\n try {\n const task = JSON.parse(line) as PebblesTask;\n\n // Basic validation\n if (task.type && task.id && task.title) {\n this.upsertToCache(task);\n // Add to in-memory cache for fast access\n this.taskCache.set(task.id, task, {\n ttl: 3600000, // 1 hour cache\n });\n loaded++;\n }\n } catch (error) {\n errors++;\n logger.warn('Failed to parse JSONL line', {\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n logger.info('Loaded tasks from JSONL', {\n loaded,\n errors,\n file: this.tasksFile,\n });\n } catch (error) {\n logger.error('Failed to load tasks from JSONL', error as Error);\n }\n }\n\n /**\n * Create a new task with content-hash ID\n */\n public createTask(options: {\n title: string;\n description?: string;\n priority?: TaskPriority;\n frameId: string;\n parentId?: string;\n dependsOn?: string[];\n tags?: string[];\n estimatedEffort?: number;\n assignee?: string;\n }): string {\n const now = Math.floor(Date.now() / 1000);\n\n // Create content for hash (ensures deterministic ID)\n const content = `${options.title}:${options.frameId}:${now}:${Math.random()}`;\n const id = this.generateTaskId(content);\n\n const task: PebblesTask = {\n id,\n type: 'task_create',\n timestamp: now,\n parent_id: options.parentId,\n frame_id: options.frameId,\n title: options.title,\n description: options.description,\n status: 'pending',\n priority: options.priority || 'medium',\n assignee: options.assignee,\n created_at: now,\n estimated_effort: options.estimatedEffort,\n depends_on: options.dependsOn || [],\n blocks: [],\n tags: options.tags || [],\n context_score: 0.5,\n };\n\n this.appendTask(task);\n this.emit('task:created', task);\n this.emit('sync:needed', 'task:created');\n return id;\n }\n\n /**\n * Update task status with new event\n */\n public updateTaskStatus(\n taskId: string,\n newStatus: TaskStatus,\n _reason?: string\n ): void {\n const existing = this.getTask(taskId);\n if (!existing) {\n throw new TaskError(\n `Task not found: ${taskId}`,\n ErrorCode.TASK_NOT_FOUND,\n {\n taskId,\n newStatus,\n operation: 'updateTaskStatus',\n }\n );\n }\n\n // Validate status transition\n if (existing.status === 'completed' && newStatus !== 'cancelled') {\n throw new TaskError(\n `Cannot change completed task status from ${existing.status} to ${newStatus}`,\n ErrorCode.TASK_INVALID_STATE,\n {\n taskId,\n currentStatus: existing.status,\n newStatus,\n operation: 'updateTaskStatus',\n }\n );\n }\n\n const now = Math.floor(Date.now() / 1000);\n const updates: Partial<PebblesTask> = {\n status: newStatus,\n timestamp: now,\n };\n\n // Automatic time tracking\n if (newStatus === 'in_progress' && existing.status === 'pending') {\n updates.started_at = now;\n updates.type = 'task_update';\n } else if (newStatus === 'completed' && existing.status === 'in_progress') {\n updates.completed_at = now;\n updates.type = 'task_complete';\n if (existing.started_at) {\n updates.actual_effort = Math.floor((now - existing.started_at) / 60); // Minutes\n }\n } else if (newStatus === 'blocked') {\n updates.type = 'task_block';\n }\n\n const updatedTask: PebblesTask = { ...existing, ...updates };\n this.appendTask(updatedTask);\n \n if (newStatus === 'completed') {\n this.emit('task:completed', updatedTask);\n }\n this.emit('sync:needed', 'task:updated');\n }\n\n /**\n * Add dependency relationship\n */\n public addDependency(taskId: string, dependsOnId: string): void {\n const task = this.getTask(taskId);\n const dependsOnTask = this.getTask(dependsOnId);\n\n if (!task) {\n throw new TaskError(\n `Task not found: ${taskId}`,\n ErrorCode.TASK_NOT_FOUND,\n {\n taskId,\n operation: 'addDependency',\n }\n );\n }\n\n if (!dependsOnTask) {\n throw new TaskError(\n `Dependency task not found: ${dependsOnId}`,\n ErrorCode.TASK_NOT_FOUND,\n {\n dependsOnId,\n taskId,\n operation: 'addDependency',\n }\n );\n }\n\n // Check for circular dependency\n if (this.wouldCreateCircularDependency(taskId, dependsOnId)) {\n throw new TaskError(\n `Adding dependency would create circular dependency: ${taskId} -> ${dependsOnId}`,\n ErrorCode.TASK_CIRCULAR_DEPENDENCY,\n {\n taskId,\n dependsOnId,\n operation: 'addDependency',\n }\n );\n }\n\n // Update task dependencies\n const updatedTask: PebblesTask = {\n ...task,\n depends_on: [...new Set([...task.depends_on, dependsOnId])],\n timestamp: Math.floor(Date.now() / 1000),\n type: 'task_update',\n };\n\n // Update blocking task\n const updatedBlockingTask: PebblesTask = {\n ...dependsOnTask,\n blocks: [...new Set([...dependsOnTask.blocks, taskId])],\n timestamp: Math.floor(Date.now() / 1000),\n type: 'task_update',\n };\n\n this.appendTask(updatedTask);\n this.appendTask(updatedBlockingTask);\n }\n\n /**\n * Get current active tasks\n */\n public getActiveTasks(frameId?: string): PebblesTask[] {\n try {\n let query = `\n SELECT * FROM task_cache \n WHERE status IN ('pending', 'in_progress')\n `;\n const params: any[] = [];\n\n if (frameId) {\n query += ` AND frame_id = ?`;\n params.push(frameId);\n }\n\n query += ` ORDER BY priority DESC, created_at ASC`;\n\n const rows = this.db.prepare(query).all(...params) as any[];\n return this.hydrateTasks(rows);\n } catch (error) {\n throw new DatabaseError(\n 'Failed to get active tasks',\n ErrorCode.DB_QUERY_FAILED,\n {\n frameId,\n operation: 'getActiveTasks',\n },\n error instanceof Error ? error : undefined\n );\n }\n }\n\n /**\n * Get task by ID (latest version)\n */\n public getTask(taskId: string): PebblesTask | undefined {\n try {\n const row = this.db\n .prepare(\n `\n SELECT * FROM task_cache WHERE id = ?\n `\n )\n .get(taskId) as any;\n\n return row ? this.hydrateTask(row) : undefined;\n } catch (error) {\n throw new DatabaseError(\n `Failed to get task: ${taskId}`,\n ErrorCode.DB_QUERY_FAILED,\n {\n taskId,\n operation: 'getTask',\n },\n error instanceof Error ? error : undefined\n );\n }\n }\n\n /**\n * Get tasks that are blocking other tasks\n */\n public getBlockingTasks(): PebblesTask[] {\n try {\n const rows = this.db\n .prepare(\n `\n SELECT * FROM task_cache \n WHERE JSON_ARRAY_LENGTH(blocks) > 0 \n AND status NOT IN ('completed', 'cancelled')\n ORDER BY priority DESC\n `\n )\n .all() as any[];\n\n return this.hydrateTasks(rows);\n } catch (error) {\n throw new DatabaseError(\n 'Failed to get blocking tasks',\n ErrorCode.DB_QUERY_FAILED,\n {\n operation: 'getBlockingTasks',\n },\n error instanceof Error ? error : undefined\n );\n }\n }\n\n /**\n * Get metrics for current project\n */\n public getMetrics(): TaskMetrics {\n try {\n const statusCounts = this.db\n .prepare(\n `\n SELECT status, COUNT(*) as count \n FROM task_cache \n GROUP BY status\n `\n )\n .all() as { status: TaskStatus; count: number }[];\n\n const priorityCounts = this.db\n .prepare(\n `\n SELECT priority, COUNT(*) as count \n FROM task_cache \n GROUP BY priority \n `\n )\n .all() as { priority: TaskPriority; count: number }[];\n\n const totalTasks = statusCounts.reduce((sum, s) => sum + s.count, 0);\n const completedTasks =\n statusCounts.find((s) => s.status === 'completed')?.count || 0;\n const blockedTasks =\n statusCounts.find((s) => s.status === 'blocked')?.count || 0;\n\n // Calculate effort accuracy\n const effortRows = this.db\n .prepare(\n `\n SELECT estimated_effort, actual_effort \n FROM task_cache \n WHERE estimated_effort IS NOT NULL \n AND actual_effort IS NOT NULL\n `\n )\n .all() as { estimated_effort: number; actual_effort: number }[];\n\n let avgEffortAccuracy = 0;\n if (effortRows.length > 0) {\n const accuracies = effortRows.map(\n (r) =>\n 1 -\n Math.abs(r.estimated_effort - r.actual_effort) /\n Math.max(r.estimated_effort, 1)\n );\n avgEffortAccuracy =\n accuracies.reduce((sum, acc) => sum + acc, 0) / accuracies.length;\n }\n\n return {\n total_tasks: totalTasks,\n by_status: Object.fromEntries(\n statusCounts.map((s) => [s.status, s.count])\n ) as any,\n by_priority: Object.fromEntries(\n priorityCounts.map((p) => [p.priority, p.count])\n ) as any,\n completion_rate: totalTasks > 0 ? completedTasks / totalTasks : 0,\n avg_effort_accuracy: avgEffortAccuracy,\n blocked_tasks: blockedTasks,\n overdue_tasks: 0, // TODO: implement due dates\n };\n } catch (error) {\n throw new DatabaseError(\n 'Failed to get task metrics',\n ErrorCode.DB_QUERY_FAILED,\n {\n operation: 'getMetrics',\n },\n error instanceof Error ? error : undefined\n );\n }\n }\n\n /**\n * Export tasks for Linear integration (Phase 2)\n */\n public exportForLinear(): Array<{\n title: string;\n description?: string;\n priority: number;\n status: string;\n estimate?: number;\n dependencies: string[];\n }> {\n const tasks = this.db\n .prepare(\n `\n SELECT * FROM task_cache \n WHERE external_refs IS NULL OR JSON_EXTRACT(external_refs, '$.linear') IS NULL\n ORDER BY created_at ASC\n `\n )\n .all() as any[];\n\n return tasks.map((task) => ({\n title: task.title,\n description: task.description,\n priority: this.mapPriorityToLinear(task.priority),\n status: this.mapStatusToLinear(task.status),\n estimate: task.estimated_effort,\n dependencies: JSON.parse(task.depends_on || '[]'),\n }));\n }\n\n // Private methods\n private appendTask(task: PebblesTask) {\n try {\n // Append to JSONL file (git-tracked source of truth)\n const jsonLine = JSON.stringify(task) + '\\n';\n appendFile(this.tasksFile, jsonLine, (err) => {\n if (err) {\n logger.error(\n `Failed to append task ${task.id} to JSONL: ${err.message}`,\n err,\n {\n taskId: task.id,\n tasksFile: this.tasksFile,\n }\n );\n }\n });\n\n // Update SQLite cache (for fast queries) with retry logic\n retry(() => Promise.resolve(this.upsertToCache(task)), {\n maxAttempts: 3,\n initialDelay: 100,\n onRetry: (attempt, error) => {\n logger.warn(`Retrying task cache upsert (attempt ${attempt})`, {\n taskId: task.id,\n errorMessage:\n error instanceof Error ? error.message : String(error),\n });\n },\n }).catch((error) => {\n logger.error(\n 'Failed to upsert task to cache after retries',\n error instanceof Error ? error : new Error(String(error)),\n {\n taskId: task.id,\n }\n );\n throw error;\n });\n\n logger.info('Appended task', {\n id: task.id,\n type: task.type,\n title: task.title,\n status: task.status,\n });\n } catch (error) {\n throw new SystemError(\n `Failed to append task: ${task.id}`,\n ErrorCode.INTERNAL_ERROR,\n {\n taskId: task.id,\n operation: 'appendTask',\n },\n error instanceof Error ? error : undefined\n );\n }\n }\n\n private upsertToCache(task: PebblesTask) {\n try {\n this.db\n .prepare(\n `\n INSERT OR REPLACE INTO task_cache (\n id, type, timestamp, parent_id, frame_id, title, description,\n status, priority, assignee, created_at, started_at, completed_at,\n estimated_effort, actual_effort, depends_on, blocks, tags,\n external_refs, context_score, last_accessed\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n `\n )\n .run(\n task.id,\n task.type,\n task.timestamp,\n task.parent_id,\n task.frame_id,\n task.title,\n task.description,\n task.status,\n task.priority,\n task.assignee,\n task.created_at,\n task.started_at,\n task.completed_at,\n task.estimated_effort,\n task.actual_effort,\n JSON.stringify(task.depends_on),\n JSON.stringify(task.blocks),\n JSON.stringify(task.tags),\n JSON.stringify(task.external_refs || {}),\n task.context_score,\n task.last_accessed\n );\n } catch (error) {\n throw new DatabaseError(\n `Failed to upsert task to cache: ${task.id}`,\n ErrorCode.DB_QUERY_FAILED,\n {\n taskId: task.id,\n taskTitle: task.title,\n operation: 'upsertToCache',\n },\n error instanceof Error ? error : undefined\n );\n }\n }\n\n private generateTaskId(content: string): string {\n const hash = createHash('sha256').update(content).digest('hex');\n return `tsk-${hash.substring(0, 8)}`;\n }\n\n private hydrateTask = (row: any): PebblesTask => ({\n ...row,\n depends_on: JSON.parse(row.depends_on || '[]'),\n blocks: JSON.parse(row.blocks || '[]'),\n tags: JSON.parse(row.tags || '[]'),\n external_refs: JSON.parse(row.external_refs || '{}'),\n });\n\n private hydrateTasks(rows: any[]): PebblesTask[] {\n return rows.map(this.hydrateTask);\n }\n\n private mapPriorityToLinear(priority: TaskPriority): number {\n const map = { low: 1, medium: 2, high: 3, urgent: 4 };\n return map[priority] || 2;\n }\n\n private mapStatusToLinear(status: TaskStatus): string {\n const map = {\n pending: 'Backlog',\n in_progress: 'In Progress',\n completed: 'Done',\n blocked: 'Blocked',\n cancelled: 'Cancelled',\n };\n return map[status] || 'Backlog';\n }\n\n /**\n * Check if adding a dependency would create a circular dependency\n */\n private wouldCreateCircularDependency(\n taskId: string,\n dependsOnId: string\n ): boolean {\n const visited = new Set<string>();\n const stack = [dependsOnId];\n\n while (stack.length > 0) {\n const currentId = stack.pop()!;\n\n if (currentId === taskId) {\n return true; // Found circular dependency\n }\n\n if (visited.has(currentId)) {\n continue;\n }\n\n visited.add(currentId);\n\n // Get dependencies of current task\n const currentTask = this.getTask(currentId);\n if (currentTask) {\n stack.push(...currentTask.depends_on);\n }\n }\n\n return false;\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * Pebbles Task Storage\n * Git-native JSONL storage with SQLite cache for tasks\n */\n\nimport Database from 'better-sqlite3';\nimport { EventEmitter } from 'events';\nimport { createHash } from 'crypto';\nimport { appendFile, existsSync, mkdirSync, readFileSync } from 'fs';\nimport { join } from 'path';\nimport { logger } from '../../core/monitoring/logger.js';\nimport {\n DatabaseError,\n TaskError,\n SystemError,\n ErrorCode,\n wrapError,\n createErrorHandler,\n} from '../../core/errors/index.js';\nimport { retry, withTimeout } from '../../core/errors/recovery.js';\nimport { StreamingJSONLParser } from '../../core/performance/streaming-jsonl-parser.js';\nimport { ContextCache } from '../../core/performance/context-cache.js';\n\nexport type TaskStatus =\n | 'pending'\n | 'in_progress'\n | 'completed'\n | 'blocked'\n | 'cancelled';\nexport type TaskPriority = 'low' | 'medium' | 'high' | 'urgent';\n\nexport interface PebblesTask {\n id: string; // Content-hash based (merge-friendly)\n type: 'task_create' | 'task_update' | 'task_complete' | 'task_block';\n timestamp: number;\n parent_id?: string; // For subtasks\n frame_id: string; // Associated call stack frame\n\n // Task data\n title: string;\n description?: string;\n status: TaskStatus;\n priority: TaskPriority;\n assignee?: string;\n\n // Tracking\n created_at: number;\n started_at?: number;\n completed_at?: number;\n estimated_effort?: number; // Minutes\n actual_effort?: number;\n\n // Relationships\n depends_on: string[]; // Task IDs\n blocks: string[]; // Task IDs this blocks\n tags: string[]; // For filtering\n\n // Integration hooks (for Linear phase)\n external_refs?: {\n linear?: { id: string; url: string };\n github?: { issue: number; url: string };\n };\n\n // Context relevance\n context_score?: number; // For intelligent assembly\n last_accessed?: number;\n}\n\nexport interface TaskMetrics {\n total_tasks: number;\n by_status: Record<TaskStatus, number>;\n by_priority: Record<TaskPriority, number>;\n completion_rate: number;\n avg_effort_accuracy: number;\n blocked_tasks: number;\n overdue_tasks: number;\n}\n\nexport class PebblesTaskStore extends EventEmitter {\n private db: Database.Database;\n private projectRoot: string;\n private tasksFile: string;\n private cacheFile: string;\n private jsonlParser: StreamingJSONLParser;\n private taskCache: ContextCache<PebblesTask>;\n\n constructor(projectRoot: string, db: Database.Database) {\n super();\n this.projectRoot = projectRoot;\n this.db = db;\n\n // Ensure .stackmemory directory exists\n const stackmemoryDir = join(projectRoot, '.stackmemory');\n if (!existsSync(stackmemoryDir)) {\n mkdirSync(stackmemoryDir, { recursive: true });\n }\n\n this.tasksFile = join(stackmemoryDir, 'tasks.jsonl');\n this.cacheFile = join(stackmemoryDir, 'cache.db');\n\n // Initialize performance optimizations\n this.jsonlParser = new StreamingJSONLParser();\n this.taskCache = new ContextCache<PebblesTask>({\n maxSize: 10 * 1024 * 1024, // 10MB for tasks\n maxItems: 1000,\n defaultTTL: 3600000, // 1 hour\n });\n\n this.initializeCache();\n // Load existing tasks from JSONL synchronously\n this.loadFromJSONLSync();\n }\n\n private initializeCache() {\n const errorHandler = createErrorHandler({\n operation: 'initializeCache',\n projectRoot: this.projectRoot,\n });\n\n try {\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS task_cache (\n id TEXT PRIMARY KEY,\n type TEXT NOT NULL,\n timestamp INTEGER NOT NULL,\n parent_id TEXT,\n frame_id TEXT NOT NULL,\n title TEXT NOT NULL,\n description TEXT,\n status TEXT NOT NULL,\n priority TEXT NOT NULL,\n assignee TEXT,\n created_at INTEGER NOT NULL,\n started_at INTEGER,\n completed_at INTEGER,\n estimated_effort INTEGER,\n actual_effort INTEGER,\n depends_on TEXT DEFAULT '[]',\n blocks TEXT DEFAULT '[]',\n tags TEXT DEFAULT '[]',\n external_refs TEXT DEFAULT '{}',\n context_score REAL DEFAULT 0.5,\n last_accessed INTEGER\n );\n \n CREATE INDEX IF NOT EXISTS idx_task_status ON task_cache(status);\n CREATE INDEX IF NOT EXISTS idx_task_priority ON task_cache(priority);\n CREATE INDEX IF NOT EXISTS idx_task_frame ON task_cache(frame_id);\n CREATE INDEX IF NOT EXISTS idx_task_timestamp ON task_cache(timestamp);\n CREATE INDEX IF NOT EXISTS idx_task_parent ON task_cache(parent_id);\n `);\n } catch (error: unknown) {\n const dbError = errorHandler(error, {\n operation: 'initializeCache',\n schema: 'task_cache',\n });\n\n throw new DatabaseError(\n 'Failed to initialize task cache schema',\n ErrorCode.DB_MIGRATION_FAILED,\n {\n projectRoot: this.projectRoot,\n cacheFile: this.cacheFile,\n operation: 'initializeCache',\n },\n error instanceof Error ? error : undefined\n );\n }\n }\n\n /**\n * Load existing tasks from JSONL into SQLite cache (optimized)\n */\n private async loadFromJSONL() {\n if (!existsSync(this.tasksFile)) return;\n\n const errorHandler = createErrorHandler({\n operation: 'loadFromJSONL',\n tasksFile: this.tasksFile,\n });\n\n try {\n let loaded = 0;\n let errors = 0;\n\n // Use streaming parser for memory efficiency\n for await (const batch of this.jsonlParser.parseStream<PebblesTask>(\n this.tasksFile,\n {\n batchSize: 100,\n filter: (obj) => obj.type && obj.id && obj.title, // Basic validation\n onProgress: (count) => {\n if (count % 500 === 0) {\n logger.debug('Loading tasks progress', { loaded: count });\n }\n },\n }\n )) {\n for (const task of batch) {\n try {\n this.upsertToCache(task);\n // Add to in-memory cache for fast access\n this.taskCache.set(task.id, task, {\n ttl: 3600000, // 1 hour cache\n });\n loaded++;\n } catch (error: unknown) {\n errors++;\n logger.warn('Failed to cache task', {\n taskId: task.id,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n }\n\n logger.info('Loaded tasks from JSONL', {\n loaded,\n errors,\n file: this.tasksFile,\n cacheStats: this.taskCache.getStats(),\n });\n } catch (error: unknown) {\n const systemError = errorHandler(error, {\n operation: 'loadFromJSONL',\n file: this.tasksFile,\n });\n\n throw new SystemError(\n 'Failed to load tasks from JSONL file',\n ErrorCode.INTERNAL_ERROR,\n {\n tasksFile: this.tasksFile,\n operation: 'loadFromJSONL',\n },\n error instanceof Error ? error : undefined\n );\n }\n }\n\n /**\n * Load existing tasks from JSONL synchronously (for constructor)\n */\n private loadFromJSONLSync() {\n if (!existsSync(this.tasksFile)) return;\n\n try {\n const content = readFileSync(this.tasksFile, 'utf-8');\n const lines = content.split('\\n').filter((line) => line.trim());\n\n let loaded = 0;\n let errors = 0;\n\n for (const line of lines) {\n try {\n const task = JSON.parse(line) as PebblesTask;\n\n // Basic validation\n if (task.type && task.id && task.title) {\n this.upsertToCache(task);\n // Add to in-memory cache for fast access\n this.taskCache.set(task.id, task, {\n ttl: 3600000, // 1 hour cache\n });\n loaded++;\n }\n } catch (error: unknown) {\n errors++;\n logger.warn('Failed to parse JSONL line', {\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n logger.info('Loaded tasks from JSONL', {\n loaded,\n errors,\n file: this.tasksFile,\n });\n } catch (error: unknown) {\n logger.error('Failed to load tasks from JSONL', error as Error);\n }\n }\n\n /**\n * Create a new task with content-hash ID\n */\n public createTask(options: {\n title: string;\n description?: string;\n priority?: TaskPriority;\n frameId: string;\n parentId?: string;\n dependsOn?: string[];\n tags?: string[];\n estimatedEffort?: number;\n assignee?: string;\n }): string {\n const now = Math.floor(Date.now() / 1000);\n\n // Create content for hash (ensures deterministic ID)\n const content = `${options.title}:${options.frameId}:${now}:${Math.random()}`;\n const id = this.generateTaskId(content);\n\n const task: PebblesTask = {\n id,\n type: 'task_create',\n timestamp: now,\n parent_id: options.parentId,\n frame_id: options.frameId,\n title: options.title,\n description: options.description,\n status: 'pending',\n priority: options.priority || 'medium',\n assignee: options.assignee,\n created_at: now,\n estimated_effort: options.estimatedEffort,\n depends_on: options.dependsOn || [],\n blocks: [],\n tags: options.tags || [],\n context_score: 0.5,\n };\n\n this.appendTask(task);\n this.emit('task:created', task);\n this.emit('sync:needed', 'task:created');\n return id;\n }\n\n /**\n * Update task status with new event\n */\n public updateTaskStatus(\n taskId: string,\n newStatus: TaskStatus,\n _reason?: string\n ): void {\n const existing = this.getTask(taskId);\n if (!existing) {\n throw new TaskError(\n `Task not found: ${taskId}`,\n ErrorCode.TASK_NOT_FOUND,\n {\n taskId,\n newStatus,\n operation: 'updateTaskStatus',\n }\n );\n }\n\n // Validate status transition\n if (existing.status === 'completed' && newStatus !== 'cancelled') {\n throw new TaskError(\n `Cannot change completed task status from ${existing.status} to ${newStatus}`,\n ErrorCode.TASK_INVALID_STATE,\n {\n taskId,\n currentStatus: existing.status,\n newStatus,\n operation: 'updateTaskStatus',\n }\n );\n }\n\n const now = Math.floor(Date.now() / 1000);\n const updates: Partial<PebblesTask> = {\n status: newStatus,\n timestamp: now,\n };\n\n // Automatic time tracking\n if (newStatus === 'in_progress' && existing.status === 'pending') {\n updates.started_at = now;\n updates.type = 'task_update';\n } else if (newStatus === 'completed' && existing.status === 'in_progress') {\n updates.completed_at = now;\n updates.type = 'task_complete';\n if (existing.started_at) {\n updates.actual_effort = Math.floor((now - existing.started_at) / 60); // Minutes\n }\n } else if (newStatus === 'blocked') {\n updates.type = 'task_block';\n }\n\n const updatedTask: PebblesTask = { ...existing, ...updates };\n this.appendTask(updatedTask);\n \n if (newStatus === 'completed') {\n this.emit('task:completed', updatedTask);\n }\n this.emit('sync:needed', 'task:updated');\n }\n\n /**\n * Add dependency relationship\n */\n public addDependency(taskId: string, dependsOnId: string): void {\n const task = this.getTask(taskId);\n const dependsOnTask = this.getTask(dependsOnId);\n\n if (!task) {\n throw new TaskError(\n `Task not found: ${taskId}`,\n ErrorCode.TASK_NOT_FOUND,\n {\n taskId,\n operation: 'addDependency',\n }\n );\n }\n\n if (!dependsOnTask) {\n throw new TaskError(\n `Dependency task not found: ${dependsOnId}`,\n ErrorCode.TASK_NOT_FOUND,\n {\n dependsOnId,\n taskId,\n operation: 'addDependency',\n }\n );\n }\n\n // Check for circular dependency\n if (this.wouldCreateCircularDependency(taskId, dependsOnId)) {\n throw new TaskError(\n `Adding dependency would create circular dependency: ${taskId} -> ${dependsOnId}`,\n ErrorCode.TASK_CIRCULAR_DEPENDENCY,\n {\n taskId,\n dependsOnId,\n operation: 'addDependency',\n }\n );\n }\n\n // Update task dependencies\n const updatedTask: PebblesTask = {\n ...task,\n depends_on: [...new Set([...task.depends_on, dependsOnId])],\n timestamp: Math.floor(Date.now() / 1000),\n type: 'task_update',\n };\n\n // Update blocking task\n const updatedBlockingTask: PebblesTask = {\n ...dependsOnTask,\n blocks: [...new Set([...dependsOnTask.blocks, taskId])],\n timestamp: Math.floor(Date.now() / 1000),\n type: 'task_update',\n };\n\n this.appendTask(updatedTask);\n this.appendTask(updatedBlockingTask);\n }\n\n /**\n * Get current active tasks\n */\n public getActiveTasks(frameId?: string): PebblesTask[] {\n try {\n let query = `\n SELECT * FROM task_cache \n WHERE status IN ('pending', 'in_progress')\n `;\n const params: any[] = [];\n\n if (frameId) {\n query += ` AND frame_id = ?`;\n params.push(frameId);\n }\n\n query += ` ORDER BY priority DESC, created_at ASC`;\n\n const rows = this.db.prepare(query).all(...params) as any[];\n return this.hydrateTasks(rows);\n } catch (error: unknown) {\n throw new DatabaseError(\n 'Failed to get active tasks',\n ErrorCode.DB_QUERY_FAILED,\n {\n frameId,\n operation: 'getActiveTasks',\n },\n error instanceof Error ? error : undefined\n );\n }\n }\n\n /**\n * Get task by ID (latest version)\n */\n public getTask(taskId: string): PebblesTask | undefined {\n try {\n const row = this.db\n .prepare(\n `\n SELECT * FROM task_cache WHERE id = ?\n `\n )\n .get(taskId) as any;\n\n return row ? this.hydrateTask(row) : undefined;\n } catch (error: unknown) {\n throw new DatabaseError(\n `Failed to get task: ${taskId}`,\n ErrorCode.DB_QUERY_FAILED,\n {\n taskId,\n operation: 'getTask',\n },\n error instanceof Error ? error : undefined\n );\n }\n }\n\n /**\n * Get tasks that are blocking other tasks\n */\n public getBlockingTasks(): PebblesTask[] {\n try {\n const rows = this.db\n .prepare(\n `\n SELECT * FROM task_cache \n WHERE JSON_ARRAY_LENGTH(blocks) > 0 \n AND status NOT IN ('completed', 'cancelled')\n ORDER BY priority DESC\n `\n )\n .all() as any[];\n\n return this.hydrateTasks(rows);\n } catch (error: unknown) {\n throw new DatabaseError(\n 'Failed to get blocking tasks',\n ErrorCode.DB_QUERY_FAILED,\n {\n operation: 'getBlockingTasks',\n },\n error instanceof Error ? error : undefined\n );\n }\n }\n\n /**\n * Get metrics for current project\n */\n public getMetrics(): TaskMetrics {\n try {\n const statusCounts = this.db\n .prepare(\n `\n SELECT status, COUNT(*) as count \n FROM task_cache \n GROUP BY status\n `\n )\n .all() as { status: TaskStatus; count: number }[];\n\n const priorityCounts = this.db\n .prepare(\n `\n SELECT priority, COUNT(*) as count \n FROM task_cache \n GROUP BY priority \n `\n )\n .all() as { priority: TaskPriority; count: number }[];\n\n const totalTasks = statusCounts.reduce((sum, s) => sum + s.count, 0);\n const completedTasks =\n statusCounts.find((s) => s.status === 'completed')?.count || 0;\n const blockedTasks =\n statusCounts.find((s) => s.status === 'blocked')?.count || 0;\n\n // Calculate effort accuracy\n const effortRows = this.db\n .prepare(\n `\n SELECT estimated_effort, actual_effort \n FROM task_cache \n WHERE estimated_effort IS NOT NULL \n AND actual_effort IS NOT NULL\n `\n )\n .all() as { estimated_effort: number; actual_effort: number }[];\n\n let avgEffortAccuracy = 0;\n if (effortRows.length > 0) {\n const accuracies = effortRows.map(\n (r) =>\n 1 -\n Math.abs(r.estimated_effort - r.actual_effort) /\n Math.max(r.estimated_effort, 1)\n );\n avgEffortAccuracy =\n accuracies.reduce((sum, acc) => sum + acc, 0) / accuracies.length;\n }\n\n return {\n total_tasks: totalTasks,\n by_status: Object.fromEntries(\n statusCounts.map((s) => [s.status, s.count])\n ) as any,\n by_priority: Object.fromEntries(\n priorityCounts.map((p) => [p.priority, p.count])\n ) as any,\n completion_rate: totalTasks > 0 ? completedTasks / totalTasks : 0,\n avg_effort_accuracy: avgEffortAccuracy,\n blocked_tasks: blockedTasks,\n overdue_tasks: 0, // TODO: implement due dates\n };\n } catch (error: unknown) {\n throw new DatabaseError(\n 'Failed to get task metrics',\n ErrorCode.DB_QUERY_FAILED,\n {\n operation: 'getMetrics',\n },\n error instanceof Error ? error : undefined\n );\n }\n }\n\n /**\n * Export tasks for Linear integration (Phase 2)\n */\n public exportForLinear(): Array<{\n title: string;\n description?: string;\n priority: number;\n status: string;\n estimate?: number;\n dependencies: string[];\n }> {\n const tasks = this.db\n .prepare(\n `\n SELECT * FROM task_cache \n WHERE external_refs IS NULL OR JSON_EXTRACT(external_refs, '$.linear') IS NULL\n ORDER BY created_at ASC\n `\n )\n .all() as any[];\n\n return tasks.map((task) => ({\n title: task.title,\n description: task.description,\n priority: this.mapPriorityToLinear(task.priority),\n status: this.mapStatusToLinear(task.status),\n estimate: task.estimated_effort,\n dependencies: JSON.parse(task.depends_on || '[]'),\n }));\n }\n\n // Private methods\n private appendTask(task: PebblesTask) {\n try {\n // Append to JSONL file (git-tracked source of truth)\n const jsonLine = JSON.stringify(task) + '\\n';\n appendFile(this.tasksFile, jsonLine, (err) => {\n if (err) {\n logger.error(\n `Failed to append task ${task.id} to JSONL: ${err.message}`,\n err,\n {\n taskId: task.id,\n tasksFile: this.tasksFile,\n }\n );\n }\n });\n\n // Update SQLite cache (for fast queries) with retry logic\n retry(() => Promise.resolve(this.upsertToCache(task)), {\n maxAttempts: 3,\n initialDelay: 100,\n onRetry: (attempt, error) => {\n logger.warn(`Retrying task cache upsert (attempt ${attempt})`, {\n taskId: task.id,\n errorMessage:\n error instanceof Error ? error.message : String(error),\n });\n },\n }).catch((error) => {\n logger.error(\n 'Failed to upsert task to cache after retries',\n error instanceof Error ? error : new Error(String(error)),\n {\n taskId: task.id,\n }\n );\n throw error;\n });\n\n logger.info('Appended task', {\n id: task.id,\n type: task.type,\n title: task.title,\n status: task.status,\n });\n } catch (error: unknown) {\n throw new SystemError(\n `Failed to append task: ${task.id}`,\n ErrorCode.INTERNAL_ERROR,\n {\n taskId: task.id,\n operation: 'appendTask',\n },\n error instanceof Error ? error : undefined\n );\n }\n }\n\n private upsertToCache(task: PebblesTask) {\n try {\n this.db\n .prepare(\n `\n INSERT OR REPLACE INTO task_cache (\n id, type, timestamp, parent_id, frame_id, title, description,\n status, priority, assignee, created_at, started_at, completed_at,\n estimated_effort, actual_effort, depends_on, blocks, tags,\n external_refs, context_score, last_accessed\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n `\n )\n .run(\n task.id,\n task.type,\n task.timestamp,\n task.parent_id,\n task.frame_id,\n task.title,\n task.description,\n task.status,\n task.priority,\n task.assignee,\n task.created_at,\n task.started_at,\n task.completed_at,\n task.estimated_effort,\n task.actual_effort,\n JSON.stringify(task.depends_on),\n JSON.stringify(task.blocks),\n JSON.stringify(task.tags),\n JSON.stringify(task.external_refs || {}),\n task.context_score,\n task.last_accessed\n );\n } catch (error: unknown) {\n throw new DatabaseError(\n `Failed to upsert task to cache: ${task.id}`,\n ErrorCode.DB_QUERY_FAILED,\n {\n taskId: task.id,\n taskTitle: task.title,\n operation: 'upsertToCache',\n },\n error instanceof Error ? error : undefined\n );\n }\n }\n\n private generateTaskId(content: string): string {\n const hash = createHash('sha256').update(content).digest('hex');\n return `tsk-${hash.substring(0, 8)}`;\n }\n\n private hydrateTask = (row: any): PebblesTask => ({\n ...row,\n depends_on: JSON.parse(row.depends_on || '[]'),\n blocks: JSON.parse(row.blocks || '[]'),\n tags: JSON.parse(row.tags || '[]'),\n external_refs: JSON.parse(row.external_refs || '{}'),\n });\n\n private hydrateTasks(rows: any[]): PebblesTask[] {\n return rows.map(this.hydrateTask);\n }\n\n private mapPriorityToLinear(priority: TaskPriority): number {\n const map = { low: 1, medium: 2, high: 3, urgent: 4 };\n return map[priority] || 2;\n }\n\n private mapStatusToLinear(status: TaskStatus): string {\n const map = {\n pending: 'Backlog',\n in_progress: 'In Progress',\n completed: 'Done',\n blocked: 'Blocked',\n cancelled: 'Cancelled',\n };\n return map[status] || 'Backlog';\n }\n\n /**\n * Check if adding a dependency would create a circular dependency\n */\n private wouldCreateCircularDependency(\n taskId: string,\n dependsOnId: string\n ): boolean {\n const visited = new Set<string>();\n const stack = [dependsOnId];\n\n while (stack.length > 0) {\n const currentId = stack.pop()!;\n\n if (currentId === taskId) {\n return true; // Found circular dependency\n }\n\n if (visited.has(currentId)) {\n continue;\n }\n\n visited.add(currentId);\n\n // Get dependencies of current task\n const currentTask = this.getTask(currentId);\n if (currentTask) {\n stack.push(...currentTask.depends_on);\n }\n }\n\n return false;\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/features/tui/components/analytics-panel.ts"],
4
- "sourcesContent": ["/**\n * Analytics Panel Component\n * Real-time charts and metrics visualization\n */\n\nimport contrib from 'blessed-contrib';\nimport { EventEmitter } from 'events';\nimport type { AnalyticsData } from '../types.js';\n\nexport class AnalyticsPanel extends EventEmitter {\n private line: any; // contrib.line type\n private currentMetric: 'tokens' | 'velocity' | 'quality' | 'performance' = 'tokens';\n private data: AnalyticsData | null = null;\n\n constructor(line: any) {\n super();\n this.line = line;\n this.initializeUI();\n }\n\n private initializeUI(): void {\n // Cycle through metrics\n this.line.screen.key(['m'], () => {\n this.cycleMetric();\n });\n\n // Set initial display\n this.showTokenUsage();\n }\n\n private cycleMetric(): void {\n const metrics: Array<typeof this.currentMetric> = ['tokens', 'velocity', 'quality', 'performance'];\n const currentIndex = metrics.indexOf(this.currentMetric);\n this.currentMetric = metrics[(currentIndex + 1) % metrics.length];\n \n switch (this.currentMetric) {\n case 'tokens':\n this.showTokenUsage();\n break;\n case 'velocity':\n this.showVelocity();\n break;\n case 'quality':\n this.showQuality();\n break;\n case 'performance':\n this.showPerformance();\n break;\n }\n }\n\n private showTokenUsage(): void {\n if (!this.data) return;\n \n const data = [{\n title: 'Token Usage',\n x: this.data.tokens.labels.map((_, i) => i.toString()),\n y: this.data.tokens.values,\n style: { line: 'yellow' }\n }];\n \n this.line.setData(data);\n if (typeof this.line.setLabel === 'function') {\n this.line.setLabel(' \uD83D\uDCC8 Analytics - Token Usage [m] cycle ');\n }\n this.line.screen.render();\n }\n\n private showVelocity(): void {\n if (!this.data) return;\n \n const data = [{\n title: 'Task Velocity',\n x: this.data.tasks.velocity.map((_, i) => `Sprint ${i + 1}`),\n y: this.data.tasks.velocity,\n style: { line: 'green' }\n }];\n \n this.line.setData(data);\n if (typeof this.line.setLabel === 'function') {\n this.line.setLabel(' \uD83D\uDCC8 Analytics - Task Velocity [m] cycle ');\n }\n this.line.screen.render();\n }\n\n private showQuality(): void {\n if (!this.data) return;\n \n const data = [\n {\n title: 'Tests Passed',\n x: ['1', '2', '3', '4', '5'],\n y: [this.data.quality.testsPassed, this.data.quality.testsPassed, this.data.quality.testsPassed, this.data.quality.testsPassed, this.data.quality.testsPassed],\n style: { line: 'green' }\n },\n {\n title: 'Coverage %',\n x: ['1', '2', '3', '4', '5'],\n y: [this.data.quality.coverage, this.data.quality.coverage, this.data.quality.coverage, this.data.quality.coverage, this.data.quality.coverage],\n style: { line: 'blue' }\n }\n ];\n \n this.line.setData(data);\n if (typeof this.line.setLabel === 'function') {\n this.line.setLabel(' \uD83D\uDCC8 Analytics - Code Quality [m] cycle ');\n }\n this.line.screen.render();\n }\n\n private showPerformance(): void {\n if (!this.data) return;\n \n const data = [\n {\n title: 'Response Time (ms)',\n x: this.data.performance.avgResponseTime.map((_, i) => i.toString()),\n y: this.data.performance.avgResponseTime,\n style: { line: 'cyan' }\n },\n {\n title: 'Error Rate (%)',\n x: this.data.performance.errorRate.map((_, i) => i.toString()),\n y: this.data.performance.errorRate.map(r => r * 100),\n style: { line: 'red' }\n }\n ];\n \n this.line.setData(data);\n if (typeof this.line.setLabel === 'function') {\n this.line.setLabel(' \uD83D\uDCC8 Analytics - Performance [m] cycle ');\n }\n this.line.screen.render();\n }\n\n public update(data: AnalyticsData): void {\n this.data = data;\n \n // Refresh current view\n switch (this.currentMetric) {\n case 'tokens':\n this.showTokenUsage();\n break;\n case 'velocity':\n this.showVelocity();\n break;\n case 'quality':\n this.showQuality();\n break;\n case 'performance':\n this.showPerformance();\n break;\n }\n }\n\n public focus(): void {\n // Line chart doesn't have traditional focus\n this.emit('focused');\n }\n\n public hasFocus(): boolean {\n return false; // Line charts don't take focus\n }\n}"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * Analytics Panel Component\n * Real-time charts and metrics visualization\n */\n\nimport contrib from 'blessed-contrib';\nimport { EventEmitter } from 'events';\nimport type { AnalyticsData } from '../types.js';\n\nexport class AnalyticsPanel extends EventEmitter {\n private line: any; // contrib.line type\n private currentMetric: 'tokens' | 'velocity' | 'quality' | 'performance' = 'tokens';\n private data: AnalyticsData | null = null;\n\n constructor(line: any) {\n super();\n this.line = line;\n this.initializeUI();\n }\n\n private initializeUI(): void {\n // Cycle through metrics\n this.line.screen.key(['m'], () => {\n this.cycleMetric();\n });\n\n // Set initial display\n this.showTokenUsage();\n }\n\n private cycleMetric(): void {\n const metrics: Array<typeof this.currentMetric> = ['tokens', 'velocity', 'quality', 'performance'];\n const currentIndex = metrics.indexOf(this.currentMetric);\n this.currentMetric = metrics[(currentIndex + 1) % metrics.length];\n \n switch (this.currentMetric) {\n case 'tokens':\n this.showTokenUsage();\n break;\n case 'velocity':\n this.showVelocity();\n break;\n case 'quality':\n this.showQuality();\n break;\n case 'performance':\n this.showPerformance();\n break;\n }\n }\n\n private showTokenUsage(): void {\n if (!this.data) return;\n \n const data = [{\n title: 'Token Usage',\n x: this.data.tokens.labels.map((_, i) => i.toString()),\n y: this.data.tokens.values,\n style: { line: 'yellow' }\n }];\n \n this.line.setData(data);\n if (typeof this.line.setLabel === 'function') {\n this.line.setLabel(' \uD83D\uDCC8 Analytics - Token Usage [m] cycle ');\n }\n this.line.screen.render();\n }\n\n private showVelocity(): void {\n if (!this.data) return;\n \n const data = [{\n title: 'Task Velocity',\n x: this.data.tasks.velocity.map((_, i) => `Sprint ${i + 1}`),\n y: this.data.tasks.velocity,\n style: { line: 'green' }\n }];\n \n this.line.setData(data);\n if (typeof this.line.setLabel === 'function') {\n this.line.setLabel(' \uD83D\uDCC8 Analytics - Task Velocity [m] cycle ');\n }\n this.line.screen.render();\n }\n\n private showQuality(): void {\n if (!this.data) return;\n \n const data = [\n {\n title: 'Tests Passed',\n x: ['1', '2', '3', '4', '5'],\n y: [this.data.quality.testsPassed, this.data.quality.testsPassed, this.data.quality.testsPassed, this.data.quality.testsPassed, this.data.quality.testsPassed],\n style: { line: 'green' }\n },\n {\n title: 'Coverage %',\n x: ['1', '2', '3', '4', '5'],\n y: [this.data.quality.coverage, this.data.quality.coverage, this.data.quality.coverage, this.data.quality.coverage, this.data.quality.coverage],\n style: { line: 'blue' }\n }\n ];\n \n this.line.setData(data);\n if (typeof this.line.setLabel === 'function') {\n this.line.setLabel(' \uD83D\uDCC8 Analytics - Code Quality [m] cycle ');\n }\n this.line.screen.render();\n }\n\n private showPerformance(): void {\n if (!this.data) return;\n \n const data = [\n {\n title: 'Response Time (ms)',\n x: this.data.performance.avgResponseTime.map((_, i) => i.toString()),\n y: this.data.performance.avgResponseTime,\n style: { line: 'cyan' }\n },\n {\n title: 'Error Rate (%)',\n x: this.data.performance.errorRate.map((_, i) => i.toString()),\n y: this.data.performance.errorRate.map((r: any) => r * 100),\n style: { line: 'red' }\n }\n ];\n \n this.line.setData(data);\n if (typeof this.line.setLabel === 'function') {\n this.line.setLabel(' \uD83D\uDCC8 Analytics - Performance [m] cycle ');\n }\n this.line.screen.render();\n }\n\n public update(data: AnalyticsData): void {\n this.data = data;\n \n // Refresh current view\n switch (this.currentMetric) {\n case 'tokens':\n this.showTokenUsage();\n break;\n case 'velocity':\n this.showVelocity();\n break;\n case 'quality':\n this.showQuality();\n break;\n case 'performance':\n this.showPerformance();\n break;\n }\n }\n\n public focus(): void {\n // Line chart doesn't have traditional focus\n this.emit('focused');\n }\n\n public hasFocus(): boolean {\n return false; // Line charts don't take focus\n }\n}"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/features/tui/components/pr-tracker.ts"],
4
- "sourcesContent": ["/**\n * PR/Issue Tracker Component\n * Displays GitHub PRs and issues with status indicators\n */\n\nimport blessed from 'blessed';\nimport { EventEmitter } from 'events';\nimport type { PRData, IssueData } from '../types.js';\n\nexport class PRTracker extends EventEmitter {\n private list: blessed.Widgets.ListElement;\n private prs: Map<string, PRData>;\n private issues: Map<string, IssueData>;\n private selectedItem: string | null = null;\n private viewMode: 'prs' | 'issues' = 'prs';\n\n constructor(list: blessed.Widgets.ListElement) {\n super();\n this.list = list;\n this.prs = new Map();\n this.issues = new Map();\n this.initializeUI();\n }\n\n private initializeUI(): void {\n this.list.on('select', (item, index) => {\n if (this.viewMode === 'prs') {\n const prId = Array.from(this.prs.keys())[index];\n this.selectPR(prId);\n } else {\n const issueId = Array.from(this.issues.keys())[index];\n this.selectIssue(issueId);\n }\n });\n\n // Toggle between PRs and Issues\n this.list.key(['tab'], () => {\n this.toggleView();\n });\n }\n\n private formatPRItem(pr: PRData): string {\n const status = this.getPRStatusIcon(pr);\n const checks = this.getChecksStatus(pr.checks);\n const reviews = this.getReviewStatus(pr.reviews);\n \n let item = `${status} #${pr.number}: ${pr.title}\\n`;\n item += ` {gray-fg}@${pr.author.login} | ${checks} | ${reviews} | +${pr.additions}/-${pr.deletions}{/}`;\n \n if (pr.linkedIssues?.length) {\n item += ` | {cyan-fg}\uD83D\uDD17${pr.linkedIssues.length}{/}`;\n }\n \n return item;\n }\n\n private formatIssueItem(issue: IssueData): string {\n const status = issue.state === 'open' ? '{green-fg}\u25CF{/}' : '{gray-fg}\u25CF{/}';\n const assignees = issue.assignees?.map(a => `@${a}`).join(', ') || 'unassigned';\n \n let item = `${status} #${issue.number}: ${issue.title}\\n`;\n item += ` {gray-fg}@${issue.author.login} | ${assignees} | \uD83D\uDCAC${issue.comments}{/}`;\n \n return item;\n }\n\n private getPRStatusIcon(pr: PRData): string {\n if (pr.state === 'merged') return '{magenta-fg}\u2B24{/}';\n if (pr.state === 'closed') return '{red-fg}\u2B24{/}';\n if (pr.draft) return '{gray-fg}\u25CB{/}';\n return '{green-fg}\u25CF{/}';\n }\n\n private getChecksStatus(checks?: PRData['checks']): string {\n if (!checks) return '{gray-fg}no checks{/}';\n if (checks.failed > 0) return `{red-fg}\u2717 ${checks.failed}/${checks.total}{/}`;\n if (checks.pending > 0) return `{yellow-fg}\u23F3 ${checks.pending}/${checks.total}{/}`;\n return `{green-fg}\u2713 ${checks.passed}/${checks.total}{/}`;\n }\n\n private getReviewStatus(reviews: PRData['reviews']): string {\n const approved = reviews.filter(r => r.state === 'approved').length;\n const changes = reviews.filter(r => r.state === 'changes_requested').length;\n \n if (changes > 0) return `{red-fg}\uD83D\uDC4E${changes}{/}`;\n if (approved > 0) return `{green-fg}\uD83D\uDC4D${approved}{/}`;\n return '{gray-fg}no reviews{/}';\n }\n\n public update(data: { prs?: PRData[], issues?: IssueData[] }): void {\n if (data.prs) {\n this.prs.clear();\n data.prs.forEach(pr => this.prs.set(pr.id, pr));\n }\n \n if (data.issues) {\n this.issues.clear();\n data.issues.forEach(issue => this.issues.set(issue.id, issue));\n }\n \n this.refreshDisplay();\n }\n\n private refreshDisplay(): void {\n let items: string[] = [];\n let label = '';\n \n if (this.viewMode === 'prs') {\n items = Array.from(this.prs.values()).map(pr => this.formatPRItem(pr));\n const open = Array.from(this.prs.values()).filter(pr => pr.state === 'open').length;\n label = ` \uD83D\uDD00 Pull Requests (${open}/${this.prs.size}) [Tab] Issues `;\n } else {\n items = Array.from(this.issues.values()).map(issue => this.formatIssueItem(issue));\n const open = Array.from(this.issues.values()).filter(i => i.state === 'open').length;\n label = ` \uD83D\uDC1B Issues (${open}/${this.issues.size}) [Tab] PRs `;\n }\n \n this.list.setItems(items);\n if (this.list.parent && typeof (this.list.parent as any).setLabel === 'function') {\n (this.list.parent as any).setLabel(label);\n }\n \n this.list.screen.render();\n }\n\n private toggleView(): void {\n this.viewMode = this.viewMode === 'prs' ? 'issues' : 'prs';\n this.refreshDisplay();\n }\n\n private selectPR(prId: string): void {\n const pr = this.prs.get(prId);\n if (pr) {\n this.emit('pr:selected', pr);\n }\n }\n\n private selectIssue(issueId: string): void {\n const issue = this.issues.get(issueId);\n if (issue) {\n this.emit('issue:selected', issue);\n }\n }\n\n public focus(): void {\n this.list.focus();\n }\n\n public hasFocus(): boolean {\n return this.list === this.list.screen.focused;\n }\n}"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * PR/Issue Tracker Component\n * Displays GitHub PRs and issues with status indicators\n */\n\nimport blessed from 'blessed';\nimport { EventEmitter } from 'events';\nimport type { PRData, IssueData } from '../types.js';\n\nexport class PRTracker extends EventEmitter {\n private list: blessed.Widgets.ListElement;\n private prs: Map<string, PRData>;\n private issues: Map<string, IssueData>;\n private selectedItem: string | null = null;\n private viewMode: 'prs' | 'issues' = 'prs';\n\n constructor(list: blessed.Widgets.ListElement) {\n super();\n this.list = list;\n this.prs = new Map();\n this.issues = new Map();\n this.initializeUI();\n }\n\n private initializeUI(): void {\n this.list.on('select', (item, index) => {\n if (this.viewMode === 'prs') {\n const prId = Array.from(this.prs.keys())[index];\n this.selectPR(prId);\n } else {\n const issueId = Array.from(this.issues.keys())[index];\n this.selectIssue(issueId);\n }\n });\n\n // Toggle between PRs and Issues\n this.list.key(['tab'], () => {\n this.toggleView();\n });\n }\n\n private formatPRItem(pr: PRData): string {\n const status = this.getPRStatusIcon(pr);\n const checks = this.getChecksStatus(pr.checks);\n const reviews = this.getReviewStatus(pr.reviews);\n \n let item = `${status} #${pr.number}: ${pr.title}\\n`;\n item += ` {gray-fg}@${pr.author.login} | ${checks} | ${reviews} | +${pr.additions}/-${pr.deletions}{/}`;\n \n if (pr.linkedIssues?.length) {\n item += ` | {cyan-fg}\uD83D\uDD17${pr.linkedIssues.length}{/}`;\n }\n \n return item;\n }\n\n private formatIssueItem(issue: IssueData): string {\n const status = issue.state === 'open' ? '{green-fg}\u25CF{/}' : '{gray-fg}\u25CF{/}';\n const assignees = issue.assignees?.map((a: any) => `@${a}`).join(', ') || 'unassigned';\n \n let item = `${status} #${issue.number}: ${issue.title}\\n`;\n item += ` {gray-fg}@${issue.author.login} | ${assignees} | \uD83D\uDCAC${issue.comments}{/}`;\n \n return item;\n }\n\n private getPRStatusIcon(pr: PRData): string {\n if (pr.state === 'merged') return '{magenta-fg}\u2B24{/}';\n if (pr.state === 'closed') return '{red-fg}\u2B24{/}';\n if (pr.draft) return '{gray-fg}\u25CB{/}';\n return '{green-fg}\u25CF{/}';\n }\n\n private getChecksStatus(checks?: PRData['checks']): string {\n if (!checks) return '{gray-fg}no checks{/}';\n if (checks.failed > 0) return `{red-fg}\u2717 ${checks.failed}/${checks.total}{/}`;\n if (checks.pending > 0) return `{yellow-fg}\u23F3 ${checks.pending}/${checks.total}{/}`;\n return `{green-fg}\u2713 ${checks.passed}/${checks.total}{/}`;\n }\n\n private getReviewStatus(reviews: PRData['reviews']): string {\n const approved = reviews.filter((r: any) => r.state === 'approved').length;\n const changes = reviews.filter((r: any) => r.state === 'changes_requested').length;\n \n if (changes > 0) return `{red-fg}\uD83D\uDC4E${changes}{/}`;\n if (approved > 0) return `{green-fg}\uD83D\uDC4D${approved}{/}`;\n return '{gray-fg}no reviews{/}';\n }\n\n public update(data: { prs?: PRData[], issues?: IssueData[] }): void {\n if (data.prs) {\n this.prs.clear();\n data.prs.forEach(pr => this.prs.set(pr.id, pr));\n }\n \n if (data.issues) {\n this.issues.clear();\n data.issues.forEach(issue => this.issues.set(issue.id, issue));\n }\n \n this.refreshDisplay();\n }\n\n private refreshDisplay(): void {\n let items: string[] = [];\n let label = '';\n \n if (this.viewMode === 'prs') {\n items = Array.from(this.prs.values()).map((pr: any) => this.formatPRItem(pr));\n const open = Array.from(this.prs.values()).filter((pr: any) => pr.state === 'open').length;\n label = ` \uD83D\uDD00 Pull Requests (${open}/${this.prs.size}) [Tab] Issues `;\n } else {\n items = Array.from(this.issues.values()).map((issue: any) => this.formatIssueItem(issue));\n const open = Array.from(this.issues.values()).filter((i: any) => i.state === 'open').length;\n label = ` \uD83D\uDC1B Issues (${open}/${this.issues.size}) [Tab] PRs `;\n }\n \n this.list.setItems(items);\n if (this.list.parent && typeof (this.list.parent as any).setLabel === 'function') {\n (this.list.parent as any).setLabel(label);\n }\n \n this.list.screen.render();\n }\n\n private toggleView(): void {\n this.viewMode = this.viewMode === 'prs' ? 'issues' : 'prs';\n this.refreshDisplay();\n }\n\n private selectPR(prId: string): void {\n const pr = this.prs.get(prId);\n if (pr) {\n this.emit('pr:selected', pr);\n }\n }\n\n private selectIssue(issueId: string): void {\n const issue = this.issues.get(issueId);\n if (issue) {\n this.emit('issue:selected', issue);\n }\n }\n\n public focus(): void {\n this.list.focus();\n }\n\n public hasFocus(): boolean {\n return this.list === this.list.screen.focused;\n }\n}"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/features/tui/components/session-monitor.ts"],
4
- "sourcesContent": ["/**\n * Session Monitor Component\n * Displays active sessions with auto-tagging based on work context\n */\n\nimport blessed from 'blessed';\nimport { EventEmitter } from 'events';\nimport type { SessionData, SessionMetrics } from '../types.js';\n\nexport class SessionMonitor extends EventEmitter {\n private container: blessed.Widgets.BoxElement;\n private sessionList: blessed.Widgets.ListElement;\n private sessions: Map<string, SessionData>;\n private selectedSession: string | null = null;\n\n constructor(container: blessed.Widgets.BoxElement) {\n super();\n this.container = container;\n this.sessions = new Map();\n this.initializeUI();\n }\n\n private initializeUI(): void {\n // Session list with auto-tagged names\n this.sessionList = blessed.list({\n parent: this.container,\n top: 0,\n left: 0,\n width: '100%',\n height: '100%-3',\n style: {\n selected: {\n bg: 'blue',\n fg: 'white',\n bold: true\n },\n item: {\n fg: 'cyan'\n }\n },\n mouse: true,\n keys: true,\n vi: true,\n scrollable: true,\n tags: true\n });\n\n // Summary footer\n const footer = blessed.box({\n parent: this.container,\n bottom: 0,\n left: 0,\n width: '100%',\n height: 3,\n content: 'Active: 0 | Idle: 0 | Total: 0',\n tags: true,\n style: {\n fg: 'white',\n bg: 'black'\n }\n });\n\n this.sessionList.on('select', (item, index) => {\n const sessionId = Array.from(this.sessions.keys())[index];\n this.selectSession(sessionId);\n });\n }\n\n /**\n * Auto-tag session based on work context\n */\n private autoTagSession(session: SessionData): string {\n const tags: string[] = [];\n \n // Analyze recent activities for context\n if (session.recentActivities) {\n // File-based tagging\n const files = session.recentActivities\n .filter(a => a.type === 'file_edit')\n .map(a => a.data?.path || '');\n \n if (files.some(f => f.includes('test'))) tags.push('testing');\n if (files.some(f => f.includes('.tsx') || f.includes('.jsx'))) tags.push('frontend');\n if (files.some(f => f.includes('api') || f.includes('server'))) tags.push('backend');\n if (files.some(f => f.includes('db') || f.includes('migration'))) tags.push('database');\n \n // Command-based tagging\n const commands = session.recentActivities\n .filter(a => a.type === 'command')\n .map(a => a.data?.command || '');\n \n if (commands.some(c => c.includes('npm test') || c.includes('jest'))) tags.push('testing');\n if (commands.some(c => c.includes('git'))) tags.push('git-ops');\n if (commands.some(c => c.includes('deploy'))) tags.push('deployment');\n if (commands.some(c => c.includes('debug'))) tags.push('debugging');\n }\n\n // Task-based tagging from Linear\n if (session.linearTask) {\n tags.push(`linear:${session.linearTask.identifier}`);\n if (session.linearTask.labels) {\n tags.push(...session.linearTask.labels.map(l => l.toLowerCase()));\n }\n }\n\n // Branch-based tagging\n if (session.gitBranch) {\n const branch = session.gitBranch;\n if (branch.includes('feature/')) tags.push('feature');\n if (branch.includes('fix/') || branch.includes('bugfix/')) tags.push('bugfix');\n if (branch.includes('refactor/')) tags.push('refactor');\n if (branch.includes('docs/')) tags.push('documentation');\n }\n\n // AI agent type tagging\n if (session.agentType) {\n tags.push(`agent:${session.agentType}`);\n }\n\n return tags.length > 0 ? tags.join(' \u2022 ') : 'general';\n }\n\n /**\n * Generate session display name with context\n */\n private generateSessionName(session: SessionData): string {\n const autoTags = this.autoTagSession(session);\n const timestamp = new Date(session.startTime).toLocaleTimeString();\n \n // Create descriptive name based on primary activity\n let primaryActivity = 'Session';\n \n if (session.linearTask) {\n primaryActivity = session.linearTask.title || session.linearTask.identifier;\n } else if (session.gitBranch && session.gitBranch !== 'main' && session.gitBranch !== 'master') {\n primaryActivity = session.gitBranch.split('/').pop() || session.gitBranch;\n } else if (session.primaryFile) {\n primaryActivity = session.primaryFile.split('/').pop() || 'Code';\n }\n\n return `${primaryActivity} [${autoTags}] - ${timestamp}`;\n }\n\n /**\n * Format session item for display\n */\n private formatSessionItem(session: SessionData): string {\n const status = this.getSessionStatus(session);\n const statusIcon = this.getStatusIcon(status);\n const name = this.generateSessionName(session);\n const metrics = this.getSessionMetrics(session);\n \n const contextUsage = Math.round(session.contextUsage * 100);\n const contextColor = contextUsage > 80 ? 'red' : contextUsage > 60 ? 'yellow' : 'green';\n \n return `${statusIcon} ${name}\\n` +\n ` {gray-fg}Tokens: ${metrics.tokens} | Context: {${contextColor}-fg}${contextUsage}%{/} | Duration: ${metrics.duration}{/}`;\n }\n\n private getSessionStatus(session: SessionData): 'active' | 'idle' | 'completed' | 'error' {\n if (session.error) return 'error';\n if (session.completed) return 'completed';\n \n const now = Date.now();\n const lastActivity = session.lastActivity || session.startTime;\n const idleTime = now - lastActivity;\n \n if (idleTime > 5 * 60 * 1000) return 'idle'; // 5 minutes\n return 'active';\n }\n\n private getStatusIcon(status: string): string {\n switch (status) {\n case 'active': return '{green-fg}\u25CF{/}';\n case 'idle': return '{yellow-fg}\u25CF{/}';\n case 'completed': return '{gray-fg}\u25CF{/}';\n case 'error': return '{red-fg}\u25CF{/}';\n default: return '{white-fg}\u25CB{/}';\n }\n }\n\n private getSessionMetrics(session: SessionData): SessionMetrics {\n const now = Date.now();\n const duration = now - session.startTime;\n \n const hours = Math.floor(duration / (1000 * 60 * 60));\n const minutes = Math.floor((duration % (1000 * 60 * 60)) / (1000 * 60));\n \n return {\n tokens: session.totalTokens || 0,\n duration: hours > 0 ? `${hours}h ${minutes}m` : `${minutes}m`,\n filesEdited: session.filesEdited?.length || 0,\n commandsRun: session.commandsRun || 0,\n errorsEncountered: session.errors?.length || 0\n };\n }\n\n public update(sessions: SessionData[]): void {\n // Update session map\n this.sessions.clear();\n sessions.forEach(session => {\n this.sessions.set(session.id, session);\n });\n\n // Update list display\n const items = sessions.map(session => this.formatSessionItem(session));\n this.sessionList.setItems(items);\n\n // Update footer statistics\n const active = sessions.filter(s => this.getSessionStatus(s) === 'active').length;\n const idle = sessions.filter(s => this.getSessionStatus(s) === 'idle').length;\n const total = sessions.length;\n \n const footer = this.container.children[1] as blessed.Widgets.BoxElement;\n if (footer) {\n footer.setContent(\n `{bold}Active:{/} {green-fg}${active}{/} | ` +\n `{bold}Idle:{/} {yellow-fg}${idle}{/} | ` +\n `{bold}Total:{/} ${total}`\n );\n }\n\n this.container.screen.render();\n }\n\n private selectSession(sessionId: string): void {\n this.selectedSession = sessionId;\n const session = this.sessions.get(sessionId);\n if (session) {\n this.emit('session:selected', session);\n this.showSessionDetails(session);\n }\n }\n\n private showSessionDetails(session: SessionData): void {\n const details = blessed.box({\n parent: this.container.screen,\n top: 'center',\n left: 'center',\n width: '80%',\n height: '80%',\n content: this.formatSessionDetails(session),\n tags: true,\n border: {\n type: 'line'\n },\n style: {\n border: {\n fg: 'cyan'\n }\n },\n scrollable: true,\n keys: true,\n vi: true,\n mouse: true,\n hidden: false,\n label: ` Session: ${this.generateSessionName(session)} `\n });\n\n details.key(['escape', 'q'], () => {\n details.destroy();\n this.container.screen.render();\n });\n\n details.focus();\n this.container.screen.render();\n }\n\n private formatSessionDetails(session: SessionData): string {\n const metrics = this.getSessionMetrics(session);\n const status = this.getSessionStatus(session);\n const tags = this.autoTagSession(session);\n \n let details = `{bold}Session ID:{/} ${session.id}\\n`;\n details += `{bold}Status:{/} ${status}\\n`;\n details += `{bold}Tags:{/} ${tags}\\n`;\n details += `{bold}Started:{/} ${new Date(session.startTime).toLocaleString()}\\n`;\n \n if (session.lastActivity) {\n details += `{bold}Last Activity:{/} ${new Date(session.lastActivity).toLocaleString()}\\n`;\n }\n \n details += `\\n{bold}Metrics:{/}\\n`;\n details += ` Tokens Used: ${metrics.tokens}\\n`;\n details += ` Context Usage: ${Math.round(session.contextUsage * 100)}%\\n`;\n details += ` Duration: ${metrics.duration}\\n`;\n details += ` Files Edited: ${metrics.filesEdited}\\n`;\n details += ` Commands Run: ${metrics.commandsRun}\\n`;\n details += ` Errors: ${metrics.errorsEncountered}\\n`;\n \n if (session.linearTask) {\n details += `\\n{bold}Linear Task:{/}\\n`;\n details += ` ID: ${session.linearTask.identifier}\\n`;\n details += ` Title: ${session.linearTask.title}\\n`;\n details += ` State: ${session.linearTask.state}\\n`;\n }\n \n if (session.gitBranch) {\n details += `\\n{bold}Git:{/}\\n`;\n details += ` Branch: ${session.gitBranch}\\n`;\n if (session.lastCommit) {\n details += ` Last Commit: ${session.lastCommit}\\n`;\n }\n }\n \n if (session.recentActivities && session.recentActivities.length > 0) {\n details += `\\n{bold}Recent Activities:{/}\\n`;\n session.recentActivities.slice(-10).forEach(activity => {\n details += ` ${new Date(activity.timestamp).toLocaleTimeString()} - ${activity.type}: ${activity.description}\\n`;\n });\n }\n \n return details;\n }\n\n public focus(): void {\n this.sessionList.focus();\n }\n\n public hasFocus(): boolean {\n return this.sessionList === this.container.screen.focused;\n }\n}"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * Session Monitor Component\n * Displays active sessions with auto-tagging based on work context\n */\n\nimport blessed from 'blessed';\nimport { EventEmitter } from 'events';\nimport type { SessionData, SessionMetrics } from '../types.js';\n\nexport class SessionMonitor extends EventEmitter {\n private container: blessed.Widgets.BoxElement;\n private sessionList: blessed.Widgets.ListElement;\n private sessions: Map<string, SessionData>;\n private selectedSession: string | null = null;\n\n constructor(container: blessed.Widgets.BoxElement) {\n super();\n this.container = container;\n this.sessions = new Map();\n this.initializeUI();\n }\n\n private initializeUI(): void {\n // Session list with auto-tagged names\n this.sessionList = blessed.list({\n parent: this.container,\n top: 0,\n left: 0,\n width: '100%',\n height: '100%-3',\n style: {\n selected: {\n bg: 'blue',\n fg: 'white',\n bold: true\n },\n item: {\n fg: 'cyan'\n }\n },\n mouse: true,\n keys: true,\n vi: true,\n scrollable: true,\n tags: true\n });\n\n // Summary footer\n const footer = blessed.box({\n parent: this.container,\n bottom: 0,\n left: 0,\n width: '100%',\n height: 3,\n content: 'Active: 0 | Idle: 0 | Total: 0',\n tags: true,\n style: {\n fg: 'white',\n bg: 'black'\n }\n });\n\n this.sessionList.on('select', (item, index) => {\n const sessionId = Array.from(this.sessions.keys())[index];\n this.selectSession(sessionId);\n });\n }\n\n /**\n * Auto-tag session based on work context\n */\n private autoTagSession(session: SessionData): string {\n const tags: string[] = [];\n \n // Analyze recent activities for context\n if (session.recentActivities) {\n // File-based tagging\n const files = session.recentActivities\n .filter((a: any) => a.type === 'file_edit')\n .map((a: any) => a.data?.path || '');\n \n if (files.some(f => f.includes('test'))) tags.push('testing');\n if (files.some(f => f.includes('.tsx') || f.includes('.jsx'))) tags.push('frontend');\n if (files.some(f => f.includes('api') || f.includes('server'))) tags.push('backend');\n if (files.some(f => f.includes('db') || f.includes('migration'))) tags.push('database');\n \n // Command-based tagging\n const commands = session.recentActivities\n .filter((a: any) => a.type === 'command')\n .map((a: any) => a.data?.command || '');\n \n if (commands.some(c => c.includes('npm test') || c.includes('jest'))) tags.push('testing');\n if (commands.some(c => c.includes('git'))) tags.push('git-ops');\n if (commands.some(c => c.includes('deploy'))) tags.push('deployment');\n if (commands.some(c => c.includes('debug'))) tags.push('debugging');\n }\n\n // Task-based tagging from Linear\n if (session.linearTask) {\n tags.push(`linear:${session.linearTask.identifier}`);\n if (session.linearTask.labels) {\n tags.push(...session.linearTask.labels.map((l: any) => l.toLowerCase()));\n }\n }\n\n // Branch-based tagging\n if (session.gitBranch) {\n const branch = session.gitBranch;\n if (branch.includes('feature/')) tags.push('feature');\n if (branch.includes('fix/') || branch.includes('bugfix/')) tags.push('bugfix');\n if (branch.includes('refactor/')) tags.push('refactor');\n if (branch.includes('docs/')) tags.push('documentation');\n }\n\n // AI agent type tagging\n if (session.agentType) {\n tags.push(`agent:${session.agentType}`);\n }\n\n return tags.length > 0 ? tags.join(' \u2022 ') : 'general';\n }\n\n /**\n * Generate session display name with context\n */\n private generateSessionName(session: SessionData): string {\n const autoTags = this.autoTagSession(session);\n const timestamp = new Date(session.startTime).toLocaleTimeString();\n \n // Create descriptive name based on primary activity\n let primaryActivity = 'Session';\n \n if (session.linearTask) {\n primaryActivity = session.linearTask.title || session.linearTask.identifier;\n } else if (session.gitBranch && session.gitBranch !== 'main' && session.gitBranch !== 'master') {\n primaryActivity = session.gitBranch.split('/').pop() || session.gitBranch;\n } else if (session.primaryFile) {\n primaryActivity = session.primaryFile.split('/').pop() || 'Code';\n }\n\n return `${primaryActivity} [${autoTags}] - ${timestamp}`;\n }\n\n /**\n * Format session item for display\n */\n private formatSessionItem(session: SessionData): string {\n const status = this.getSessionStatus(session);\n const statusIcon = this.getStatusIcon(status);\n const name = this.generateSessionName(session);\n const metrics = this.getSessionMetrics(session);\n \n const contextUsage = Math.round(session.contextUsage * 100);\n const contextColor = contextUsage > 80 ? 'red' : contextUsage > 60 ? 'yellow' : 'green';\n \n return `${statusIcon} ${name}\\n` +\n ` {gray-fg}Tokens: ${metrics.tokens} | Context: {${contextColor}-fg}${contextUsage}%{/} | Duration: ${metrics.duration}{/}`;\n }\n\n private getSessionStatus(session: SessionData): 'active' | 'idle' | 'completed' | 'error' {\n if (session.error) return 'error';\n if (session.completed) return 'completed';\n \n const now = Date.now();\n const lastActivity = session.lastActivity || session.startTime;\n const idleTime = now - lastActivity;\n \n if (idleTime > 5 * 60 * 1000) return 'idle'; // 5 minutes\n return 'active';\n }\n\n private getStatusIcon(status: string): string {\n switch (status) {\n case 'active': return '{green-fg}\u25CF{/}';\n case 'idle': return '{yellow-fg}\u25CF{/}';\n case 'completed': return '{gray-fg}\u25CF{/}';\n case 'error': return '{red-fg}\u25CF{/}';\n default: return '{white-fg}\u25CB{/}';\n }\n }\n\n private getSessionMetrics(session: SessionData): SessionMetrics {\n const now = Date.now();\n const duration = now - session.startTime;\n \n const hours = Math.floor(duration / (1000 * 60 * 60));\n const minutes = Math.floor((duration % (1000 * 60 * 60)) / (1000 * 60));\n \n return {\n tokens: session.totalTokens || 0,\n duration: hours > 0 ? `${hours}h ${minutes}m` : `${minutes}m`,\n filesEdited: session.filesEdited?.length || 0,\n commandsRun: session.commandsRun || 0,\n errorsEncountered: session.errors?.length || 0\n };\n }\n\n public update(sessions: SessionData[]): void {\n // Update session map\n this.sessions.clear();\n sessions.forEach(session => {\n this.sessions.set(session.id, session);\n });\n\n // Update list display\n const items = sessions.map((session: any) => this.formatSessionItem(session));\n this.sessionList.setItems(items);\n\n // Update footer statistics\n const active = sessions.filter((s: any) => this.getSessionStatus(s) === 'active').length;\n const idle = sessions.filter((s: any) => this.getSessionStatus(s) === 'idle').length;\n const total = sessions.length;\n \n const footer = this.container.children[1] as blessed.Widgets.BoxElement;\n if (footer) {\n footer.setContent(\n `{bold}Active:{/} {green-fg}${active}{/} | ` +\n `{bold}Idle:{/} {yellow-fg}${idle}{/} | ` +\n `{bold}Total:{/} ${total}`\n );\n }\n\n this.container.screen.render();\n }\n\n private selectSession(sessionId: string): void {\n this.selectedSession = sessionId;\n const session = this.sessions.get(sessionId);\n if (session) {\n this.emit('session:selected', session);\n this.showSessionDetails(session);\n }\n }\n\n private showSessionDetails(session: SessionData): void {\n const details = blessed.box({\n parent: this.container.screen,\n top: 'center',\n left: 'center',\n width: '80%',\n height: '80%',\n content: this.formatSessionDetails(session),\n tags: true,\n border: {\n type: 'line'\n },\n style: {\n border: {\n fg: 'cyan'\n }\n },\n scrollable: true,\n keys: true,\n vi: true,\n mouse: true,\n hidden: false,\n label: ` Session: ${this.generateSessionName(session)} `\n });\n\n details.key(['escape', 'q'], () => {\n details.destroy();\n this.container.screen.render();\n });\n\n details.focus();\n this.container.screen.render();\n }\n\n private formatSessionDetails(session: SessionData): string {\n const metrics = this.getSessionMetrics(session);\n const status = this.getSessionStatus(session);\n const tags = this.autoTagSession(session);\n \n let details = `{bold}Session ID:{/} ${session.id}\\n`;\n details += `{bold}Status:{/} ${status}\\n`;\n details += `{bold}Tags:{/} ${tags}\\n`;\n details += `{bold}Started:{/} ${new Date(session.startTime).toLocaleString()}\\n`;\n \n if (session.lastActivity) {\n details += `{bold}Last Activity:{/} ${new Date(session.lastActivity).toLocaleString()}\\n`;\n }\n \n details += `\\n{bold}Metrics:{/}\\n`;\n details += ` Tokens Used: ${metrics.tokens}\\n`;\n details += ` Context Usage: ${Math.round(session.contextUsage * 100)}%\\n`;\n details += ` Duration: ${metrics.duration}\\n`;\n details += ` Files Edited: ${metrics.filesEdited}\\n`;\n details += ` Commands Run: ${metrics.commandsRun}\\n`;\n details += ` Errors: ${metrics.errorsEncountered}\\n`;\n \n if (session.linearTask) {\n details += `\\n{bold}Linear Task:{/}\\n`;\n details += ` ID: ${session.linearTask.identifier}\\n`;\n details += ` Title: ${session.linearTask.title}\\n`;\n details += ` State: ${session.linearTask.state}\\n`;\n }\n \n if (session.gitBranch) {\n details += `\\n{bold}Git:{/}\\n`;\n details += ` Branch: ${session.gitBranch}\\n`;\n if (session.lastCommit) {\n details += ` Last Commit: ${session.lastCommit}\\n`;\n }\n }\n \n if (session.recentActivities && session.recentActivities.length > 0) {\n details += `\\n{bold}Recent Activities:{/}\\n`;\n session.recentActivities.slice(-10).forEach(activity => {\n details += ` ${new Date(activity.timestamp).toLocaleTimeString()} - ${activity.type}: ${activity.description}\\n`;\n });\n }\n \n return details;\n }\n\n public focus(): void {\n this.sessionList.focus();\n }\n\n public hasFocus(): boolean {\n return this.sessionList === this.container.screen.focused;\n }\n}"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/features/tui/components/subagent-fleet.ts"],
4
- "sourcesContent": ["/**\n * Subagent Fleet Component\n * Monitors and displays status of all active subagents\n */\n\nimport blessed from 'blessed';\nimport { EventEmitter } from 'events';\nimport type { SubagentData } from '../types.js';\n\nexport class SubagentFleet extends EventEmitter {\n private container: blessed.Widgets.BoxElement;\n private agentList: blessed.Widgets.ListElement;\n private statsBox: blessed.Widgets.BoxElement;\n private agents: Map<string, SubagentData>;\n private selectedAgent: string | null = null;\n\n constructor(container: blessed.Widgets.BoxElement) {\n super();\n this.container = container;\n this.agents = new Map();\n this.initializeUI();\n }\n\n private initializeUI(): void {\n // Agent list (left side)\n this.agentList = blessed.list({\n parent: this.container,\n top: 0,\n left: 0,\n width: '60%',\n height: '100%-3',\n style: {\n selected: {\n bg: 'magenta',\n fg: 'white',\n bold: true\n },\n item: {\n fg: 'white'\n }\n },\n mouse: true,\n keys: true,\n vi: true,\n scrollable: true,\n tags: true\n });\n\n // Stats panel (right side)\n this.statsBox = blessed.box({\n parent: this.container,\n top: 0,\n right: 0,\n width: '40%',\n height: '100%-3',\n content: this.getFleetStats(),\n tags: true,\n scrollable: true,\n style: {\n fg: 'white'\n }\n });\n\n // Fleet summary footer\n const footer = blessed.box({\n parent: this.container,\n bottom: 0,\n left: 0,\n width: '100%',\n height: 3,\n content: 'Fleet: 0 agents | Active: 0 | Idle: 0',\n tags: true,\n style: {\n fg: 'white',\n bg: 'black'\n }\n });\n\n this.agentList.on('select', (item, index) => {\n const agentId = Array.from(this.agents.keys())[index];\n this.selectAgent(agentId);\n });\n\n // Keyboard shortcuts\n this.setupKeyboardShortcuts();\n }\n\n private setupKeyboardShortcuts(): void {\n this.container.key(['t'], () => {\n if (this.selectedAgent) {\n this.terminateAgent(this.selectedAgent);\n }\n });\n\n this.container.key(['r'], () => {\n if (this.selectedAgent) {\n this.restartAgent(this.selectedAgent);\n }\n });\n\n this.container.key(['l'], () => {\n if (this.selectedAgent) {\n this.showAgentLogs(this.selectedAgent);\n }\n });\n }\n\n /**\n * Format agent item for display\n */\n private formatAgentItem(agent: SubagentData): string {\n const status = this.getStatusIcon(agent.status);\n const type = this.getAgentTypeIcon(agent.type);\n const successRate = Math.round(agent.successRate * 100);\n const rateColor = successRate >= 90 ? 'green' : successRate >= 70 ? 'yellow' : 'red';\n \n let item = `${status} ${type} ${agent.type} (${agent.id.substring(0, 8)})\\n`;\n \n if (agent.currentTask) {\n const progress = Math.round(agent.currentTask.progress * 100);\n const elapsed = this.formatDuration(Date.now() - agent.currentTask.startTime);\n item += ` {cyan-fg}\u25B6 ${agent.currentTask.description.substring(0, 30)}...{/}\\n`;\n item += ` Progress: ${this.createProgressBar(agent.currentTask.progress)} ${progress}% (${elapsed})`;\n } else {\n item += ` Completed: ${agent.tasksCompleted} | Failed: ${agent.tasksFailed}\\n`;\n item += ` Success Rate: {${rateColor}-fg}${successRate}%{/} | Avg Time: ${this.formatDuration(agent.averageTime)}`;\n }\n \n // Resource usage indicators\n if (agent.cpuUsage !== undefined || agent.memoryUsage !== undefined) {\n item += '\\n ';\n if (agent.cpuUsage !== undefined) {\n const cpuColor = agent.cpuUsage > 80 ? 'red' : agent.cpuUsage > 50 ? 'yellow' : 'green';\n item += `CPU: {${cpuColor}-fg}${Math.round(agent.cpuUsage)}%{/} `;\n }\n if (agent.memoryUsage !== undefined) {\n const memColor = agent.memoryUsage > 80 ? 'red' : agent.memoryUsage > 50 ? 'yellow' : 'green';\n item += `MEM: {${memColor}-fg}${Math.round(agent.memoryUsage)}%{/} `;\n }\n if (agent.tokenUsage !== undefined) {\n item += `Tokens: ${this.formatTokens(agent.tokenUsage)}`;\n }\n }\n \n // Error indicator\n if (agent.lastError) {\n const errorAge = this.formatDuration(Date.now() - agent.lastError.timestamp);\n item += `\\n {red-fg}\u26A0 Error ${errorAge} ago: ${agent.lastError.message.substring(0, 40)}{/}`;\n }\n \n return item;\n }\n\n private getStatusIcon(status: string): string {\n switch (status) {\n case 'active': return '{green-fg}\u25CF{/}';\n case 'idle': return '{cyan-fg}\u25CF{/}';\n case 'error': return '{red-fg}\u25CF{/}';\n case 'completed': return '{gray-fg}\u25CF{/}';\n default: return '{white-fg}\u25CB{/}';\n }\n }\n\n private getAgentTypeIcon(type: string): string {\n const icons: Record<string, string> = {\n 'analyzer': '\uD83D\uDD0D',\n 'builder': '\uD83D\uDD28',\n 'debugger': '\uD83D\uDC1B',\n 'tester': '\uD83E\uDDEA',\n 'reviewer': '\uD83D\uDC41\uFE0F',\n 'refactorer': '\u267B\uFE0F',\n 'documenter': '\uD83D\uDCDD',\n 'security': '\uD83D\uDD12',\n 'performance': '\u26A1',\n 'general': '\uD83E\uDD16'\n };\n return icons[type.toLowerCase()] || '\uD83E\uDD16';\n }\n\n private createProgressBar(progress: number): string {\n const width = 10;\n const filled = Math.round(progress * width);\n const empty = width - filled;\n \n const color = progress >= 0.8 ? 'green' : progress >= 0.5 ? 'yellow' : 'cyan';\n return `{${color}-fg}${'\u2588'.repeat(filled)}{/}{gray-fg}${'\u2591'.repeat(empty)}{/}`;\n }\n\n private formatDuration(ms: number): string {\n if (ms < 1000) return `${ms}ms`;\n if (ms < 60000) return `${Math.round(ms / 1000)}s`;\n if (ms < 3600000) return `${Math.round(ms / 60000)}m`;\n return `${Math.round(ms / 3600000)}h`;\n }\n\n private formatTokens(tokens: number): string {\n if (tokens < 1000) return `${tokens}`;\n if (tokens < 1000000) return `${(tokens / 1000).toFixed(1)}K`;\n return `${(tokens / 1000000).toFixed(1)}M`;\n }\n\n /**\n * Generate fleet statistics\n */\n private getFleetStats(): string {\n const agents = Array.from(this.agents.values());\n \n if (agents.length === 0) {\n return '{gray-fg}No agents active{/}';\n }\n \n // Calculate statistics\n const stats = {\n total: agents.length,\n active: agents.filter(a => a.status === 'active').length,\n idle: agents.filter(a => a.status === 'idle').length,\n error: agents.filter(a => a.status === 'error').length,\n totalTasks: agents.reduce((sum, a) => sum + a.tasksCompleted + a.tasksFailed, 0),\n successfulTasks: agents.reduce((sum, a) => sum + a.tasksCompleted, 0),\n failedTasks: agents.reduce((sum, a) => sum + a.tasksFailed, 0),\n avgSuccessRate: agents.reduce((sum, a) => sum + a.successRate, 0) / agents.length,\n totalTokens: agents.reduce((sum, a) => sum + (a.tokenUsage || 0), 0),\n avgCpu: agents.reduce((sum, a) => sum + (a.cpuUsage || 0), 0) / agents.length,\n avgMemory: agents.reduce((sum, a) => sum + (a.memoryUsage || 0), 0) / agents.length\n };\n \n // Group by type\n const typeGroups = new Map<string, number>();\n agents.forEach(agent => {\n typeGroups.set(agent.type, (typeGroups.get(agent.type) || 0) + 1);\n });\n \n let output = '{bold}Fleet Statistics{/}\\n\\n';\n \n output += '{bold}Status:{/}\\n';\n output += ` Total: ${stats.total}\\n`;\n output += ` Active: {green-fg}${stats.active}{/}\\n`;\n output += ` Idle: {cyan-fg}${stats.idle}{/}\\n`;\n output += ` Error: {red-fg}${stats.error}{/}\\n`;\n \n output += '\\n{bold}Performance:{/}\\n';\n output += ` Tasks: ${stats.successfulTasks}/${stats.totalTasks}\\n`;\n const rateColor = stats.avgSuccessRate >= 0.9 ? 'green' : stats.avgSuccessRate >= 0.7 ? 'yellow' : 'red';\n output += ` Success: {${rateColor}-fg}${Math.round(stats.avgSuccessRate * 100)}%{/}\\n`;\n output += ` Tokens: ${this.formatTokens(stats.totalTokens)}\\n`;\n \n output += '\\n{bold}Resources:{/}\\n';\n const cpuColor = stats.avgCpu > 80 ? 'red' : stats.avgCpu > 50 ? 'yellow' : 'green';\n const memColor = stats.avgMemory > 80 ? 'red' : stats.avgMemory > 50 ? 'yellow' : 'green';\n output += ` CPU: {${cpuColor}-fg}${Math.round(stats.avgCpu)}%{/}\\n`;\n output += ` Memory: {${memColor}-fg}${Math.round(stats.avgMemory)}%{/}\\n`;\n \n output += '\\n{bold}Types:{/}\\n';\n Array.from(typeGroups.entries())\n .sort((a, b) => b[1] - a[1])\n .forEach(([type, count]) => {\n const icon = this.getAgentTypeIcon(type);\n output += ` ${icon} ${type}: ${count}\\n`;\n });\n \n return output;\n }\n\n public update(agents: SubagentData[]): void {\n // Update agent map\n this.agents.clear();\n agents.forEach(agent => {\n this.agents.set(agent.id, agent);\n });\n\n // Update list display\n const items = agents.map(agent => this.formatAgentItem(agent));\n this.agentList.setItems(items);\n\n // Update stats panel\n this.statsBox.setContent(this.getFleetStats());\n\n // Update footer\n const active = agents.filter(a => a.status === 'active').length;\n const idle = agents.filter(a => a.status === 'idle').length;\n const total = agents.length;\n \n const footer = this.container.children[2] as blessed.Widgets.BoxElement;\n if (footer) {\n footer.setContent(\n `{bold}Fleet:{/} ${total} agents | ` +\n `{bold}Active:{/} {green-fg}${active}{/} | ` +\n `{bold}Idle:{/} {cyan-fg}${idle}{/}`\n );\n }\n\n this.container.screen.render();\n }\n\n private selectAgent(agentId: string): void {\n this.selectedAgent = agentId;\n const agent = this.agents.get(agentId);\n if (agent) {\n this.emit('agent:selected', agent);\n this.showAgentDetails(agent);\n }\n }\n\n private showAgentDetails(agent: SubagentData): void {\n const details = blessed.box({\n parent: this.container.screen,\n top: 'center',\n left: 'center',\n width: '70%',\n height: '70%',\n content: this.formatAgentDetails(agent),\n tags: true,\n border: {\n type: 'line'\n },\n style: {\n border: {\n fg: 'magenta'\n }\n },\n scrollable: true,\n keys: true,\n vi: true,\n mouse: true,\n hidden: false,\n label: ` Agent: ${agent.type} (${agent.id}) `\n });\n\n details.key(['escape', 'q'], () => {\n details.destroy();\n this.container.screen.render();\n });\n\n details.focus();\n this.container.screen.render();\n }\n\n private formatAgentDetails(agent: SubagentData): string {\n let details = `{bold}Agent ID:{/} ${agent.id}\\n`;\n details += `{bold}Type:{/} ${this.getAgentTypeIcon(agent.type)} ${agent.type}\\n`;\n details += `{bold}Status:{/} ${this.getStatusIcon(agent.status)} ${agent.status}\\n`;\n \n if (agent.currentTask) {\n details += `\\n{bold}Current Task:{/}\\n`;\n details += ` ID: ${agent.currentTask.id}\\n`;\n details += ` Description: ${agent.currentTask.description}\\n`;\n details += ` Progress: ${Math.round(agent.currentTask.progress * 100)}%\\n`;\n details += ` Started: ${new Date(agent.currentTask.startTime).toLocaleString()}\\n`;\n details += ` Elapsed: ${this.formatDuration(Date.now() - agent.currentTask.startTime)}\\n`;\n }\n \n details += `\\n{bold}Performance Metrics:{/}\\n`;\n details += ` Tasks Completed: ${agent.tasksCompleted}\\n`;\n details += ` Tasks Failed: ${agent.tasksFailed}\\n`;\n details += ` Success Rate: ${Math.round(agent.successRate * 100)}%\\n`;\n details += ` Average Time: ${this.formatDuration(agent.averageTime)}\\n`;\n \n if (agent.cpuUsage !== undefined || agent.memoryUsage !== undefined || agent.tokenUsage !== undefined) {\n details += `\\n{bold}Resource Usage:{/}\\n`;\n if (agent.cpuUsage !== undefined) {\n details += ` CPU: ${Math.round(agent.cpuUsage)}%\\n`;\n }\n if (agent.memoryUsage !== undefined) {\n details += ` Memory: ${Math.round(agent.memoryUsage)}%\\n`;\n }\n if (agent.tokenUsage !== undefined) {\n details += ` Tokens: ${this.formatTokens(agent.tokenUsage)}\\n`;\n }\n }\n \n if (agent.lastError) {\n details += `\\n{bold}Last Error:{/}\\n`;\n details += ` Message: ${agent.lastError.message}\\n`;\n details += ` Time: ${new Date(agent.lastError.timestamp).toLocaleString()}\\n`;\n details += ` Recoverable: ${agent.lastError.recoverable ? 'Yes' : 'No'}\\n`;\n }\n \n details += `\\n{gray-fg}[t] Terminate | [r] Restart | [l] View Logs{/}\\n`;\n \n return details;\n }\n\n private terminateAgent(agentId: string): void {\n this.emit('agent:terminate', { agentId });\n // Optimistically update UI\n const agent = this.agents.get(agentId);\n if (agent) {\n agent.status = 'completed';\n this.update(Array.from(this.agents.values()));\n }\n }\n\n private restartAgent(agentId: string): void {\n this.emit('agent:restart', { agentId });\n // Optimistically update UI\n const agent = this.agents.get(agentId);\n if (agent) {\n agent.status = 'idle';\n agent.lastError = undefined;\n this.update(Array.from(this.agents.values()));\n }\n }\n\n private showAgentLogs(agentId: string): void {\n this.emit('agent:logs', { agentId });\n }\n\n public focus(): void {\n this.agentList.focus();\n }\n\n public hasFocus(): boolean {\n return this.agentList === this.container.screen.focused;\n }\n}"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * Subagent Fleet Component\n * Monitors and displays status of all active subagents\n */\n\nimport blessed from 'blessed';\nimport { EventEmitter } from 'events';\nimport type { SubagentData } from '../types.js';\n\nexport class SubagentFleet extends EventEmitter {\n private container: blessed.Widgets.BoxElement;\n private agentList: blessed.Widgets.ListElement;\n private statsBox: blessed.Widgets.BoxElement;\n private agents: Map<string, SubagentData>;\n private selectedAgent: string | null = null;\n\n constructor(container: blessed.Widgets.BoxElement) {\n super();\n this.container = container;\n this.agents = new Map();\n this.initializeUI();\n }\n\n private initializeUI(): void {\n // Agent list (left side)\n this.agentList = blessed.list({\n parent: this.container,\n top: 0,\n left: 0,\n width: '60%',\n height: '100%-3',\n style: {\n selected: {\n bg: 'magenta',\n fg: 'white',\n bold: true\n },\n item: {\n fg: 'white'\n }\n },\n mouse: true,\n keys: true,\n vi: true,\n scrollable: true,\n tags: true\n });\n\n // Stats panel (right side)\n this.statsBox = blessed.box({\n parent: this.container,\n top: 0,\n right: 0,\n width: '40%',\n height: '100%-3',\n content: this.getFleetStats(),\n tags: true,\n scrollable: true,\n style: {\n fg: 'white'\n }\n });\n\n // Fleet summary footer\n const footer = blessed.box({\n parent: this.container,\n bottom: 0,\n left: 0,\n width: '100%',\n height: 3,\n content: 'Fleet: 0 agents | Active: 0 | Idle: 0',\n tags: true,\n style: {\n fg: 'white',\n bg: 'black'\n }\n });\n\n this.agentList.on('select', (item, index) => {\n const agentId = Array.from(this.agents.keys())[index];\n this.selectAgent(agentId);\n });\n\n // Keyboard shortcuts\n this.setupKeyboardShortcuts();\n }\n\n private setupKeyboardShortcuts(): void {\n this.container.key(['t'], () => {\n if (this.selectedAgent) {\n this.terminateAgent(this.selectedAgent);\n }\n });\n\n this.container.key(['r'], () => {\n if (this.selectedAgent) {\n this.restartAgent(this.selectedAgent);\n }\n });\n\n this.container.key(['l'], () => {\n if (this.selectedAgent) {\n this.showAgentLogs(this.selectedAgent);\n }\n });\n }\n\n /**\n * Format agent item for display\n */\n private formatAgentItem(agent: SubagentData): string {\n const status = this.getStatusIcon(agent.status);\n const type = this.getAgentTypeIcon(agent.type);\n const successRate = Math.round(agent.successRate * 100);\n const rateColor = successRate >= 90 ? 'green' : successRate >= 70 ? 'yellow' : 'red';\n \n let item = `${status} ${type} ${agent.type} (${agent.id.substring(0, 8)})\\n`;\n \n if (agent.currentTask) {\n const progress = Math.round(agent.currentTask.progress * 100);\n const elapsed = this.formatDuration(Date.now() - agent.currentTask.startTime);\n item += ` {cyan-fg}\u25B6 ${agent.currentTask.description.substring(0, 30)}...{/}\\n`;\n item += ` Progress: ${this.createProgressBar(agent.currentTask.progress)} ${progress}% (${elapsed})`;\n } else {\n item += ` Completed: ${agent.tasksCompleted} | Failed: ${agent.tasksFailed}\\n`;\n item += ` Success Rate: {${rateColor}-fg}${successRate}%{/} | Avg Time: ${this.formatDuration(agent.averageTime)}`;\n }\n \n // Resource usage indicators\n if (agent.cpuUsage !== undefined || agent.memoryUsage !== undefined) {\n item += '\\n ';\n if (agent.cpuUsage !== undefined) {\n const cpuColor = agent.cpuUsage > 80 ? 'red' : agent.cpuUsage > 50 ? 'yellow' : 'green';\n item += `CPU: {${cpuColor}-fg}${Math.round(agent.cpuUsage)}%{/} `;\n }\n if (agent.memoryUsage !== undefined) {\n const memColor = agent.memoryUsage > 80 ? 'red' : agent.memoryUsage > 50 ? 'yellow' : 'green';\n item += `MEM: {${memColor}-fg}${Math.round(agent.memoryUsage)}%{/} `;\n }\n if (agent.tokenUsage !== undefined) {\n item += `Tokens: ${this.formatTokens(agent.tokenUsage)}`;\n }\n }\n \n // Error indicator\n if (agent.lastError) {\n const errorAge = this.formatDuration(Date.now() - agent.lastError.timestamp);\n item += `\\n {red-fg}\u26A0 Error ${errorAge} ago: ${agent.lastError.message.substring(0, 40)}{/}`;\n }\n \n return item;\n }\n\n private getStatusIcon(status: string): string {\n switch (status) {\n case 'active': return '{green-fg}\u25CF{/}';\n case 'idle': return '{cyan-fg}\u25CF{/}';\n case 'error': return '{red-fg}\u25CF{/}';\n case 'completed': return '{gray-fg}\u25CF{/}';\n default: return '{white-fg}\u25CB{/}';\n }\n }\n\n private getAgentTypeIcon(type: string): string {\n const icons: Record<string, string> = {\n 'analyzer': '\uD83D\uDD0D',\n 'builder': '\uD83D\uDD28',\n 'debugger': '\uD83D\uDC1B',\n 'tester': '\uD83E\uDDEA',\n 'reviewer': '\uD83D\uDC41\uFE0F',\n 'refactorer': '\u267B\uFE0F',\n 'documenter': '\uD83D\uDCDD',\n 'security': '\uD83D\uDD12',\n 'performance': '\u26A1',\n 'general': '\uD83E\uDD16'\n };\n return icons[type.toLowerCase()] || '\uD83E\uDD16';\n }\n\n private createProgressBar(progress: number): string {\n const width = 10;\n const filled = Math.round(progress * width);\n const empty = width - filled;\n \n const color = progress >= 0.8 ? 'green' : progress >= 0.5 ? 'yellow' : 'cyan';\n return `{${color}-fg}${'\u2588'.repeat(filled)}{/}{gray-fg}${'\u2591'.repeat(empty)}{/}`;\n }\n\n private formatDuration(ms: number): string {\n if (ms < 1000) return `${ms}ms`;\n if (ms < 60000) return `${Math.round(ms / 1000)}s`;\n if (ms < 3600000) return `${Math.round(ms / 60000)}m`;\n return `${Math.round(ms / 3600000)}h`;\n }\n\n private formatTokens(tokens: number): string {\n if (tokens < 1000) return `${tokens}`;\n if (tokens < 1000000) return `${(tokens / 1000).toFixed(1)}K`;\n return `${(tokens / 1000000).toFixed(1)}M`;\n }\n\n /**\n * Generate fleet statistics\n */\n private getFleetStats(): string {\n const agents = Array.from(this.agents.values());\n \n if (agents.length === 0) {\n return '{gray-fg}No agents active{/}';\n }\n \n // Calculate statistics\n const stats = {\n total: agents.length,\n active: agents.filter((a: any) => a.status === 'active').length,\n idle: agents.filter((a: any) => a.status === 'idle').length,\n error: agents.filter((a: any) => a.status === 'error').length,\n totalTasks: agents.reduce((sum, a) => sum + a.tasksCompleted + a.tasksFailed, 0),\n successfulTasks: agents.reduce((sum, a) => sum + a.tasksCompleted, 0),\n failedTasks: agents.reduce((sum, a) => sum + a.tasksFailed, 0),\n avgSuccessRate: agents.reduce((sum, a) => sum + a.successRate, 0) / agents.length,\n totalTokens: agents.reduce((sum, a) => sum + (a.tokenUsage || 0), 0),\n avgCpu: agents.reduce((sum, a) => sum + (a.cpuUsage || 0), 0) / agents.length,\n avgMemory: agents.reduce((sum, a) => sum + (a.memoryUsage || 0), 0) / agents.length\n };\n \n // Group by type\n const typeGroups = new Map<string, number>();\n agents.forEach(agent => {\n typeGroups.set(agent.type, (typeGroups.get(agent.type) || 0) + 1);\n });\n \n let output = '{bold}Fleet Statistics{/}\\n\\n';\n \n output += '{bold}Status:{/}\\n';\n output += ` Total: ${stats.total}\\n`;\n output += ` Active: {green-fg}${stats.active}{/}\\n`;\n output += ` Idle: {cyan-fg}${stats.idle}{/}\\n`;\n output += ` Error: {red-fg}${stats.error}{/}\\n`;\n \n output += '\\n{bold}Performance:{/}\\n';\n output += ` Tasks: ${stats.successfulTasks}/${stats.totalTasks}\\n`;\n const rateColor = stats.avgSuccessRate >= 0.9 ? 'green' : stats.avgSuccessRate >= 0.7 ? 'yellow' : 'red';\n output += ` Success: {${rateColor}-fg}${Math.round(stats.avgSuccessRate * 100)}%{/}\\n`;\n output += ` Tokens: ${this.formatTokens(stats.totalTokens)}\\n`;\n \n output += '\\n{bold}Resources:{/}\\n';\n const cpuColor = stats.avgCpu > 80 ? 'red' : stats.avgCpu > 50 ? 'yellow' : 'green';\n const memColor = stats.avgMemory > 80 ? 'red' : stats.avgMemory > 50 ? 'yellow' : 'green';\n output += ` CPU: {${cpuColor}-fg}${Math.round(stats.avgCpu)}%{/}\\n`;\n output += ` Memory: {${memColor}-fg}${Math.round(stats.avgMemory)}%{/}\\n`;\n \n output += '\\n{bold}Types:{/}\\n';\n Array.from(typeGroups.entries())\n .sort((a, b) => b[1] - a[1])\n .forEach(([type, count]) => {\n const icon = this.getAgentTypeIcon(type);\n output += ` ${icon} ${type}: ${count}\\n`;\n });\n \n return output;\n }\n\n public update(agents: SubagentData[]): void {\n // Update agent map\n this.agents.clear();\n agents.forEach(agent => {\n this.agents.set(agent.id, agent);\n });\n\n // Update list display\n const items = agents.map((agent: any) => this.formatAgentItem(agent));\n this.agentList.setItems(items);\n\n // Update stats panel\n this.statsBox.setContent(this.getFleetStats());\n\n // Update footer\n const active = agents.filter((a: any) => a.status === 'active').length;\n const idle = agents.filter((a: any) => a.status === 'idle').length;\n const total = agents.length;\n \n const footer = this.container.children[2] as blessed.Widgets.BoxElement;\n if (footer) {\n footer.setContent(\n `{bold}Fleet:{/} ${total} agents | ` +\n `{bold}Active:{/} {green-fg}${active}{/} | ` +\n `{bold}Idle:{/} {cyan-fg}${idle}{/}`\n );\n }\n\n this.container.screen.render();\n }\n\n private selectAgent(agentId: string): void {\n this.selectedAgent = agentId;\n const agent = this.agents.get(agentId);\n if (agent) {\n this.emit('agent:selected', agent);\n this.showAgentDetails(agent);\n }\n }\n\n private showAgentDetails(agent: SubagentData): void {\n const details = blessed.box({\n parent: this.container.screen,\n top: 'center',\n left: 'center',\n width: '70%',\n height: '70%',\n content: this.formatAgentDetails(agent),\n tags: true,\n border: {\n type: 'line'\n },\n style: {\n border: {\n fg: 'magenta'\n }\n },\n scrollable: true,\n keys: true,\n vi: true,\n mouse: true,\n hidden: false,\n label: ` Agent: ${agent.type} (${agent.id}) `\n });\n\n details.key(['escape', 'q'], () => {\n details.destroy();\n this.container.screen.render();\n });\n\n details.focus();\n this.container.screen.render();\n }\n\n private formatAgentDetails(agent: SubagentData): string {\n let details = `{bold}Agent ID:{/} ${agent.id}\\n`;\n details += `{bold}Type:{/} ${this.getAgentTypeIcon(agent.type)} ${agent.type}\\n`;\n details += `{bold}Status:{/} ${this.getStatusIcon(agent.status)} ${agent.status}\\n`;\n \n if (agent.currentTask) {\n details += `\\n{bold}Current Task:{/}\\n`;\n details += ` ID: ${agent.currentTask.id}\\n`;\n details += ` Description: ${agent.currentTask.description}\\n`;\n details += ` Progress: ${Math.round(agent.currentTask.progress * 100)}%\\n`;\n details += ` Started: ${new Date(agent.currentTask.startTime).toLocaleString()}\\n`;\n details += ` Elapsed: ${this.formatDuration(Date.now() - agent.currentTask.startTime)}\\n`;\n }\n \n details += `\\n{bold}Performance Metrics:{/}\\n`;\n details += ` Tasks Completed: ${agent.tasksCompleted}\\n`;\n details += ` Tasks Failed: ${agent.tasksFailed}\\n`;\n details += ` Success Rate: ${Math.round(agent.successRate * 100)}%\\n`;\n details += ` Average Time: ${this.formatDuration(agent.averageTime)}\\n`;\n \n if (agent.cpuUsage !== undefined || agent.memoryUsage !== undefined || agent.tokenUsage !== undefined) {\n details += `\\n{bold}Resource Usage:{/}\\n`;\n if (agent.cpuUsage !== undefined) {\n details += ` CPU: ${Math.round(agent.cpuUsage)}%\\n`;\n }\n if (agent.memoryUsage !== undefined) {\n details += ` Memory: ${Math.round(agent.memoryUsage)}%\\n`;\n }\n if (agent.tokenUsage !== undefined) {\n details += ` Tokens: ${this.formatTokens(agent.tokenUsage)}\\n`;\n }\n }\n \n if (agent.lastError) {\n details += `\\n{bold}Last Error:{/}\\n`;\n details += ` Message: ${agent.lastError.message}\\n`;\n details += ` Time: ${new Date(agent.lastError.timestamp).toLocaleString()}\\n`;\n details += ` Recoverable: ${agent.lastError.recoverable ? 'Yes' : 'No'}\\n`;\n }\n \n details += `\\n{gray-fg}[t] Terminate | [r] Restart | [l] View Logs{/}\\n`;\n \n return details;\n }\n\n private terminateAgent(agentId: string): void {\n this.emit('agent:terminate', { agentId });\n // Optimistically update UI\n const agent = this.agents.get(agentId);\n if (agent) {\n agent.status = 'completed';\n this.update(Array.from(this.agents.values()));\n }\n }\n\n private restartAgent(agentId: string): void {\n this.emit('agent:restart', { agentId });\n // Optimistically update UI\n const agent = this.agents.get(agentId);\n if (agent) {\n agent.status = 'idle';\n agent.lastError = undefined;\n this.update(Array.from(this.agents.values()));\n }\n }\n\n private showAgentLogs(agentId: string): void {\n this.emit('agent:logs', { agentId });\n }\n\n public focus(): void {\n this.agentList.focus();\n }\n\n public hasFocus(): boolean {\n return this.agentList === this.container.screen.focused;\n }\n}"],
5
+ "mappings": "AAKA,OAAO,aAAa;AACpB,SAAS,oBAAoB;AAGtB,MAAM,sBAAsB,aAAa;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,gBAA+B;AAAA,EAEvC,YAAY,WAAuC;AACjD,UAAM;AACN,SAAK,YAAY;AACjB,SAAK,SAAS,oBAAI,IAAI;AACtB,SAAK,aAAa;AAAA,EACpB;AAAA,EAEQ,eAAqB;AAE3B,SAAK,YAAY,QAAQ,KAAK;AAAA,MAC5B,QAAQ,KAAK;AAAA,MACb,KAAK;AAAA,MACL,MAAM;AAAA,MACN,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,OAAO;AAAA,QACL,UAAU;AAAA,UACR,IAAI;AAAA,UACJ,IAAI;AAAA,UACJ,MAAM;AAAA,QACR;AAAA,QACA,MAAM;AAAA,UACJ,IAAI;AAAA,QACN;AAAA,MACF;AAAA,MACA,OAAO;AAAA,MACP,MAAM;AAAA,MACN,IAAI;AAAA,MACJ,YAAY;AAAA,MACZ,MAAM;AAAA,IACR,CAAC;AAGD,SAAK,WAAW,QAAQ,IAAI;AAAA,MAC1B,QAAQ,KAAK;AAAA,MACb,KAAK;AAAA,MACL,OAAO;AAAA,MACP,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,SAAS,KAAK,cAAc;AAAA,MAC5B,MAAM;AAAA,MACN,YAAY;AAAA,MACZ,OAAO;AAAA,QACL,IAAI;AAAA,MACN;AAAA,IACF,CAAC;AAGD,UAAM,SAAS,QAAQ,IAAI;AAAA,MACzB,QAAQ,KAAK;AAAA,MACb,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,MAAM;AAAA,MACN,OAAO;AAAA,QACL,IAAI;AAAA,QACJ,IAAI;AAAA,MACN;AAAA,IACF,CAAC;AAED,SAAK,UAAU,GAAG,UAAU,CAAC,MAAM,UAAU;AAC3C,YAAM,UAAU,MAAM,KAAK,KAAK,OAAO,KAAK,CAAC,EAAE,KAAK;AACpD,WAAK,YAAY,OAAO;AAAA,IAC1B,CAAC;AAGD,SAAK,uBAAuB;AAAA,EAC9B;AAAA,EAEQ,yBAA+B;AACrC,SAAK,UAAU,IAAI,CAAC,GAAG,GAAG,MAAM;AAC9B,UAAI,KAAK,eAAe;AACtB,aAAK,eAAe,KAAK,aAAa;AAAA,MACxC;AAAA,IACF,CAAC;AAED,SAAK,UAAU,IAAI,CAAC,GAAG,GAAG,MAAM;AAC9B,UAAI,KAAK,eAAe;AACtB,aAAK,aAAa,KAAK,aAAa;AAAA,MACtC;AAAA,IACF,CAAC;AAED,SAAK,UAAU,IAAI,CAAC,GAAG,GAAG,MAAM;AAC9B,UAAI,KAAK,eAAe;AACtB,aAAK,cAAc,KAAK,aAAa;AAAA,MACvC;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKQ,gBAAgB,OAA6B;AACnD,UAAM,SAAS,KAAK,cAAc,MAAM,MAAM;AAC9C,UAAM,OAAO,KAAK,iBAAiB,MAAM,IAAI;AAC7C,UAAM,cAAc,KAAK,MAAM,MAAM,cAAc,GAAG;AACtD,UAAM,YAAY,eAAe,KAAK,UAAU,eAAe,KAAK,WAAW;AAE/E,QAAI,OAAO,GAAG,MAAM,IAAI,IAAI,IAAI,MAAM,IAAI,KAAK,MAAM,GAAG,UAAU,GAAG,CAAC,CAAC;AAAA;AAEvE,QAAI,MAAM,aAAa;AACrB,YAAM,WAAW,KAAK,MAAM,MAAM,YAAY,WAAW,GAAG;AAC5D,YAAM,UAAU,KAAK,eAAe,KAAK,IAAI,IAAI,MAAM,YAAY,SAAS;AAC5E,cAAQ,sBAAiB,MAAM,YAAY,YAAY,UAAU,GAAG,EAAE,CAAC;AAAA;AACvE,cAAQ,gBAAgB,KAAK,kBAAkB,MAAM,YAAY,QAAQ,CAAC,IAAI,QAAQ,MAAM,OAAO;AAAA,IACrG,OAAO;AACL,cAAQ,iBAAiB,MAAM,cAAc,cAAc,MAAM,WAAW;AAAA;AAC5E,cAAQ,qBAAqB,SAAS,OAAO,WAAW,oBAAoB,KAAK,eAAe,MAAM,WAAW,CAAC;AAAA,IACpH;AAGA,QAAI,MAAM,aAAa,UAAa,MAAM,gBAAgB,QAAW;AACnE,cAAQ;AACR,UAAI,MAAM,aAAa,QAAW;AAChC,cAAM,WAAW,MAAM,WAAW,KAAK,QAAQ,MAAM,WAAW,KAAK,WAAW;AAChF,gBAAQ,SAAS,QAAQ,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AAAA,MAC5D;AACA,UAAI,MAAM,gBAAgB,QAAW;AACnC,cAAM,WAAW,MAAM,cAAc,KAAK,QAAQ,MAAM,cAAc,KAAK,WAAW;AACtF,gBAAQ,SAAS,QAAQ,OAAO,KAAK,MAAM,MAAM,WAAW,CAAC;AAAA,MAC/D;AACA,UAAI,MAAM,eAAe,QAAW;AAClC,gBAAQ,WAAW,KAAK,aAAa,MAAM,UAAU,CAAC;AAAA,MACxD;AAAA,IACF;AAGA,QAAI,MAAM,WAAW;AACnB,YAAM,WAAW,KAAK,eAAe,KAAK,IAAI,IAAI,MAAM,UAAU,SAAS;AAC3E,cAAQ;AAAA,0BAAwB,QAAQ,SAAS,MAAM,UAAU,QAAQ,UAAU,GAAG,EAAE,CAAC;AAAA,IAC3F;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,cAAc,QAAwB;AAC5C,YAAQ,QAAQ;AAAA,MACd,KAAK;AAAU,eAAO;AAAA,MACtB,KAAK;AAAQ,eAAO;AAAA,MACpB,KAAK;AAAS,eAAO;AAAA,MACrB,KAAK;AAAa,eAAO;AAAA,MACzB;AAAS,eAAO;AAAA,IAClB;AAAA,EACF;AAAA,EAEQ,iBAAiB,MAAsB;AAC7C,UAAM,QAAgC;AAAA,MACpC,YAAY;AAAA,MACZ,WAAW;AAAA,MACX,YAAY;AAAA,MACZ,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,cAAc;AAAA,MACd,cAAc;AAAA,MACd,YAAY;AAAA,MACZ,eAAe;AAAA,MACf,WAAW;AAAA,IACb;AACA,WAAO,MAAM,KAAK,YAAY,CAAC,KAAK;AAAA,EACtC;AAAA,EAEQ,kBAAkB,UAA0B;AAClD,UAAM,QAAQ;AACd,UAAM,SAAS,KAAK,MAAM,WAAW,KAAK;AAC1C,UAAM,QAAQ,QAAQ;AAEtB,UAAM,QAAQ,YAAY,MAAM,UAAU,YAAY,MAAM,WAAW;AACvE,WAAO,IAAI,KAAK,OAAO,SAAI,OAAO,MAAM,CAAC,eAAe,SAAI,OAAO,KAAK,CAAC;AAAA,EAC3E;AAAA,EAEQ,eAAe,IAAoB;AACzC,QAAI,KAAK,IAAM,QAAO,GAAG,EAAE;AAC3B,QAAI,KAAK,IAAO,QAAO,GAAG,KAAK,MAAM,KAAK,GAAI,CAAC;AAC/C,QAAI,KAAK,KAAS,QAAO,GAAG,KAAK,MAAM,KAAK,GAAK,CAAC;AAClD,WAAO,GAAG,KAAK,MAAM,KAAK,IAAO,CAAC;AAAA,EACpC;AAAA,EAEQ,aAAa,QAAwB;AAC3C,QAAI,SAAS,IAAM,QAAO,GAAG,MAAM;AACnC,QAAI,SAAS,IAAS,QAAO,IAAI,SAAS,KAAM,QAAQ,CAAC,CAAC;AAC1D,WAAO,IAAI,SAAS,KAAS,QAAQ,CAAC,CAAC;AAAA,EACzC;AAAA;AAAA;AAAA;AAAA,EAKQ,gBAAwB;AAC9B,UAAM,SAAS,MAAM,KAAK,KAAK,OAAO,OAAO,CAAC;AAE9C,QAAI,OAAO,WAAW,GAAG;AACvB,aAAO;AAAA,IACT;AAGA,UAAM,QAAQ;AAAA,MACZ,OAAO,OAAO;AAAA,MACd,QAAQ,OAAO,OAAO,CAAC,MAAW,EAAE,WAAW,QAAQ,EAAE;AAAA,MACzD,MAAM,OAAO,OAAO,CAAC,MAAW,EAAE,WAAW,MAAM,EAAE;AAAA,MACrD,OAAO,OAAO,OAAO,CAAC,MAAW,EAAE,WAAW,OAAO,EAAE;AAAA,MACvD,YAAY,OAAO,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,iBAAiB,EAAE,aAAa,CAAC;AAAA,MAC/E,iBAAiB,OAAO,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,gBAAgB,CAAC;AAAA,MACpE,aAAa,OAAO,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,aAAa,CAAC;AAAA,MAC7D,gBAAgB,OAAO,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,aAAa,CAAC,IAAI,OAAO;AAAA,MAC3E,aAAa,OAAO,OAAO,CAAC,KAAK,MAAM,OAAO,EAAE,cAAc,IAAI,CAAC;AAAA,MACnE,QAAQ,OAAO,OAAO,CAAC,KAAK,MAAM,OAAO,EAAE,YAAY,IAAI,CAAC,IAAI,OAAO;AAAA,MACvE,WAAW,OAAO,OAAO,CAAC,KAAK,MAAM,OAAO,EAAE,eAAe,IAAI,CAAC,IAAI,OAAO;AAAA,IAC/E;AAGA,UAAM,aAAa,oBAAI,IAAoB;AAC3C,WAAO,QAAQ,WAAS;AACtB,iBAAW,IAAI,MAAM,OAAO,WAAW,IAAI,MAAM,IAAI,KAAK,KAAK,CAAC;AAAA,IAClE,CAAC;AAED,QAAI,SAAS;AAEb,cAAU;AACV,cAAU,YAAY,MAAM,KAAK;AAAA;AACjC,cAAU,uBAAuB,MAAM,MAAM;AAAA;AAC7C,cAAU,oBAAoB,MAAM,IAAI;AAAA;AACxC,cAAU,oBAAoB,MAAM,KAAK;AAAA;AAEzC,cAAU;AACV,cAAU,YAAY,MAAM,eAAe,IAAI,MAAM,UAAU;AAAA;AAC/D,UAAM,YAAY,MAAM,kBAAkB,MAAM,UAAU,MAAM,kBAAkB,MAAM,WAAW;AACnG,cAAU,eAAe,SAAS,OAAO,KAAK,MAAM,MAAM,iBAAiB,GAAG,CAAC;AAAA;AAC/E,cAAU,aAAa,KAAK,aAAa,MAAM,WAAW,CAAC;AAAA;AAE3D,cAAU;AACV,UAAM,WAAW,MAAM,SAAS,KAAK,QAAQ,MAAM,SAAS,KAAK,WAAW;AAC5E,UAAM,WAAW,MAAM,YAAY,KAAK,QAAQ,MAAM,YAAY,KAAK,WAAW;AAClF,cAAU,WAAW,QAAQ,OAAO,KAAK,MAAM,MAAM,MAAM,CAAC;AAAA;AAC5D,cAAU,cAAc,QAAQ,OAAO,KAAK,MAAM,MAAM,SAAS,CAAC;AAAA;AAElE,cAAU;AACV,UAAM,KAAK,WAAW,QAAQ,CAAC,EAC5B,KAAK,CAAC,GAAG,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,EAC1B,QAAQ,CAAC,CAAC,MAAM,KAAK,MAAM;AAC1B,YAAM,OAAO,KAAK,iBAAiB,IAAI;AACvC,gBAAU,KAAK,IAAI,IAAI,IAAI,KAAK,KAAK;AAAA;AAAA,IACvC,CAAC;AAEH,WAAO;AAAA,EACT;AAAA,EAEO,OAAO,QAA8B;AAE1C,SAAK,OAAO,MAAM;AAClB,WAAO,QAAQ,WAAS;AACtB,WAAK,OAAO,IAAI,MAAM,IAAI,KAAK;AAAA,IACjC,CAAC;AAGD,UAAM,QAAQ,OAAO,IAAI,CAAC,UAAe,KAAK,gBAAgB,KAAK,CAAC;AACpE,SAAK,UAAU,SAAS,KAAK;AAG7B,SAAK,SAAS,WAAW,KAAK,cAAc,CAAC;AAG7C,UAAM,SAAS,OAAO,OAAO,CAAC,MAAW,EAAE,WAAW,QAAQ,EAAE;AAChE,UAAM,OAAO,OAAO,OAAO,CAAC,MAAW,EAAE,WAAW,MAAM,EAAE;AAC5D,UAAM,QAAQ,OAAO;AAErB,UAAM,SAAS,KAAK,UAAU,SAAS,CAAC;AACxC,QAAI,QAAQ;AACV,aAAO;AAAA,QACL,mBAAmB,KAAK,wCACM,MAAM,iCACT,IAAI;AAAA,MACjC;AAAA,IACF;AAEA,SAAK,UAAU,OAAO,OAAO;AAAA,EAC/B;AAAA,EAEQ,YAAY,SAAuB;AACzC,SAAK,gBAAgB;AACrB,UAAM,QAAQ,KAAK,OAAO,IAAI,OAAO;AACrC,QAAI,OAAO;AACT,WAAK,KAAK,kBAAkB,KAAK;AACjC,WAAK,iBAAiB,KAAK;AAAA,IAC7B;AAAA,EACF;AAAA,EAEQ,iBAAiB,OAA2B;AAClD,UAAM,UAAU,QAAQ,IAAI;AAAA,MAC1B,QAAQ,KAAK,UAAU;AAAA,MACvB,KAAK;AAAA,MACL,MAAM;AAAA,MACN,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,SAAS,KAAK,mBAAmB,KAAK;AAAA,MACtC,MAAM;AAAA,MACN,QAAQ;AAAA,QACN,MAAM;AAAA,MACR;AAAA,MACA,OAAO;AAAA,QACL,QAAQ;AAAA,UACN,IAAI;AAAA,QACN;AAAA,MACF;AAAA,MACA,YAAY;AAAA,MACZ,MAAM;AAAA,MACN,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,OAAO,WAAW,MAAM,IAAI,KAAK,MAAM,EAAE;AAAA,IAC3C,CAAC;AAED,YAAQ,IAAI,CAAC,UAAU,GAAG,GAAG,MAAM;AACjC,cAAQ,QAAQ;AAChB,WAAK,UAAU,OAAO,OAAO;AAAA,IAC/B,CAAC;AAED,YAAQ,MAAM;AACd,SAAK,UAAU,OAAO,OAAO;AAAA,EAC/B;AAAA,EAEQ,mBAAmB,OAA6B;AACtD,QAAI,UAAU,sBAAsB,MAAM,EAAE;AAAA;AAC5C,eAAW,kBAAkB,KAAK,iBAAiB,MAAM,IAAI,CAAC,IAAI,MAAM,IAAI;AAAA;AAC5E,eAAW,oBAAoB,KAAK,cAAc,MAAM,MAAM,CAAC,IAAI,MAAM,MAAM;AAAA;AAE/E,QAAI,MAAM,aAAa;AACrB,iBAAW;AAAA;AAAA;AACX,iBAAW,SAAS,MAAM,YAAY,EAAE;AAAA;AACxC,iBAAW,kBAAkB,MAAM,YAAY,WAAW;AAAA;AAC1D,iBAAW,eAAe,KAAK,MAAM,MAAM,YAAY,WAAW,GAAG,CAAC;AAAA;AACtE,iBAAW,cAAc,IAAI,KAAK,MAAM,YAAY,SAAS,EAAE,eAAe,CAAC;AAAA;AAC/E,iBAAW,cAAc,KAAK,eAAe,KAAK,IAAI,IAAI,MAAM,YAAY,SAAS,CAAC;AAAA;AAAA,IACxF;AAEA,eAAW;AAAA;AAAA;AACX,eAAW,sBAAsB,MAAM,cAAc;AAAA;AACrD,eAAW,mBAAmB,MAAM,WAAW;AAAA;AAC/C,eAAW,mBAAmB,KAAK,MAAM,MAAM,cAAc,GAAG,CAAC;AAAA;AACjE,eAAW,mBAAmB,KAAK,eAAe,MAAM,WAAW,CAAC;AAAA;AAEpE,QAAI,MAAM,aAAa,UAAa,MAAM,gBAAgB,UAAa,MAAM,eAAe,QAAW;AACrG,iBAAW;AAAA;AAAA;AACX,UAAI,MAAM,aAAa,QAAW;AAChC,mBAAW,UAAU,KAAK,MAAM,MAAM,QAAQ,CAAC;AAAA;AAAA,MACjD;AACA,UAAI,MAAM,gBAAgB,QAAW;AACnC,mBAAW,aAAa,KAAK,MAAM,MAAM,WAAW,CAAC;AAAA;AAAA,MACvD;AACA,UAAI,MAAM,eAAe,QAAW;AAClC,mBAAW,aAAa,KAAK,aAAa,MAAM,UAAU,CAAC;AAAA;AAAA,MAC7D;AAAA,IACF;AAEA,QAAI,MAAM,WAAW;AACnB,iBAAW;AAAA;AAAA;AACX,iBAAW,cAAc,MAAM,UAAU,OAAO;AAAA;AAChD,iBAAW,WAAW,IAAI,KAAK,MAAM,UAAU,SAAS,EAAE,eAAe,CAAC;AAAA;AAC1E,iBAAW,kBAAkB,MAAM,UAAU,cAAc,QAAQ,IAAI;AAAA;AAAA,IACzE;AAEA,eAAW;AAAA;AAAA;AAEX,WAAO;AAAA,EACT;AAAA,EAEQ,eAAe,SAAuB;AAC5C,SAAK,KAAK,mBAAmB,EAAE,QAAQ,CAAC;AAExC,UAAM,QAAQ,KAAK,OAAO,IAAI,OAAO;AACrC,QAAI,OAAO;AACT,YAAM,SAAS;AACf,WAAK,OAAO,MAAM,KAAK,KAAK,OAAO,OAAO,CAAC,CAAC;AAAA,IAC9C;AAAA,EACF;AAAA,EAEQ,aAAa,SAAuB;AAC1C,SAAK,KAAK,iBAAiB,EAAE,QAAQ,CAAC;AAEtC,UAAM,QAAQ,KAAK,OAAO,IAAI,OAAO;AACrC,QAAI,OAAO;AACT,YAAM,SAAS;AACf,YAAM,YAAY;AAClB,WAAK,OAAO,MAAM,KAAK,KAAK,OAAO,OAAO,CAAC,CAAC;AAAA,IAC9C;AAAA,EACF;AAAA,EAEQ,cAAc,SAAuB;AAC3C,SAAK,KAAK,cAAc,EAAE,QAAQ,CAAC;AAAA,EACrC;AAAA,EAEO,QAAc;AACnB,SAAK,UAAU,MAAM;AAAA,EACvB;AAAA,EAEO,WAAoB;AACzB,WAAO,KAAK,cAAc,KAAK,UAAU,OAAO;AAAA,EAClD;AACF;",
6
6
  "names": []
7
7
  }