prjct-cli 0.11.5 → 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 (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 +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/{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 +598 -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 +36 -6
  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
@@ -3,7 +3,8 @@
3
3
  * Tests for centralized date operations and formatting
4
4
  */
5
5
 
6
- const {
6
+ import { describe, it, expect, beforeEach, afterEach, setSystemTime } from 'bun:test'
7
+ import {
7
8
  formatDate,
8
9
  formatMonth,
9
10
  getTodayKey,
@@ -20,7 +21,7 @@ const {
20
21
  calculateDuration,
21
22
  getStartOfDay,
22
23
  getEndOfDay,
23
- } = require('../../utils/date-helper')
24
+ } from '../../utils/date-helper'
24
25
 
25
26
  describe('DateHelper', () => {
26
27
  describe('formatDate', () => {
@@ -64,12 +65,9 @@ describe('DateHelper', () => {
64
65
 
65
66
  describe('getTodayKey', () => {
66
67
  it('should return today in YYYY-MM-DD format', () => {
67
- vi.useFakeTimers()
68
- vi.setSystemTime(new Date(2025, 5, 15)) // June 15, 2025
69
-
68
+ setSystemTime(new Date(2025, 5, 15)) // June 15, 2025
70
69
  expect(getTodayKey()).toBe('2025-06-15')
71
-
72
- vi.useRealTimers()
70
+ setSystemTime()
73
71
  })
74
72
  })
75
73
 
@@ -93,14 +91,12 @@ describe('DateHelper', () => {
93
91
  it('should pad month values', () => {
94
92
  const date = new Date(2025, 0, 15) // Jan 15, 2025
95
93
  const result = getYearMonthDay(date)
96
-
97
94
  expect(result.month).toBe('01')
98
95
  })
99
96
 
100
97
  it('should pad day values', () => {
101
98
  const date = new Date(2025, 5, 7) // June 7, 2025
102
99
  const result = getYearMonthDay(date)
103
-
104
100
  expect(result.day).toBe('07')
105
101
  })
106
102
  })
@@ -122,12 +118,9 @@ describe('DateHelper', () => {
122
118
 
123
119
  describe('getTimestamp', () => {
124
120
  it('should return ISO timestamp', () => {
125
- vi.useFakeTimers()
126
- vi.setSystemTime(new Date('2025-10-04T14:30:00.000Z'))
127
-
121
+ setSystemTime(new Date('2025-10-04T14:30:00.000Z'))
128
122
  expect(getTimestamp()).toBe('2025-10-04T14:30:00.000Z')
129
-
130
- vi.useRealTimers()
123
+ setSystemTime()
131
124
  })
132
125
 
133
126
  it('should include milliseconds', () => {
@@ -138,12 +131,11 @@ describe('DateHelper', () => {
138
131
 
139
132
  describe('getDaysAgo', () => {
140
133
  beforeEach(() => {
141
- vi.useFakeTimers()
142
- vi.setSystemTime(new Date(2025, 9, 15)) // Oct 15, 2025
134
+ setSystemTime(new Date(2025, 9, 15)) // Oct 15, 2025
143
135
  })
144
136
 
145
137
  afterEach(() => {
146
- vi.useRealTimers()
138
+ setSystemTime()
147
139
  })
148
140
 
149
141
  it('should calculate past dates correctly', () => {
@@ -164,12 +156,11 @@ describe('DateHelper', () => {
164
156
 
165
157
  describe('getDaysFromNow', () => {
166
158
  beforeEach(() => {
167
- vi.useFakeTimers()
168
- vi.setSystemTime(new Date(2025, 9, 15)) // Oct 15, 2025
159
+ setSystemTime(new Date(2025, 9, 15)) // Oct 15, 2025
169
160
  })
170
161
 
171
162
  afterEach(() => {
172
- vi.useRealTimers()
163
+ setSystemTime()
173
164
  })
174
165
 
175
166
  it('should calculate future dates correctly', () => {
@@ -241,12 +232,11 @@ describe('DateHelper', () => {
241
232
 
242
233
  describe('isToday', () => {
243
234
  beforeEach(() => {
244
- vi.useFakeTimers()
245
- vi.setSystemTime(new Date(2025, 9, 15)) // Oct 15, 2025
235
+ setSystemTime(new Date(2025, 9, 15)) // Oct 15, 2025
246
236
  })
247
237
 
248
238
  afterEach(() => {
249
- vi.useRealTimers()
239
+ setSystemTime()
250
240
  })
251
241
 
252
242
  it('should return true for today', () => {
@@ -272,12 +262,11 @@ describe('DateHelper', () => {
272
262
 
273
263
  describe('isWithinLastDays', () => {
274
264
  beforeEach(() => {
275
- vi.useFakeTimers()
276
- vi.setSystemTime(new Date(2025, 9, 15, 12, 0, 0)) // Oct 15, 2025 at noon
265
+ setSystemTime(new Date(2025, 9, 15, 12, 0, 0)) // Oct 15, 2025 at noon
277
266
  })
278
267
 
279
268
  afterEach(() => {
280
- vi.useRealTimers()
269
+ setSystemTime()
281
270
  })
282
271
 
283
272
  it('should return true for dates within range', () => {
@@ -296,7 +285,8 @@ describe('DateHelper', () => {
296
285
  })
297
286
 
298
287
  it('should include boundary date', () => {
299
- const boundary = new Date(2025, 9, 8) // exactly 7 days ago
288
+ // Oct 8 at noon is exactly 7 days before Oct 15 at noon
289
+ const boundary = new Date(2025, 9, 8, 12, 0, 0)
300
290
  expect(isWithinLastDays(boundary, 7)).toBe(true)
301
291
  })
302
292
  })
@@ -339,13 +329,12 @@ describe('DateHelper', () => {
339
329
  })
340
330
 
341
331
  it('should default to now if no end date', () => {
342
- vi.useFakeTimers()
343
- vi.setSystemTime(new Date('2025-10-15T12:00:00.000Z'))
332
+ setSystemTime(new Date('2025-10-15T12:00:00.000Z'))
344
333
 
345
334
  const start = new Date('2025-10-15T10:00:00.000Z')
346
335
  expect(calculateDuration(start)).toBe('2h 0m')
347
336
 
348
- vi.useRealTimers()
337
+ setSystemTime()
349
338
  })
350
339
 
351
340
  it('should handle short durations', () => {
@@ -3,18 +3,16 @@
3
3
  * Minimal output system for prjct-cli
4
4
  */
5
5
 
6
- const out = require('../../utils/output')
6
+ import { describe, it, expect, beforeEach, afterEach, spyOn } from 'bun:test'
7
+ import out from '../../utils/output'
7
8
 
8
9
  describe('Output Module', () => {
9
- let consoleLogSpy
10
- let stdoutWriteSpy
10
+ let consoleLogSpy: ReturnType<typeof spyOn>
11
+ let stdoutWriteSpy: ReturnType<typeof spyOn>
11
12
 
12
13
  beforeEach(() => {
13
- // Mock console.log
14
- consoleLogSpy = vi.spyOn(console, 'log').mockImplementation(() => {})
15
- // Mock process.stdout.write
16
- stdoutWriteSpy = vi.spyOn(process.stdout, 'write').mockImplementation(() => {})
17
- // Ensure spinner is stopped before each test
14
+ consoleLogSpy = spyOn(console, 'log').mockImplementation(() => {})
15
+ stdoutWriteSpy = spyOn(process.stdout, 'write').mockImplementation(() => true)
18
16
  out.stop()
19
17
  })
20
18
 
@@ -39,7 +37,6 @@ describe('Output Module', () => {
39
37
  out.done(longMessage)
40
38
 
41
39
  const output = consoleLogSpy.mock.calls[0][0]
42
- // Should be truncated to ~65 chars + checkmark
43
40
  expect(output.length).toBeLessThan(80)
44
41
  })
45
42
 
@@ -90,20 +87,16 @@ describe('Output Module', () => {
90
87
  })
91
88
 
92
89
  describe('spin()', () => {
93
- it('should start spinner with message', () => {
94
- vi.useFakeTimers()
95
-
90
+ it('should start spinner with message', async () => {
96
91
  out.spin('loading')
97
92
 
98
- // Advance timer to trigger interval
99
- vi.advanceTimersByTime(100)
93
+ await new Promise(resolve => setTimeout(resolve, 150))
100
94
 
101
95
  expect(stdoutWriteSpy).toHaveBeenCalled()
102
96
  const output = stdoutWriteSpy.mock.calls[0][0]
103
97
  expect(output).toContain('loading')
104
98
 
105
99
  out.stop()
106
- vi.useRealTimers()
107
100
  })
108
101
 
109
102
  it('should return self for chaining', () => {
@@ -114,19 +107,14 @@ describe('Output Module', () => {
114
107
  })
115
108
 
116
109
  describe('stop()', () => {
117
- it('should stop spinner and clear line', () => {
118
- vi.useFakeTimers()
119
-
110
+ it('should stop spinner and clear line', async () => {
120
111
  out.spin('loading')
121
- vi.advanceTimersByTime(100)
112
+ await new Promise(resolve => setTimeout(resolve, 150))
122
113
 
123
114
  stdoutWriteSpy.mockClear()
124
115
  out.stop()
125
116
 
126
- // Should write clearing spaces
127
117
  expect(stdoutWriteSpy).toHaveBeenCalled()
128
-
129
- vi.useRealTimers()
130
118
  })
131
119
 
132
120
  it('should be safe to call multiple times', () => {
@@ -151,8 +139,8 @@ describe('Output Module', () => {
151
139
  })
152
140
 
153
141
  it('should handle null/undefined messages', () => {
154
- expect(() => out.done(null)).not.toThrow()
155
- expect(() => out.done(undefined)).not.toThrow()
142
+ expect(() => out.done(null as unknown as string)).not.toThrow()
143
+ expect(() => out.done(undefined as unknown as string)).not.toThrow()
156
144
  })
157
145
 
158
146
  it('should handle messages with special characters', () => {
@@ -0,0 +1,137 @@
1
+ /**
2
+ * Agent Router
3
+ * Orchestrates agent loading and context building for Claude delegation.
4
+ *
5
+ * @module agentic/agent-router
6
+ * @version 2.0.0
7
+ */
8
+
9
+ import fs from 'fs/promises'
10
+ import path from 'path'
11
+ import configManager from '../infrastructure/config-manager'
12
+ import pathManager from '../infrastructure/path-manager'
13
+
14
+ interface Agent {
15
+ name: string
16
+ content: string
17
+ }
18
+
19
+ interface AssignmentContext {
20
+ task: string
21
+ availableAgents: string[]
22
+ projectPath: string
23
+ projectId: string | null
24
+ _template: string
25
+ }
26
+
27
+ /**
28
+ * Routes tasks to specialized agents based on Claude's decisions.
29
+ * Handles agent loading, context building, and usage logging.
30
+ */
31
+ class AgentRouter {
32
+ projectId: string | null = null
33
+ agentsPath: string | null = null
34
+
35
+ /**
36
+ * Initialize router with project context
37
+ */
38
+ async initialize(projectPath: string): Promise<void> {
39
+ this.projectId = await configManager.getProjectId(projectPath)
40
+ this.agentsPath = pathManager.getPath(this.projectId!, 'agents')
41
+ }
42
+
43
+ /**
44
+ * Load all available agents from project
45
+ */
46
+ async loadAvailableAgents(): Promise<Agent[]> {
47
+ try {
48
+ const files = await fs.readdir(this.agentsPath!)
49
+ const agents: Agent[] = []
50
+
51
+ for (const file of files) {
52
+ if (file.endsWith('.md')) {
53
+ const name = file.replace('.md', '')
54
+ const content = await fs.readFile(path.join(this.agentsPath!, file), 'utf-8')
55
+ agents.push({ name, content })
56
+ }
57
+ }
58
+
59
+ return agents
60
+ } catch {
61
+ return []
62
+ }
63
+ }
64
+
65
+ /**
66
+ * Get list of available agent names
67
+ */
68
+ async getAgentNames(): Promise<string[]> {
69
+ const agents = await this.loadAvailableAgents()
70
+ return agents.map((a) => a.name)
71
+ }
72
+
73
+ /**
74
+ * Load a specific agent by name
75
+ */
76
+ async loadAgent(name: string): Promise<Agent | null> {
77
+ try {
78
+ const filePath = path.join(this.agentsPath!, `${name}.md`)
79
+ const content = await fs.readFile(filePath, 'utf-8')
80
+ return { name, content }
81
+ } catch {
82
+ return null
83
+ }
84
+ }
85
+
86
+ /**
87
+ * Build context for Claude to decide agent assignment
88
+ */
89
+ async buildAssignmentContext(
90
+ task: string | { description?: string },
91
+ projectPath: string
92
+ ): Promise<AssignmentContext> {
93
+ const agents = await this.getAgentNames()
94
+
95
+ return {
96
+ task: typeof task === 'string' ? task : task.description || '',
97
+ availableAgents: agents,
98
+ projectPath,
99
+ projectId: this.projectId,
100
+ // Claude reads this and decides via template
101
+ _template: 'templates/agent-assignment.md',
102
+ }
103
+ }
104
+
105
+ /**
106
+ * Log agent usage to JSONL file
107
+ */
108
+ async logUsage(
109
+ task: string | { description?: string },
110
+ agent: string | { name?: string },
111
+ _projectPath: string
112
+ ): Promise<void> {
113
+ try {
114
+ const logPath = path.join(
115
+ process.env.HOME || '',
116
+ '.prjct-cli',
117
+ 'projects',
118
+ this.projectId || '',
119
+ 'agent-usage.jsonl'
120
+ )
121
+
122
+ const entry =
123
+ JSON.stringify({
124
+ timestamp: new Date().toISOString(),
125
+ task: typeof task === 'string' ? task : task.description,
126
+ agent: typeof agent === 'string' ? agent : agent.name,
127
+ projectId: this.projectId,
128
+ }) + '\n'
129
+
130
+ await fs.appendFile(logPath, entry)
131
+ } catch {
132
+ // Silent fail for logging
133
+ }
134
+ }
135
+ }
136
+
137
+ export default AgentRouter
@@ -0,0 +1,228 @@
1
+ /**
2
+ * Chain of Thought Reasoning
3
+ * Implements step-by-step reasoning for complex commands
4
+ *
5
+ * @module agentic/chain-of-thought
6
+ * @version 1.0.0
7
+ */
8
+
9
+ interface Context {
10
+ projectId?: string | null
11
+ projectPath: string
12
+ params: Record<string, unknown>
13
+ }
14
+
15
+ interface State {
16
+ now?: string | null
17
+ next?: string | null
18
+ shipped?: string | null
19
+ analysis?: string | null
20
+ [key: string]: unknown
21
+ }
22
+
23
+ interface ReasoningStep {
24
+ step: string
25
+ passed: boolean
26
+ details?: string
27
+ }
28
+
29
+ interface ReasoningResult {
30
+ commandName: string
31
+ reasoning: {
32
+ steps: ReasoningStep[]
33
+ allPassed: boolean
34
+ criticalIssues: string[]
35
+ } | null
36
+ plan: string[]
37
+ confidence: number
38
+ }
39
+
40
+ /**
41
+ * Commands that require chain of thought reasoning
42
+ */
43
+ const REASONING_REQUIRED_COMMANDS = ['ship', 'feature', 'spec', 'cleanup', 'migrate']
44
+
45
+ /**
46
+ * Check if command requires reasoning
47
+ */
48
+ function requiresReasoning(commandName: string): boolean {
49
+ return REASONING_REQUIRED_COMMANDS.includes(commandName)
50
+ }
51
+
52
+ /**
53
+ * Reason through a command before execution
54
+ */
55
+ async function reason(commandName: string, context: Context, state: State): Promise<ReasoningResult> {
56
+ const steps: ReasoningStep[] = []
57
+ const plan: string[] = []
58
+ const criticalIssues: string[] = []
59
+
60
+ switch (commandName) {
61
+ case 'ship':
62
+ // Check prerequisites
63
+ if (state.now && !state.now.includes('No current task')) {
64
+ steps.push({ step: 'Has active task', passed: true })
65
+ } else {
66
+ steps.push({ step: 'Has active task', passed: false, details: 'No active task to ship' })
67
+ criticalIssues.push('No active task')
68
+ }
69
+
70
+ // Check if there's content to ship
71
+ if (state.shipped) {
72
+ steps.push({ step: 'Shipped log accessible', passed: true })
73
+ } else {
74
+ steps.push({ step: 'Shipped log accessible', passed: false, details: 'shipped.md not found' })
75
+ }
76
+
77
+ // Plan
78
+ plan.push('Read current task from now.md')
79
+ plan.push('Calculate duration')
80
+ plan.push('Append to shipped.md')
81
+ plan.push('Clear now.md')
82
+ plan.push('Update metrics')
83
+ break
84
+
85
+ case 'feature':
86
+ // Check if description provided
87
+ if (context.params.description || context.params.feature) {
88
+ steps.push({ step: 'Has feature description', passed: true })
89
+ } else {
90
+ steps.push({ step: 'Has feature description', passed: false, details: 'No description provided' })
91
+ criticalIssues.push('Missing feature description')
92
+ }
93
+
94
+ // Check roadmap accessibility
95
+ if (state.analysis) {
96
+ steps.push({ step: 'Project analyzed', passed: true })
97
+ } else {
98
+ steps.push({ step: 'Project analyzed', passed: false, details: 'Run /p:sync first' })
99
+ }
100
+
101
+ // Plan
102
+ plan.push('Parse feature description')
103
+ plan.push('Generate tasks breakdown')
104
+ plan.push('Add to roadmap.md')
105
+ plan.push('Add tasks to next.md')
106
+ plan.push('Suggest starting first task')
107
+ break
108
+
109
+ case 'spec':
110
+ // Check if feature name provided
111
+ if (context.params.feature || context.params.name) {
112
+ steps.push({ step: 'Has spec name', passed: true })
113
+ } else {
114
+ steps.push({ step: 'Has spec name', passed: false, details: 'No spec name provided' })
115
+ criticalIssues.push('Missing spec name')
116
+ }
117
+
118
+ // Plan
119
+ plan.push('Generate spec template')
120
+ plan.push('Analyze requirements')
121
+ plan.push('Create spec file')
122
+ plan.push('Link to roadmap')
123
+ break
124
+
125
+ case 'cleanup':
126
+ // Check for analysis
127
+ if (state.analysis) {
128
+ steps.push({ step: 'Has code analysis', passed: true })
129
+ } else {
130
+ steps.push({ step: 'Has code analysis', passed: false, details: 'Run /p:analyze first' })
131
+ }
132
+
133
+ // Plan
134
+ plan.push('Scan for unused code')
135
+ plan.push('Identify dead imports')
136
+ plan.push('List files to clean')
137
+ plan.push('Show preview')
138
+ plan.push('Wait for approval')
139
+ plan.push('Execute cleanup')
140
+ break
141
+
142
+ case 'migrate':
143
+ // Always warn for migrate
144
+ steps.push({
145
+ step: 'Migration safety check',
146
+ passed: true,
147
+ details: 'Will require manual approval',
148
+ })
149
+
150
+ // Plan
151
+ plan.push('Analyze current state')
152
+ plan.push('Generate migration plan')
153
+ plan.push('Show affected files')
154
+ plan.push('Request approval')
155
+ plan.push('Execute migration')
156
+ plan.push('Verify results')
157
+ break
158
+
159
+ default:
160
+ // Generic plan
161
+ plan.push('Execute command')
162
+ break
163
+ }
164
+
165
+ // Calculate confidence
166
+ const passedSteps = steps.filter((s) => s.passed).length
167
+ const totalSteps = steps.length
168
+ const confidence = totalSteps > 0 ? passedSteps / totalSteps : 1
169
+
170
+ return {
171
+ commandName,
172
+ reasoning:
173
+ steps.length > 0
174
+ ? {
175
+ steps,
176
+ allPassed: criticalIssues.length === 0,
177
+ criticalIssues,
178
+ }
179
+ : null,
180
+ plan,
181
+ confidence,
182
+ }
183
+ }
184
+
185
+ /**
186
+ * Format reasoning plan for display
187
+ */
188
+ function formatPlan(result: ReasoningResult): string {
189
+ const lines: string[] = []
190
+
191
+ lines.push(`📋 Chain of Thought: ${result.commandName}`)
192
+ lines.push('')
193
+
194
+ if (result.reasoning) {
195
+ lines.push('Steps:')
196
+ result.reasoning.steps.forEach((step) => {
197
+ const icon = step.passed ? '✅' : '❌'
198
+ lines.push(` ${icon} ${step.step}`)
199
+ if (step.details) {
200
+ lines.push(` ${step.details}`)
201
+ }
202
+ })
203
+ lines.push('')
204
+
205
+ if (result.reasoning.criticalIssues.length > 0) {
206
+ lines.push('Critical Issues:')
207
+ result.reasoning.criticalIssues.forEach((issue) => {
208
+ lines.push(` ⚠️ ${issue}`)
209
+ })
210
+ lines.push('')
211
+ }
212
+ }
213
+
214
+ if (result.plan.length > 0) {
215
+ lines.push('Plan:')
216
+ result.plan.forEach((step, i) => {
217
+ lines.push(` ${i + 1}. ${step}`)
218
+ })
219
+ lines.push('')
220
+ }
221
+
222
+ lines.push(`Confidence: ${Math.round(result.confidence * 100)}%`)
223
+
224
+ return lines.join('\n')
225
+ }
226
+
227
+ export { requiresReasoning, reason, formatPlan, REASONING_REQUIRED_COMMANDS }
228
+ export default { requiresReasoning, reason, formatPlan }