prjct-cli 0.11.4 → 0.12.0

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 (385) hide show
  1. package/CHANGELOG.md +72 -0
  2. package/README.md +81 -25
  3. package/bin/dev.js +1 -1
  4. package/bin/generate-views.js +209 -0
  5. package/bin/migrate-to-json.js +742 -0
  6. package/bin/prjct +5 -5
  7. package/bin/serve.js +246 -54
  8. package/core/__tests__/agentic/{memory-system.test.js → memory-system.test.ts} +12 -23
  9. package/core/__tests__/agentic/{plan-mode.test.js → plan-mode.test.ts} +26 -24
  10. package/core/__tests__/agentic/{prompt-builder.test.js → prompt-builder.test.ts} +3 -8
  11. package/core/__tests__/utils/date-helper.test.ts +405 -0
  12. package/core/__tests__/utils/{output.test.js → output.test.ts} +12 -24
  13. package/core/agentic/agent-router.ts +137 -0
  14. package/core/agentic/chain-of-thought.ts +228 -0
  15. package/core/agentic/command-executor/command-executor.ts +384 -0
  16. package/core/agentic/command-executor/index.ts +16 -0
  17. package/core/agentic/command-executor/status-signal.ts +38 -0
  18. package/core/agentic/command-executor/types.ts +79 -0
  19. package/core/agentic/command-executor.ts +8 -0
  20. package/core/agentic/{context-builder.js → context-builder.ts} +99 -89
  21. package/core/agentic/context-filter.ts +365 -0
  22. package/core/agentic/ground-truth/index.ts +76 -0
  23. package/core/agentic/ground-truth/types.ts +33 -0
  24. package/core/agentic/ground-truth/utils.ts +48 -0
  25. package/core/agentic/ground-truth/verifiers/analyze.ts +54 -0
  26. package/core/agentic/ground-truth/verifiers/done.ts +75 -0
  27. package/core/agentic/ground-truth/verifiers/feature.ts +70 -0
  28. package/core/agentic/ground-truth/verifiers/index.ts +37 -0
  29. package/core/agentic/ground-truth/verifiers/init.ts +52 -0
  30. package/core/agentic/ground-truth/verifiers/now.ts +57 -0
  31. package/core/agentic/ground-truth/verifiers/ship.ts +85 -0
  32. package/core/agentic/ground-truth/verifiers/spec.ts +45 -0
  33. package/core/agentic/ground-truth/verifiers/sync.ts +47 -0
  34. package/core/agentic/ground-truth/verifiers.ts +6 -0
  35. package/core/agentic/ground-truth.ts +8 -0
  36. package/core/agentic/loop-detector/error-analysis.ts +97 -0
  37. package/core/agentic/loop-detector/hallucination.ts +71 -0
  38. package/core/agentic/loop-detector/index.ts +41 -0
  39. package/core/agentic/loop-detector/loop-detector.ts +222 -0
  40. package/core/agentic/loop-detector/types.ts +66 -0
  41. package/core/agentic/loop-detector.ts +8 -0
  42. package/core/agentic/memory-system/history.ts +53 -0
  43. package/core/agentic/memory-system/index.ts +192 -0
  44. package/core/agentic/memory-system/patterns.ts +156 -0
  45. package/core/agentic/memory-system/semantic-memories.ts +277 -0
  46. package/core/agentic/memory-system/session.ts +21 -0
  47. package/core/agentic/memory-system/types.ts +159 -0
  48. package/core/agentic/memory-system.ts +8 -0
  49. package/core/agentic/parallel-tools.ts +165 -0
  50. package/core/agentic/plan-mode/approval.ts +57 -0
  51. package/core/agentic/plan-mode/constants.ts +44 -0
  52. package/core/agentic/plan-mode/index.ts +28 -0
  53. package/core/agentic/plan-mode/plan-mode.ts +406 -0
  54. package/core/agentic/plan-mode/types.ts +193 -0
  55. package/core/agentic/plan-mode.ts +8 -0
  56. package/core/agentic/prompt-builder.ts +566 -0
  57. package/core/agentic/response-templates.ts +164 -0
  58. package/core/agentic/semantic-compression.ts +273 -0
  59. package/core/agentic/services.ts +206 -0
  60. package/core/agentic/smart-context.ts +476 -0
  61. package/core/agentic/{template-loader.js → template-loader.ts} +35 -18
  62. package/core/agentic/think-blocks.ts +202 -0
  63. package/core/agentic/tool-registry.ts +119 -0
  64. package/core/agentic/validation-rules.ts +313 -0
  65. package/core/agents/index.ts +28 -0
  66. package/core/agents/performance.ts +444 -0
  67. package/core/agents/types.ts +126 -0
  68. package/core/bus/{index.js → index.ts} +57 -61
  69. package/core/command-registry/categories.ts +23 -0
  70. package/core/command-registry/commands.ts +15 -0
  71. package/core/command-registry/core-commands.ts +319 -0
  72. package/core/command-registry/index.ts +158 -0
  73. package/core/command-registry/optional-commands.ts +119 -0
  74. package/core/command-registry/setup-commands.ts +53 -0
  75. package/core/command-registry/types.ts +59 -0
  76. package/core/command-registry.ts +9 -0
  77. package/core/commands/analysis.ts +298 -0
  78. package/core/commands/analytics.ts +288 -0
  79. package/core/commands/base.ts +273 -0
  80. package/core/commands/index.ts +211 -0
  81. package/core/commands/maintenance.ts +226 -0
  82. package/core/commands/planning.ts +311 -0
  83. package/core/commands/setup.ts +309 -0
  84. package/core/commands/shipping.ts +188 -0
  85. package/core/commands/types.ts +183 -0
  86. package/core/commands/workflow.ts +226 -0
  87. package/core/commands.ts +11 -0
  88. package/core/constants/formats.ts +187 -0
  89. package/core/constants/index.ts +7 -0
  90. package/core/{context-sync.js → context-sync.ts} +59 -26
  91. package/core/data/agents-manager.ts +76 -0
  92. package/core/data/analysis-manager.ts +83 -0
  93. package/core/data/base-manager.ts +156 -0
  94. package/core/data/ideas-manager.ts +81 -0
  95. package/core/data/index.ts +32 -0
  96. package/core/data/outcomes-manager.ts +96 -0
  97. package/core/data/project-manager.ts +75 -0
  98. package/core/data/roadmap-manager.ts +118 -0
  99. package/core/data/shipped-manager.ts +65 -0
  100. package/core/data/state-manager.ts +214 -0
  101. package/core/domain/{agent-generator.js → agent-generator.ts} +77 -57
  102. package/core/domain/{agent-loader.js → agent-loader.ts} +65 -56
  103. package/core/domain/{agent-matcher.js → agent-matcher.ts} +51 -24
  104. package/core/domain/{agent-validator.js → agent-validator.ts} +70 -37
  105. package/core/domain/{analyzer.js → analyzer.ts} +91 -85
  106. package/core/domain/{architect-session.js → architect-session.ts} +49 -34
  107. package/core/domain/{architecture-generator.js → architecture-generator.ts} +25 -13
  108. package/core/domain/{context-estimator.js → context-estimator.ts} +57 -36
  109. package/core/domain/{product-standards.js → product-standards.ts} +40 -26
  110. package/core/domain/{smart-cache.js → smart-cache.ts} +39 -30
  111. package/core/domain/{snapshot-manager.js → snapshot-manager.ts} +103 -100
  112. package/core/domain/{task-analyzer.js → task-analyzer.ts} +82 -43
  113. package/core/domain/task-stack/index.ts +19 -0
  114. package/core/domain/task-stack/parser.ts +86 -0
  115. package/core/domain/task-stack/storage.ts +123 -0
  116. package/core/domain/task-stack/task-stack.ts +340 -0
  117. package/core/domain/task-stack/types.ts +51 -0
  118. package/core/domain/task-stack.ts +8 -0
  119. package/core/{index.js → index.ts} +61 -18
  120. package/core/infrastructure/{agent-detector.js → agent-detector.ts} +62 -23
  121. package/core/infrastructure/agents/{claude-agent.js → claude-agent.ts} +61 -21
  122. package/core/infrastructure/{author-detector.js → author-detector.ts} +42 -49
  123. package/core/infrastructure/{capability-installer.js → capability-installer.ts} +51 -27
  124. package/core/infrastructure/{command-installer.js → command-installer/command-installer.ts} +43 -144
  125. package/core/infrastructure/command-installer/global-config.ts +106 -0
  126. package/core/infrastructure/command-installer/index.ts +25 -0
  127. package/core/infrastructure/command-installer/types.ts +41 -0
  128. package/core/infrastructure/command-installer.ts +8 -0
  129. package/core/infrastructure/{config-manager.js → config-manager.ts} +60 -80
  130. package/core/infrastructure/{editors-config.js → editors-config.ts} +33 -31
  131. package/core/infrastructure/legacy-installer-detector/cleanup.ts +216 -0
  132. package/core/infrastructure/legacy-installer-detector/detection.ts +95 -0
  133. package/core/infrastructure/legacy-installer-detector/index.ts +171 -0
  134. package/core/infrastructure/legacy-installer-detector/migration.ts +87 -0
  135. package/core/infrastructure/legacy-installer-detector/types.ts +42 -0
  136. package/core/infrastructure/legacy-installer-detector.ts +7 -0
  137. package/core/infrastructure/migrator/file-operations.ts +125 -0
  138. package/core/infrastructure/migrator/index.ts +288 -0
  139. package/core/infrastructure/migrator/project-scanner.ts +89 -0
  140. package/core/infrastructure/migrator/reports.ts +117 -0
  141. package/core/infrastructure/migrator/types.ts +124 -0
  142. package/core/infrastructure/migrator/validation.ts +94 -0
  143. package/core/infrastructure/migrator/version-migration.ts +117 -0
  144. package/core/infrastructure/migrator.ts +10 -0
  145. package/core/infrastructure/{path-manager.js → path-manager.ts} +51 -91
  146. package/core/infrastructure/session-manager/index.ts +23 -0
  147. package/core/infrastructure/session-manager/migration.ts +88 -0
  148. package/core/infrastructure/session-manager/session-manager.ts +307 -0
  149. package/core/infrastructure/session-manager/types.ts +45 -0
  150. package/core/infrastructure/session-manager.ts +8 -0
  151. package/core/infrastructure/{setup.js → setup.ts} +29 -21
  152. package/core/infrastructure/{update-checker.js → update-checker.ts} +40 -18
  153. package/core/outcomes/analyzer.ts +333 -0
  154. package/core/outcomes/index.ts +34 -0
  155. package/core/outcomes/recorder.ts +194 -0
  156. package/core/outcomes/types.ts +145 -0
  157. package/core/plugin/{hooks.js → hooks.ts} +56 -58
  158. package/core/plugin/{index.js → index.ts} +19 -8
  159. package/core/plugin/{loader.js → loader.ts} +87 -69
  160. package/core/plugin/{registry.js → registry.ts} +49 -45
  161. package/core/plugins/{webhook.js → webhook.ts} +43 -27
  162. package/core/schemas/agents.ts +27 -0
  163. package/core/schemas/analysis.ts +41 -0
  164. package/core/schemas/ideas.ts +83 -0
  165. package/core/schemas/index.ts +73 -0
  166. package/core/schemas/outcomes.ts +22 -0
  167. package/core/schemas/project.ts +26 -0
  168. package/core/schemas/roadmap.ts +90 -0
  169. package/core/schemas/shipped.ts +82 -0
  170. package/core/schemas/state.ts +107 -0
  171. package/core/session/index.ts +17 -0
  172. package/core/session/{metrics.js → metrics.ts} +64 -46
  173. package/core/session/{index.js → session-manager.ts} +51 -117
  174. package/core/session/types.ts +29 -0
  175. package/core/session/utils.ts +57 -0
  176. package/core/state/index.ts +25 -0
  177. package/core/state/manager.ts +376 -0
  178. package/core/state/types.ts +185 -0
  179. package/core/tsconfig.json +22 -0
  180. package/core/types/index.ts +506 -0
  181. package/core/utils/{animations.js → animations.ts} +74 -28
  182. package/core/utils/{branding.js → branding.ts} +29 -4
  183. package/core/utils/{date-helper.js → date-helper.ts} +31 -74
  184. package/core/utils/file-helper.ts +262 -0
  185. package/core/utils/{jsonl-helper.js → jsonl-helper.ts} +71 -107
  186. package/core/utils/{logger.js → logger.ts} +24 -12
  187. package/core/utils/{output.js → output.ts} +25 -13
  188. package/core/utils/{project-capabilities.js → project-capabilities.ts} +31 -18
  189. package/core/utils/{session-helper.js → session-helper.ts} +79 -66
  190. package/core/utils/{version.js → version.ts} +23 -31
  191. package/core/view-generator.ts +536 -0
  192. package/package.json +23 -17
  193. package/packages/shared/.turbo/turbo-build.log +14 -0
  194. package/packages/shared/dist/index.d.ts +8 -613
  195. package/packages/shared/dist/index.d.ts.map +1 -0
  196. package/packages/shared/dist/index.js +4110 -118
  197. package/packages/shared/dist/schemas.d.ts +408 -0
  198. package/packages/shared/dist/schemas.d.ts.map +1 -0
  199. package/packages/shared/dist/types.d.ts +144 -0
  200. package/packages/shared/dist/types.d.ts.map +1 -0
  201. package/packages/shared/dist/unified.d.ts +139 -0
  202. package/packages/shared/dist/unified.d.ts.map +1 -0
  203. package/packages/shared/dist/utils.d.ts +60 -0
  204. package/packages/shared/dist/utils.d.ts.map +1 -0
  205. package/packages/shared/package.json +4 -4
  206. package/packages/shared/src/index.ts +1 -0
  207. package/packages/shared/src/unified.ts +174 -0
  208. package/packages/web/app/api/claude/sessions/route.ts +1 -1
  209. package/packages/web/app/api/claude/status/route.ts +1 -1
  210. package/packages/web/app/api/migrate/route.ts +46 -0
  211. package/packages/web/app/api/projects/[id]/route.ts +1 -1
  212. package/packages/web/app/api/projects/[id]/stats/route.ts +30 -2
  213. package/packages/web/app/api/projects/[id]/status/route.ts +1 -1
  214. package/packages/web/app/api/projects/route.ts +1 -1
  215. package/packages/web/app/api/settings/route.ts +97 -0
  216. package/packages/web/app/api/v2/projects/[id]/unified/route.ts +57 -0
  217. package/packages/web/app/globals.css +38 -0
  218. package/packages/web/app/layout.tsx +10 -2
  219. package/packages/web/app/page.tsx +9 -224
  220. package/packages/web/app/project/[id]/page.tsx +191 -63
  221. package/packages/web/app/project/[id]/stats/loading.tsx +43 -0
  222. package/packages/web/app/project/[id]/stats/page.tsx +203 -403
  223. package/packages/web/app/settings/page.tsx +222 -2
  224. package/packages/web/components/ActivityTimeline/ActivityTimeline.constants.ts +2 -0
  225. package/packages/web/components/ActivityTimeline/ActivityTimeline.tsx +50 -0
  226. package/packages/web/components/ActivityTimeline/ActivityTimeline.types.ts +8 -0
  227. package/packages/web/components/ActivityTimeline/hooks/index.ts +2 -0
  228. package/packages/web/components/ActivityTimeline/hooks/useExpandable.ts +9 -0
  229. package/packages/web/components/ActivityTimeline/hooks/useGroupedEvents.ts +23 -0
  230. package/packages/web/components/ActivityTimeline/index.ts +2 -0
  231. package/packages/web/components/AgentsCard/AgentsCard.tsx +63 -0
  232. package/packages/web/components/AgentsCard/AgentsCard.types.ts +13 -0
  233. package/packages/web/components/AgentsCard/index.ts +2 -0
  234. package/packages/web/components/AppSidebar/AppSidebar.tsx +134 -0
  235. package/packages/web/components/AppSidebar/index.ts +1 -0
  236. package/packages/web/components/BackLink/BackLink.tsx +18 -0
  237. package/packages/web/components/BackLink/BackLink.types.ts +5 -0
  238. package/packages/web/components/BackLink/index.ts +2 -0
  239. package/packages/web/components/BentoCard/BentoCard.constants.ts +16 -0
  240. package/packages/web/components/BentoCard/BentoCard.tsx +47 -0
  241. package/packages/web/components/BentoCard/BentoCard.types.ts +15 -0
  242. package/packages/web/components/BentoCard/index.ts +2 -0
  243. package/packages/web/components/BentoCardSkeleton/BentoCardSkeleton.constants.ts +9 -0
  244. package/packages/web/components/BentoCardSkeleton/BentoCardSkeleton.tsx +18 -0
  245. package/packages/web/components/BentoCardSkeleton/BentoCardSkeleton.types.ts +5 -0
  246. package/packages/web/components/BentoCardSkeleton/index.ts +2 -0
  247. package/packages/web/components/BentoGrid/BentoGrid.tsx +18 -0
  248. package/packages/web/components/BentoGrid/BentoGrid.types.ts +4 -0
  249. package/packages/web/components/BentoGrid/index.ts +2 -0
  250. package/packages/web/components/CommandButton/index.ts +1 -0
  251. package/packages/web/components/ConnectionStatus/index.ts +1 -0
  252. package/packages/web/components/DashboardContent/DashboardContent.tsx +254 -0
  253. package/packages/web/components/DashboardContent/index.ts +1 -0
  254. package/packages/web/components/DateGroup/DateGroup.tsx +18 -0
  255. package/packages/web/components/DateGroup/DateGroup.types.ts +6 -0
  256. package/packages/web/components/DateGroup/DateGroup.utils.ts +11 -0
  257. package/packages/web/components/DateGroup/index.ts +2 -0
  258. package/packages/web/components/EmptyState/EmptyState.tsx +58 -0
  259. package/packages/web/components/EmptyState/EmptyState.types.ts +10 -0
  260. package/packages/web/components/EmptyState/index.ts +2 -0
  261. package/packages/web/components/EventRow/EventRow.constants.ts +10 -0
  262. package/packages/web/components/EventRow/EventRow.tsx +49 -0
  263. package/packages/web/components/EventRow/EventRow.types.ts +7 -0
  264. package/packages/web/components/EventRow/EventRow.utils.ts +49 -0
  265. package/packages/web/components/EventRow/index.ts +2 -0
  266. package/packages/web/components/ExpandButton/ExpandButton.tsx +18 -0
  267. package/packages/web/components/ExpandButton/ExpandButton.types.ts +6 -0
  268. package/packages/web/components/ExpandButton/index.ts +2 -0
  269. package/packages/web/components/HealthGradientBackground/HealthGradientBackground.tsx +14 -0
  270. package/packages/web/components/HealthGradientBackground/HealthGradientBackground.types.ts +5 -0
  271. package/packages/web/components/HealthGradientBackground/HealthGradientBackground.utils.ts +13 -0
  272. package/packages/web/components/HealthGradientBackground/index.ts +2 -0
  273. package/packages/web/components/HeroSection/HeroSection.tsx +55 -0
  274. package/packages/web/components/HeroSection/HeroSection.types.ts +14 -0
  275. package/packages/web/components/HeroSection/HeroSection.utils.ts +7 -0
  276. package/packages/web/components/HeroSection/hooks/index.ts +2 -0
  277. package/packages/web/components/HeroSection/hooks/useCountUp.ts +45 -0
  278. package/packages/web/components/HeroSection/hooks/useWeeklyActivity.ts +18 -0
  279. package/packages/web/components/HeroSection/index.ts +2 -0
  280. package/packages/web/components/IdeasCard/IdeasCard.tsx +48 -0
  281. package/packages/web/components/IdeasCard/IdeasCard.types.ts +9 -0
  282. package/packages/web/components/IdeasCard/index.ts +2 -0
  283. package/packages/web/components/InsightMessage/InsightMessage.tsx +9 -0
  284. package/packages/web/components/InsightMessage/InsightMessage.types.ts +3 -0
  285. package/packages/web/components/InsightMessage/index.ts +2 -0
  286. package/packages/web/components/Logo/index.ts +1 -0
  287. package/packages/web/components/MarkdownContent/index.ts +1 -0
  288. package/packages/web/components/NowCard/NowCard.tsx +93 -0
  289. package/packages/web/components/NowCard/NowCard.types.ts +15 -0
  290. package/packages/web/components/NowCard/index.ts +2 -0
  291. package/packages/web/components/ProgressRing/ProgressRing.constants.ts +20 -0
  292. package/packages/web/components/ProgressRing/ProgressRing.tsx +51 -0
  293. package/packages/web/components/ProgressRing/ProgressRing.types.ts +11 -0
  294. package/packages/web/components/ProgressRing/index.ts +2 -0
  295. package/packages/web/components/ProjectAvatar/index.ts +1 -0
  296. package/packages/web/components/Providers/index.ts +1 -0
  297. package/packages/web/components/QueueCard/QueueCard.tsx +72 -0
  298. package/packages/web/components/QueueCard/QueueCard.types.ts +11 -0
  299. package/packages/web/components/QueueCard/QueueCard.utils.ts +12 -0
  300. package/packages/web/components/QueueCard/index.ts +2 -0
  301. package/packages/web/components/RoadmapCard/RoadmapCard.tsx +77 -0
  302. package/packages/web/components/RoadmapCard/RoadmapCard.types.ts +15 -0
  303. package/packages/web/components/RoadmapCard/index.ts +2 -0
  304. package/packages/web/components/ShipsCard/ShipsCard.tsx +52 -0
  305. package/packages/web/components/ShipsCard/ShipsCard.types.ts +12 -0
  306. package/packages/web/components/ShipsCard/ShipsCard.utils.ts +4 -0
  307. package/packages/web/components/ShipsCard/index.ts +2 -0
  308. package/packages/web/components/SparklineChart/SparklineChart.tsx +38 -0
  309. package/packages/web/components/SparklineChart/SparklineChart.types.ts +6 -0
  310. package/packages/web/components/SparklineChart/index.ts +2 -0
  311. package/packages/web/components/StreakCard/StreakCard.constants.ts +2 -0
  312. package/packages/web/components/StreakCard/StreakCard.tsx +53 -0
  313. package/packages/web/components/StreakCard/StreakCard.types.ts +4 -0
  314. package/packages/web/components/StreakCard/index.ts +2 -0
  315. package/packages/web/components/TasksCounter/TasksCounter.tsx +14 -0
  316. package/packages/web/components/TasksCounter/TasksCounter.types.ts +3 -0
  317. package/packages/web/components/TasksCounter/index.ts +2 -0
  318. package/packages/web/components/TechStackBadges/index.ts +1 -0
  319. package/packages/web/components/{TerminalTab.tsx → TerminalTabs/TerminalTab.tsx} +11 -0
  320. package/packages/web/components/{TerminalTabs.tsx → TerminalTabs/TerminalTabs.tsx} +29 -28
  321. package/packages/web/components/TerminalTabs/index.ts +1 -0
  322. package/packages/web/components/VelocityBadge/VelocityBadge.tsx +27 -0
  323. package/packages/web/components/VelocityBadge/VelocityBadge.types.ts +3 -0
  324. package/packages/web/components/VelocityBadge/index.ts +2 -0
  325. package/packages/web/components/VelocityCard/VelocityCard.tsx +71 -0
  326. package/packages/web/components/VelocityCard/VelocityCard.types.ts +7 -0
  327. package/packages/web/components/VelocityCard/index.ts +2 -0
  328. package/packages/web/components/WeeklySparkline/WeeklySparkline.tsx +13 -0
  329. package/packages/web/components/WeeklySparkline/WeeklySparkline.types.ts +3 -0
  330. package/packages/web/components/WeeklySparkline/index.ts +2 -0
  331. package/packages/web/components/ui/input.tsx +21 -0
  332. package/packages/web/components/ui/tooltip.tsx +2 -2
  333. package/packages/web/context/TerminalTabsContext.tsx +46 -1
  334. package/packages/web/hooks/useClaudeTerminal.ts +71 -21
  335. package/packages/web/hooks/useProjectStats.ts +55 -0
  336. package/packages/web/hooks/useProjects.ts +6 -6
  337. package/packages/web/lib/actions/projects.ts +15 -0
  338. package/packages/web/lib/json-loader.ts +630 -0
  339. package/packages/web/lib/services/index.ts +9 -0
  340. package/packages/web/lib/services/migration.server.ts +598 -0
  341. package/packages/web/lib/services/projects.server.ts +52 -0
  342. package/packages/web/lib/services/stats.server.ts +264 -0
  343. package/packages/web/lib/unified-loader.ts +396 -0
  344. package/packages/web/next-env.d.ts +1 -1
  345. package/packages/web/package.json +10 -6
  346. package/packages/web/server.ts +36 -6
  347. package/templates/commands/done.md +76 -32
  348. package/templates/commands/feature.md +121 -47
  349. package/templates/commands/idea.md +81 -8
  350. package/templates/commands/now.md +41 -17
  351. package/templates/commands/ship.md +64 -25
  352. package/templates/commands/sync.md +28 -3
  353. package/core/agentic/agent-router.js +0 -128
  354. package/core/agentic/chain-of-thought.js +0 -578
  355. package/core/agentic/command-executor.js +0 -421
  356. package/core/agentic/context-filter.js +0 -354
  357. package/core/agentic/ground-truth.js +0 -591
  358. package/core/agentic/loop-detector.js +0 -406
  359. package/core/agentic/memory-system.js +0 -850
  360. package/core/agentic/parallel-tools.js +0 -366
  361. package/core/agentic/plan-mode.js +0 -572
  362. package/core/agentic/prompt-builder.js +0 -338
  363. package/core/agentic/response-templates.js +0 -290
  364. package/core/agentic/semantic-compression.js +0 -517
  365. package/core/agentic/think-blocks.js +0 -657
  366. package/core/agentic/tool-registry.js +0 -184
  367. package/core/agentic/validation-rules.js +0 -380
  368. package/core/command-registry.js +0 -698
  369. package/core/commands.js +0 -2237
  370. package/core/domain/task-stack.js +0 -497
  371. package/core/infrastructure/legacy-installer-detector.js +0 -546
  372. package/core/infrastructure/migrator.js +0 -799
  373. package/core/infrastructure/session-manager.js +0 -390
  374. package/core/utils/file-helper.js +0 -329
  375. package/packages/web/app/api/projects/[id]/delete/route.ts +0 -21
  376. package/packages/web/app/api/stats/route.ts +0 -38
  377. package/packages/web/components/AppSidebar.tsx +0 -113
  378. package/packages/web/hooks/useStats.ts +0 -28
  379. /package/packages/web/components/{CommandButton.tsx → CommandButton/CommandButton.tsx} +0 -0
  380. /package/packages/web/components/{ConnectionStatus.tsx → ConnectionStatus/ConnectionStatus.tsx} +0 -0
  381. /package/packages/web/components/{Logo.tsx → Logo/Logo.tsx} +0 -0
  382. /package/packages/web/components/{MarkdownContent.tsx → MarkdownContent/MarkdownContent.tsx} +0 -0
  383. /package/packages/web/components/{ProjectAvatar.tsx → ProjectAvatar/ProjectAvatar.tsx} +0 -0
  384. /package/packages/web/components/{providers.tsx → Providers/Providers.tsx} +0 -0
  385. /package/packages/web/components/{TechStackBadges.tsx → TechStackBadges/TechStackBadges.tsx} +0 -0
@@ -0,0 +1,333 @@
1
+ /**
2
+ * Outcome Analyzer
3
+ *
4
+ * Analyzes outcomes to extract patterns and insights.
5
+ * Powers the learning loop for better estimates and agent selection.
6
+ */
7
+
8
+ import outcomeRecorder from './recorder'
9
+ import type { Outcome, OutcomeSummary, QualityScore } from './types'
10
+
11
+ /**
12
+ * Pattern detected from outcomes.
13
+ */
14
+ export interface DetectedPattern {
15
+ /** Pattern description */
16
+ description: string
17
+
18
+ /** Confidence level (0-1) */
19
+ confidence: number
20
+
21
+ /** Number of occurrences supporting this pattern */
22
+ occurrences: number
23
+
24
+ /** Suggested action based on pattern */
25
+ suggestedAction?: string
26
+ }
27
+
28
+ /**
29
+ * Agent performance metrics.
30
+ */
31
+ export interface AgentMetrics {
32
+ /** Agent name */
33
+ agent: string
34
+
35
+ /** Number of tasks completed */
36
+ tasksCompleted: number
37
+
38
+ /** Success rate (0-100) */
39
+ successRate: number
40
+
41
+ /** Average quality score */
42
+ avgQualityScore: number
43
+
44
+ /** Estimate accuracy */
45
+ estimateAccuracy: number
46
+
47
+ /** Best task types for this agent */
48
+ bestFor: string[]
49
+ }
50
+
51
+ /**
52
+ * OutcomeAnalyzer - Extracts insights from outcomes.
53
+ */
54
+ export class OutcomeAnalyzer {
55
+ /**
56
+ * Generate summary of all outcomes.
57
+ */
58
+ async summarize(projectId: string): Promise<OutcomeSummary> {
59
+ const outcomes = await outcomeRecorder.getAll(projectId)
60
+
61
+ if (outcomes.length === 0) {
62
+ return {
63
+ totalOutcomes: 0,
64
+ avgQualityScore: 0,
65
+ estimateAccuracy: 0,
66
+ topBlockers: [],
67
+ topAgents: [],
68
+ patternsDetected: [],
69
+ }
70
+ }
71
+
72
+ // Calculate average quality
73
+ const avgQuality =
74
+ outcomes.reduce((sum, o) => sum + o.qualityScore, 0) / outcomes.length
75
+
76
+ // Calculate estimate accuracy
77
+ const estimateAccuracy = await outcomeRecorder.getEstimateAccuracy(projectId)
78
+
79
+ // Find top blockers
80
+ const blockerCounts = new Map<string, number>()
81
+ for (const outcome of outcomes) {
82
+ for (const blocker of outcome.blockers || []) {
83
+ blockerCounts.set(blocker, (blockerCounts.get(blocker) || 0) + 1)
84
+ }
85
+ }
86
+ const topBlockers = [...blockerCounts.entries()]
87
+ .sort((a, b) => b[1] - a[1])
88
+ .slice(0, 5)
89
+ .map(([blocker]) => blocker)
90
+
91
+ // Find top agents
92
+ const agentMetrics = await this.getAgentMetrics(projectId)
93
+ const topAgents = agentMetrics
94
+ .sort((a, b) => b.successRate - a.successRate)
95
+ .slice(0, 3)
96
+ .map((m) => m.agent)
97
+
98
+ // Detect patterns
99
+ const patterns = await this.detectPatterns(projectId)
100
+ const patternsDetected = patterns.map((p) => p.description)
101
+
102
+ return {
103
+ totalOutcomes: outcomes.length,
104
+ avgQualityScore: Math.round(avgQuality * 10) / 10,
105
+ estimateAccuracy,
106
+ topBlockers,
107
+ topAgents,
108
+ patternsDetected,
109
+ }
110
+ }
111
+
112
+ /**
113
+ * Get metrics for each agent.
114
+ */
115
+ async getAgentMetrics(projectId: string): Promise<AgentMetrics[]> {
116
+ const outcomes = await outcomeRecorder.getAll(projectId)
117
+
118
+ // Group by agent
119
+ const byAgent = new Map<string, Outcome[]>()
120
+ for (const outcome of outcomes) {
121
+ const agent = outcome.agentUsed || 'unknown'
122
+ if (!byAgent.has(agent)) {
123
+ byAgent.set(agent, [])
124
+ }
125
+ byAgent.get(agent)!.push(outcome)
126
+ }
127
+
128
+ const metrics: AgentMetrics[] = []
129
+
130
+ for (const [agent, agentOutcomes] of byAgent) {
131
+ const tasksCompleted = agentOutcomes.length
132
+ const successful = agentOutcomes.filter((o) => o.completedAsPlanned)
133
+ const successRate = Math.round((successful.length / tasksCompleted) * 100)
134
+
135
+ const avgQuality =
136
+ agentOutcomes.reduce((sum, o) => sum + o.qualityScore, 0) / tasksCompleted
137
+
138
+ // Calculate estimate accuracy for this agent
139
+ const accurateEstimates = agentOutcomes.filter((o) => {
140
+ if (!o.variance) return false
141
+ const variance = this.parseVariance(o.variance)
142
+ const estimated = this.parseDuration(o.estimatedDuration)
143
+ if (estimated === 0) return false
144
+ return Math.abs(variance) / estimated <= 0.2
145
+ })
146
+ const estimateAccuracy = Math.round(
147
+ (accurateEstimates.length / tasksCompleted) * 100
148
+ )
149
+
150
+ // Find best task types
151
+ const taskTypes = new Map<string, number>()
152
+ for (const o of agentOutcomes.filter((o) => o.completedAsPlanned)) {
153
+ for (const tag of o.tags || []) {
154
+ taskTypes.set(tag, (taskTypes.get(tag) || 0) + 1)
155
+ }
156
+ }
157
+ const bestFor = [...taskTypes.entries()]
158
+ .sort((a, b) => b[1] - a[1])
159
+ .slice(0, 3)
160
+ .map(([type]) => type)
161
+
162
+ metrics.push({
163
+ agent,
164
+ tasksCompleted,
165
+ successRate,
166
+ avgQualityScore: Math.round(avgQuality * 10) / 10,
167
+ estimateAccuracy,
168
+ bestFor,
169
+ })
170
+ }
171
+
172
+ return metrics
173
+ }
174
+
175
+ /**
176
+ * Detect patterns from outcomes.
177
+ */
178
+ async detectPatterns(projectId: string): Promise<DetectedPattern[]> {
179
+ const outcomes = await outcomeRecorder.getAll(projectId)
180
+ const patterns: DetectedPattern[] = []
181
+
182
+ if (outcomes.length < 3) {
183
+ return patterns // Need at least 3 outcomes to detect patterns
184
+ }
185
+
186
+ // Pattern: Consistent underestimation
187
+ const underestimated = outcomes.filter((o) => {
188
+ const variance = this.parseVariance(o.variance)
189
+ return variance > 0
190
+ })
191
+ if (underestimated.length / outcomes.length > 0.6) {
192
+ patterns.push({
193
+ description: 'Tasks consistently take longer than estimated',
194
+ confidence: underestimated.length / outcomes.length,
195
+ occurrences: underestimated.length,
196
+ suggestedAction: 'Add 30% buffer to estimates',
197
+ })
198
+ }
199
+
200
+ // Pattern: Consistent overestimation
201
+ const overestimated = outcomes.filter((o) => {
202
+ const variance = this.parseVariance(o.variance)
203
+ return variance < 0
204
+ })
205
+ if (overestimated.length / outcomes.length > 0.6) {
206
+ patterns.push({
207
+ description: 'Tasks consistently finish faster than estimated',
208
+ confidence: overestimated.length / outcomes.length,
209
+ occurrences: overestimated.length,
210
+ suggestedAction: 'Reduce estimates by 20%',
211
+ })
212
+ }
213
+
214
+ // Pattern: Common blockers
215
+ const blockerCounts = new Map<string, number>()
216
+ for (const outcome of outcomes) {
217
+ for (const blocker of outcome.blockers || []) {
218
+ blockerCounts.set(blocker, (blockerCounts.get(blocker) || 0) + 1)
219
+ }
220
+ }
221
+ for (const [blocker, count] of blockerCounts) {
222
+ if (count >= 3) {
223
+ patterns.push({
224
+ description: `Recurring blocker: ${blocker}`,
225
+ confidence: count / outcomes.length,
226
+ occurrences: count,
227
+ suggestedAction: `Address root cause of "${blocker}"`,
228
+ })
229
+ }
230
+ }
231
+
232
+ // Pattern: Agent performance
233
+ const agentMetrics = await this.getAgentMetrics(projectId)
234
+ for (const metrics of agentMetrics) {
235
+ if (metrics.tasksCompleted >= 5 && metrics.successRate > 90) {
236
+ patterns.push({
237
+ description: `${metrics.agent} has high success rate (${metrics.successRate}%)`,
238
+ confidence: 0.9,
239
+ occurrences: metrics.tasksCompleted,
240
+ suggestedAction: `Prefer ${metrics.agent} for similar tasks`,
241
+ })
242
+ }
243
+ }
244
+
245
+ return patterns.sort((a, b) => b.confidence - a.confidence)
246
+ }
247
+
248
+ /**
249
+ * Suggest estimate for a task type based on history.
250
+ */
251
+ async suggestEstimate(
252
+ projectId: string,
253
+ taskType: string
254
+ ): Promise<string | null> {
255
+ const outcomes = await outcomeRecorder.getAll(projectId)
256
+
257
+ // Filter by task type (using tags)
258
+ const relevant = outcomes.filter((o) => o.tags?.includes(taskType))
259
+
260
+ if (relevant.length < 2) {
261
+ return null // Not enough data
262
+ }
263
+
264
+ // Calculate average actual duration
265
+ const totalMinutes = relevant.reduce((sum, o) => {
266
+ return sum + this.parseDuration(o.actualDuration)
267
+ }, 0)
268
+
269
+ const avgMinutes = Math.round(totalMinutes / relevant.length)
270
+
271
+ // Format as duration string
272
+ if (avgMinutes >= 60) {
273
+ const hours = Math.floor(avgMinutes / 60)
274
+ const mins = avgMinutes % 60
275
+ return mins > 0 ? `${hours}h ${mins}m` : `${hours}h`
276
+ }
277
+ return `${avgMinutes}m`
278
+ }
279
+
280
+ /**
281
+ * Suggest best agent for a task type.
282
+ */
283
+ async suggestAgent(projectId: string, taskType: string): Promise<string | null> {
284
+ const agentMetrics = await this.getAgentMetrics(projectId)
285
+
286
+ // Find agents good at this task type
287
+ const suitable = agentMetrics.filter((m) => m.bestFor.includes(taskType))
288
+
289
+ if (suitable.length === 0) {
290
+ return null
291
+ }
292
+
293
+ // Return the one with highest success rate
294
+ return suitable.sort((a, b) => b.successRate - a.successRate)[0].agent
295
+ }
296
+
297
+ /**
298
+ * Parse variance string to minutes.
299
+ */
300
+ private parseVariance(variance: string): number {
301
+ const match = variance.match(/^([+-])(\d+)([mh])$/)
302
+ if (!match) return 0
303
+
304
+ const sign = match[1] === '-' ? -1 : 1
305
+ const value = parseInt(match[2], 10)
306
+ const unit = match[3]
307
+
308
+ return sign * (unit === 'h' ? value * 60 : value)
309
+ }
310
+
311
+ /**
312
+ * Parse duration string to minutes.
313
+ */
314
+ private parseDuration(duration: string): number {
315
+ let minutes = 0
316
+
317
+ const hourMatch = duration.match(/(\d+)h/)
318
+ if (hourMatch) {
319
+ minutes += parseInt(hourMatch[1], 10) * 60
320
+ }
321
+
322
+ const minMatch = duration.match(/(\d+)m/)
323
+ if (minMatch) {
324
+ minutes += parseInt(minMatch[1], 10)
325
+ }
326
+
327
+ return minutes
328
+ }
329
+ }
330
+
331
+ // Singleton instance
332
+ const outcomeAnalyzer = new OutcomeAnalyzer()
333
+ export default outcomeAnalyzer
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Outcomes Module
3
+ *
4
+ * Records and analyzes execution outcomes for learning.
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * import { outcomeRecorder, outcomeAnalyzer } from './outcomes'
9
+ *
10
+ * // Record an outcome
11
+ * await outcomeRecorder.record(projectId, {
12
+ * sessionId: 'session_123',
13
+ * command: '/p:now',
14
+ * task: 'implement auth',
15
+ * startedAt: '2025-12-09T14:00:00Z',
16
+ * completedAt: '2025-12-09T16:30:00Z',
17
+ * estimatedDuration: '2h',
18
+ * actualDuration: '2h 30m',
19
+ * variance: '+30m',
20
+ * completedAsPlanned: true,
21
+ * qualityScore: 4,
22
+ * agentUsed: 'backend-specialist',
23
+ * tags: ['auth', 'backend']
24
+ * })
25
+ *
26
+ * // Analyze outcomes
27
+ * const summary = await outcomeAnalyzer.summarize(projectId)
28
+ * const patterns = await outcomeAnalyzer.detectPatterns(projectId)
29
+ * ```
30
+ */
31
+
32
+ export { OutcomeRecorder, default as outcomeRecorder } from './recorder'
33
+ export { OutcomeAnalyzer, default as outcomeAnalyzer } from './analyzer'
34
+ export * from './types'
@@ -0,0 +1,194 @@
1
+ /**
2
+ * Outcome Recorder
3
+ *
4
+ * Records execution outcomes for learning and analysis.
5
+ * Appends to JSONL files for efficient streaming.
6
+ */
7
+
8
+ import path from 'path'
9
+ import * as fileHelper from '../utils/file-helper'
10
+ import pathManager from '../infrastructure/path-manager'
11
+ import type { Outcome, OutcomeInput, OutcomeFilter } from './types'
12
+
13
+ const OUTCOMES_DIR = 'outcomes'
14
+ const OUTCOMES_FILE = 'outcomes.jsonl'
15
+
16
+ /**
17
+ * OutcomeRecorder - Records and retrieves execution outcomes.
18
+ */
19
+ export class OutcomeRecorder {
20
+ /**
21
+ * Get outcomes directory path for a project.
22
+ */
23
+ private getOutcomesDir(projectId: string): string {
24
+ const globalPath = pathManager.getGlobalProjectPath(projectId)
25
+ return path.join(globalPath, OUTCOMES_DIR)
26
+ }
27
+
28
+ /**
29
+ * Get outcomes file path for a project.
30
+ */
31
+ private getOutcomesPath(projectId: string): string {
32
+ return path.join(this.getOutcomesDir(projectId), OUTCOMES_FILE)
33
+ }
34
+
35
+ /**
36
+ * Record an outcome.
37
+ */
38
+ async record(projectId: string, input: OutcomeInput): Promise<Outcome> {
39
+ const outcome: Outcome = {
40
+ ...input,
41
+ id: `outcome_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`,
42
+ }
43
+
44
+ const outcomesPath = this.getOutcomesPath(projectId)
45
+
46
+ // Ensure directory exists
47
+ await fileHelper.ensureDir(path.dirname(outcomesPath))
48
+
49
+ // Append to JSONL
50
+ await fileHelper.appendLine(outcomesPath, JSON.stringify(outcome))
51
+
52
+ return outcome
53
+ }
54
+
55
+ /**
56
+ * Get all outcomes for a project.
57
+ */
58
+ async getAll(projectId: string): Promise<Outcome[]> {
59
+ const outcomesPath = this.getOutcomesPath(projectId)
60
+
61
+ if (!(await fileHelper.fileExists(outcomesPath))) {
62
+ return []
63
+ }
64
+
65
+ const content = await fileHelper.readFile(outcomesPath)
66
+ if (!content.trim()) {
67
+ return []
68
+ }
69
+
70
+ return content
71
+ .trim()
72
+ .split('\n')
73
+ .filter((line) => line.trim())
74
+ .map((line) => JSON.parse(line) as Outcome)
75
+ }
76
+
77
+ /**
78
+ * Get outcomes matching a filter.
79
+ */
80
+ async filter(projectId: string, filter: OutcomeFilter): Promise<Outcome[]> {
81
+ const all = await this.getAll(projectId)
82
+
83
+ return all.filter((outcome) => {
84
+ if (filter.sessionId && outcome.sessionId !== filter.sessionId) {
85
+ return false
86
+ }
87
+ if (filter.command && outcome.command !== filter.command) {
88
+ return false
89
+ }
90
+ if (filter.agent && outcome.agentUsed !== filter.agent) {
91
+ return false
92
+ }
93
+ if (filter.fromDate && outcome.startedAt < filter.fromDate) {
94
+ return false
95
+ }
96
+ if (filter.toDate && outcome.completedAt > filter.toDate) {
97
+ return false
98
+ }
99
+ if (filter.minQuality && outcome.qualityScore < filter.minQuality) {
100
+ return false
101
+ }
102
+ if (filter.tags && filter.tags.length > 0) {
103
+ const outcomeTags = outcome.tags || []
104
+ if (!filter.tags.some((tag) => outcomeTags.includes(tag))) {
105
+ return false
106
+ }
107
+ }
108
+ return true
109
+ })
110
+ }
111
+
112
+ /**
113
+ * Get recent outcomes (last N).
114
+ */
115
+ async getRecent(projectId: string, count: number = 10): Promise<Outcome[]> {
116
+ const all = await this.getAll(projectId)
117
+ return all.slice(-count)
118
+ }
119
+
120
+ /**
121
+ * Get outcomes for a specific command.
122
+ */
123
+ async getByCommand(projectId: string, command: string): Promise<Outcome[]> {
124
+ return this.filter(projectId, { command })
125
+ }
126
+
127
+ /**
128
+ * Get outcomes for a specific agent.
129
+ */
130
+ async getByAgent(projectId: string, agent: string): Promise<Outcome[]> {
131
+ return this.filter(projectId, { agent })
132
+ }
133
+
134
+ /**
135
+ * Calculate estimate accuracy.
136
+ */
137
+ async getEstimateAccuracy(projectId: string): Promise<number> {
138
+ const outcomes = await this.getAll(projectId)
139
+
140
+ if (outcomes.length === 0) {
141
+ return 0
142
+ }
143
+
144
+ // Count outcomes where variance was within 20%
145
+ const accurate = outcomes.filter((o) => {
146
+ if (!o.variance) return false
147
+ const variance = this.parseVariance(o.variance)
148
+ const estimated = this.parseDuration(o.estimatedDuration)
149
+ if (estimated === 0) return false
150
+ return Math.abs(variance) / estimated <= 0.2
151
+ })
152
+
153
+ return Math.round((accurate.length / outcomes.length) * 100)
154
+ }
155
+
156
+ /**
157
+ * Parse variance string to minutes.
158
+ * "+30m" → 30, "-15m" → -15
159
+ */
160
+ private parseVariance(variance: string): number {
161
+ const match = variance.match(/^([+-])(\d+)([mh])$/)
162
+ if (!match) return 0
163
+
164
+ const sign = match[1] === '-' ? -1 : 1
165
+ const value = parseInt(match[2], 10)
166
+ const unit = match[3]
167
+
168
+ return sign * (unit === 'h' ? value * 60 : value)
169
+ }
170
+
171
+ /**
172
+ * Parse duration string to minutes.
173
+ * "2h" → 120, "30m" → 30, "1h 30m" → 90
174
+ */
175
+ private parseDuration(duration: string): number {
176
+ let minutes = 0
177
+
178
+ const hourMatch = duration.match(/(\d+)h/)
179
+ if (hourMatch) {
180
+ minutes += parseInt(hourMatch[1], 10) * 60
181
+ }
182
+
183
+ const minMatch = duration.match(/(\d+)m/)
184
+ if (minMatch) {
185
+ minutes += parseInt(minMatch[1], 10)
186
+ }
187
+
188
+ return minutes
189
+ }
190
+ }
191
+
192
+ // Singleton instance
193
+ const outcomeRecorder = new OutcomeRecorder()
194
+ export default outcomeRecorder
@@ -0,0 +1,145 @@
1
+ /**
2
+ * Outcome Types
3
+ *
4
+ * Types for recording execution results.
5
+ * Enables learning from past executions.
6
+ */
7
+
8
+ /**
9
+ * Quality score for task completion.
10
+ * 1 = Poor, 5 = Excellent
11
+ */
12
+ export type QualityScore = 1 | 2 | 3 | 4 | 5
13
+
14
+ /**
15
+ * Outcome of a command or task execution.
16
+ *
17
+ * @property id - Unique outcome ID
18
+ * @property sessionId - Session this outcome belongs to
19
+ * @property command - Command that was executed
20
+ * @property task - Task description
21
+ */
22
+ export interface Outcome {
23
+ /** Unique outcome ID */
24
+ id: string
25
+
26
+ /** Session this outcome belongs to */
27
+ sessionId: string
28
+
29
+ /** Command that was executed */
30
+ command: string
31
+
32
+ /** Task description */
33
+ task: string
34
+
35
+ // =========== Timing ===========
36
+
37
+ /** When execution started */
38
+ startedAt: string
39
+
40
+ /** When execution completed */
41
+ completedAt: string
42
+
43
+ /** Estimated duration (before execution) */
44
+ estimatedDuration: string
45
+
46
+ /** Actual duration */
47
+ actualDuration: string
48
+
49
+ /**
50
+ * Variance from estimate.
51
+ * Positive = took longer ("+30m")
52
+ * Negative = faster ("-15m")
53
+ */
54
+ variance: string
55
+
56
+ // =========== Quality ===========
57
+
58
+ /** Whether task was completed as planned */
59
+ completedAsPlanned: boolean
60
+
61
+ /** Quality score (1-5) */
62
+ qualityScore: QualityScore
63
+
64
+ /** Blockers encountered during execution */
65
+ blockers?: string[]
66
+
67
+ /** Error messages if any */
68
+ errors?: string[]
69
+
70
+ // =========== Agent ===========
71
+
72
+ /** Agent used for this task */
73
+ agentUsed?: string
74
+
75
+ /** Agent confidence level (0-1) */
76
+ agentConfidence?: number
77
+
78
+ /** Whether agent performed well */
79
+ agentPerformedWell?: boolean
80
+
81
+ // =========== Learning ===========
82
+
83
+ /** Pattern detected from this execution */
84
+ patternDetected?: string
85
+
86
+ /** Suggested estimate for similar tasks */
87
+ nextTimeEstimate?: string
88
+
89
+ /** Tags for categorization */
90
+ tags?: string[]
91
+ }
92
+
93
+ /**
94
+ * Summary of outcomes for analysis.
95
+ */
96
+ export interface OutcomeSummary {
97
+ /** Total outcomes analyzed */
98
+ totalOutcomes: number
99
+
100
+ /** Average quality score */
101
+ avgQualityScore: number
102
+
103
+ /** Estimate accuracy percentage (0-100) */
104
+ estimateAccuracy: number
105
+
106
+ /** Most common blockers */
107
+ topBlockers: string[]
108
+
109
+ /** Best performing agents */
110
+ topAgents: string[]
111
+
112
+ /** Patterns detected */
113
+ patternsDetected: string[]
114
+ }
115
+
116
+ /**
117
+ * Outcome filter options.
118
+ */
119
+ export interface OutcomeFilter {
120
+ /** Filter by session ID */
121
+ sessionId?: string
122
+
123
+ /** Filter by command */
124
+ command?: string
125
+
126
+ /** Filter by agent */
127
+ agent?: string
128
+
129
+ /** Filter by date range start */
130
+ fromDate?: string
131
+
132
+ /** Filter by date range end */
133
+ toDate?: string
134
+
135
+ /** Filter by minimum quality */
136
+ minQuality?: QualityScore
137
+
138
+ /** Filter by tags */
139
+ tags?: string[]
140
+ }
141
+
142
+ /**
143
+ * Outcome creation input.
144
+ */
145
+ export type OutcomeInput = Omit<Outcome, 'id'>