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
@@ -0,0 +1,192 @@
1
+ /**
2
+ * Layered Memory System
3
+ * Three-tier memory for learning user patterns and preferences.
4
+ *
5
+ * @module agentic/memory-system
6
+ * @version 3.3
7
+ */
8
+
9
+ import { SemanticMemories } from './semantic-memories'
10
+ import { PatternStore } from './patterns'
11
+ import { HistoryStore } from './history'
12
+ import { SessionStore } from './session'
13
+ import type { Memory, Context, Workflow } from './types'
14
+ export { MEMORY_TAGS } from './types'
15
+
16
+ /**
17
+ * Three-tier memory system for learning user patterns.
18
+ * Tier 1: Session (ephemeral), Tier 2: Patterns (persistent), Tier 3: History (JSONL)
19
+ */
20
+ class MemorySystem {
21
+ private _semanticMemories: SemanticMemories
22
+ private _patternStore: PatternStore
23
+ private _historyStore: HistoryStore
24
+ private _sessionStore: SessionStore
25
+
26
+ constructor() {
27
+ this._semanticMemories = new SemanticMemories()
28
+ this._patternStore = new PatternStore()
29
+ this._historyStore = new HistoryStore()
30
+ this._sessionStore = new SessionStore()
31
+ }
32
+
33
+ // ═══════════════════════════════════════════════════════════
34
+ // P3.3: SEMANTIC MEMORIES
35
+ // ═══════════════════════════════════════════════════════════
36
+
37
+ loadMemories(projectId: string) {
38
+ return this._semanticMemories.loadMemories(projectId)
39
+ }
40
+
41
+ saveMemories(projectId: string) {
42
+ return this._semanticMemories.saveMemories(projectId)
43
+ }
44
+
45
+ createMemory(
46
+ projectId: string,
47
+ options: { title: string; content: string; tags?: string[]; userTriggered?: boolean }
48
+ ): Promise<string> {
49
+ return this._semanticMemories.createMemory(projectId, options)
50
+ }
51
+
52
+ updateMemory(
53
+ projectId: string,
54
+ memoryId: string,
55
+ updates: { title?: string; content?: string; tags?: string[] }
56
+ ): Promise<boolean> {
57
+ return this._semanticMemories.updateMemory(projectId, memoryId, updates)
58
+ }
59
+
60
+ deleteMemory(projectId: string, memoryId: string): Promise<boolean> {
61
+ return this._semanticMemories.deleteMemory(projectId, memoryId)
62
+ }
63
+
64
+ findByTags(projectId: string, tags: string[], matchAll?: boolean): Promise<Memory[]> {
65
+ return this._semanticMemories.findByTags(projectId, tags, matchAll)
66
+ }
67
+
68
+ searchMemories(projectId: string, query: string): Promise<Memory[]> {
69
+ return this._semanticMemories.searchMemories(projectId, query)
70
+ }
71
+
72
+ getRelevantMemories(projectId: string, context: Context, limit?: number): Promise<Memory[]> {
73
+ return this._semanticMemories.getRelevantMemories(projectId, context, limit)
74
+ }
75
+
76
+ autoRemember(projectId: string, decisionType: string, value: string, context?: string): Promise<void> {
77
+ return this._semanticMemories.autoRemember(projectId, decisionType, value, context)
78
+ }
79
+
80
+ getAllMemories(projectId: string): Promise<Memory[]> {
81
+ return this._semanticMemories.getAllMemories(projectId)
82
+ }
83
+
84
+ getMemoryStats(projectId: string) {
85
+ return this._semanticMemories.getMemoryStats(projectId)
86
+ }
87
+
88
+ // ═══════════════════════════════════════════════════════════
89
+ // TIER 1: Session Memory
90
+ // ═══════════════════════════════════════════════════════════
91
+
92
+ setSession(key: string, value: unknown): void {
93
+ this._sessionStore.setSession(key, value)
94
+ }
95
+
96
+ getSession(key: string): unknown {
97
+ return this._sessionStore.getSession(key)
98
+ }
99
+
100
+ clearSession(): void {
101
+ this._sessionStore.clearSession()
102
+ }
103
+
104
+ // ═══════════════════════════════════════════════════════════
105
+ // TIER 2: Patterns
106
+ // ═══════════════════════════════════════════════════════════
107
+
108
+ loadPatterns(projectId: string) {
109
+ return this._patternStore.loadPatterns(projectId)
110
+ }
111
+
112
+ savePatterns(projectId: string) {
113
+ return this._patternStore.savePatterns(projectId)
114
+ }
115
+
116
+ recordDecision(projectId: string, key: string, value: string, context?: string): Promise<void> {
117
+ return this._patternStore.recordDecision(projectId, key, value, context)
118
+ }
119
+
120
+ getDecision(projectId: string, key: string): Promise<{ value: string; confidence: string } | null> {
121
+ return this._patternStore.getDecision(projectId, key)
122
+ }
123
+
124
+ hasPattern(projectId: string, key: string): Promise<boolean> {
125
+ return this._patternStore.hasPattern(projectId, key)
126
+ }
127
+
128
+ recordWorkflow(projectId: string, workflowName: string, pattern: Record<string, unknown>): Promise<void> {
129
+ return this._patternStore.recordWorkflow(projectId, workflowName, pattern)
130
+ }
131
+
132
+ getWorkflow(projectId: string, workflowName: string): Promise<Workflow | null> {
133
+ return this._patternStore.getWorkflow(projectId, workflowName)
134
+ }
135
+
136
+ setPreference(projectId: string, key: string, value: unknown): Promise<void> {
137
+ return this._patternStore.setPreference(projectId, key, value)
138
+ }
139
+
140
+ getPreference(projectId: string, key: string, defaultValue?: unknown): Promise<unknown> {
141
+ return this._patternStore.getPreference(projectId, key, defaultValue)
142
+ }
143
+
144
+ getPatternsSummary(projectId: string) {
145
+ return this._patternStore.getPatternsSummary(projectId)
146
+ }
147
+
148
+ // ═══════════════════════════════════════════════════════════
149
+ // TIER 3: History
150
+ // ═══════════════════════════════════════════════════════════
151
+
152
+ appendHistory(projectId: string, entry: Record<string, unknown>): Promise<void> {
153
+ return this._historyStore.appendHistory(projectId, entry)
154
+ }
155
+
156
+ getRecentHistory(projectId: string, limit?: number) {
157
+ return this._historyStore.getRecentHistory(projectId, limit)
158
+ }
159
+
160
+ // ═══════════════════════════════════════════════════════════
161
+ // CONVENIENCE: Combined operations
162
+ // ═══════════════════════════════════════════════════════════
163
+
164
+ async getSmartDecision(projectId: string, key: string): Promise<string | null> {
165
+ const sessionValue = this.getSession(`decision:${key}`)
166
+ if (sessionValue !== undefined) return sessionValue as string
167
+
168
+ const pattern = await this.getDecision(projectId, key)
169
+ if (pattern) return pattern.value
170
+
171
+ return null
172
+ }
173
+
174
+ async learnDecision(projectId: string, key: string, value: string, context: string = ''): Promise<void> {
175
+ this.setSession(`decision:${key}`, value)
176
+ await this.recordDecision(projectId, key, value, context)
177
+ await this.appendHistory(projectId, { type: 'decision', key, value, context })
178
+ }
179
+
180
+ /**
181
+ * Reset internal state (for testing)
182
+ */
183
+ resetState(): void {
184
+ this._sessionStore.clearSession()
185
+ this._semanticMemories.reset()
186
+ this._patternStore.reset()
187
+ }
188
+ }
189
+
190
+ const memorySystem = new MemorySystem()
191
+ export default memorySystem
192
+ export { MemorySystem }
@@ -0,0 +1,156 @@
1
+ /**
2
+ * Patterns - Tier 2
3
+ * Persistent learned preferences and decisions.
4
+ */
5
+
6
+ import fs from 'fs/promises'
7
+ import path from 'path'
8
+ import pathManager from '../../infrastructure/path-manager'
9
+ import type { Patterns, Decision, Workflow } from './types'
10
+
11
+ export class PatternStore {
12
+ private _patterns: Patterns | null = null
13
+ private _patternsLoaded: boolean = false
14
+
15
+ private _getPatternsPath(projectId: string): string {
16
+ return path.join(pathManager.getGlobalProjectPath(projectId), 'memory', 'patterns.json')
17
+ }
18
+
19
+ async loadPatterns(projectId: string): Promise<Patterns> {
20
+ if (this._patternsLoaded && this._patterns) {
21
+ return this._patterns
22
+ }
23
+
24
+ try {
25
+ const patternsPath = this._getPatternsPath(projectId)
26
+ const content = await fs.readFile(patternsPath, 'utf-8')
27
+ this._patterns = JSON.parse(content)
28
+ this._patternsLoaded = true
29
+ return this._patterns!
30
+ } catch {
31
+ this._patterns = {
32
+ version: 1,
33
+ decisions: {},
34
+ preferences: {},
35
+ workflows: {},
36
+ counters: {},
37
+ }
38
+ this._patternsLoaded = true
39
+ return this._patterns
40
+ }
41
+ }
42
+
43
+ async savePatterns(projectId: string): Promise<void> {
44
+ if (!this._patterns) return
45
+
46
+ const patternsPath = this._getPatternsPath(projectId)
47
+ await fs.mkdir(path.dirname(patternsPath), { recursive: true })
48
+ await fs.writeFile(patternsPath, JSON.stringify(this._patterns, null, 2), 'utf-8')
49
+ }
50
+
51
+ async recordDecision(projectId: string, key: string, value: string, context: string = ''): Promise<void> {
52
+ const patterns = await this.loadPatterns(projectId)
53
+
54
+ if (!patterns.decisions[key]) {
55
+ patterns.decisions[key] = {
56
+ value,
57
+ count: 1,
58
+ firstSeen: new Date().toISOString(),
59
+ lastSeen: new Date().toISOString(),
60
+ confidence: 'low',
61
+ contexts: [context].filter(Boolean),
62
+ }
63
+ } else {
64
+ const decision = patterns.decisions[key]
65
+
66
+ if (decision.value === value) {
67
+ decision.count++
68
+ decision.lastSeen = new Date().toISOString()
69
+ if (context && !decision.contexts.includes(context)) {
70
+ decision.contexts.push(context)
71
+ }
72
+
73
+ if (decision.count >= 5) {
74
+ decision.confidence = 'high'
75
+ } else if (decision.count >= 3) {
76
+ decision.confidence = 'medium'
77
+ }
78
+ } else {
79
+ decision.value = value
80
+ decision.count = 1
81
+ decision.lastSeen = new Date().toISOString()
82
+ decision.confidence = 'low'
83
+ }
84
+ }
85
+
86
+ await this.savePatterns(projectId)
87
+ }
88
+
89
+ async getDecision(projectId: string, key: string): Promise<{ value: string; confidence: string } | null> {
90
+ const patterns = await this.loadPatterns(projectId)
91
+ const decision = patterns.decisions[key]
92
+
93
+ if (!decision) return null
94
+ if (decision.confidence === 'low') return null
95
+
96
+ return { value: decision.value, confidence: decision.confidence }
97
+ }
98
+
99
+ async hasPattern(projectId: string, key: string): Promise<boolean> {
100
+ const decision = await this.getDecision(projectId, key)
101
+ return decision !== null
102
+ }
103
+
104
+ async recordWorkflow(projectId: string, workflowName: string, pattern: Record<string, unknown>): Promise<void> {
105
+ const patterns = await this.loadPatterns(projectId)
106
+
107
+ if (!patterns.workflows[workflowName]) {
108
+ patterns.workflows[workflowName] = {
109
+ ...pattern,
110
+ count: 1,
111
+ firstSeen: new Date().toISOString(),
112
+ lastSeen: new Date().toISOString(),
113
+ }
114
+ } else {
115
+ patterns.workflows[workflowName].count++
116
+ patterns.workflows[workflowName].lastSeen = new Date().toISOString()
117
+ }
118
+
119
+ await this.savePatterns(projectId)
120
+ }
121
+
122
+ async getWorkflow(projectId: string, workflowName: string): Promise<Workflow | null> {
123
+ const patterns = await this.loadPatterns(projectId)
124
+ const workflow = patterns.workflows[workflowName]
125
+
126
+ if (!workflow || workflow.count < 3) return null
127
+ return workflow
128
+ }
129
+
130
+ async setPreference(projectId: string, key: string, value: unknown): Promise<void> {
131
+ const patterns = await this.loadPatterns(projectId)
132
+ patterns.preferences[key] = { value, updatedAt: new Date().toISOString() }
133
+ await this.savePatterns(projectId)
134
+ }
135
+
136
+ async getPreference(projectId: string, key: string, defaultValue: unknown = null): Promise<unknown> {
137
+ const patterns = await this.loadPatterns(projectId)
138
+ return patterns.preferences[key]?.value ?? defaultValue
139
+ }
140
+
141
+ async getPatternsSummary(projectId: string) {
142
+ const patterns = await this.loadPatterns(projectId)
143
+
144
+ return {
145
+ decisions: Object.keys(patterns.decisions).length,
146
+ learnedDecisions: Object.values(patterns.decisions).filter((d) => d.confidence !== 'low').length,
147
+ workflows: Object.keys(patterns.workflows).length,
148
+ preferences: Object.keys(patterns.preferences).length,
149
+ }
150
+ }
151
+
152
+ reset(): void {
153
+ this._patterns = null
154
+ this._patternsLoaded = false
155
+ }
156
+ }
@@ -0,0 +1,277 @@
1
+ /**
2
+ * Semantic Memories
3
+ * P3.3: Tagged, searchable, CRUD memory operations.
4
+ */
5
+
6
+ import fs from 'fs/promises'
7
+ import path from 'path'
8
+ import pathManager from '../../infrastructure/path-manager'
9
+ import type { Memory, MemoryDatabase, Context } from './types'
10
+ import { MEMORY_TAGS } from './types'
11
+
12
+ export class SemanticMemories {
13
+ private _memories: MemoryDatabase | null = null
14
+ private _memoriesLoaded: boolean = false
15
+
16
+ private _getMemoriesPath(projectId: string): string {
17
+ return path.join(pathManager.getGlobalProjectPath(projectId), 'memory', 'memories.json')
18
+ }
19
+
20
+ async loadMemories(projectId: string): Promise<MemoryDatabase> {
21
+ if (this._memoriesLoaded && this._memories) {
22
+ return this._memories
23
+ }
24
+
25
+ try {
26
+ const memoriesPath = this._getMemoriesPath(projectId)
27
+ const content = await fs.readFile(memoriesPath, 'utf-8')
28
+ this._memories = JSON.parse(content)
29
+ this._memoriesLoaded = true
30
+ return this._memories!
31
+ } catch {
32
+ this._memories = {
33
+ version: 1,
34
+ memories: [],
35
+ index: {},
36
+ }
37
+ this._memoriesLoaded = true
38
+ return this._memories
39
+ }
40
+ }
41
+
42
+ async saveMemories(projectId: string): Promise<void> {
43
+ if (!this._memories) return
44
+
45
+ const memoriesPath = this._getMemoriesPath(projectId)
46
+ await fs.mkdir(path.dirname(memoriesPath), { recursive: true })
47
+ await fs.writeFile(memoriesPath, JSON.stringify(this._memories, null, 2), 'utf-8')
48
+ }
49
+
50
+ async createMemory(
51
+ projectId: string,
52
+ {
53
+ title,
54
+ content,
55
+ tags = [],
56
+ userTriggered = false,
57
+ }: { title: string; content: string; tags?: string[]; userTriggered?: boolean }
58
+ ): Promise<string> {
59
+ const db = await this.loadMemories(projectId)
60
+
61
+ const memory: Memory = {
62
+ id: `mem_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
63
+ title,
64
+ content,
65
+ tags,
66
+ userTriggered,
67
+ createdAt: new Date().toISOString(),
68
+ updatedAt: new Date().toISOString(),
69
+ }
70
+
71
+ db.memories.push(memory)
72
+
73
+ for (const tag of tags) {
74
+ if (!db.index[tag]) db.index[tag] = []
75
+ db.index[tag].push(memory.id)
76
+ }
77
+
78
+ await this.saveMemories(projectId)
79
+ return memory.id
80
+ }
81
+
82
+ async updateMemory(
83
+ projectId: string,
84
+ memoryId: string,
85
+ updates: { title?: string; content?: string; tags?: string[] }
86
+ ): Promise<boolean> {
87
+ const db = await this.loadMemories(projectId)
88
+
89
+ const index = db.memories.findIndex((m) => m.id === memoryId)
90
+ if (index === -1) return false
91
+
92
+ const memory = db.memories[index]
93
+ const oldTags = memory.tags || []
94
+
95
+ if (updates.title) memory.title = updates.title
96
+ if (updates.content) memory.content = updates.content
97
+ if (updates.tags) {
98
+ for (const tag of oldTags) {
99
+ if (db.index[tag]) {
100
+ db.index[tag] = db.index[tag].filter((id) => id !== memoryId)
101
+ }
102
+ }
103
+ for (const tag of updates.tags) {
104
+ if (!db.index[tag]) db.index[tag] = []
105
+ db.index[tag].push(memoryId)
106
+ }
107
+ memory.tags = updates.tags
108
+ }
109
+
110
+ memory.updatedAt = new Date().toISOString()
111
+ await this.saveMemories(projectId)
112
+ return true
113
+ }
114
+
115
+ async deleteMemory(projectId: string, memoryId: string): Promise<boolean> {
116
+ const db = await this.loadMemories(projectId)
117
+
118
+ const index = db.memories.findIndex((m) => m.id === memoryId)
119
+ if (index === -1) return false
120
+
121
+ const memory = db.memories[index]
122
+
123
+ for (const tag of memory.tags || []) {
124
+ if (db.index[tag]) {
125
+ db.index[tag] = db.index[tag].filter((id) => id !== memoryId)
126
+ }
127
+ }
128
+
129
+ db.memories.splice(index, 1)
130
+ await this.saveMemories(projectId)
131
+ return true
132
+ }
133
+
134
+ async findByTags(projectId: string, tags: string[], matchAll: boolean = false): Promise<Memory[]> {
135
+ const db = await this.loadMemories(projectId)
136
+
137
+ if (matchAll) {
138
+ return db.memories.filter((m) => tags.every((tag) => (m.tags || []).includes(tag)))
139
+ } else {
140
+ const matchingIds = new Set<string>()
141
+ for (const tag of tags) {
142
+ const ids = db.index[tag] || []
143
+ ids.forEach((id) => matchingIds.add(id))
144
+ }
145
+ return db.memories.filter((m) => matchingIds.has(m.id))
146
+ }
147
+ }
148
+
149
+ async searchMemories(projectId: string, query: string): Promise<Memory[]> {
150
+ const db = await this.loadMemories(projectId)
151
+ const queryLower = query.toLowerCase()
152
+
153
+ return db.memories.filter(
154
+ (m) => m.title.toLowerCase().includes(queryLower) || m.content.toLowerCase().includes(queryLower)
155
+ )
156
+ }
157
+
158
+ async getRelevantMemories(projectId: string, context: Context, limit: number = 5): Promise<Memory[]> {
159
+ const db = await this.loadMemories(projectId)
160
+
161
+ const scored = db.memories.map((memory) => {
162
+ let score = 0
163
+
164
+ const contextTags = this._extractContextTags(context)
165
+ for (const tag of memory.tags || []) {
166
+ if (contextTags.includes(tag)) score += 10
167
+ }
168
+
169
+ const age = Date.now() - new Date(memory.updatedAt).getTime()
170
+ const daysSinceUpdate = age / (1000 * 60 * 60 * 24)
171
+ score += Math.max(0, 5 - daysSinceUpdate)
172
+
173
+ if (memory.userTriggered) score += 5
174
+
175
+ const keywords = this._extractKeywords(context)
176
+ for (const keyword of keywords) {
177
+ if (memory.content.toLowerCase().includes(keyword)) score += 2
178
+ if (memory.title.toLowerCase().includes(keyword)) score += 3
179
+ }
180
+
181
+ return { ...memory, _score: score }
182
+ })
183
+
184
+ return scored
185
+ .filter((m) => m._score > 0)
186
+ .sort((a, b) => b._score - a._score)
187
+ .slice(0, limit)
188
+ .map(({ _score, ...memory }) => memory as Memory)
189
+ }
190
+
191
+ private _extractContextTags(context: Context): string[] {
192
+ const tags: string[] = []
193
+
194
+ const commandTags: Record<string, string[]> = {
195
+ ship: [MEMORY_TAGS.COMMIT_STYLE, MEMORY_TAGS.SHIP_WORKFLOW, MEMORY_TAGS.TEST_BEHAVIOR],
196
+ feature: [MEMORY_TAGS.ARCHITECTURE, MEMORY_TAGS.CODE_STYLE],
197
+ done: [MEMORY_TAGS.SHIP_WORKFLOW],
198
+ analyze: [MEMORY_TAGS.TECH_STACK, MEMORY_TAGS.ARCHITECTURE],
199
+ spec: [MEMORY_TAGS.ARCHITECTURE, MEMORY_TAGS.CODE_STYLE],
200
+ }
201
+
202
+ if (context.commandName && commandTags[context.commandName]) {
203
+ tags.push(...commandTags[context.commandName])
204
+ }
205
+
206
+ return tags
207
+ }
208
+
209
+ private _extractKeywords(context: Context): string[] {
210
+ const keywords: string[] = []
211
+
212
+ if (context.params?.description) {
213
+ keywords.push(...(context.params.description as string).toLowerCase().split(/\s+/))
214
+ }
215
+ if (context.params?.feature) {
216
+ keywords.push(...(context.params.feature as string).toLowerCase().split(/\s+/))
217
+ }
218
+
219
+ const stopWords = ['the', 'a', 'an', 'is', 'are', 'to', 'for', 'and', 'or', 'in']
220
+ return keywords.filter((k) => k.length > 2 && !stopWords.includes(k))
221
+ }
222
+
223
+ async autoRemember(projectId: string, decisionType: string, value: string, context: string = ''): Promise<void> {
224
+ const tagMap: Record<string, string[]> = {
225
+ commit_footer: [MEMORY_TAGS.COMMIT_STYLE],
226
+ branch_naming: [MEMORY_TAGS.BRANCH_NAMING],
227
+ test_before_ship: [MEMORY_TAGS.TEST_BEHAVIOR, MEMORY_TAGS.SHIP_WORKFLOW],
228
+ preferred_agent: [MEMORY_TAGS.AGENT_PREFERENCE],
229
+ code_style: [MEMORY_TAGS.CODE_STYLE],
230
+ verbosity: [MEMORY_TAGS.OUTPUT_VERBOSITY],
231
+ }
232
+
233
+ const tags = tagMap[decisionType] || []
234
+
235
+ const existing = await this.searchMemories(projectId, decisionType)
236
+ if (existing.length > 0) {
237
+ await this.updateMemory(projectId, existing[0].id, {
238
+ content: `${decisionType}: ${value}`,
239
+ tags,
240
+ })
241
+ } else {
242
+ await this.createMemory(projectId, {
243
+ title: `Preference: ${decisionType}`,
244
+ content: `${decisionType}: ${value}${context ? `\nContext: ${context}` : ''}`,
245
+ tags,
246
+ userTriggered: true,
247
+ })
248
+ }
249
+ }
250
+
251
+ async getAllMemories(projectId: string): Promise<Memory[]> {
252
+ const db = await this.loadMemories(projectId)
253
+ return db.memories
254
+ }
255
+
256
+ async getMemoryStats(projectId: string) {
257
+ const db = await this.loadMemories(projectId)
258
+
259
+ const tagCounts: Record<string, number> = {}
260
+ for (const [tag, ids] of Object.entries(db.index)) {
261
+ tagCounts[tag] = ids.length
262
+ }
263
+
264
+ return {
265
+ totalMemories: db.memories.length,
266
+ userTriggered: db.memories.filter((m) => m.userTriggered).length,
267
+ tagCounts,
268
+ oldestMemory: db.memories[0]?.createdAt,
269
+ newestMemory: db.memories[db.memories.length - 1]?.createdAt,
270
+ }
271
+ }
272
+
273
+ reset(): void {
274
+ this._memories = null
275
+ this._memoriesLoaded = false
276
+ }
277
+ }
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Session Memory - Tier 1
3
+ * Ephemeral, single command context.
4
+ */
5
+
6
+ export class SessionStore {
7
+ private _sessionMemory: Map<string, { value: unknown; timestamp: number }> = new Map()
8
+
9
+ setSession(key: string, value: unknown): void {
10
+ this._sessionMemory.set(key, { value, timestamp: Date.now() })
11
+ }
12
+
13
+ getSession(key: string): unknown {
14
+ const entry = this._sessionMemory.get(key)
15
+ return entry?.value
16
+ }
17
+
18
+ clearSession(): void {
19
+ this._sessionMemory.clear()
20
+ }
21
+ }