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,70 @@
1
+ /**
2
+ * Feature Command Verifier
3
+ * Verify feature can be added
4
+ */
5
+
6
+ import fs from 'fs/promises'
7
+ import type { Context, VerificationResult } from '../types'
8
+ import { escapeRegex } from '../utils'
9
+
10
+ export async function verifyFeature(context: Context): Promise<VerificationResult> {
11
+ const warnings: string[] = []
12
+ const recommendations: string[] = []
13
+ const actual: Record<string, unknown> = {}
14
+
15
+ // 1. Check next.md capacity
16
+ const nextPath = context.paths.next
17
+ try {
18
+ const nextContent = await fs.readFile(nextPath, 'utf-8')
19
+ actual.nextExists = true
20
+ const tasks = nextContent.match(/- \[[ x]\]/g) || []
21
+ actual.taskCount = tasks.length
22
+ actual.pendingTasks = (nextContent.match(/- \[ \]/g) || []).length
23
+
24
+ if ((actual.taskCount as number) >= 90) {
25
+ warnings.push(`Queue nearly full (${actual.taskCount}/100 tasks)`)
26
+ recommendations.push('Complete some tasks before adding more')
27
+ }
28
+ } catch {
29
+ actual.nextExists = false
30
+ actual.taskCount = 0
31
+ }
32
+
33
+ // 2. Check roadmap.md for duplicate features
34
+ const roadmapPath = context.paths.roadmap
35
+ try {
36
+ const roadmapContent = await fs.readFile(roadmapPath, 'utf-8')
37
+ actual.roadmapExists = true
38
+
39
+ const featureName = context.params.description || context.params.feature
40
+ if (featureName) {
41
+ const featurePattern = new RegExp(escapeRegex(featureName), 'i')
42
+ if (featurePattern.test(roadmapContent)) {
43
+ warnings.push(`Feature "${featureName}" may already exist in roadmap`)
44
+ recommendations.push('Check roadmap for duplicates with /p:roadmap')
45
+ }
46
+ }
47
+ } catch {
48
+ actual.roadmapExists = false
49
+ }
50
+
51
+ // 3. Check if there's an active task (should complete first?)
52
+ const nowPath = context.paths.now
53
+ try {
54
+ const nowContent = await fs.readFile(nowPath, 'utf-8')
55
+ actual.hasActiveTask = nowContent.trim().length > 0 && !nowContent.includes('No current task')
56
+
57
+ if (actual.hasActiveTask) {
58
+ recommendations.push('Consider completing current task first with /p:done')
59
+ }
60
+ } catch {
61
+ actual.hasActiveTask = false
62
+ }
63
+
64
+ return {
65
+ verified: warnings.length === 0,
66
+ actual,
67
+ warnings,
68
+ recommendations,
69
+ }
70
+ }
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Ground Truth Verifiers Index
3
+ * Re-exports all command verifiers
4
+ */
5
+
6
+ import type { Verifier } from '../types'
7
+ import { verifyDone } from './done'
8
+ import { verifyShip } from './ship'
9
+ import { verifyFeature } from './feature'
10
+ import { verifyNow } from './now'
11
+ import { verifyInit } from './init'
12
+ import { verifySync } from './sync'
13
+ import { verifyAnalyze } from './analyze'
14
+ import { verifySpec } from './spec'
15
+
16
+ /**
17
+ * Command-specific ground truth verifiers
18
+ */
19
+ export const verifiers: Record<string, Verifier> = {
20
+ done: verifyDone,
21
+ ship: verifyShip,
22
+ feature: verifyFeature,
23
+ now: verifyNow,
24
+ init: verifyInit,
25
+ sync: verifySync,
26
+ analyze: verifyAnalyze,
27
+ spec: verifySpec,
28
+ }
29
+
30
+ export { verifyDone } from './done'
31
+ export { verifyShip } from './ship'
32
+ export { verifyFeature } from './feature'
33
+ export { verifyNow } from './now'
34
+ export { verifyInit } from './init'
35
+ export { verifySync } from './sync'
36
+ export { verifyAnalyze } from './analyze'
37
+ export { verifySpec } from './spec'
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Init Command Verifier
3
+ * Verify project can be initialized
4
+ */
5
+
6
+ import fs from 'fs/promises'
7
+ import path from 'path'
8
+ import os from 'os'
9
+ import type { Context, VerificationResult } from '../types'
10
+
11
+ export async function verifyInit(context: Context): Promise<VerificationResult> {
12
+ const warnings: string[] = []
13
+ const recommendations: string[] = []
14
+ const actual: Record<string, unknown> = {}
15
+
16
+ // 1. Check if already initialized
17
+ const configPath = path.join(context.projectPath, '.prjct/prjct.config.json')
18
+ try {
19
+ const configContent = await fs.readFile(configPath, 'utf-8')
20
+ actual.alreadyInitialized = true
21
+ actual.existingConfig = JSON.parse(configContent)
22
+ warnings.push('Project already initialized')
23
+ recommendations.push('Use /p:analyze to refresh analysis or delete .prjct/ to reinitialize')
24
+ } catch {
25
+ actual.alreadyInitialized = false
26
+ }
27
+
28
+ // 2. Check if global storage path is writable
29
+ const globalPath = path.join(os.homedir(), '.prjct-cli')
30
+ try {
31
+ await fs.access(globalPath, fs.constants.W_OK)
32
+ actual.globalPathWritable = true
33
+ } catch {
34
+ try {
35
+ // Try to create it
36
+ await fs.mkdir(globalPath, { recursive: true })
37
+ actual.globalPathWritable = true
38
+ actual.globalPathCreated = true
39
+ } catch {
40
+ actual.globalPathWritable = false
41
+ warnings.push('Cannot write to ~/.prjct-cli')
42
+ recommendations.push('Check directory permissions')
43
+ }
44
+ }
45
+
46
+ return {
47
+ verified: warnings.length === 0,
48
+ actual,
49
+ warnings,
50
+ recommendations,
51
+ }
52
+ }
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Now Command Verifier
3
+ * Verify task can be set (anti-hallucination: warn if replacing)
4
+ */
5
+
6
+ import fs from 'fs/promises'
7
+ import type { Context, VerificationResult } from '../types'
8
+
9
+ export async function verifyNow(context: Context): Promise<VerificationResult> {
10
+ const warnings: string[] = []
11
+ const recommendations: string[] = []
12
+ const actual: Record<string, unknown> = {}
13
+
14
+ // 1. Check if there's already an active task
15
+ const nowPath = context.paths.now
16
+ try {
17
+ const nowContent = await fs.readFile(nowPath, 'utf-8')
18
+ actual.nowExists = true
19
+ actual.nowContent = nowContent.trim()
20
+
21
+ const hasRealTask =
22
+ nowContent.trim().length > 0 && !nowContent.includes('No current task') && !nowContent.match(/^#\s*NOW\s*$/m)
23
+
24
+ actual.hasActiveTask = hasRealTask
25
+
26
+ // ANTI-HALLUCINATION: Warn if replacing existing task
27
+ if (hasRealTask && context.params.task) {
28
+ const taskPreview = nowContent.substring(0, 50).replace(/\n/g, ' ')
29
+ warnings.push(`Replacing existing task: "${taskPreview}..."`)
30
+ recommendations.push('Use /p:done first to track completion')
31
+ }
32
+ } catch {
33
+ actual.nowExists = false
34
+ actual.hasActiveTask = false
35
+ }
36
+
37
+ // 2. Check next.md for available tasks
38
+ const nextPath = context.paths.next
39
+ try {
40
+ const nextContent = await fs.readFile(nextPath, 'utf-8')
41
+ const pendingTasks = (nextContent.match(/- \[ \]/g) || []).length
42
+ actual.pendingTasks = pendingTasks
43
+
44
+ if (!context.params.task && pendingTasks > 0) {
45
+ recommendations.push(`${pendingTasks} tasks available in queue`)
46
+ }
47
+ } catch {
48
+ actual.pendingTasks = 0
49
+ }
50
+
51
+ return {
52
+ verified: warnings.length === 0,
53
+ actual,
54
+ warnings,
55
+ recommendations,
56
+ }
57
+ }
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Ship Command Verifier
3
+ * Verify feature is ready to ship
4
+ */
5
+
6
+ import fs from 'fs/promises'
7
+ import path from 'path'
8
+ import { execSync } from 'child_process'
9
+ import type { Context, VerificationResult } from '../types'
10
+ import { escapeRegex } from '../utils'
11
+
12
+ export async function verifyShip(context: Context): Promise<VerificationResult> {
13
+ const warnings: string[] = []
14
+ const recommendations: string[] = []
15
+ const actual: Record<string, unknown> = {}
16
+
17
+ // 1. Check for uncommitted changes
18
+ try {
19
+ const gitStatus = execSync('git status --porcelain', {
20
+ cwd: context.projectPath,
21
+ encoding: 'utf-8',
22
+ })
23
+ actual.hasUncommittedChanges = gitStatus.trim().length > 0
24
+ actual.uncommittedFiles = gitStatus.trim().split('\n').filter(Boolean).length
25
+
26
+ if (actual.hasUncommittedChanges) {
27
+ warnings.push(`${actual.uncommittedFiles} uncommitted file(s)`)
28
+ recommendations.push('Commit changes before shipping')
29
+ }
30
+ } catch {
31
+ actual.gitAvailable = false
32
+ // Not a git repo or git not available - not a blocker
33
+ }
34
+
35
+ // 2. Check for package.json version (if exists)
36
+ const pkgPath = path.join(context.projectPath, 'package.json')
37
+ try {
38
+ const pkgContent = await fs.readFile(pkgPath, 'utf-8')
39
+ const pkg = JSON.parse(pkgContent)
40
+ actual.currentVersion = pkg.version
41
+ actual.hasPackageJson = true
42
+ } catch {
43
+ actual.hasPackageJson = false
44
+ }
45
+
46
+ // 3. Check shipped.md for duplicate feature names
47
+ const shippedPath = context.paths.shipped
48
+ try {
49
+ const shippedContent = await fs.readFile(shippedPath, 'utf-8')
50
+ actual.shippedExists = true
51
+
52
+ // Check if feature name already shipped today
53
+ const featureName = context.params.feature || context.params.description
54
+ if (featureName) {
55
+ const today = new Date().toISOString().split('T')[0]
56
+ const todayPattern = new RegExp(`${today}.*${escapeRegex(featureName)}`, 'i')
57
+ if (todayPattern.test(shippedContent)) {
58
+ warnings.push(`Feature "${featureName}" already shipped today`)
59
+ recommendations.push('Use a different feature name or skip /p:ship')
60
+ }
61
+ }
62
+ } catch {
63
+ actual.shippedExists = false
64
+ }
65
+
66
+ // 4. Check for test failures (if test script exists)
67
+ if (actual.hasPackageJson) {
68
+ try {
69
+ const pkgContent = await fs.readFile(pkgPath, 'utf-8')
70
+ const pkg = JSON.parse(pkgContent)
71
+ actual.hasTestScript = !!pkg.scripts?.test
72
+ // Note: We don't run tests here, just check if they exist
73
+ // Running tests is the user's responsibility
74
+ } catch {
75
+ actual.hasTestScript = false
76
+ }
77
+ }
78
+
79
+ return {
80
+ verified: warnings.length === 0,
81
+ actual,
82
+ warnings,
83
+ recommendations,
84
+ }
85
+ }
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Spec Command Verifier
3
+ * Verify spec can be created
4
+ */
5
+
6
+ import fs from 'fs/promises'
7
+ import type { Context, VerificationResult } from '../types'
8
+
9
+ export async function verifySpec(context: Context): Promise<VerificationResult> {
10
+ const warnings: string[] = []
11
+ const recommendations: string[] = []
12
+ const actual: Record<string, unknown> = {}
13
+
14
+ // 1. Check specs directory exists
15
+ const specsPath = context.paths.specs
16
+ try {
17
+ await fs.access(specsPath)
18
+ actual.specsExists = true
19
+
20
+ // List existing specs
21
+ const files = await fs.readdir(specsPath)
22
+ actual.existingSpecs = files.filter((f) => f.endsWith('.md'))
23
+ actual.specCount = (actual.existingSpecs as string[]).length
24
+ } catch {
25
+ actual.specsExists = false
26
+ actual.specCount = 0
27
+ }
28
+
29
+ // 2. Check for duplicate spec name
30
+ const featureName = context.params.feature || context.params.name || context.params.description
31
+ if (featureName && actual.existingSpecs) {
32
+ const slug = featureName.toLowerCase().replace(/\s+/g, '-')
33
+ if ((actual.existingSpecs as string[]).includes(`${slug}.md`)) {
34
+ warnings.push(`Spec "${featureName}" already exists`)
35
+ recommendations.push('Use a different name or edit existing spec')
36
+ }
37
+ }
38
+
39
+ return {
40
+ verified: warnings.length === 0,
41
+ actual,
42
+ warnings,
43
+ recommendations,
44
+ }
45
+ }
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Sync Command Verifier
3
+ * Verify sync can proceed
4
+ */
5
+
6
+ import fs from 'fs/promises'
7
+ import path from 'path'
8
+ import os from 'os'
9
+ import type { Context, VerificationResult } from '../types'
10
+
11
+ export async function verifySync(context: Context): Promise<VerificationResult> {
12
+ const warnings: string[] = []
13
+ const recommendations: string[] = []
14
+ const actual: Record<string, unknown> = {}
15
+
16
+ // 1. Check if project is initialized
17
+ const configPath = path.join(context.projectPath, '.prjct/prjct.config.json')
18
+ try {
19
+ const configContent = await fs.readFile(configPath, 'utf-8')
20
+ actual.hasConfig = true
21
+ actual.config = JSON.parse(configContent)
22
+ } catch {
23
+ actual.hasConfig = false
24
+ warnings.push('Project not initialized')
25
+ recommendations.push('Run /p:init first')
26
+ return { verified: false, actual, warnings, recommendations }
27
+ }
28
+
29
+ // 2. Check if global storage exists
30
+ const projectId = (actual.config as { projectId?: string })?.projectId
31
+ const globalProjectPath = path.join(os.homedir(), '.prjct-cli/projects', projectId || '')
32
+ try {
33
+ await fs.access(globalProjectPath)
34
+ actual.globalStorageExists = true
35
+ } catch {
36
+ actual.globalStorageExists = false
37
+ warnings.push('Global storage missing')
38
+ recommendations.push('Run /p:init to recreate')
39
+ }
40
+
41
+ return {
42
+ verified: warnings.length === 0,
43
+ actual,
44
+ warnings,
45
+ recommendations,
46
+ }
47
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Ground Truth Verifiers
3
+ * Re-exports from verifiers/index.ts for backwards compatibility.
4
+ */
5
+
6
+ export * from './verifiers/index'
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Ground Truth Verification
3
+ * Re-exports from ground-truth/index.ts for backwards compatibility.
4
+ */
5
+
6
+ import groundTruth from './ground-truth/index'
7
+ export * from './ground-truth/index'
8
+ export default groundTruth
@@ -0,0 +1,97 @@
1
+ /**
2
+ * Error Analysis
3
+ * Pattern detection and suggestion generation for errors
4
+ */
5
+
6
+ import type { ErrorEntry, ErrorPattern } from './types'
7
+
8
+ /**
9
+ * Check if two errors are similar
10
+ */
11
+ export function isSimilarError(error1: string, error2: string): boolean {
12
+ if (!error1 || !error2) return false
13
+
14
+ // Normalize errors
15
+ const normalize = (e: string) =>
16
+ e
17
+ .toLowerCase()
18
+ .replace(/[0-9]+/g, 'N') // Replace numbers
19
+ .replace(/['"`]/g, '') // Remove quotes
20
+ .replace(/\s+/g, ' ') // Normalize whitespace
21
+ .trim()
22
+
23
+ return normalize(error1) === normalize(error2)
24
+ }
25
+
26
+ /**
27
+ * Analyze error pattern from history
28
+ */
29
+ export function analyzeErrorPattern(errors: ErrorEntry[]): ErrorPattern {
30
+ if (!errors || errors.length === 0) {
31
+ return { type: 'unknown', description: 'No error information' }
32
+ }
33
+
34
+ const lastError = errors[errors.length - 1]?.message?.toLowerCase() || ''
35
+
36
+ // Detect common patterns (ORDER MATTERS - more specific patterns first)
37
+ if (lastError.includes('permission') || lastError.includes('access denied')) {
38
+ return { type: 'permission', description: 'File or directory permission issue' }
39
+ }
40
+ if (lastError.includes('not found') || lastError.includes('no such file')) {
41
+ return { type: 'not_found', description: 'File or resource not found' }
42
+ }
43
+ if (lastError.includes('syntax') || lastError.includes('parse')) {
44
+ return { type: 'syntax', description: 'Syntax or parsing error' }
45
+ }
46
+ if (lastError.includes('timeout') || lastError.includes('timed out')) {
47
+ return { type: 'timeout', description: 'Operation timed out' }
48
+ }
49
+ if (lastError.includes('network') || lastError.includes('connection')) {
50
+ return { type: 'network', description: 'Network or connection issue' }
51
+ }
52
+ // Config pattern MUST be checked before validation (since "invalid config" contains both)
53
+ if (lastError.includes('config') || lastError.includes('configuration')) {
54
+ return { type: 'config', description: 'Configuration issue' }
55
+ }
56
+ if (lastError.includes('validation') || lastError.includes('invalid')) {
57
+ return { type: 'validation', description: 'Validation failed' }
58
+ }
59
+
60
+ return { type: 'unknown', description: 'Unrecognized error pattern' }
61
+ }
62
+
63
+ /**
64
+ * Generate user-friendly escalation message
65
+ */
66
+ export function generateEscalationMessage(command: string, errorPattern: ErrorPattern, maxAttempts: number): string {
67
+ const messages: Record<string, string> = {
68
+ permission: `I've tried ${command} ${maxAttempts} times but keep hitting permission issues.`,
69
+ not_found: `After ${maxAttempts} attempts, I still can't find the required file or resource.`,
70
+ syntax: `I'm encountering repeated syntax errors with ${command}.`,
71
+ timeout: `The operation keeps timing out after ${maxAttempts} attempts.`,
72
+ network: `Network issues are preventing ${command} from completing.`,
73
+ validation: `Validation keeps failing for ${command}.`,
74
+ config: `There seems to be a configuration issue affecting ${command}.`,
75
+ unknown: `I've tried ${command} ${maxAttempts} times without success.`,
76
+ }
77
+
78
+ return messages[errorPattern.type] || messages.unknown
79
+ }
80
+
81
+ /**
82
+ * Generate actionable suggestion based on error pattern
83
+ */
84
+ export function generateSuggestion(errorPattern: ErrorPattern): string {
85
+ const suggestions: Record<string, string> = {
86
+ permission: 'Check file permissions. Try: chmod -R u+w ~/.prjct-cli/',
87
+ not_found: 'Verify the file path exists. Run /p:init if project not initialized.',
88
+ syntax: 'Check the file format. There may be invalid JSON or markdown.',
89
+ timeout: 'Check your network connection or try again in a moment.',
90
+ network: 'Verify internet connection and try again.',
91
+ validation: 'Review the input parameters and try with different values.',
92
+ config: 'Check .prjct/prjct.config.json for issues. Try /p:init to reinitialize.',
93
+ unknown: 'Can you check the issue manually and provide more context?',
94
+ }
95
+
96
+ return suggestions[errorPattern.type] || suggestions.unknown
97
+ }
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Hallucination Detection
3
+ * ANTI-HALLUCINATION: Patterns that indicate Claude may be hallucinating
4
+ */
5
+
6
+ import type { HallucinationPattern, HallucinationResult } from './types'
7
+
8
+ /**
9
+ * ANTI-HALLUCINATION: Patterns that indicate Claude may be hallucinating
10
+ * These patterns detect contradictory or impossible statements
11
+ */
12
+ export const HALLUCINATION_PATTERNS: HallucinationPattern[] = [
13
+ // Contradictory file operations
14
+ { pattern: /file.*not found.*created/i, type: 'contradiction', description: 'Claims file created but also not found' },
15
+ { pattern: /created.*but.*error/i, type: 'contradiction', description: 'Claims success but also error' },
16
+ { pattern: /successfully.*failed/i, type: 'contradiction', description: 'Contradictory success/failure' },
17
+
18
+ // Impossible task states
19
+ {
20
+ pattern: /already.*completed.*completing/i,
21
+ type: 'state',
22
+ description: 'Completing already-completed task',
23
+ },
24
+ { pattern: /no task.*marking complete/i, type: 'state', description: 'Completing non-existent task' },
25
+ { pattern: /no.*active.*done with/i, type: 'state', description: 'Finishing task that doesnt exist' },
26
+
27
+ // Invented data
28
+ {
29
+ pattern: /version.*updated.*no package/i,
30
+ type: 'invented',
31
+ description: 'Version update without package.json',
32
+ },
33
+ { pattern: /committed.*nothing to commit/i, type: 'invented', description: 'Commit without changes' },
34
+ { pattern: /pushed.*no remote/i, type: 'invented', description: 'Push without remote' },
35
+ ]
36
+
37
+ /**
38
+ * Get suggestion for handling detected hallucination
39
+ */
40
+ export function getHallucinationSuggestion(type: string): string {
41
+ const suggestions: Record<string, string> = {
42
+ contradiction: 'Verify file/resource state before reporting. Use Read tool to check actual state.',
43
+ state: 'Check current task state from now.md before assuming completion.',
44
+ invented: 'Verify prerequisites exist (package.json, git remote) before claiming actions.',
45
+ }
46
+ return suggestions[type] || 'Verify actual state before proceeding.'
47
+ }
48
+
49
+ /**
50
+ * Detect potential hallucination patterns in output
51
+ */
52
+ export function detectHallucination(output: string): HallucinationResult {
53
+ if (!output || typeof output !== 'string') {
54
+ return { detected: false }
55
+ }
56
+
57
+ for (const { pattern, type, description } of HALLUCINATION_PATTERNS) {
58
+ if (pattern.test(output)) {
59
+ return {
60
+ detected: true,
61
+ type,
62
+ pattern: pattern.source,
63
+ description,
64
+ message: `Potential hallucination detected: ${description}`,
65
+ suggestion: getHallucinationSuggestion(type),
66
+ }
67
+ }
68
+ }
69
+
70
+ return { detected: false }
71
+ }
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Loop Detection & User Escalation
3
+ *
4
+ * Detects when commands are failing repeatedly and escalates to user
5
+ * instead of continuing in infinite loops.
6
+ *
7
+ * OPTIMIZATION (P2.4): Loop Detection
8
+ * - Track attempt counts per command/error type
9
+ * - Auto-escalate after 3 failed attempts
10
+ * - Provide specific help based on error patterns
11
+ *
12
+ * ANTI-HALLUCINATION: Detects contradictory/impossible outputs
13
+ * - Patterns that indicate Claude is hallucinating (saying file exists when it doesn't)
14
+ * - Contradictory statements in same response
15
+ * - Completing tasks that were never started
16
+ *
17
+ * Source: Augment Code pattern
18
+ * "If you notice yourself going around in circles... ask the user for help"
19
+ */
20
+
21
+ export type {
22
+ ErrorEntry,
23
+ AttemptRecord,
24
+ ErrorPattern,
25
+ EscalationInfo,
26
+ AttemptResult,
27
+ AttemptInfo,
28
+ HallucinationPattern,
29
+ HallucinationResult,
30
+ OutputAnalysis,
31
+ } from './types'
32
+
33
+ export { HALLUCINATION_PATTERNS, detectHallucination, getHallucinationSuggestion } from './hallucination'
34
+ export { isSimilarError, analyzeErrorPattern, generateEscalationMessage, generateSuggestion } from './error-analysis'
35
+ export { LoopDetector } from './loop-detector'
36
+
37
+ import { LoopDetector } from './loop-detector'
38
+
39
+ // Singleton instance
40
+ const loopDetector = new LoopDetector()
41
+ export default loopDetector