prjct-cli 0.11.5 → 0.12.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (391) hide show
  1. package/CHANGELOG.md +58 -0
  2. package/README.md +81 -25
  3. package/bin/dev.js +1 -1
  4. package/bin/generate-views.js +209 -0
  5. package/bin/migrate-to-json.js +742 -0
  6. package/bin/prjct +5 -5
  7. package/bin/serve.js +226 -50
  8. package/core/__tests__/agentic/{memory-system.test.js → memory-system.test.ts} +12 -23
  9. package/core/__tests__/agentic/{plan-mode.test.js → plan-mode.test.ts} +26 -24
  10. package/core/__tests__/agentic/{prompt-builder.test.js → prompt-builder.test.ts} +3 -8
  11. package/core/__tests__/utils/{date-helper.test.js → date-helper.test.ts} +19 -30
  12. package/core/__tests__/utils/{output.test.js → output.test.ts} +12 -24
  13. package/core/agentic/agent-router.ts +137 -0
  14. package/core/agentic/chain-of-thought.ts +228 -0
  15. package/core/agentic/command-executor/command-executor.ts +384 -0
  16. package/core/agentic/command-executor/index.ts +16 -0
  17. package/core/agentic/command-executor/status-signal.ts +38 -0
  18. package/core/agentic/command-executor/types.ts +79 -0
  19. package/core/agentic/command-executor.ts +8 -0
  20. package/core/agentic/{context-builder.js → context-builder.ts} +92 -81
  21. package/core/agentic/context-filter.ts +365 -0
  22. package/core/agentic/ground-truth/index.ts +76 -0
  23. package/core/agentic/ground-truth/types.ts +33 -0
  24. package/core/agentic/ground-truth/utils.ts +48 -0
  25. package/core/agentic/ground-truth/verifiers/analyze.ts +54 -0
  26. package/core/agentic/ground-truth/verifiers/done.ts +75 -0
  27. package/core/agentic/ground-truth/verifiers/feature.ts +70 -0
  28. package/core/agentic/ground-truth/verifiers/index.ts +37 -0
  29. package/core/agentic/ground-truth/verifiers/init.ts +52 -0
  30. package/core/agentic/ground-truth/verifiers/now.ts +57 -0
  31. package/core/agentic/ground-truth/verifiers/ship.ts +85 -0
  32. package/core/agentic/ground-truth/verifiers/spec.ts +45 -0
  33. package/core/agentic/ground-truth/verifiers/sync.ts +47 -0
  34. package/core/agentic/ground-truth/verifiers.ts +6 -0
  35. package/core/agentic/ground-truth.ts +8 -0
  36. package/core/agentic/loop-detector/error-analysis.ts +97 -0
  37. package/core/agentic/loop-detector/hallucination.ts +71 -0
  38. package/core/agentic/loop-detector/index.ts +41 -0
  39. package/core/agentic/loop-detector/loop-detector.ts +222 -0
  40. package/core/agentic/loop-detector/types.ts +66 -0
  41. package/core/agentic/loop-detector.ts +8 -0
  42. package/core/agentic/memory-system/history.ts +53 -0
  43. package/core/agentic/memory-system/index.ts +192 -0
  44. package/core/agentic/memory-system/patterns.ts +156 -0
  45. package/core/agentic/memory-system/semantic-memories.ts +277 -0
  46. package/core/agentic/memory-system/session.ts +21 -0
  47. package/core/agentic/memory-system/types.ts +159 -0
  48. package/core/agentic/memory-system.ts +8 -0
  49. package/core/agentic/parallel-tools.ts +165 -0
  50. package/core/agentic/plan-mode/approval.ts +57 -0
  51. package/core/agentic/plan-mode/constants.ts +44 -0
  52. package/core/agentic/plan-mode/index.ts +28 -0
  53. package/core/agentic/plan-mode/plan-mode.ts +406 -0
  54. package/core/agentic/plan-mode/types.ts +193 -0
  55. package/core/agentic/plan-mode.ts +8 -0
  56. package/core/agentic/prompt-builder.ts +566 -0
  57. package/core/agentic/response-templates.ts +164 -0
  58. package/core/agentic/semantic-compression.ts +273 -0
  59. package/core/agentic/services.ts +206 -0
  60. package/core/agentic/smart-context.ts +476 -0
  61. package/core/agentic/{template-loader.js → template-loader.ts} +27 -16
  62. package/core/agentic/think-blocks.ts +202 -0
  63. package/core/agentic/tool-registry.ts +119 -0
  64. package/core/agentic/validation-rules.ts +313 -0
  65. package/core/agents/index.ts +28 -0
  66. package/core/agents/performance.ts +444 -0
  67. package/core/agents/types.ts +126 -0
  68. package/core/bus/{index.js → index.ts} +57 -61
  69. package/core/command-registry/categories.ts +23 -0
  70. package/core/command-registry/commands.ts +15 -0
  71. package/core/command-registry/core-commands.ts +319 -0
  72. package/core/command-registry/index.ts +158 -0
  73. package/core/command-registry/optional-commands.ts +119 -0
  74. package/core/command-registry/setup-commands.ts +53 -0
  75. package/core/command-registry/types.ts +59 -0
  76. package/core/command-registry.ts +9 -0
  77. package/core/commands/analysis.ts +298 -0
  78. package/core/commands/analytics.ts +288 -0
  79. package/core/commands/base.ts +273 -0
  80. package/core/commands/index.ts +211 -0
  81. package/core/commands/maintenance.ts +226 -0
  82. package/core/commands/planning.ts +311 -0
  83. package/core/commands/setup.ts +309 -0
  84. package/core/commands/shipping.ts +188 -0
  85. package/core/commands/types.ts +183 -0
  86. package/core/commands/workflow.ts +226 -0
  87. package/core/commands.ts +11 -0
  88. package/core/constants/formats.ts +187 -0
  89. package/core/constants/index.ts +7 -0
  90. package/core/{context-sync.js → context-sync.ts} +59 -26
  91. package/core/data/agents-manager.ts +76 -0
  92. package/core/data/analysis-manager.ts +83 -0
  93. package/core/data/base-manager.ts +156 -0
  94. package/core/data/ideas-manager.ts +81 -0
  95. package/core/data/index.ts +32 -0
  96. package/core/data/outcomes-manager.ts +96 -0
  97. package/core/data/project-manager.ts +75 -0
  98. package/core/data/roadmap-manager.ts +118 -0
  99. package/core/data/shipped-manager.ts +65 -0
  100. package/core/data/state-manager.ts +214 -0
  101. package/core/domain/{agent-generator.js → agent-generator.ts} +77 -57
  102. package/core/domain/{agent-loader.js → agent-loader.ts} +65 -56
  103. package/core/domain/{agent-matcher.js → agent-matcher.ts} +51 -24
  104. package/core/domain/{agent-validator.js → agent-validator.ts} +70 -37
  105. package/core/domain/{analyzer.js → analyzer.ts} +91 -85
  106. package/core/domain/{architect-session.js → architect-session.ts} +49 -34
  107. package/core/domain/{architecture-generator.js → architecture-generator.ts} +25 -13
  108. package/core/domain/{context-estimator.js → context-estimator.ts} +57 -36
  109. package/core/domain/{product-standards.js → product-standards.ts} +40 -26
  110. package/core/domain/{smart-cache.js → smart-cache.ts} +39 -30
  111. package/core/domain/{snapshot-manager.js → snapshot-manager.ts} +103 -100
  112. package/core/domain/{task-analyzer.js → task-analyzer.ts} +82 -43
  113. package/core/domain/task-stack/index.ts +19 -0
  114. package/core/domain/task-stack/parser.ts +86 -0
  115. package/core/domain/task-stack/storage.ts +123 -0
  116. package/core/domain/task-stack/task-stack.ts +340 -0
  117. package/core/domain/task-stack/types.ts +51 -0
  118. package/core/domain/task-stack.ts +8 -0
  119. package/core/{index.js → index.ts} +61 -18
  120. package/core/infrastructure/{agent-detector.js → agent-detector.ts} +55 -19
  121. package/core/infrastructure/agents/{claude-agent.js → claude-agent.ts} +61 -21
  122. package/core/infrastructure/{author-detector.js → author-detector.ts} +42 -49
  123. package/core/infrastructure/{capability-installer.js → capability-installer.ts} +51 -27
  124. package/core/infrastructure/{command-installer.js → command-installer/command-installer.ts} +43 -144
  125. package/core/infrastructure/command-installer/global-config.ts +106 -0
  126. package/core/infrastructure/command-installer/index.ts +25 -0
  127. package/core/infrastructure/command-installer/types.ts +41 -0
  128. package/core/infrastructure/command-installer.ts +8 -0
  129. package/core/infrastructure/{config-manager.js → config-manager.ts} +60 -80
  130. package/core/infrastructure/{editors-config.js → editors-config.ts} +33 -31
  131. package/core/infrastructure/legacy-installer-detector/cleanup.ts +216 -0
  132. package/core/infrastructure/legacy-installer-detector/detection.ts +95 -0
  133. package/core/infrastructure/legacy-installer-detector/index.ts +171 -0
  134. package/core/infrastructure/legacy-installer-detector/migration.ts +87 -0
  135. package/core/infrastructure/legacy-installer-detector/types.ts +42 -0
  136. package/core/infrastructure/legacy-installer-detector.ts +7 -0
  137. package/core/infrastructure/migrator/file-operations.ts +125 -0
  138. package/core/infrastructure/migrator/index.ts +288 -0
  139. package/core/infrastructure/migrator/project-scanner.ts +89 -0
  140. package/core/infrastructure/migrator/reports.ts +117 -0
  141. package/core/infrastructure/migrator/types.ts +124 -0
  142. package/core/infrastructure/migrator/validation.ts +94 -0
  143. package/core/infrastructure/migrator/version-migration.ts +117 -0
  144. package/core/infrastructure/migrator.ts +10 -0
  145. package/core/infrastructure/{path-manager.js → path-manager.ts} +51 -91
  146. package/core/infrastructure/session-manager/index.ts +23 -0
  147. package/core/infrastructure/session-manager/migration.ts +88 -0
  148. package/core/infrastructure/session-manager/session-manager.ts +307 -0
  149. package/core/infrastructure/session-manager/types.ts +45 -0
  150. package/core/infrastructure/session-manager.ts +8 -0
  151. package/core/infrastructure/{setup.js → setup.ts} +29 -21
  152. package/core/infrastructure/{update-checker.js → update-checker.ts} +40 -18
  153. package/core/outcomes/analyzer.ts +333 -0
  154. package/core/outcomes/index.ts +34 -0
  155. package/core/outcomes/recorder.ts +194 -0
  156. package/core/outcomes/types.ts +145 -0
  157. package/core/plugin/{hooks.js → hooks.ts} +56 -58
  158. package/core/plugin/{index.js → index.ts} +19 -8
  159. package/core/plugin/{loader.js → loader.ts} +87 -69
  160. package/core/plugin/{registry.js → registry.ts} +49 -45
  161. package/core/plugins/{webhook.js → webhook.ts} +43 -27
  162. package/core/schemas/agents.ts +27 -0
  163. package/core/schemas/analysis.ts +41 -0
  164. package/core/schemas/ideas.ts +83 -0
  165. package/core/schemas/index.ts +73 -0
  166. package/core/schemas/outcomes.ts +22 -0
  167. package/core/schemas/project.ts +26 -0
  168. package/core/schemas/roadmap.ts +90 -0
  169. package/core/schemas/shipped.ts +82 -0
  170. package/core/schemas/state.ts +107 -0
  171. package/core/session/index.ts +17 -0
  172. package/core/session/{metrics.js → metrics.ts} +64 -46
  173. package/core/session/{index.js → session-manager.ts} +51 -117
  174. package/core/session/types.ts +29 -0
  175. package/core/session/utils.ts +57 -0
  176. package/core/state/index.ts +25 -0
  177. package/core/state/manager.ts +376 -0
  178. package/core/state/types.ts +185 -0
  179. package/core/tsconfig.json +22 -0
  180. package/core/types/index.ts +506 -0
  181. package/core/utils/{animations.js → animations.ts} +74 -28
  182. package/core/utils/{branding.js → branding.ts} +29 -4
  183. package/core/utils/{date-helper.js → date-helper.ts} +31 -74
  184. package/core/utils/file-helper.ts +262 -0
  185. package/core/utils/{jsonl-helper.js → jsonl-helper.ts} +71 -107
  186. package/core/utils/{logger.js → logger.ts} +24 -12
  187. package/core/utils/{output.js → output.ts} +25 -13
  188. package/core/utils/{project-capabilities.js → project-capabilities.ts} +31 -18
  189. package/core/utils/{session-helper.js → session-helper.ts} +79 -66
  190. package/core/utils/{version.js → version.ts} +23 -31
  191. package/core/view-generator.ts +536 -0
  192. package/package.json +23 -17
  193. package/packages/shared/.turbo/turbo-build.log +14 -0
  194. package/packages/shared/dist/index.d.ts +8 -613
  195. package/packages/shared/dist/index.d.ts.map +1 -0
  196. package/packages/shared/dist/index.js +4110 -118
  197. package/packages/shared/dist/schemas.d.ts +408 -0
  198. package/packages/shared/dist/schemas.d.ts.map +1 -0
  199. package/packages/shared/dist/types.d.ts +144 -0
  200. package/packages/shared/dist/types.d.ts.map +1 -0
  201. package/packages/shared/dist/unified.d.ts +139 -0
  202. package/packages/shared/dist/unified.d.ts.map +1 -0
  203. package/packages/shared/dist/utils.d.ts +60 -0
  204. package/packages/shared/dist/utils.d.ts.map +1 -0
  205. package/packages/shared/package.json +4 -4
  206. package/packages/shared/src/index.ts +1 -0
  207. package/packages/shared/src/unified.ts +174 -0
  208. package/packages/web/app/api/claude/sessions/route.ts +1 -1
  209. package/packages/web/app/api/claude/status/route.ts +1 -1
  210. package/packages/web/app/api/migrate/route.ts +46 -0
  211. package/packages/web/app/api/projects/[id]/route.ts +1 -1
  212. package/packages/web/app/api/projects/[id]/stats/route.ts +30 -2
  213. package/packages/web/app/api/projects/[id]/status/route.ts +1 -1
  214. package/packages/web/app/api/projects/route.ts +1 -1
  215. package/packages/web/app/api/settings/route.ts +97 -0
  216. package/packages/web/app/api/v2/projects/[id]/unified/route.ts +57 -0
  217. package/packages/web/app/globals.css +38 -0
  218. package/packages/web/app/layout.tsx +10 -2
  219. package/packages/web/app/page.tsx +9 -224
  220. package/packages/web/app/project/[id]/page.tsx +191 -63
  221. package/packages/web/app/project/[id]/stats/loading.tsx +43 -0
  222. package/packages/web/app/project/[id]/stats/page.tsx +204 -163
  223. package/packages/web/app/settings/page.tsx +222 -2
  224. package/packages/web/components/ActivityTimeline/ActivityTimeline.constants.ts +2 -0
  225. package/packages/web/components/ActivityTimeline/ActivityTimeline.tsx +50 -0
  226. package/packages/web/components/ActivityTimeline/ActivityTimeline.types.ts +8 -0
  227. package/packages/web/components/ActivityTimeline/hooks/index.ts +2 -0
  228. package/packages/web/components/ActivityTimeline/hooks/useExpandable.ts +9 -0
  229. package/packages/web/components/ActivityTimeline/hooks/useGroupedEvents.ts +23 -0
  230. package/packages/web/components/ActivityTimeline/index.ts +2 -0
  231. package/packages/web/components/AgentsCard/AgentsCard.tsx +63 -0
  232. package/packages/web/components/AgentsCard/AgentsCard.types.ts +13 -0
  233. package/packages/web/components/AgentsCard/index.ts +2 -0
  234. package/packages/web/components/AppSidebar/AppSidebar.tsx +190 -0
  235. package/packages/web/components/AppSidebar/index.ts +1 -0
  236. package/packages/web/components/BackLink/BackLink.tsx +18 -0
  237. package/packages/web/components/BackLink/BackLink.types.ts +5 -0
  238. package/packages/web/components/BackLink/index.ts +2 -0
  239. package/packages/web/components/BentoCard/BentoCard.constants.ts +16 -0
  240. package/packages/web/components/BentoCard/BentoCard.tsx +47 -0
  241. package/packages/web/components/BentoCard/BentoCard.types.ts +15 -0
  242. package/packages/web/components/BentoCard/index.ts +2 -0
  243. package/packages/web/components/BentoCardSkeleton/BentoCardSkeleton.constants.ts +9 -0
  244. package/packages/web/components/BentoCardSkeleton/BentoCardSkeleton.tsx +18 -0
  245. package/packages/web/components/BentoCardSkeleton/BentoCardSkeleton.types.ts +5 -0
  246. package/packages/web/components/BentoCardSkeleton/index.ts +2 -0
  247. package/packages/web/components/{stats → BentoGrid}/BentoGrid.tsx +4 -8
  248. package/packages/web/components/BentoGrid/BentoGrid.types.ts +4 -0
  249. package/packages/web/components/BentoGrid/index.ts +2 -0
  250. package/packages/web/components/CommandButton/index.ts +1 -0
  251. package/packages/web/components/ConnectionStatus/index.ts +1 -0
  252. package/packages/web/components/DashboardContent/DashboardContent.tsx +254 -0
  253. package/packages/web/components/DashboardContent/index.ts +1 -0
  254. package/packages/web/components/DateGroup/DateGroup.tsx +18 -0
  255. package/packages/web/components/DateGroup/DateGroup.types.ts +6 -0
  256. package/packages/web/components/DateGroup/DateGroup.utils.ts +11 -0
  257. package/packages/web/components/DateGroup/index.ts +2 -0
  258. package/packages/web/components/{stats → EmptyState}/EmptyState.tsx +1 -10
  259. package/packages/web/components/EmptyState/EmptyState.types.ts +10 -0
  260. package/packages/web/components/EmptyState/index.ts +2 -0
  261. package/packages/web/components/EventRow/EventRow.constants.ts +10 -0
  262. package/packages/web/components/EventRow/EventRow.tsx +49 -0
  263. package/packages/web/components/EventRow/EventRow.types.ts +7 -0
  264. package/packages/web/components/EventRow/EventRow.utils.ts +49 -0
  265. package/packages/web/components/EventRow/index.ts +2 -0
  266. package/packages/web/components/ExpandButton/ExpandButton.tsx +18 -0
  267. package/packages/web/components/ExpandButton/ExpandButton.types.ts +6 -0
  268. package/packages/web/components/ExpandButton/index.ts +2 -0
  269. package/packages/web/components/HealthGradientBackground/HealthGradientBackground.tsx +14 -0
  270. package/packages/web/components/HealthGradientBackground/HealthGradientBackground.types.ts +5 -0
  271. package/packages/web/components/HealthGradientBackground/HealthGradientBackground.utils.ts +13 -0
  272. package/packages/web/components/HealthGradientBackground/index.ts +2 -0
  273. package/packages/web/components/HeroSection/HeroSection.tsx +55 -0
  274. package/packages/web/components/HeroSection/HeroSection.types.ts +14 -0
  275. package/packages/web/components/HeroSection/HeroSection.utils.ts +7 -0
  276. package/packages/web/components/HeroSection/hooks/index.ts +2 -0
  277. package/packages/web/components/HeroSection/hooks/useCountUp.ts +45 -0
  278. package/packages/web/components/HeroSection/hooks/useWeeklyActivity.ts +18 -0
  279. package/packages/web/components/HeroSection/index.ts +2 -0
  280. package/packages/web/components/{stats → IdeasCard}/IdeasCard.tsx +3 -14
  281. package/packages/web/components/IdeasCard/IdeasCard.types.ts +9 -0
  282. package/packages/web/components/IdeasCard/index.ts +2 -0
  283. package/packages/web/components/InsightMessage/InsightMessage.tsx +9 -0
  284. package/packages/web/components/InsightMessage/InsightMessage.types.ts +3 -0
  285. package/packages/web/components/InsightMessage/index.ts +2 -0
  286. package/packages/web/components/Logo/index.ts +1 -0
  287. package/packages/web/components/MarkdownContent/index.ts +1 -0
  288. package/packages/web/components/NowCard/NowCard.tsx +93 -0
  289. package/packages/web/components/NowCard/NowCard.types.ts +15 -0
  290. package/packages/web/components/NowCard/index.ts +2 -0
  291. package/packages/web/components/ProgressRing/ProgressRing.constants.ts +20 -0
  292. package/packages/web/components/{stats → ProgressRing}/ProgressRing.tsx +4 -27
  293. package/packages/web/components/ProgressRing/ProgressRing.types.ts +11 -0
  294. package/packages/web/components/ProgressRing/index.ts +2 -0
  295. package/packages/web/components/ProjectAvatar/index.ts +1 -0
  296. package/packages/web/components/Providers/index.ts +1 -0
  297. package/packages/web/components/QueueCard/QueueCard.tsx +72 -0
  298. package/packages/web/components/QueueCard/QueueCard.types.ts +11 -0
  299. package/packages/web/components/QueueCard/QueueCard.utils.ts +12 -0
  300. package/packages/web/components/QueueCard/index.ts +2 -0
  301. package/packages/web/components/{stats → RoadmapCard}/RoadmapCard.tsx +3 -23
  302. package/packages/web/components/RoadmapCard/RoadmapCard.types.ts +15 -0
  303. package/packages/web/components/RoadmapCard/index.ts +2 -0
  304. package/packages/web/components/{stats → ShipsCard}/ShipsCard.tsx +4 -22
  305. package/packages/web/components/ShipsCard/ShipsCard.types.ts +12 -0
  306. package/packages/web/components/ShipsCard/ShipsCard.utils.ts +4 -0
  307. package/packages/web/components/ShipsCard/index.ts +2 -0
  308. package/packages/web/components/{stats → SparklineChart}/SparklineChart.tsx +1 -7
  309. package/packages/web/components/SparklineChart/SparklineChart.types.ts +6 -0
  310. package/packages/web/components/SparklineChart/index.ts +2 -0
  311. package/packages/web/components/StreakCard/StreakCard.constants.ts +2 -0
  312. package/packages/web/components/{stats → StreakCard}/StreakCard.tsx +5 -11
  313. package/packages/web/components/StreakCard/StreakCard.types.ts +4 -0
  314. package/packages/web/components/StreakCard/index.ts +2 -0
  315. package/packages/web/components/TasksCounter/TasksCounter.tsx +14 -0
  316. package/packages/web/components/TasksCounter/TasksCounter.types.ts +3 -0
  317. package/packages/web/components/TasksCounter/index.ts +2 -0
  318. package/packages/web/components/TechStackBadges/index.ts +1 -0
  319. package/packages/web/components/{TerminalTab.tsx → TerminalTabs/TerminalTab.tsx} +11 -0
  320. package/packages/web/components/{TerminalTabs.tsx → TerminalTabs/TerminalTabs.tsx} +29 -28
  321. package/packages/web/components/TerminalTabs/index.ts +1 -0
  322. package/packages/web/components/VelocityBadge/VelocityBadge.tsx +27 -0
  323. package/packages/web/components/VelocityBadge/VelocityBadge.types.ts +3 -0
  324. package/packages/web/components/VelocityBadge/index.ts +2 -0
  325. package/packages/web/components/VelocityCard/VelocityCard.tsx +71 -0
  326. package/packages/web/components/VelocityCard/VelocityCard.types.ts +7 -0
  327. package/packages/web/components/VelocityCard/index.ts +2 -0
  328. package/packages/web/components/WeeklySparkline/WeeklySparkline.tsx +13 -0
  329. package/packages/web/components/WeeklySparkline/WeeklySparkline.types.ts +3 -0
  330. package/packages/web/components/WeeklySparkline/index.ts +2 -0
  331. package/packages/web/components/ui/input.tsx +21 -0
  332. package/packages/web/context/TerminalTabsContext.tsx +46 -1
  333. package/packages/web/hooks/useClaudeTerminal.ts +71 -21
  334. package/packages/web/hooks/useProjectStats.ts +55 -0
  335. package/packages/web/hooks/useProjects.ts +6 -6
  336. package/packages/web/lib/actions/projects.ts +15 -0
  337. package/packages/web/lib/json-loader.ts +630 -0
  338. package/packages/web/lib/services/index.ts +9 -0
  339. package/packages/web/lib/services/migration.server.ts +600 -0
  340. package/packages/web/lib/services/projects.server.ts +52 -0
  341. package/packages/web/lib/services/stats.server.ts +264 -0
  342. package/packages/web/lib/unified-loader.ts +396 -0
  343. package/packages/web/package.json +10 -7
  344. package/packages/web/server.ts +58 -8
  345. package/templates/commands/done.md +76 -32
  346. package/templates/commands/feature.md +121 -47
  347. package/templates/commands/idea.md +81 -8
  348. package/templates/commands/now.md +41 -17
  349. package/templates/commands/ship.md +64 -25
  350. package/templates/commands/sync.md +28 -3
  351. package/core/agentic/agent-router.js +0 -140
  352. package/core/agentic/chain-of-thought.js +0 -578
  353. package/core/agentic/command-executor.js +0 -417
  354. package/core/agentic/context-filter.js +0 -354
  355. package/core/agentic/ground-truth.js +0 -591
  356. package/core/agentic/loop-detector.js +0 -406
  357. package/core/agentic/memory-system.js +0 -845
  358. package/core/agentic/parallel-tools.js +0 -366
  359. package/core/agentic/plan-mode.js +0 -572
  360. package/core/agentic/prompt-builder.js +0 -352
  361. package/core/agentic/response-templates.js +0 -290
  362. package/core/agentic/semantic-compression.js +0 -517
  363. package/core/agentic/think-blocks.js +0 -657
  364. package/core/agentic/tool-registry.js +0 -184
  365. package/core/agentic/validation-rules.js +0 -380
  366. package/core/command-registry.js +0 -698
  367. package/core/commands.js +0 -2237
  368. package/core/domain/task-stack.js +0 -497
  369. package/core/infrastructure/legacy-installer-detector.js +0 -546
  370. package/core/infrastructure/migrator.js +0 -796
  371. package/core/infrastructure/session-manager.js +0 -390
  372. package/core/utils/file-helper.js +0 -329
  373. package/packages/web/app/api/projects/[id]/delete/route.ts +0 -21
  374. package/packages/web/app/api/stats/route.ts +0 -38
  375. package/packages/web/components/AppSidebar.tsx +0 -113
  376. package/packages/web/components/stats/ActivityTimeline.tsx +0 -201
  377. package/packages/web/components/stats/AgentsCard.tsx +0 -56
  378. package/packages/web/components/stats/BentoCard.tsx +0 -88
  379. package/packages/web/components/stats/HeroSection.tsx +0 -172
  380. package/packages/web/components/stats/NowCard.tsx +0 -71
  381. package/packages/web/components/stats/QueueCard.tsx +0 -58
  382. package/packages/web/components/stats/VelocityCard.tsx +0 -60
  383. package/packages/web/components/stats/index.ts +0 -17
  384. package/packages/web/hooks/useStats.ts +0 -28
  385. /package/packages/web/components/{CommandButton.tsx → CommandButton/CommandButton.tsx} +0 -0
  386. /package/packages/web/components/{ConnectionStatus.tsx → ConnectionStatus/ConnectionStatus.tsx} +0 -0
  387. /package/packages/web/components/{Logo.tsx → Logo/Logo.tsx} +0 -0
  388. /package/packages/web/components/{MarkdownContent.tsx → MarkdownContent/MarkdownContent.tsx} +0 -0
  389. /package/packages/web/components/{ProjectAvatar.tsx → ProjectAvatar/ProjectAvatar.tsx} +0 -0
  390. /package/packages/web/components/{providers.tsx → Providers/Providers.tsx} +0 -0
  391. /package/packages/web/components/{TechStackBadges.tsx → TechStackBadges/TechStackBadges.tsx} +0 -0
@@ -0,0 +1,18 @@
1
+ 'use client'
2
+
3
+ import { useMemo } from 'react'
4
+ import type { TimelineEvent } from '../HeroSection.types'
5
+
6
+ export function useWeeklyActivity(timeline: TimelineEvent[]): number[] {
7
+ return useMemo(() => {
8
+ const today = new Date()
9
+
10
+ return Array.from({ length: 7 }, (_, i) => {
11
+ const date = new Date(today)
12
+ date.setDate(date.getDate() - (6 - i))
13
+ const dateStr = date.toISOString().split('T')[0]
14
+
15
+ return timeline.filter(e => e.ts?.startsWith(dateStr)).length
16
+ })
17
+ }, [timeline])
18
+ }
@@ -0,0 +1,2 @@
1
+ export { HeroSection } from './HeroSection'
2
+ export type { HeroProps } from './HeroSection.types'
@@ -1,19 +1,8 @@
1
- 'use client'
2
-
3
- import { BentoCard } from './BentoCard'
4
- import { EmptyState } from './EmptyState'
1
+ import { BentoCard } from '@/components/BentoCard'
2
+ import { EmptyState } from '@/components/EmptyState'
5
3
  import { Lightbulb } from 'lucide-react'
6
4
  import { cn } from '@/lib/utils'
7
-
8
- interface Idea {
9
- title: string
10
- impact?: string
11
- }
12
-
13
- interface IdeasCardProps {
14
- ideas: Idea[]
15
- className?: string
16
- }
5
+ import type { IdeasCardProps } from './IdeasCard.types'
17
6
 
18
7
  export function IdeasCard({ ideas, className }: IdeasCardProps) {
19
8
  const displayIdeas = ideas.slice(0, 4)
@@ -0,0 +1,9 @@
1
+ export interface Idea {
2
+ title: string
3
+ impact?: string
4
+ }
5
+
6
+ export interface IdeasCardProps {
7
+ ideas: Idea[]
8
+ className?: string
9
+ }
@@ -0,0 +1,2 @@
1
+ export { IdeasCard } from './IdeasCard'
2
+ export type { IdeasCardProps } from './IdeasCard.types'
@@ -0,0 +1,9 @@
1
+ import type { InsightMessageProps } from './InsightMessage.types'
2
+
3
+ export function InsightMessage({ message }: InsightMessageProps) {
4
+ return (
5
+ <p className="text-sm md:text-base text-muted-foreground mt-2 md:mt-3 max-w-md">
6
+ {message}
7
+ </p>
8
+ )
9
+ }
@@ -0,0 +1,3 @@
1
+ export interface InsightMessageProps {
2
+ message: string
3
+ }
@@ -0,0 +1,2 @@
1
+ export { InsightMessage } from './InsightMessage'
2
+ export type { InsightMessageProps } from './InsightMessage.types'
@@ -0,0 +1 @@
1
+ export { Logo } from './Logo'
@@ -0,0 +1 @@
1
+ export { MarkdownContent } from './MarkdownContent'
@@ -0,0 +1,93 @@
1
+ import { BentoCard } from '@/components/BentoCard'
2
+ import { EmptyState } from '@/components/EmptyState'
3
+ import { Target, Clock, Bot, Pause } from 'lucide-react'
4
+ import { cn } from '@/lib/utils'
5
+ import type { NowCardProps } from './NowCard.types'
6
+
7
+ export function NowCard({ currentTask, className }: NowCardProps) {
8
+ return (
9
+ <BentoCard
10
+ size="2x2"
11
+ title="Now"
12
+ icon={Target}
13
+ accentColor={currentTask ? 'warning' : 'default'}
14
+ className={className}
15
+ >
16
+ {currentTask ? (
17
+ <div className="flex flex-col h-full">
18
+ <div className="flex items-center gap-2 mb-3">
19
+ {currentTask.pausedAt ? (
20
+ <>
21
+ <Pause className="w-3 h-3 text-muted-foreground" />
22
+ <span className="text-[10px] font-semibold text-muted-foreground uppercase tracking-wider">
23
+ Paused
24
+ </span>
25
+ </>
26
+ ) : (
27
+ <>
28
+ <div className="w-2 h-2 rounded-full bg-amber-500 animate-pulse" />
29
+ <span className="text-[10px] font-semibold text-amber-600 dark:text-amber-400 uppercase tracking-wider">
30
+ Working
31
+ </span>
32
+ </>
33
+ )}
34
+ </div>
35
+
36
+ <p className="text-xl font-semibold leading-tight flex-1">
37
+ {currentTask.task}
38
+ </p>
39
+
40
+ {currentTask.agent && (
41
+ <div className="flex items-center gap-2 mt-2 text-xs text-muted-foreground">
42
+ <Bot className="h-3 w-3" />
43
+ <span className="font-mono">{currentTask.agent}</span>
44
+ {currentTask.agentConfidence !== undefined && (
45
+ <span className={cn(
46
+ 'px-1.5 py-0.5 rounded text-[10px]',
47
+ currentTask.agentConfidence >= 0.8 ? 'bg-emerald-500/10 text-emerald-600' :
48
+ currentTask.agentConfidence >= 0.5 ? 'bg-amber-500/10 text-amber-600' :
49
+ 'bg-muted text-muted-foreground'
50
+ )}>
51
+ {Math.round(currentTask.agentConfidence * 100)}% confidence
52
+ </span>
53
+ )}
54
+ </div>
55
+ )}
56
+
57
+ <div className="flex items-center gap-4 mt-3 text-muted-foreground">
58
+ {currentTask.duration && (
59
+ <div className="flex items-center gap-1.5">
60
+ <Clock className="h-3.5 w-3.5" />
61
+ <span className="text-sm">{currentTask.duration}</span>
62
+ </div>
63
+ )}
64
+ {currentTask.estimatedDuration && (
65
+ <span className="text-xs">
66
+ / est. {currentTask.estimatedDuration}
67
+ </span>
68
+ )}
69
+ </div>
70
+
71
+ <div className="mt-4">
72
+ <div className="h-1.5 bg-muted rounded-full overflow-hidden">
73
+ <div
74
+ className={cn(
75
+ "h-full rounded-full",
76
+ currentTask.pausedAt ? "bg-muted-foreground" : "bg-amber-500 animate-pulse"
77
+ )}
78
+ style={{ width: '60%' }}
79
+ />
80
+ </div>
81
+ </div>
82
+ </div>
83
+ ) : (
84
+ <EmptyState
85
+ icon={Target}
86
+ title="No active task"
87
+ description="Start working on something"
88
+ command="/p:now"
89
+ />
90
+ )}
91
+ </BentoCard>
92
+ )
93
+ }
@@ -0,0 +1,15 @@
1
+ export interface CurrentTask {
2
+ task: string
3
+ startedAt?: string
4
+ agent?: string
5
+ agentConfidence?: number
6
+ estimatedDuration?: string
7
+ pausedAt?: string
8
+ pauseReason?: string
9
+ duration?: string
10
+ }
11
+
12
+ export interface NowCardProps {
13
+ currentTask: CurrentTask | null
14
+ className?: string
15
+ }
@@ -0,0 +1,2 @@
1
+ export { NowCard } from './NowCard'
2
+ export type { NowCardProps } from './NowCard.types'
@@ -0,0 +1,20 @@
1
+ import type { ProgressRingSize, AccentColor } from './ProgressRing.types'
2
+
3
+ export const PROGRESS_RING_SIZES: Record<ProgressRingSize, {
4
+ container: string
5
+ text: string
6
+ viewBox: number
7
+ radius: number
8
+ }> = {
9
+ sm: { container: 'h-8 w-8', text: 'text-[10px]', viewBox: 36, radius: 14 },
10
+ md: { container: 'h-12 w-12', text: 'text-xs', viewBox: 36, radius: 14 },
11
+ lg: { container: 'h-16 w-16', text: 'text-sm', viewBox: 36, radius: 14 },
12
+ xl: { container: 'h-20 w-20', text: 'text-base', viewBox: 36, radius: 14 },
13
+ }
14
+
15
+ export const PROGRESS_RING_COLOR_STYLES: Record<AccentColor, string> = {
16
+ default: 'text-foreground',
17
+ success: 'text-emerald-500',
18
+ warning: 'text-amber-500',
19
+ destructive: 'text-destructive',
20
+ }
@@ -1,29 +1,8 @@
1
1
  'use client'
2
2
 
3
3
  import { cn } from '@/lib/utils'
4
-
5
- interface ProgressRingProps {
6
- value: number // 0-100
7
- size?: 'sm' | 'md' | 'lg' | 'xl'
8
- showValue?: boolean
9
- strokeWidth?: number
10
- className?: string
11
- accentColor?: 'default' | 'success' | 'warning' | 'destructive'
12
- }
13
-
14
- const sizes = {
15
- sm: { container: 'h-8 w-8', text: 'text-[10px]', viewBox: 36, radius: 14 },
16
- md: { container: 'h-12 w-12', text: 'text-xs', viewBox: 36, radius: 14 },
17
- lg: { container: 'h-16 w-16', text: 'text-sm', viewBox: 36, radius: 14 },
18
- xl: { container: 'h-20 w-20', text: 'text-base', viewBox: 36, radius: 14 },
19
- }
20
-
21
- const colorStyles = {
22
- default: 'text-foreground',
23
- success: 'text-emerald-500',
24
- warning: 'text-amber-500',
25
- destructive: 'text-destructive',
26
- }
4
+ import { PROGRESS_RING_SIZES, PROGRESS_RING_COLOR_STYLES } from './ProgressRing.constants'
5
+ import type { ProgressRingProps } from './ProgressRing.types'
27
6
 
28
7
  export function ProgressRing({
29
8
  value,
@@ -33,14 +12,13 @@ export function ProgressRing({
33
12
  className,
34
13
  accentColor = 'default',
35
14
  }: ProgressRingProps) {
36
- const { container, text, viewBox, radius } = sizes[size]
15
+ const { container, text, viewBox, radius } = PROGRESS_RING_SIZES[size]
37
16
  const circumference = 2 * Math.PI * radius
38
17
  const strokeDashoffset = circumference - (value / 100) * circumference
39
18
 
40
19
  return (
41
20
  <div className={cn('relative', container, className)}>
42
21
  <svg className="h-full w-full -rotate-90" viewBox={`0 0 ${viewBox} ${viewBox}`}>
43
- {/* Background ring */}
44
22
  <circle
45
23
  cx={viewBox / 2}
46
24
  cy={viewBox / 2}
@@ -50,7 +28,6 @@ export function ProgressRing({
50
28
  strokeWidth={strokeWidth}
51
29
  className="text-foreground/10"
52
30
  />
53
- {/* Progress ring */}
54
31
  <circle
55
32
  cx={viewBox / 2}
56
33
  cy={viewBox / 2}
@@ -61,7 +38,7 @@ export function ProgressRing({
61
38
  strokeDasharray={circumference}
62
39
  strokeDashoffset={strokeDashoffset}
63
40
  strokeLinecap="round"
64
- className={cn('transition-all duration-700 ease-out', colorStyles[accentColor])}
41
+ className={cn('transition-all duration-700 ease-out', PROGRESS_RING_COLOR_STYLES[accentColor])}
65
42
  />
66
43
  </svg>
67
44
  {showValue && (
@@ -0,0 +1,11 @@
1
+ export type ProgressRingSize = 'sm' | 'md' | 'lg' | 'xl'
2
+ export type AccentColor = 'default' | 'success' | 'warning' | 'destructive'
3
+
4
+ export interface ProgressRingProps {
5
+ value: number
6
+ size?: ProgressRingSize
7
+ showValue?: boolean
8
+ strokeWidth?: number
9
+ className?: string
10
+ accentColor?: AccentColor
11
+ }
@@ -0,0 +1,2 @@
1
+ export { ProgressRing } from './ProgressRing'
2
+ export type { ProgressRingProps } from './ProgressRing.types'
@@ -0,0 +1 @@
1
+ export { ProjectAvatar } from './ProjectAvatar'
@@ -0,0 +1 @@
1
+ export { Providers } from './Providers'
@@ -0,0 +1,72 @@
1
+ import { BentoCard } from '@/components/BentoCard'
2
+ import { EmptyState } from '@/components/EmptyState'
3
+ import { ListTodo, Bot } from 'lucide-react'
4
+ import { cn } from '@/lib/utils'
5
+ import { getPriorityColor } from './QueueCard.utils'
6
+ import type { QueueCardProps } from './QueueCard.types'
7
+
8
+ export function QueueCard({ queue, className }: QueueCardProps) {
9
+ const displayItems = queue.slice(0, 5)
10
+ const remaining = queue.length - 5
11
+
12
+ return (
13
+ <BentoCard
14
+ size="1x2"
15
+ title="Queue"
16
+ icon={ListTodo}
17
+ count={queue.length}
18
+ className={className}
19
+ >
20
+ {queue.length === 0 ? (
21
+ <EmptyState
22
+ icon={ListTodo}
23
+ title="Queue empty"
24
+ description="Plan your next tasks"
25
+ command="/p:next"
26
+ compact
27
+ />
28
+ ) : (
29
+ <div className="space-y-2">
30
+ {displayItems.map((item, i) => {
31
+ const priorityColor = getPriorityColor(item.priority)
32
+ return (
33
+ <div key={i} className="flex items-start gap-2 group">
34
+ <span className={cn(
35
+ "text-[10px] font-medium w-4 shrink-0 pt-0.5 tabular-nums",
36
+ priorityColor
37
+ )}>
38
+ {i + 1}
39
+ </span>
40
+ <div className="flex-1 min-w-0">
41
+ <p className="text-sm leading-tight truncate group-hover:text-foreground transition-colors">
42
+ {item.task}
43
+ </p>
44
+ {(item.suggestedAgent || item.estimatedDuration) && (
45
+ <div className="flex items-center gap-2 mt-0.5">
46
+ {item.suggestedAgent && (
47
+ <span className="inline-flex items-center gap-0.5 text-[9px] text-muted-foreground">
48
+ <Bot className="h-2.5 w-2.5" />
49
+ {item.suggestedAgent}
50
+ </span>
51
+ )}
52
+ {item.estimatedDuration && (
53
+ <span className="text-[9px] text-muted-foreground">
54
+ ~{item.estimatedDuration}
55
+ </span>
56
+ )}
57
+ </div>
58
+ )}
59
+ </div>
60
+ </div>
61
+ )
62
+ })}
63
+ {remaining > 0 && (
64
+ <p className="text-[10px] text-muted-foreground mt-2 pl-6">
65
+ +{remaining} more
66
+ </p>
67
+ )}
68
+ </div>
69
+ )}
70
+ </BentoCard>
71
+ )
72
+ }
@@ -0,0 +1,11 @@
1
+ export interface QueueItem {
2
+ task: string
3
+ priority?: 'low' | 'medium' | 'high' | 'critical' | number
4
+ suggestedAgent?: string
5
+ estimatedDuration?: string
6
+ }
7
+
8
+ export interface QueueCardProps {
9
+ queue: QueueItem[]
10
+ className?: string
11
+ }
@@ -0,0 +1,12 @@
1
+ export function getPriorityColor(priority?: 'low' | 'medium' | 'high' | 'critical' | number): string {
2
+ if (typeof priority === 'string') {
3
+ const colors: Record<string, string> = {
4
+ critical: 'text-red-500',
5
+ high: 'text-amber-500',
6
+ medium: 'text-blue-500',
7
+ low: 'text-muted-foreground',
8
+ }
9
+ return colors[priority] ?? 'text-muted-foreground'
10
+ }
11
+ return 'text-muted-foreground'
12
+ }
@@ -0,0 +1,2 @@
1
+ export { QueueCard } from './QueueCard'
2
+ export type { QueueCardProps } from './QueueCard.types'
@@ -1,25 +1,8 @@
1
- 'use client'
2
-
3
- import { BentoCard } from './BentoCard'
4
- import { EmptyState } from './EmptyState'
1
+ import { BentoCard } from '@/components/BentoCard'
2
+ import { EmptyState } from '@/components/EmptyState'
5
3
  import { Map } from 'lucide-react'
6
4
  import { cn } from '@/lib/utils'
7
-
8
- interface RoadmapPhase {
9
- name: string
10
- progress: number
11
- features?: { name: string; status: string }[]
12
- }
13
-
14
- interface RoadmapData {
15
- phases: RoadmapPhase[]
16
- progress: number
17
- }
18
-
19
- interface RoadmapCardProps {
20
- roadmap: RoadmapData | null
21
- className?: string
22
- }
5
+ import type { RoadmapCardProps } from './RoadmapCard.types'
23
6
 
24
7
  export function RoadmapCard({ roadmap, className }: RoadmapCardProps) {
25
8
  const hasPhases = roadmap?.phases && roadmap.phases.length > 0
@@ -41,7 +24,6 @@ export function RoadmapCard({ roadmap, className }: RoadmapCardProps) {
41
24
  />
42
25
  ) : (
43
26
  <div className="flex flex-col h-full">
44
- {/* Overall progress */}
45
27
  <div className="mb-4">
46
28
  <div className="flex items-center justify-between text-xs mb-1.5">
47
29
  <span className="text-muted-foreground">Overall progress</span>
@@ -58,7 +40,6 @@ export function RoadmapCard({ roadmap, className }: RoadmapCardProps) {
58
40
  </div>
59
41
  </div>
60
42
 
61
- {/* Phases */}
62
43
  <div className="space-y-3 flex-1">
63
44
  {roadmap.phases
64
45
  .filter(p => (p.features || []).length > 0)
@@ -84,7 +65,6 @@ export function RoadmapCard({ roadmap, className }: RoadmapCardProps) {
84
65
  ))}
85
66
  </div>
86
67
 
87
- {/* Feature count */}
88
68
  {roadmap.phases.length > 0 && (
89
69
  <p className="text-[10px] text-muted-foreground mt-3">
90
70
  {roadmap.phases.reduce((acc, p) => acc + (p.features?.length || 0), 0)} features across {roadmap.phases.length} phases
@@ -0,0 +1,15 @@
1
+ export interface RoadmapPhase {
2
+ name: string
3
+ progress: number
4
+ features?: Array<{ name: string; status: string }>
5
+ }
6
+
7
+ export interface RoadmapData {
8
+ phases: RoadmapPhase[]
9
+ progress: number
10
+ }
11
+
12
+ export interface RoadmapCardProps {
13
+ roadmap: RoadmapData | null
14
+ className?: string
15
+ }
@@ -0,0 +1,2 @@
1
+ export { RoadmapCard } from './RoadmapCard'
2
+ export type { RoadmapCardProps } from './RoadmapCard.types'
@@ -1,27 +1,9 @@
1
- 'use client'
2
-
3
- import { BentoCard } from './BentoCard'
4
- import { EmptyState } from './EmptyState'
1
+ import { BentoCard } from '@/components/BentoCard'
2
+ import { EmptyState } from '@/components/EmptyState'
5
3
  import { Rocket } from 'lucide-react'
6
4
  import { Badge } from '@/components/ui/badge'
7
-
8
- interface Ship {
9
- name: string
10
- date: string
11
- version?: string
12
- duration?: string
13
- }
14
-
15
- interface ShipsCardProps {
16
- ships: Ship[]
17
- totalShips?: number
18
- className?: string
19
- }
20
-
21
- function formatShipDate(dateString: string): string {
22
- const date = new Date(dateString)
23
- return date.toLocaleDateString('en-US', { month: 'short', day: 'numeric' })
24
- }
5
+ import { formatShipDate } from './ShipsCard.utils'
6
+ import type { ShipsCardProps } from './ShipsCard.types'
25
7
 
26
8
  export function ShipsCard({ ships, totalShips = 0, className }: ShipsCardProps) {
27
9
  const displayShips = ships.slice(0, 4)
@@ -0,0 +1,12 @@
1
+ export interface Ship {
2
+ name: string
3
+ date: string
4
+ version?: string
5
+ duration?: string
6
+ }
7
+
8
+ export interface ShipsCardProps {
9
+ ships: Ship[]
10
+ totalShips?: number
11
+ className?: string
12
+ }
@@ -0,0 +1,4 @@
1
+ export function formatShipDate(dateString: string): string {
2
+ const date = new Date(dateString)
3
+ return date.toLocaleDateString('en-US', { month: 'short', day: 'numeric' })
4
+ }
@@ -0,0 +1,2 @@
1
+ export { ShipsCard } from './ShipsCard'
2
+ export type { ShipsCardProps } from './ShipsCard.types'
@@ -1,13 +1,7 @@
1
1
  'use client'
2
2
 
3
3
  import { Area, AreaChart, ResponsiveContainer } from 'recharts'
4
-
5
- interface SparklineChartProps {
6
- data: number[]
7
- color?: string
8
- height?: number
9
- showArea?: boolean
10
- }
4
+ import type { SparklineChartProps } from './SparklineChart.types'
11
5
 
12
6
  export function SparklineChart({
13
7
  data,
@@ -0,0 +1,6 @@
1
+ export interface SparklineChartProps {
2
+ data: number[]
3
+ color?: string
4
+ height?: number
5
+ showArea?: boolean
6
+ }
@@ -0,0 +1,2 @@
1
+ export { SparklineChart } from './SparklineChart'
2
+ export type { SparklineChartProps } from './SparklineChart.types'
@@ -0,0 +1,2 @@
1
+ export const STREAK_HOT_THRESHOLD = 3
2
+ export const STREAK_ON_FIRE_THRESHOLD = 7
@@ -1,17 +1,12 @@
1
- 'use client'
2
-
3
- import { BentoCard } from './BentoCard'
1
+ import { BentoCard } from '@/components/BentoCard'
4
2
  import { Flame } from 'lucide-react'
5
3
  import { cn } from '@/lib/utils'
6
-
7
- interface StreakCardProps {
8
- streak: number
9
- className?: string
10
- }
4
+ import { STREAK_HOT_THRESHOLD, STREAK_ON_FIRE_THRESHOLD } from './StreakCard.constants'
5
+ import type { StreakCardProps } from './StreakCard.types'
11
6
 
12
7
  export function StreakCard({ streak, className }: StreakCardProps) {
13
- const isHot = streak >= 3
14
- const isOnFire = streak >= 7
8
+ const isHot = streak >= STREAK_HOT_THRESHOLD
9
+ const isOnFire = streak >= STREAK_ON_FIRE_THRESHOLD
15
10
 
16
11
  return (
17
12
  <BentoCard
@@ -35,7 +30,6 @@ export function StreakCard({ streak, className }: StreakCardProps) {
35
30
  </div>
36
31
  </div>
37
32
 
38
- {/* Visual streak indicator - dots */}
39
33
  <div className="flex gap-1 mt-3">
40
34
  {Array.from({ length: 7 }).map((_, i) => (
41
35
  <div
@@ -0,0 +1,4 @@
1
+ export interface StreakCardProps {
2
+ streak: number
3
+ className?: string
4
+ }
@@ -0,0 +1,2 @@
1
+ export { StreakCard } from './StreakCard'
2
+ export type { StreakCardProps } from './StreakCard.types'
@@ -0,0 +1,14 @@
1
+ import type { TasksCounterProps } from './TasksCounter.types'
2
+
3
+ export function TasksCounter({ count }: TasksCounterProps) {
4
+ return (
5
+ <div className="flex flex-col sm:flex-row sm:items-baseline gap-1 sm:gap-3">
6
+ <span className="text-5xl sm:text-6xl md:text-7xl font-bold tracking-tighter tabular-nums">
7
+ {count}
8
+ </span>
9
+ <span className="text-sm sm:text-base md:text-lg text-muted-foreground">
10
+ tasks completed
11
+ </span>
12
+ </div>
13
+ )
14
+ }
@@ -0,0 +1,3 @@
1
+ export interface TasksCounterProps {
2
+ count: number
3
+ }
@@ -0,0 +1,2 @@
1
+ export { TasksCounter } from './TasksCounter'
2
+ export type { TasksCounterProps } from './TasksCounter.types'
@@ -0,0 +1 @@
1
+ export { TechStackBadges } from './TechStackBadges'