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,277 @@
1
+ /**
2
+ * Semantic Memories
3
+ * P3.3: Tagged, searchable, CRUD memory operations.
4
+ */
5
+
6
+ import fs from 'fs/promises'
7
+ import path from 'path'
8
+ import pathManager from '../../infrastructure/path-manager'
9
+ import type { Memory, MemoryDatabase, Context } from './types'
10
+ import { MEMORY_TAGS } from './types'
11
+
12
+ export class SemanticMemories {
13
+ private _memories: MemoryDatabase | null = null
14
+ private _memoriesLoaded: boolean = false
15
+
16
+ private _getMemoriesPath(projectId: string): string {
17
+ return path.join(pathManager.getGlobalProjectPath(projectId), 'memory', 'memories.json')
18
+ }
19
+
20
+ async loadMemories(projectId: string): Promise<MemoryDatabase> {
21
+ if (this._memoriesLoaded && this._memories) {
22
+ return this._memories
23
+ }
24
+
25
+ try {
26
+ const memoriesPath = this._getMemoriesPath(projectId)
27
+ const content = await fs.readFile(memoriesPath, 'utf-8')
28
+ this._memories = JSON.parse(content)
29
+ this._memoriesLoaded = true
30
+ return this._memories!
31
+ } catch {
32
+ this._memories = {
33
+ version: 1,
34
+ memories: [],
35
+ index: {},
36
+ }
37
+ this._memoriesLoaded = true
38
+ return this._memories
39
+ }
40
+ }
41
+
42
+ async saveMemories(projectId: string): Promise<void> {
43
+ if (!this._memories) return
44
+
45
+ const memoriesPath = this._getMemoriesPath(projectId)
46
+ await fs.mkdir(path.dirname(memoriesPath), { recursive: true })
47
+ await fs.writeFile(memoriesPath, JSON.stringify(this._memories, null, 2), 'utf-8')
48
+ }
49
+
50
+ async createMemory(
51
+ projectId: string,
52
+ {
53
+ title,
54
+ content,
55
+ tags = [],
56
+ userTriggered = false,
57
+ }: { title: string; content: string; tags?: string[]; userTriggered?: boolean }
58
+ ): Promise<string> {
59
+ const db = await this.loadMemories(projectId)
60
+
61
+ const memory: Memory = {
62
+ id: `mem_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
63
+ title,
64
+ content,
65
+ tags,
66
+ userTriggered,
67
+ createdAt: new Date().toISOString(),
68
+ updatedAt: new Date().toISOString(),
69
+ }
70
+
71
+ db.memories.push(memory)
72
+
73
+ for (const tag of tags) {
74
+ if (!db.index[tag]) db.index[tag] = []
75
+ db.index[tag].push(memory.id)
76
+ }
77
+
78
+ await this.saveMemories(projectId)
79
+ return memory.id
80
+ }
81
+
82
+ async updateMemory(
83
+ projectId: string,
84
+ memoryId: string,
85
+ updates: { title?: string; content?: string; tags?: string[] }
86
+ ): Promise<boolean> {
87
+ const db = await this.loadMemories(projectId)
88
+
89
+ const index = db.memories.findIndex((m) => m.id === memoryId)
90
+ if (index === -1) return false
91
+
92
+ const memory = db.memories[index]
93
+ const oldTags = memory.tags || []
94
+
95
+ if (updates.title) memory.title = updates.title
96
+ if (updates.content) memory.content = updates.content
97
+ if (updates.tags) {
98
+ for (const tag of oldTags) {
99
+ if (db.index[tag]) {
100
+ db.index[tag] = db.index[tag].filter((id) => id !== memoryId)
101
+ }
102
+ }
103
+ for (const tag of updates.tags) {
104
+ if (!db.index[tag]) db.index[tag] = []
105
+ db.index[tag].push(memoryId)
106
+ }
107
+ memory.tags = updates.tags
108
+ }
109
+
110
+ memory.updatedAt = new Date().toISOString()
111
+ await this.saveMemories(projectId)
112
+ return true
113
+ }
114
+
115
+ async deleteMemory(projectId: string, memoryId: string): Promise<boolean> {
116
+ const db = await this.loadMemories(projectId)
117
+
118
+ const index = db.memories.findIndex((m) => m.id === memoryId)
119
+ if (index === -1) return false
120
+
121
+ const memory = db.memories[index]
122
+
123
+ for (const tag of memory.tags || []) {
124
+ if (db.index[tag]) {
125
+ db.index[tag] = db.index[tag].filter((id) => id !== memoryId)
126
+ }
127
+ }
128
+
129
+ db.memories.splice(index, 1)
130
+ await this.saveMemories(projectId)
131
+ return true
132
+ }
133
+
134
+ async findByTags(projectId: string, tags: string[], matchAll: boolean = false): Promise<Memory[]> {
135
+ const db = await this.loadMemories(projectId)
136
+
137
+ if (matchAll) {
138
+ return db.memories.filter((m) => tags.every((tag) => (m.tags || []).includes(tag)))
139
+ } else {
140
+ const matchingIds = new Set<string>()
141
+ for (const tag of tags) {
142
+ const ids = db.index[tag] || []
143
+ ids.forEach((id) => matchingIds.add(id))
144
+ }
145
+ return db.memories.filter((m) => matchingIds.has(m.id))
146
+ }
147
+ }
148
+
149
+ async searchMemories(projectId: string, query: string): Promise<Memory[]> {
150
+ const db = await this.loadMemories(projectId)
151
+ const queryLower = query.toLowerCase()
152
+
153
+ return db.memories.filter(
154
+ (m) => m.title.toLowerCase().includes(queryLower) || m.content.toLowerCase().includes(queryLower)
155
+ )
156
+ }
157
+
158
+ async getRelevantMemories(projectId: string, context: Context, limit: number = 5): Promise<Memory[]> {
159
+ const db = await this.loadMemories(projectId)
160
+
161
+ const scored = db.memories.map((memory) => {
162
+ let score = 0
163
+
164
+ const contextTags = this._extractContextTags(context)
165
+ for (const tag of memory.tags || []) {
166
+ if (contextTags.includes(tag)) score += 10
167
+ }
168
+
169
+ const age = Date.now() - new Date(memory.updatedAt).getTime()
170
+ const daysSinceUpdate = age / (1000 * 60 * 60 * 24)
171
+ score += Math.max(0, 5 - daysSinceUpdate)
172
+
173
+ if (memory.userTriggered) score += 5
174
+
175
+ const keywords = this._extractKeywords(context)
176
+ for (const keyword of keywords) {
177
+ if (memory.content.toLowerCase().includes(keyword)) score += 2
178
+ if (memory.title.toLowerCase().includes(keyword)) score += 3
179
+ }
180
+
181
+ return { ...memory, _score: score }
182
+ })
183
+
184
+ return scored
185
+ .filter((m) => m._score > 0)
186
+ .sort((a, b) => b._score - a._score)
187
+ .slice(0, limit)
188
+ .map(({ _score, ...memory }) => memory as Memory)
189
+ }
190
+
191
+ private _extractContextTags(context: Context): string[] {
192
+ const tags: string[] = []
193
+
194
+ const commandTags: Record<string, string[]> = {
195
+ ship: [MEMORY_TAGS.COMMIT_STYLE, MEMORY_TAGS.SHIP_WORKFLOW, MEMORY_TAGS.TEST_BEHAVIOR],
196
+ feature: [MEMORY_TAGS.ARCHITECTURE, MEMORY_TAGS.CODE_STYLE],
197
+ done: [MEMORY_TAGS.SHIP_WORKFLOW],
198
+ analyze: [MEMORY_TAGS.TECH_STACK, MEMORY_TAGS.ARCHITECTURE],
199
+ spec: [MEMORY_TAGS.ARCHITECTURE, MEMORY_TAGS.CODE_STYLE],
200
+ }
201
+
202
+ if (context.commandName && commandTags[context.commandName]) {
203
+ tags.push(...commandTags[context.commandName])
204
+ }
205
+
206
+ return tags
207
+ }
208
+
209
+ private _extractKeywords(context: Context): string[] {
210
+ const keywords: string[] = []
211
+
212
+ if (context.params?.description) {
213
+ keywords.push(...(context.params.description as string).toLowerCase().split(/\s+/))
214
+ }
215
+ if (context.params?.feature) {
216
+ keywords.push(...(context.params.feature as string).toLowerCase().split(/\s+/))
217
+ }
218
+
219
+ const stopWords = ['the', 'a', 'an', 'is', 'are', 'to', 'for', 'and', 'or', 'in']
220
+ return keywords.filter((k) => k.length > 2 && !stopWords.includes(k))
221
+ }
222
+
223
+ async autoRemember(projectId: string, decisionType: string, value: string, context: string = ''): Promise<void> {
224
+ const tagMap: Record<string, string[]> = {
225
+ commit_footer: [MEMORY_TAGS.COMMIT_STYLE],
226
+ branch_naming: [MEMORY_TAGS.BRANCH_NAMING],
227
+ test_before_ship: [MEMORY_TAGS.TEST_BEHAVIOR, MEMORY_TAGS.SHIP_WORKFLOW],
228
+ preferred_agent: [MEMORY_TAGS.AGENT_PREFERENCE],
229
+ code_style: [MEMORY_TAGS.CODE_STYLE],
230
+ verbosity: [MEMORY_TAGS.OUTPUT_VERBOSITY],
231
+ }
232
+
233
+ const tags = tagMap[decisionType] || []
234
+
235
+ const existing = await this.searchMemories(projectId, decisionType)
236
+ if (existing.length > 0) {
237
+ await this.updateMemory(projectId, existing[0].id, {
238
+ content: `${decisionType}: ${value}`,
239
+ tags,
240
+ })
241
+ } else {
242
+ await this.createMemory(projectId, {
243
+ title: `Preference: ${decisionType}`,
244
+ content: `${decisionType}: ${value}${context ? `\nContext: ${context}` : ''}`,
245
+ tags,
246
+ userTriggered: true,
247
+ })
248
+ }
249
+ }
250
+
251
+ async getAllMemories(projectId: string): Promise<Memory[]> {
252
+ const db = await this.loadMemories(projectId)
253
+ return db.memories
254
+ }
255
+
256
+ async getMemoryStats(projectId: string) {
257
+ const db = await this.loadMemories(projectId)
258
+
259
+ const tagCounts: Record<string, number> = {}
260
+ for (const [tag, ids] of Object.entries(db.index)) {
261
+ tagCounts[tag] = ids.length
262
+ }
263
+
264
+ return {
265
+ totalMemories: db.memories.length,
266
+ userTriggered: db.memories.filter((m) => m.userTriggered).length,
267
+ tagCounts,
268
+ oldestMemory: db.memories[0]?.createdAt,
269
+ newestMemory: db.memories[db.memories.length - 1]?.createdAt,
270
+ }
271
+ }
272
+
273
+ reset(): void {
274
+ this._memories = null
275
+ this._memoriesLoaded = false
276
+ }
277
+ }
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Session Memory - Tier 1
3
+ * Ephemeral, single command context.
4
+ */
5
+
6
+ export class SessionStore {
7
+ private _sessionMemory: Map<string, { value: unknown; timestamp: number }> = new Map()
8
+
9
+ setSession(key: string, value: unknown): void {
10
+ this._sessionMemory.set(key, { value, timestamp: Date.now() })
11
+ }
12
+
13
+ getSession(key: string): unknown {
14
+ const entry = this._sessionMemory.get(key)
15
+ return entry?.value
16
+ }
17
+
18
+ clearSession(): void {
19
+ this._sessionMemory.clear()
20
+ }
21
+ }
@@ -0,0 +1,159 @@
1
+ /**
2
+ * Memory System Types and Constants
3
+ *
4
+ * This module provides types for the memory system that tracks
5
+ * user preferences, decisions, and learned patterns.
6
+ */
7
+
8
+ /**
9
+ * Semantic tags for memory categorization.
10
+ * Use these constants instead of raw strings.
11
+ */
12
+ export const MEMORY_TAGS = {
13
+ // Code preferences
14
+ CODE_STYLE: 'code_style',
15
+ NAMING_CONVENTION: 'naming_convention',
16
+ FILE_STRUCTURE: 'file_structure',
17
+
18
+ // Workflow preferences
19
+ COMMIT_STYLE: 'commit_style',
20
+ BRANCH_NAMING: 'branch_naming',
21
+ TEST_BEHAVIOR: 'test_behavior',
22
+ SHIP_WORKFLOW: 'ship_workflow',
23
+
24
+ // Project context
25
+ TECH_STACK: 'tech_stack',
26
+ ARCHITECTURE: 'architecture',
27
+ DEPENDENCIES: 'dependencies',
28
+
29
+ // User preferences
30
+ OUTPUT_VERBOSITY: 'output_verbosity',
31
+ CONFIRMATION_LEVEL: 'confirmation_level',
32
+ AGENT_PREFERENCE: 'agent_preference',
33
+ } as const
34
+
35
+ export type MemoryTag = typeof MEMORY_TAGS[keyof typeof MEMORY_TAGS]
36
+
37
+ /**
38
+ * A single memory entry.
39
+ */
40
+ export interface Memory {
41
+ id: string
42
+ title: string
43
+ content: string
44
+ tags: MemoryTag[]
45
+ userTriggered: boolean
46
+ createdAt: string
47
+ updatedAt: string
48
+ }
49
+
50
+ /**
51
+ * Memory database structure.
52
+ */
53
+ export interface MemoryDatabase {
54
+ version: number
55
+ memories: Memory[]
56
+ /** Index of tag -> memory IDs */
57
+ index: Record<MemoryTag, string[]>
58
+ }
59
+
60
+ /**
61
+ * A history entry from session logs.
62
+ */
63
+ export interface HistoryEntry {
64
+ /** Timestamp */
65
+ ts: string
66
+ /** Event type */
67
+ type: HistoryEventType
68
+ /** Command that triggered this event */
69
+ command?: string
70
+ /** Task description */
71
+ task?: string
72
+ /** Feature name */
73
+ feature?: string
74
+ /** Duration if applicable */
75
+ duration?: string
76
+ /** Success status */
77
+ success?: boolean
78
+ /** Error message if failed */
79
+ error?: string
80
+ }
81
+
82
+ export type HistoryEventType =
83
+ | 'task_started'
84
+ | 'task_completed'
85
+ | 'task_paused'
86
+ | 'task_resumed'
87
+ | 'feature_added'
88
+ | 'feature_shipped'
89
+ | 'idea_captured'
90
+ | 'command_executed'
91
+ | 'error_occurred'
92
+
93
+ /**
94
+ * A tracked decision and its frequency.
95
+ */
96
+ export interface Decision {
97
+ value: string
98
+ count: number
99
+ firstSeen: string
100
+ lastSeen: string
101
+ confidence: 'low' | 'medium' | 'high'
102
+ contexts: string[]
103
+ }
104
+
105
+ /**
106
+ * A tracked workflow pattern.
107
+ */
108
+ export interface Workflow {
109
+ /** Times this workflow was executed */
110
+ count: number
111
+ firstSeen: string
112
+ lastSeen: string
113
+ /** Average duration */
114
+ avgDuration?: string
115
+ /** Success rate (0-1) */
116
+ successRate?: number
117
+ /** Steps in the workflow */
118
+ steps?: string[]
119
+ }
120
+
121
+ /**
122
+ * A user preference value.
123
+ */
124
+ export interface Preference {
125
+ value: string | number | boolean
126
+ updatedAt: string
127
+ }
128
+
129
+ /**
130
+ * Aggregated patterns learned from history.
131
+ */
132
+ export interface Patterns {
133
+ version: number
134
+ decisions: Record<string, Decision>
135
+ preferences: Record<string, Preference>
136
+ workflows: Record<string, Workflow>
137
+ counters: Record<string, number>
138
+ }
139
+
140
+ /**
141
+ * Context passed to memory system operations.
142
+ */
143
+ export interface MemoryContext {
144
+ /** Command being executed */
145
+ commandName?: string
146
+ /** Command parameters */
147
+ params?: MemoryContextParams
148
+ /** Project path */
149
+ projectPath?: string
150
+ /** Current task */
151
+ currentTask?: string
152
+ }
153
+
154
+ export interface MemoryContextParams {
155
+ task?: string
156
+ description?: string
157
+ feature?: string
158
+ idea?: string
159
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Memory System
3
+ * Re-exports from memory-system/index.ts for backwards compatibility.
4
+ */
5
+
6
+ import memorySystem from './memory-system/index'
7
+ export default memorySystem
8
+ export { MemorySystem, MEMORY_TAGS } from './memory-system/index'
@@ -0,0 +1,165 @@
1
+ /**
2
+ * Parallel Tools
3
+ * Execute multiple tools in parallel for performance
4
+ *
5
+ * @module agentic/parallel-tools
6
+ * @version 1.0.0
7
+ */
8
+
9
+ import fs from 'fs/promises'
10
+
11
+ interface ToolCall {
12
+ tool: string
13
+ args: unknown[]
14
+ }
15
+
16
+ interface ToolResult {
17
+ tool: string
18
+ success: boolean
19
+ result?: unknown
20
+ error?: string
21
+ duration: number
22
+ }
23
+
24
+ interface ParallelMetrics {
25
+ totalCalls: number
26
+ parallelCalls: number
27
+ sequentialCalls: number
28
+ averageDuration: number
29
+ savedTime: number
30
+ }
31
+
32
+ class ParallelTools {
33
+ private metrics: ParallelMetrics
34
+
35
+ constructor() {
36
+ this.metrics = {
37
+ totalCalls: 0,
38
+ parallelCalls: 0,
39
+ sequentialCalls: 0,
40
+ averageDuration: 0,
41
+ savedTime: 0,
42
+ }
43
+ }
44
+
45
+ /**
46
+ * Execute multiple tool calls in parallel
47
+ */
48
+ async execute(toolCalls: ToolCall[]): Promise<ToolResult[]> {
49
+ const startTime = Date.now()
50
+
51
+ const promises = toolCalls.map(async (call) => {
52
+ const callStart = Date.now()
53
+ try {
54
+ const result = await this.executeOne(call.tool, call.args)
55
+ return {
56
+ tool: call.tool,
57
+ success: true,
58
+ result,
59
+ duration: Date.now() - callStart,
60
+ }
61
+ } catch (error) {
62
+ return {
63
+ tool: call.tool,
64
+ success: false,
65
+ error: (error as Error).message,
66
+ duration: Date.now() - callStart,
67
+ }
68
+ }
69
+ })
70
+
71
+ const results = await Promise.all(promises)
72
+
73
+ // Update metrics
74
+ const totalDuration = Date.now() - startTime
75
+ const sumIndividual = results.reduce((sum, r) => sum + r.duration, 0)
76
+ this.metrics.totalCalls += toolCalls.length
77
+ this.metrics.parallelCalls += toolCalls.length
78
+ this.metrics.savedTime += sumIndividual - totalDuration
79
+ this.metrics.averageDuration =
80
+ (this.metrics.averageDuration * (this.metrics.totalCalls - toolCalls.length) + totalDuration) /
81
+ this.metrics.totalCalls
82
+
83
+ return results
84
+ }
85
+
86
+ /**
87
+ * Execute a single tool
88
+ */
89
+ private async executeOne(tool: string, args: unknown[]): Promise<unknown> {
90
+ switch (tool) {
91
+ case 'Read':
92
+ return await fs.readFile(args[0] as string, 'utf-8')
93
+
94
+ case 'Write':
95
+ await fs.writeFile(args[0] as string, args[1] as string, 'utf-8')
96
+ return true
97
+
98
+ case 'GetTimestamp':
99
+ return new Date().toISOString()
100
+
101
+ case 'GetDate':
102
+ return new Date().toISOString().split('T')[0]
103
+
104
+ default:
105
+ throw new Error(`Unknown tool: ${tool}`)
106
+ }
107
+ }
108
+
109
+ /**
110
+ * Read multiple files in parallel
111
+ */
112
+ async readAll(paths: string[]): Promise<Map<string, string | null>> {
113
+ const results = new Map<string, string | null>()
114
+
115
+ const promises = paths.map(async (path) => {
116
+ try {
117
+ const content = await fs.readFile(path, 'utf-8')
118
+ return { path, content }
119
+ } catch {
120
+ return { path, content: null }
121
+ }
122
+ })
123
+
124
+ const readResults = await Promise.all(promises)
125
+
126
+ readResults.forEach(({ path, content }) => {
127
+ results.set(path, content)
128
+ })
129
+
130
+ return results
131
+ }
132
+
133
+ /**
134
+ * Check if tools can be parallelized
135
+ */
136
+ canParallelize(tools: string[]): boolean {
137
+ // Read operations can always be parallelized
138
+ const readOnlyTools = ['Read', 'Glob', 'Grep', 'GetTimestamp', 'GetDate']
139
+ return tools.every((tool) => readOnlyTools.includes(tool))
140
+ }
141
+
142
+ /**
143
+ * Get parallelization metrics
144
+ */
145
+ getMetrics(): ParallelMetrics {
146
+ return { ...this.metrics }
147
+ }
148
+
149
+ /**
150
+ * Reset metrics
151
+ */
152
+ resetMetrics(): void {
153
+ this.metrics = {
154
+ totalCalls: 0,
155
+ parallelCalls: 0,
156
+ sequentialCalls: 0,
157
+ averageDuration: 0,
158
+ savedTime: 0,
159
+ }
160
+ }
161
+ }
162
+
163
+ const parallelTools = new ParallelTools()
164
+ export default parallelTools
165
+ export { ParallelTools }
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Plan Mode Approval Prompts
3
+ */
4
+
5
+ import type { ApprovalPrompt, ApprovalContext } from './types'
6
+
7
+ /**
8
+ * Generate approval prompt for destructive commands
9
+ */
10
+ export function generateApprovalPrompt(commandName: string, context: ApprovalContext): ApprovalPrompt {
11
+ const prompts: Record<string, ApprovalPrompt> = {
12
+ ship: {
13
+ title: 'Ship Confirmation',
14
+ message: 'Ready to commit and push changes?',
15
+ details: [
16
+ `Branch: ${context.branch || 'current'}`,
17
+ `Files: ${context.changedFiles?.length || 0} changed`,
18
+ `Commit: "${context.commitMessage || 'No message'}"`,
19
+ ],
20
+ options: [
21
+ { key: 'y', label: 'Yes, ship it', action: 'approve' },
22
+ { key: 'n', label: 'No, cancel', action: 'reject' },
23
+ { key: 'e', label: 'Edit message', action: 'edit' },
24
+ ],
25
+ },
26
+ cleanup: {
27
+ title: 'Cleanup Confirmation',
28
+ message: 'This will delete files/code. Continue?',
29
+ details: [`Files to delete: ${context.filesToDelete?.length || 0}`, `Code to remove: ${context.linesOfCode || 0} lines`],
30
+ options: [
31
+ { key: 'y', label: 'Yes, cleanup', action: 'approve' },
32
+ { key: 'n', label: 'No, cancel', action: 'reject' },
33
+ { key: 'l', label: 'List files first', action: 'list' },
34
+ ],
35
+ },
36
+ git: {
37
+ title: 'Git Operation Confirmation',
38
+ message: `Execute: ${context.operation || 'git operation'}?`,
39
+ details: context.warnings || [],
40
+ options: [
41
+ { key: 'y', label: 'Yes, execute', action: 'approve' },
42
+ { key: 'n', label: 'No, cancel', action: 'reject' },
43
+ ],
44
+ },
45
+ }
46
+
47
+ return (
48
+ prompts[commandName] || {
49
+ title: 'Confirmation Required',
50
+ message: `Execute ${commandName}?`,
51
+ options: [
52
+ { key: 'y', label: 'Yes', action: 'approve' },
53
+ { key: 'n', label: 'No', action: 'reject' },
54
+ ],
55
+ }
56
+ )
57
+ }