prjct-cli 0.11.5 → 0.12.1

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 (391) hide show
  1. package/CHANGELOG.md +58 -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 +226 -50
  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.js → date-helper.test.ts} +19 -30
  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} +92 -81
  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} +27 -16
  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} +55 -19
  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 +204 -163
  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 +190 -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/{stats → BentoGrid}/BentoGrid.tsx +4 -8
  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/{stats → EmptyState}/EmptyState.tsx +1 -10
  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/{stats → IdeasCard}/IdeasCard.tsx +3 -14
  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/{stats → ProgressRing}/ProgressRing.tsx +4 -27
  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/{stats → RoadmapCard}/RoadmapCard.tsx +3 -23
  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/{stats → ShipsCard}/ShipsCard.tsx +4 -22
  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/{stats → SparklineChart}/SparklineChart.tsx +1 -7
  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/{stats → StreakCard}/StreakCard.tsx +5 -11
  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/context/TerminalTabsContext.tsx +46 -1
  333. package/packages/web/hooks/useClaudeTerminal.ts +71 -21
  334. package/packages/web/hooks/useProjectStats.ts +55 -0
  335. package/packages/web/hooks/useProjects.ts +6 -6
  336. package/packages/web/lib/actions/projects.ts +15 -0
  337. package/packages/web/lib/json-loader.ts +630 -0
  338. package/packages/web/lib/services/index.ts +9 -0
  339. package/packages/web/lib/services/migration.server.ts +600 -0
  340. package/packages/web/lib/services/projects.server.ts +52 -0
  341. package/packages/web/lib/services/stats.server.ts +264 -0
  342. package/packages/web/lib/unified-loader.ts +396 -0
  343. package/packages/web/package.json +10 -7
  344. package/packages/web/server.ts +58 -8
  345. package/templates/commands/done.md +76 -32
  346. package/templates/commands/feature.md +121 -47
  347. package/templates/commands/idea.md +81 -8
  348. package/templates/commands/now.md +41 -17
  349. package/templates/commands/ship.md +64 -25
  350. package/templates/commands/sync.md +28 -3
  351. package/core/agentic/agent-router.js +0 -140
  352. package/core/agentic/chain-of-thought.js +0 -578
  353. package/core/agentic/command-executor.js +0 -417
  354. package/core/agentic/context-filter.js +0 -354
  355. package/core/agentic/ground-truth.js +0 -591
  356. package/core/agentic/loop-detector.js +0 -406
  357. package/core/agentic/memory-system.js +0 -845
  358. package/core/agentic/parallel-tools.js +0 -366
  359. package/core/agentic/plan-mode.js +0 -572
  360. package/core/agentic/prompt-builder.js +0 -352
  361. package/core/agentic/response-templates.js +0 -290
  362. package/core/agentic/semantic-compression.js +0 -517
  363. package/core/agentic/think-blocks.js +0 -657
  364. package/core/agentic/tool-registry.js +0 -184
  365. package/core/agentic/validation-rules.js +0 -380
  366. package/core/command-registry.js +0 -698
  367. package/core/commands.js +0 -2237
  368. package/core/domain/task-stack.js +0 -497
  369. package/core/infrastructure/legacy-installer-detector.js +0 -546
  370. package/core/infrastructure/migrator.js +0 -796
  371. package/core/infrastructure/session-manager.js +0 -390
  372. package/core/utils/file-helper.js +0 -329
  373. package/packages/web/app/api/projects/[id]/delete/route.ts +0 -21
  374. package/packages/web/app/api/stats/route.ts +0 -38
  375. package/packages/web/components/AppSidebar.tsx +0 -113
  376. package/packages/web/components/stats/ActivityTimeline.tsx +0 -201
  377. package/packages/web/components/stats/AgentsCard.tsx +0 -56
  378. package/packages/web/components/stats/BentoCard.tsx +0 -88
  379. package/packages/web/components/stats/HeroSection.tsx +0 -172
  380. package/packages/web/components/stats/NowCard.tsx +0 -71
  381. package/packages/web/components/stats/QueueCard.tsx +0 -58
  382. package/packages/web/components/stats/VelocityCard.tsx +0 -60
  383. package/packages/web/components/stats/index.ts +0 -17
  384. package/packages/web/hooks/useStats.ts +0 -28
  385. /package/packages/web/components/{CommandButton.tsx → CommandButton/CommandButton.tsx} +0 -0
  386. /package/packages/web/components/{ConnectionStatus.tsx → ConnectionStatus/ConnectionStatus.tsx} +0 -0
  387. /package/packages/web/components/{Logo.tsx → Logo/Logo.tsx} +0 -0
  388. /package/packages/web/components/{MarkdownContent.tsx → MarkdownContent/MarkdownContent.tsx} +0 -0
  389. /package/packages/web/components/{ProjectAvatar.tsx → ProjectAvatar/ProjectAvatar.tsx} +0 -0
  390. /package/packages/web/components/{providers.tsx → Providers/Providers.tsx} +0 -0
  391. /package/packages/web/components/{TechStackBadges.tsx → TechStackBadges/TechStackBadges.tsx} +0 -0
@@ -1,352 +0,0 @@
1
- /**
2
- * Prompt Builder
3
- * Builds prompts for Claude based on templates and context.
4
- * Claude decides what to do - NO if/else logic here.
5
- *
6
- * @module agentic/prompt-builder
7
- * @version 4.1
8
- */
9
-
10
- const fs = require('fs')
11
- const path = require('path')
12
-
13
- /**
14
- * Builds prompts for Claude using templates, context, and learned patterns.
15
- * Supports plan mode, think blocks, and quality checklists.
16
- */
17
- class PromptBuilder {
18
- constructor() {
19
- /** @type {Object<string, string>|null} */
20
- this._checklistsCache = null
21
- /** @type {string|null} */
22
- this._checklistRoutingCache = null
23
- }
24
-
25
- /**
26
- * Load quality checklists from templates/checklists/
27
- *
28
- * @returns {Object<string, string>} Map of checklist name to content
29
- */
30
- loadChecklists() {
31
- if (this._checklistsCache) return this._checklistsCache
32
-
33
- const checklistsDir = path.join(__dirname, '..', '..', 'templates', 'checklists')
34
- const checklists = {}
35
-
36
- try {
37
- if (fs.existsSync(checklistsDir)) {
38
- const files = fs.readdirSync(checklistsDir).filter(f => f.endsWith('.md'))
39
- for (const file of files) {
40
- const name = file.replace('.md', '')
41
- const content = fs.readFileSync(path.join(checklistsDir, file), 'utf-8')
42
- checklists[name] = content
43
- }
44
- }
45
- } catch (err) {
46
- // Silent fail - checklists are optional enhancement
47
- }
48
-
49
- this._checklistsCache = checklists
50
- return checklists
51
- }
52
-
53
- /**
54
- * Load checklist routing template for Claude to decide which checklists apply
55
- *
56
- * @returns {string|null} Routing template content or null if not found
57
- */
58
- loadChecklistRouting() {
59
- if (this._checklistRoutingCache) return this._checklistRoutingCache
60
-
61
- const routingPath = path.join(__dirname, '..', '..', 'templates', 'agentic', 'checklist-routing.md')
62
-
63
- try {
64
- if (fs.existsSync(routingPath)) {
65
- this._checklistRoutingCache = fs.readFileSync(routingPath, 'utf-8')
66
- }
67
- } catch (err) {
68
- // Silent fail
69
- }
70
-
71
- return this._checklistRoutingCache || null
72
- }
73
- /**
74
- * Build a complete prompt for Claude from template, context, and enhancements
75
- *
76
- * @param {Object} template - Template with frontmatter and content
77
- * @param {Object} context - Project context (projectPath, projectId, files, params)
78
- * @param {Object} state - Current prjct state (now, next, analysis, etc.)
79
- * @param {Object|null} [agent] - Specialized agent config (name, role, skills)
80
- * @param {Object|null} [learnedPatterns] - User preferences from memory system
81
- * @param {Object|null} [thinkBlock] - Reasoning block (plan, conclusions, confidence)
82
- * @param {Array|null} [relevantMemories] - Past decisions from semantic database
83
- * @param {Object|null} [planInfo] - Plan mode status (isPlanning, requiresApproval)
84
- * @returns {string} Complete prompt ready for Claude
85
- */
86
- build(template, context, state, agent = null, learnedPatterns = null, thinkBlock = null, relevantMemories = null, planInfo = null) {
87
- const parts = []
88
-
89
- // Store context for use in helper methods
90
- this._currentContext = context
91
-
92
- // Agent assignment (CONDITIONAL - only for code-modifying commands)
93
- // Commands like done, ship, recap, next don't need specialized agents
94
- const commandName = template.frontmatter?.name?.replace('p:', '') || ''
95
- const agentCommands = ['now', 'build', 'feature', 'design', 'fix', 'bug', 'test', 'work', 'cleanup', 'spec']
96
- const needsAgent = agentCommands.includes(commandName)
97
-
98
- if (agent && needsAgent) {
99
- // COMPRESSED: Only essential agent info (500 bytes vs 3-5KB)
100
- parts.push(`# AGENT: ${agent.name}\n`)
101
- if (agent.role) parts.push(`Role: ${agent.role}\n`)
102
- if (agent.skills?.length) parts.push(`Skills: ${agent.skills.join(', ')}\n`)
103
- parts.push(`\nApply specialized expertise. Read agent file for details if needed.\n\n`)
104
- }
105
-
106
- // Core instruction (concise)
107
- parts.push(`TASK: ${template.frontmatter.description}\n`)
108
-
109
- // Tools (inline)
110
- if (template.frontmatter['allowed-tools']) {
111
- parts.push(`TOOLS: ${template.frontmatter['allowed-tools'].join(', ')}\n`)
112
- }
113
-
114
- // Critical parameters only
115
- if (context.params?.task || context.params?.description) {
116
- parts.push(`INPUT: ${context.params.task || context.params.description}\n`)
117
- }
118
-
119
- parts.push('\n---\n')
120
-
121
- // Template (only the flow section, skip verbose explanations)
122
- const flowMatch = template.content.match(/## Flow([\s\S]*?)(?=##|$)/)
123
- if (flowMatch) {
124
- parts.push(flowMatch[0])
125
- } else {
126
- // Fallback to full template if no flow section
127
- parts.push(template.content)
128
- }
129
-
130
- // Current state (only if exists and relevant)
131
- const relevantState = this.filterRelevantState(state)
132
- if (relevantState) {
133
- parts.push('\n## PRJCT STATE (Project Management Data)\n')
134
- parts.push(relevantState)
135
- parts.push('\n')
136
- }
137
-
138
- // COMPRESSED: File list (5 files vs 20, saves ~400 bytes)
139
- if (context.files?.length > 0) {
140
- const top5 = context.files.slice(0, 5).join(', ')
141
- parts.push(`\n## FILES: ${context.files.length} available. Top: ${top5}\n`)
142
- parts.push('Read BEFORE modifying. Use Glob/Grep to find more.\n\n')
143
- } else if (context.projectPath) {
144
- parts.push(`\n## PROJECT: ${context.projectPath}\nRead files before modifying.\n\n`)
145
- }
146
-
147
- // OPTIMIZED: Only include patterns for code-modifying commands
148
- // Commands like done, ship, recap, next don't need full patterns
149
- const codeCommands = ['now', 'build', 'feature', 'design', 'cleanup', 'fix', 'bug', 'test', 'init', 'spec', 'work']
150
- const needsPatterns = codeCommands.includes(commandName)
151
-
152
- // Include code patterns analysis for code-modifying commands
153
- // COMPRESSED: Extract only conventions and anti-patterns (800 bytes max vs 6KB)
154
- const codePatternsContent = state?.codePatterns || ''
155
- if (needsPatterns && codePatternsContent && codePatternsContent.trim()) {
156
- const patternSummary = this.extractPatternSummary(codePatternsContent)
157
- if (patternSummary) {
158
- parts.push('\n## CODE PATTERNS\n')
159
- parts.push(patternSummary)
160
- parts.push('\nFull patterns: Read analysis/patterns.md\n')
161
- }
162
- }
163
-
164
- const analysisContent = state?.analysis || ''
165
- if (needsPatterns && analysisContent && analysisContent.trim()) {
166
- // Extract stack info compactly
167
- const stackMatch = analysisContent.match(/Stack[:\s]+([^\n]+)/i) ||
168
- analysisContent.match(/Technology[:\s]+([^\n]+)/i)
169
- const stack = stackMatch ? stackMatch[1].trim() : 'detected'
170
-
171
- parts.push(`\n## STACK\nStack: ${stack}\n`)
172
- if (!codePatternsContent) {
173
- parts.push('Read analysis/repo-summary.md + similar files before coding. Match patterns exactly.\n')
174
- }
175
- }
176
-
177
- // CRITICAL: Compressed rules (replaces 78 lines with 12)
178
- parts.push(this.buildCriticalRules());
179
-
180
- // P1.1: Learned Patterns (avoid asking user questions we already know)
181
- if (learnedPatterns && Object.keys(learnedPatterns).some(k => learnedPatterns[k])) {
182
- parts.push('\n## LEARNED PATTERNS (use these, do NOT ask user)\n')
183
- for (const [key, value] of Object.entries(learnedPatterns)) {
184
- if (value) {
185
- parts.push(`- ${key}: ${value}\n`)
186
- }
187
- }
188
- }
189
-
190
- // P3.1: Think Block (reasoning before action)
191
- if (thinkBlock && thinkBlock.plan && thinkBlock.plan.length > 0) {
192
- parts.push('\n## THINK FIRST (reasoning from analysis)\n')
193
- if (thinkBlock.conclusions && thinkBlock.conclusions.length > 0) {
194
- parts.push('Conclusions:\n')
195
- thinkBlock.conclusions.forEach(c => parts.push(` → ${c}\n`))
196
- }
197
- parts.push('Plan:\n')
198
- thinkBlock.plan.forEach((p, i) => parts.push(` ${i + 1}. ${p}\n`))
199
- parts.push(`Confidence: ${Math.round((thinkBlock.confidence || 0.5) * 100)}%\n`)
200
- }
201
-
202
- // P3.3: Relevant Memories (context from past decisions)
203
- if (relevantMemories && relevantMemories.length > 0) {
204
- parts.push('\n## RELEVANT MEMORIES (apply these learnings)\n')
205
- for (const memory of relevantMemories) {
206
- parts.push(`- **${memory.title}**: ${memory.content}\n`)
207
- if (memory.tags && memory.tags.length > 0) {
208
- parts.push(` Tags: ${memory.tags.join(', ')}\n`)
209
- }
210
- }
211
- }
212
-
213
- // P3.4: Plan Mode (OPTIMIZED: 30 lines → 5 lines)
214
- if (planInfo?.isPlanning) {
215
- parts.push(`\n## PLAN MODE\nRead-only. Gather info → Analyze → Propose plan → Wait for approval.\n`)
216
- if (planInfo.allowedTools) parts.push(`Tools: ${planInfo.allowedTools.join(', ')}\n`)
217
- }
218
- if (planInfo?.requiresApproval) {
219
- parts.push(`\n## APPROVAL REQUIRED\nShow changes, list affected files, ask for confirmation.\n`)
220
- }
221
-
222
- // P4.1: Quality Checklists (Claude decides which to apply)
223
- // Only for code-modifying commands that benefit from quality gates
224
- const checklistCommands = ['now', 'build', 'feature', 'design', 'fix', 'bug', 'cleanup', 'spec', 'work']
225
- if (checklistCommands.includes(commandName)) {
226
- const routing = this.loadChecklistRouting()
227
- const checklists = this.loadChecklists()
228
-
229
- if (routing && Object.keys(checklists).length > 0) {
230
- parts.push('\n## QUALITY CHECKLISTS\n')
231
- parts.push('Apply relevant checklists based on task. Read checklist-routing.md for guidance.\n')
232
- parts.push(`Available: ${Object.keys(checklists).join(', ')}\n`)
233
- parts.push('Path: templates/checklists/{name}.md\n')
234
- parts.push('Use Read tool to load checklists you determine are relevant.\n')
235
- }
236
- }
237
-
238
- // Simple execution directive
239
- parts.push('\nEXECUTE: Follow flow. Use tools. Decide.\n')
240
-
241
- return parts.join('')
242
- }
243
-
244
- /**
245
- * Filter state data to include only relevant portions for the prompt
246
- *
247
- * @param {Object} state - Full prjct state object
248
- * @returns {string|null} Formatted relevant state or null if empty
249
- */
250
- filterRelevantState(state) {
251
- if (!state || Object.keys(state).length === 0) return null
252
-
253
- const relevant = []
254
- for (const [key, content] of Object.entries(state)) {
255
- if (content && content.trim()) {
256
- // Include full content for critical files (now, next, context, patterns)
257
- const criticalFiles = ['now', 'next', 'context', 'analysis', 'codePatterns']
258
- if (criticalFiles.includes(key)) {
259
- // Include full content for critical files (up to 2000 chars)
260
- const display = content.length > 2000
261
- ? content.substring(0, 2000) + '\n... (truncated)'
262
- : content
263
- relevant.push(`### ${key}\n${display}`)
264
- } else if (content.length < 1000) {
265
- // Include full content for small files
266
- relevant.push(`### ${key}\n${content}`)
267
- } else {
268
- // Truncate large files but show more context
269
- relevant.push(`### ${key}\n${content.substring(0, 500)}... (truncated, use Read tool for full content)`)
270
- }
271
- }
272
- }
273
-
274
- return relevant.length > 0 ? relevant.join('\n\n') : null
275
- }
276
-
277
- /**
278
- * Build an analysis prompt for pre-action investigation tasks
279
- *
280
- * @param {string} analysisType - Type of analysis (e.g., 'patterns', 'stack')
281
- * @param {Object} context - Project context with projectPath and projectId
282
- * @returns {string} Analysis prompt
283
- */
284
- buildAnalysis(analysisType, context) {
285
- const parts = []
286
-
287
- parts.push(`# Analyze: ${analysisType}\n\n`)
288
- parts.push('Read the project context and provide your analysis.\n')
289
- parts.push('No predetermined patterns - decide based on what you find.\n\n')
290
-
291
- parts.push('## Project Context\n')
292
- parts.push(`- Path: ${context.projectPath}\n`)
293
- parts.push(`- ID: ${context.projectId}\n\n`)
294
-
295
- return parts.join('')
296
- }
297
-
298
- /**
299
- * Extract compressed pattern summary (conventions + high-priority anti-patterns)
300
- *
301
- * @param {string} content - Full patterns file content
302
- * @returns {string|null} Compressed summary (max 800 bytes) or null
303
- */
304
- extractPatternSummary(content) {
305
- if (!content) return null
306
-
307
- const parts = []
308
-
309
- // Extract conventions section
310
- const conventionsMatch = content.match(/## Conventions[\s\S]*?(?=##|$)/i)
311
- if (conventionsMatch) {
312
- // Compress to key lines only
313
- const conventions = conventionsMatch[0]
314
- .split('\n')
315
- .filter(line => line.includes(':') || line.startsWith('-'))
316
- .slice(0, 6)
317
- .join('\n')
318
- if (conventions) parts.push(conventions)
319
- }
320
-
321
- // Extract high priority anti-patterns only
322
- const antiPatternsMatch = content.match(/### High Priority[\s\S]*?(?=###|##|$)/i)
323
- if (antiPatternsMatch) {
324
- const antiPatterns = antiPatternsMatch[0].substring(0, 300)
325
- parts.push('\nAvoid:\n' + antiPatterns)
326
- }
327
-
328
- const result = parts.join('\n').substring(0, 800)
329
- return result || null
330
- }
331
-
332
- /**
333
- * Build critical anti-hallucination rules section
334
- *
335
- * @returns {string} Formatted rules block
336
- */
337
- buildCriticalRules() {
338
- const fileCount = this._currentContext?.files?.length || this._currentContext?.filteredSize || 0
339
- return `
340
- ## RULES (CRITICAL)
341
- 1. **READ FIRST**: Use Read tool BEFORE modifying any file. Never assume code structure.
342
- 2. **MATCH PATTERNS**: Follow existing style, architecture, naming, imports exactly.
343
- 3. **NO HALLUCINATIONS**: Don't invent files, functions, or paths. If unsure, READ first.
344
- 4. **GIT SAFETY**: Never use checkout/reset --hard/clean. Always check status first.
345
- 5. **VERIFY**: After writing, confirm code matches project patterns.
346
- Context: ${fileCount} files available. Read what you need.
347
- `;
348
- }
349
-
350
- }
351
-
352
- module.exports = new PromptBuilder()
@@ -1,290 +0,0 @@
1
- /**
2
- * Response Templates
3
- * Minimal output templates for all commands
4
- * Rule: < 4 lines, always actionable
5
- *
6
- * OPTIMIZATION (P0.3): Minimal Output
7
- * - Concise responses (< 4 lines)
8
- * - Always suggest next action
9
- * - Use symbols for status, not words
10
- *
11
- * Source: Claude Code, Kiro patterns
12
- */
13
-
14
- /**
15
- * Format duration from milliseconds or ISO strings
16
- * @param {number|string|Date} start - Start time
17
- * @param {number|string|Date} end - End time (defaults to now)
18
- * @returns {string} Human-readable duration
19
- */
20
- function formatDuration(start, end = new Date()) {
21
- const startMs = new Date(start).getTime()
22
- const endMs = new Date(end).getTime()
23
- const diffMs = endMs - startMs
24
-
25
- const hours = Math.floor(diffMs / (1000 * 60 * 60))
26
- const minutes = Math.floor((diffMs % (1000 * 60 * 60)) / (1000 * 60))
27
-
28
- if (hours > 0) {
29
- return `${hours}h ${minutes}m`
30
- }
31
- return `${minutes}m`
32
- }
33
-
34
- /**
35
- * Truncate text to max length with ellipsis
36
- * @param {string} text - Text to truncate
37
- * @param {number} maxLength - Maximum length
38
- * @returns {string}
39
- */
40
- function truncate(text, maxLength = 40) {
41
- if (!text) return ''
42
- if (text.length <= maxLength) return text
43
- return text.substring(0, maxLength - 3) + '...'
44
- }
45
-
46
- /**
47
- * Response templates for each command
48
- * Each template is a function that returns minimal formatted output
49
- */
50
- const templates = {
51
- /**
52
- * /p:done - Task completed
53
- */
54
- done: ({ task, duration, nextTask }) => {
55
- let output = `✓ '${truncate(task)}' (${duration})`
56
- if (nextTask) {
57
- output += `\n→ Next: '${truncate(nextTask)}'`
58
- }
59
- output += '\n\n/p:ship to release'
60
- return output
61
- },
62
-
63
- /**
64
- * /p:now - Current task set/shown
65
- */
66
- now: ({ task, started, isNew }) => {
67
- if (!task) {
68
- return `No active task\n→ /p:now "task" to start`
69
- }
70
- if (isNew) {
71
- return `🎯 Started: '${truncate(task)}'\n→ /p:done when complete`
72
- }
73
- return `🎯 Working on: '${truncate(task)}'\n⏱️ ${started || 'just now'}\n→ /p:done when complete`
74
- },
75
-
76
- /**
77
- * /p:next - Priority queue
78
- */
79
- next: ({ tasks, total }) => {
80
- if (!tasks || tasks.length === 0) {
81
- return `Queue empty\n→ /p:feature or /p:idea to add`
82
- }
83
- const top3 = tasks.slice(0, 3).map((t, i) =>
84
- `${i + 1}. ${truncate(t.name, 35)}`
85
- ).join('\n')
86
- const more = total > 3 ? `\n+${total - 3} more` : ''
87
- return `${top3}${more}\n\n/p:now 1 to start`
88
- },
89
-
90
- /**
91
- * /p:ship - Feature shipped
92
- */
93
- ship: ({ feature, agent, duration, version }) => {
94
- let output = `🚀 Shipped: '${truncate(feature)}'`
95
- if (agent) output += ` (${agent})`
96
- if (duration) output += ` | ${duration}`
97
- if (version) output += ` | v${version}`
98
- output += '\n→ /compact recommended'
99
- return output
100
- },
101
-
102
- /**
103
- * /p:idea - Idea captured
104
- */
105
- idea: ({ idea, addedToQueue }) => {
106
- let output = `💡 Captured: '${truncate(idea)}'`
107
- if (addedToQueue) {
108
- output += '\n→ Added to queue'
109
- }
110
- output += '\n\n/p:next to see queue'
111
- return output
112
- },
113
-
114
- /**
115
- * /p:feature - Feature added
116
- */
117
- feature: ({ feature, tasks, impact, effort }) => {
118
- let output = `📋 Feature: '${truncate(feature)}'`
119
- if (tasks) output += ` (${tasks} tasks)`
120
- if (impact) output += `\nImpact: ${impact}`
121
- if (effort) output += ` | Effort: ${effort}`
122
- output += '\n\n/p:now to start'
123
- return output
124
- },
125
-
126
- /**
127
- * /p:bug - Bug reported
128
- */
129
- bug: ({ description, priority, addedAt }) => {
130
- const priorityIcon = {
131
- 'critical': '🔴',
132
- 'high': '🟠',
133
- 'medium': '🟡',
134
- 'low': '🟢'
135
- }[priority] || '🟡'
136
-
137
- let output = `${priorityIcon} Bug: '${truncate(description)}'\nPriority: ${priority}`
138
- if (addedAt) {
139
- output += ` | Added: ${addedAt}`
140
- }
141
- output += '\n\n/p:now to fix'
142
- return output
143
- },
144
-
145
- /**
146
- * /p:pause - Task paused
147
- */
148
- pause: ({ task, duration }) => {
149
- return `⏸️ Paused: '${truncate(task)}' (${duration})\n→ /p:resume to continue`
150
- },
151
-
152
- /**
153
- * /p:resume - Task resumed
154
- */
155
- resume: ({ task, pausedFor }) => {
156
- return `▶️ Resumed: '${truncate(task)}'\nPaused for: ${pausedFor}\n→ /p:done when complete`
157
- },
158
-
159
- /**
160
- * /p:recap - Project overview
161
- */
162
- recap: ({ shipped, inProgress, queued, momentum }) => {
163
- const momentumIcon = {
164
- 'high': '🔥',
165
- 'medium': '✨',
166
- 'low': '💤'
167
- }[momentum] || '✨'
168
-
169
- return `${momentumIcon} ${shipped} shipped | ${inProgress ? '1 active' : '0 active'} | ${queued} queued`
170
- },
171
-
172
- /**
173
- * /p:progress - Progress metrics
174
- */
175
- progress: ({ period, shipped, velocity, trend }) => {
176
- const trendIcon = trend > 0 ? '↑' : trend < 0 ? '↓' : '→'
177
- return `📊 ${period}: ${shipped} shipped\nVelocity: ${velocity}/week ${trendIcon}`
178
- },
179
-
180
- /**
181
- * /p:analyze - Analysis complete
182
- */
183
- analyze: ({ stack, files, agents }) => {
184
- return `🔍 Analyzed: ${stack}\n${files} files | ${agents} agents generated\n\n/p:sync to update`
185
- },
186
-
187
- /**
188
- * /p:sync - Sync complete
189
- */
190
- sync: ({ updated, agents }) => {
191
- return `🔄 Synced: ${updated} files updated\n${agents} agents refreshed`
192
- },
193
-
194
- /**
195
- * /p:help - Help shown
196
- */
197
- help: ({ context, suggestions }) => {
198
- const sugs = suggestions.slice(0, 3).map(s => `• ${s}`).join('\n')
199
- return `📚 ${context}\n\n${sugs}`
200
- },
201
-
202
- /**
203
- * /p:suggest - Suggestions
204
- */
205
- suggest: ({ urgency, suggestion, command }) => {
206
- const urgencyIcon = {
207
- 'high': '🔥',
208
- 'medium': '💡',
209
- 'low': '✨'
210
- }[urgency] || '💡'
211
-
212
- return `${urgencyIcon} ${suggestion}\n→ ${command}`
213
- },
214
-
215
- /**
216
- * /p:spec - Spec created/updated
217
- */
218
- spec: ({ name, status, tasks, requirements, isNew }) => {
219
- let output = isNew
220
- ? `📋 Created spec: '${truncate(name)}'`
221
- : `📋 Updated spec: '${truncate(name)}'`
222
-
223
- if (requirements) output += `\n${requirements} requirements`
224
- if (tasks) output += ` | ${tasks} tasks`
225
- if (status) output += ` | Status: ${status}`
226
-
227
- output += '\n\n→ Review and approve to start'
228
- return output
229
- },
230
-
231
- /**
232
- * Generic success response
233
- */
234
- success: ({ message, nextAction }) => {
235
- let output = `✓ ${message}`
236
- if (nextAction) {
237
- output += `\n→ ${nextAction}`
238
- }
239
- return output
240
- },
241
-
242
- /**
243
- * Generic error response
244
- */
245
- error: ({ error, suggestion }) => {
246
- let output = `❌ ${error}`
247
- if (suggestion) {
248
- output += `\n→ ${suggestion}`
249
- }
250
- return output
251
- }
252
- }
253
-
254
- /**
255
- * Format a response using the appropriate template
256
- *
257
- * @param {string} commandName - Command name
258
- * @param {Object} data - Data for the template
259
- * @returns {string} Formatted response
260
- */
261
- function format(commandName, data) {
262
- const template = templates[commandName]
263
- if (!template) {
264
- // Fallback to generic success/error
265
- if (data.error) {
266
- return templates.error(data)
267
- }
268
- return templates.success(data)
269
- }
270
-
271
- return template(data)
272
- }
273
-
274
- /**
275
- * Check if response exceeds recommended length
276
- * @param {string} response - Response text
277
- * @returns {boolean} True if too long
278
- */
279
- function isTooLong(response) {
280
- const lines = response.split('\n').filter(l => l.trim())
281
- return lines.length > 4
282
- }
283
-
284
- module.exports = {
285
- format,
286
- templates,
287
- formatDuration,
288
- truncate,
289
- isTooLong
290
- }