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
@@ -7,7 +7,7 @@
7
7
  * @version 1.0.0
8
8
  */
9
9
 
10
- const { eventBus, EventTypes } = require('../bus')
10
+ import { eventBus, EventTypes } from '../bus'
11
11
 
12
12
  /**
13
13
  * Hook Points - Where plugins can intercept
@@ -38,47 +38,64 @@ const HookPoints = {
38
38
  TRANSFORM_COMMIT_MESSAGE: 'transform:commit.message',
39
39
  TRANSFORM_TASK_DATA: 'transform:task.data',
40
40
  TRANSFORM_METRICS: 'transform:metrics'
41
+ } as const
42
+
43
+ type HookPoint = typeof HookPoints[keyof typeof HookPoints]
44
+ type HookHandler = (data: unknown, context?: unknown) => unknown | Promise<unknown>
45
+
46
+ interface HookEntry {
47
+ handler: HookHandler
48
+ pluginName: string
49
+ priority: number
50
+ id: string
51
+ }
52
+
53
+ interface HookRegisterOptions {
54
+ pluginName?: string
55
+ priority?: number
56
+ }
57
+
58
+ interface PluginHookEntry {
59
+ hookPoint: string
60
+ id: string
41
61
  }
42
62
 
43
63
  class HookSystem {
64
+ private hooks: Map<string, HookEntry[]>
65
+ private pluginHooks: Map<string, PluginHookEntry[]>
66
+
44
67
  constructor() {
45
68
  this.hooks = new Map()
46
- this.pluginHooks = new Map() // Track hooks by plugin
69
+ this.pluginHooks = new Map()
47
70
  }
48
71
 
49
72
  /**
50
73
  * Register a hook handler
51
- * @param {string} hookPoint - Hook point from HookPoints
52
- * @param {Function} handler - Handler function
53
- * @param {Object} options
54
- * @param {string} options.pluginName - Name of the plugin
55
- * @param {number} options.priority - Execution order (lower = first)
56
- * @returns {Function} Unregister function
57
74
  */
58
- register(hookPoint, handler, options = {}) {
75
+ register(hookPoint: string, handler: HookHandler, options: HookRegisterOptions = {}): () => void {
59
76
  const { pluginName = 'anonymous', priority = 10 } = options
60
77
 
61
78
  if (!this.hooks.has(hookPoint)) {
62
79
  this.hooks.set(hookPoint, [])
63
80
  }
64
81
 
65
- const hookEntry = {
82
+ const hookEntry: HookEntry = {
66
83
  handler,
67
84
  pluginName,
68
85
  priority,
69
86
  id: `${pluginName}:${Date.now()}`
70
87
  }
71
88
 
72
- this.hooks.get(hookPoint).push(hookEntry)
89
+ this.hooks.get(hookPoint)!.push(hookEntry)
73
90
 
74
91
  // Sort by priority
75
- this.hooks.get(hookPoint).sort((a, b) => a.priority - b.priority)
92
+ this.hooks.get(hookPoint)!.sort((a, b) => a.priority - b.priority)
76
93
 
77
94
  // Track by plugin
78
95
  if (!this.pluginHooks.has(pluginName)) {
79
96
  this.pluginHooks.set(pluginName, [])
80
97
  }
81
- this.pluginHooks.get(pluginName).push({ hookPoint, id: hookEntry.id })
98
+ this.pluginHooks.get(pluginName)!.push({ hookPoint, id: hookEntry.id })
82
99
 
83
100
  // Return unregister function
84
101
  return () => this.unregister(hookPoint, hookEntry.id)
@@ -86,10 +103,8 @@ class HookSystem {
86
103
 
87
104
  /**
88
105
  * Unregister a hook handler
89
- * @param {string} hookPoint
90
- * @param {string} id
91
106
  */
92
- unregister(hookPoint, id) {
107
+ unregister(hookPoint: string, id: string): void {
93
108
  const hooks = this.hooks.get(hookPoint)
94
109
  if (hooks) {
95
110
  const index = hooks.findIndex(h => h.id === id)
@@ -101,9 +116,8 @@ class HookSystem {
101
116
 
102
117
  /**
103
118
  * Unregister all hooks from a plugin
104
- * @param {string} pluginName
105
119
  */
106
- unregisterPlugin(pluginName) {
120
+ unregisterPlugin(pluginName: string): void {
107
121
  const pluginEntries = this.pluginHooks.get(pluginName)
108
122
  if (pluginEntries) {
109
123
  for (const entry of pluginEntries) {
@@ -115,11 +129,8 @@ class HookSystem {
115
129
 
116
130
  /**
117
131
  * Execute a "before" hook (can modify data)
118
- * @param {string} hookPoint
119
- * @param {Object} data - Data that can be modified
120
- * @returns {Promise<Object>} Modified data
121
132
  */
122
- async executeBefore(hookPoint, data) {
133
+ async executeBefore(hookPoint: string, data: Record<string, unknown>): Promise<Record<string, unknown>> {
123
134
  const hooks = this.hooks.get(hookPoint) || []
124
135
  let result = { ...data }
125
136
 
@@ -127,10 +138,10 @@ class HookSystem {
127
138
  try {
128
139
  const modified = await hook.handler(result)
129
140
  if (modified !== undefined) {
130
- result = { ...result, ...modified }
141
+ result = { ...result, ...(modified as Record<string, unknown>) }
131
142
  }
132
143
  } catch (error) {
133
- console.error(`Hook error [${hook.pluginName}] at ${hookPoint}:`, error.message)
144
+ console.error(`Hook error [${hook.pluginName}] at ${hookPoint}:`, (error as Error).message)
134
145
  // Continue with other hooks
135
146
  }
136
147
  }
@@ -140,11 +151,8 @@ class HookSystem {
140
151
 
141
152
  /**
142
153
  * Execute an "after" hook (side effects only)
143
- * @param {string} hookPoint
144
- * @param {Object} data - Read-only data
145
- * @returns {Promise<void>}
146
154
  */
147
- async executeAfter(hookPoint, data) {
155
+ async executeAfter(hookPoint: string, data: Record<string, unknown>): Promise<void> {
148
156
  const hooks = this.hooks.get(hookPoint) || []
149
157
 
150
158
  // Execute all hooks in parallel for after hooks
@@ -153,7 +161,7 @@ class HookSystem {
153
161
  try {
154
162
  await hook.handler(data)
155
163
  } catch (error) {
156
- console.error(`Hook error [${hook.pluginName}] at ${hookPoint}:`, error.message)
164
+ console.error(`Hook error [${hook.pluginName}] at ${hookPoint}:`, (error as Error).message)
157
165
  }
158
166
  })
159
167
  )
@@ -167,12 +175,8 @@ class HookSystem {
167
175
 
168
176
  /**
169
177
  * Execute a "transform" hook (must return modified value)
170
- * @param {string} hookPoint
171
- * @param {*} value - Value to transform
172
- * @param {Object} context - Additional context
173
- * @returns {Promise<*>} Transformed value
174
178
  */
175
- async executeTransform(hookPoint, value, context = {}) {
179
+ async executeTransform<T>(hookPoint: string, value: T, context: Record<string, unknown> = {}): Promise<T> {
176
180
  const hooks = this.hooks.get(hookPoint) || []
177
181
  let result = value
178
182
 
@@ -180,10 +184,10 @@ class HookSystem {
180
184
  try {
181
185
  const transformed = await hook.handler(result, context)
182
186
  if (transformed !== undefined) {
183
- result = transformed
187
+ result = transformed as T
184
188
  }
185
189
  } catch (error) {
186
- console.error(`Transform hook error [${hook.pluginName}] at ${hookPoint}:`, error.message)
190
+ console.error(`Transform hook error [${hook.pluginName}] at ${hookPoint}:`, (error as Error).message)
187
191
  // Keep previous value on error
188
192
  }
189
193
  }
@@ -193,11 +197,9 @@ class HookSystem {
193
197
 
194
198
  /**
195
199
  * Map hook point to event type
196
- * @param {string} hookPoint
197
- * @returns {string|null}
198
200
  */
199
- hookToEvent(hookPoint) {
200
- const mapping = {
201
+ hookToEvent(hookPoint: string): string | null {
202
+ const mapping: Record<string, string> = {
201
203
  [HookPoints.AFTER_SESSION_START]: EventTypes.SESSION_STARTED,
202
204
  [HookPoints.AFTER_SESSION_COMPLETE]: EventTypes.SESSION_COMPLETED,
203
205
  [HookPoints.AFTER_TASK_CREATE]: EventTypes.TASK_CREATED,
@@ -215,10 +217,8 @@ class HookSystem {
215
217
 
216
218
  /**
217
219
  * Get all registered hooks for a point
218
- * @param {string} hookPoint
219
- * @returns {Object[]}
220
220
  */
221
- getHooks(hookPoint) {
221
+ getHooks(hookPoint: string): Array<{ pluginName: string; priority: number }> {
222
222
  return (this.hooks.get(hookPoint) || []).map(h => ({
223
223
  pluginName: h.pluginName,
224
224
  priority: h.priority
@@ -227,28 +227,24 @@ class HookSystem {
227
227
 
228
228
  /**
229
229
  * Get all hooks registered by a plugin
230
- * @param {string} pluginName
231
- * @returns {string[]} Hook points
232
230
  */
233
- getPluginHooks(pluginName) {
231
+ getPluginHooks(pluginName: string): string[] {
234
232
  const entries = this.pluginHooks.get(pluginName) || []
235
233
  return entries.map(e => e.hookPoint)
236
234
  }
237
235
 
238
236
  /**
239
237
  * Check if a hook point has any handlers
240
- * @param {string} hookPoint
241
- * @returns {boolean}
242
238
  */
243
- hasHooks(hookPoint) {
239
+ hasHooks(hookPoint: string): boolean {
244
240
  const hooks = this.hooks.get(hookPoint)
245
- return hooks && hooks.length > 0
241
+ return hooks !== undefined && hooks.length > 0
246
242
  }
247
243
 
248
244
  /**
249
245
  * Clear all hooks
250
246
  */
251
- clear() {
247
+ clear(): void {
252
248
  this.hooks.clear()
253
249
  this.pluginHooks.clear()
254
250
  }
@@ -262,7 +258,7 @@ const hooks = {
262
258
  /**
263
259
  * Register a before hook
264
260
  */
265
- before: (point, handler, options) => {
261
+ before: (point: string, handler: HookHandler, options?: HookRegisterOptions) => {
266
262
  const hookPoint = `before:${point}`
267
263
  return hookSystem.register(hookPoint, handler, options)
268
264
  },
@@ -270,7 +266,7 @@ const hooks = {
270
266
  /**
271
267
  * Register an after hook
272
268
  */
273
- after: (point, handler, options) => {
269
+ after: (point: string, handler: HookHandler, options?: HookRegisterOptions) => {
274
270
  const hookPoint = `after:${point}`
275
271
  return hookSystem.register(hookPoint, handler, options)
276
272
  },
@@ -278,7 +274,7 @@ const hooks = {
278
274
  /**
279
275
  * Register a transform hook
280
276
  */
281
- transform: (point, handler, options) => {
277
+ transform: (point: string, handler: HookHandler, options?: HookRegisterOptions) => {
282
278
  const hookPoint = `transform:${point}`
283
279
  return hookSystem.register(hookPoint, handler, options)
284
280
  },
@@ -286,28 +282,30 @@ const hooks = {
286
282
  /**
287
283
  * Execute before hooks
288
284
  */
289
- runBefore: (point, data) => {
285
+ runBefore: (point: string, data: Record<string, unknown>) => {
290
286
  return hookSystem.executeBefore(`before:${point}`, data)
291
287
  },
292
288
 
293
289
  /**
294
290
  * Execute after hooks
295
291
  */
296
- runAfter: (point, data) => {
292
+ runAfter: (point: string, data: Record<string, unknown>) => {
297
293
  return hookSystem.executeAfter(`after:${point}`, data)
298
294
  },
299
295
 
300
296
  /**
301
297
  * Execute transform hooks
302
298
  */
303
- runTransform: (point, value, context) => {
299
+ runTransform: <T>(point: string, value: T, context?: Record<string, unknown>) => {
304
300
  return hookSystem.executeTransform(`transform:${point}`, value, context)
305
301
  }
306
302
  }
307
303
 
308
- module.exports = {
304
+ export {
309
305
  HookSystem,
310
306
  HookPoints,
311
307
  hookSystem,
312
308
  hooks
313
309
  }
310
+
311
+ export default { HookSystem, HookPoints, hookSystem, hooks }
@@ -6,16 +6,14 @@
6
6
  * @version 1.0.0
7
7
  */
8
8
 
9
- const { HookSystem, HookPoints, hookSystem, hooks } = require('./hooks')
10
- const { PluginLoader, pluginLoader } = require('./loader')
11
- const { PluginRegistry, pluginRegistry } = require('./registry')
9
+ import { HookSystem, HookPoints, hookSystem, hooks } from './hooks'
10
+ import { PluginLoader, pluginLoader } from './loader'
11
+ import { PluginRegistry, pluginRegistry } from './registry'
12
12
 
13
13
  /**
14
14
  * Initialize the complete plugin system
15
- * @param {string} projectPath
16
- * @param {Object} config
17
15
  */
18
- async function initializePlugins(projectPath, config = {}) {
16
+ async function initializePlugins(projectPath: string, config: Record<string, unknown> = {}): Promise<void> {
19
17
  await pluginRegistry.initialize()
20
18
  await pluginLoader.initialize(projectPath, config)
21
19
  }
@@ -23,7 +21,7 @@ async function initializePlugins(projectPath, config = {}) {
23
21
  /**
24
22
  * Shutdown the plugin system
25
23
  */
26
- async function shutdownPlugins() {
24
+ async function shutdownPlugins(): Promise<void> {
27
25
  const plugins = pluginLoader.getAllPlugins()
28
26
 
29
27
  for (const plugin of plugins) {
@@ -31,7 +29,7 @@ async function shutdownPlugins() {
31
29
  }
32
30
  }
33
31
 
34
- module.exports = {
32
+ export {
35
33
  // Hook system
36
34
  HookSystem,
37
35
  HookPoints,
@@ -50,3 +48,16 @@ module.exports = {
50
48
  initializePlugins,
51
49
  shutdownPlugins
52
50
  }
51
+
52
+ export default {
53
+ HookSystem,
54
+ HookPoints,
55
+ hookSystem,
56
+ hooks,
57
+ PluginLoader,
58
+ pluginLoader,
59
+ PluginRegistry,
60
+ pluginRegistry,
61
+ initializePlugins,
62
+ shutdownPlugins
63
+ }
@@ -9,37 +9,66 @@
9
9
  * @version 1.0.0
10
10
  */
11
11
 
12
- const fs = require('fs').promises
13
- const path = require('path')
14
- const { hookSystem } = require('./hooks')
15
- const { eventBus } = require('../bus')
16
- const pathManager = require('../infrastructure/path-manager')
12
+ import fs from 'fs/promises'
13
+ import path from 'path'
14
+ import { hookSystem } from './hooks'
15
+ import { eventBus } from '../bus'
16
+ import pathManager from '../infrastructure/path-manager'
17
+
18
+ type PluginSource = 'builtin' | 'global' | 'project'
19
+ type HookHandler = (data: unknown) => unknown | Promise<unknown>
20
+
21
+ interface Plugin {
22
+ name: string
23
+ version?: string
24
+ description?: string
25
+ hooks?: Record<string, HookHandler>
26
+ events?: Record<string, HookHandler>
27
+ commands?: Record<string, { handler: () => void; description?: string }>
28
+ priority?: number
29
+ activate?: (context: PluginContext) => Promise<void>
30
+ deactivate?: () => Promise<void>
31
+ source?: PluginSource
32
+ config?: Record<string, unknown>
33
+ }
17
34
 
18
- /**
19
- * Plugin Interface
20
- * @typedef {Object} Plugin
21
- * @property {string} name - Unique plugin name
22
- * @property {string} version - Semver version
23
- * @property {string} [description] - Plugin description
24
- * @property {Object} [hooks] - Hook handlers
25
- * @property {Object} [commands] - Custom commands
26
- * @property {Function} [activate] - Called when plugin loads
27
- * @property {Function} [deactivate] - Called when plugin unloads
28
- */
35
+ interface PluginContext {
36
+ config: Record<string, unknown>
37
+ eventBus: typeof eventBus
38
+ hookSystem: typeof hookSystem
39
+ projectPath: string
40
+ }
41
+
42
+ interface PluginSpec {
43
+ path: string
44
+ config?: Record<string, unknown>
45
+ }
46
+
47
+ interface CommandInfo {
48
+ handler: () => void
49
+ plugin: string
50
+ description: string
51
+ }
29
52
 
30
53
  class PluginLoader {
54
+ private plugins: Map<string, Plugin>
55
+ private pluginPaths: Map<string, string>
56
+ private initialized: boolean
57
+ private projectPath: string
58
+ private config: Record<string, unknown>
59
+
31
60
  constructor() {
32
61
  this.plugins = new Map()
33
62
  this.pluginPaths = new Map()
34
63
  this.initialized = false
64
+ this.projectPath = ''
65
+ this.config = {}
35
66
  }
36
67
 
37
68
  /**
38
69
  * Initialize plugin system
39
- * @param {string} projectPath - Project root path
40
- * @param {Object} config - Project config
41
70
  */
42
- async initialize(projectPath, config = {}) {
71
+ async initialize(projectPath: string, config: Record<string, unknown> = {}): Promise<void> {
43
72
  if (this.initialized) return
44
73
 
45
74
  this.projectPath = projectPath
@@ -48,7 +77,7 @@ class PluginLoader {
48
77
  // Load plugins in order
49
78
  await this.loadBuiltinPlugins()
50
79
  await this.loadGlobalPlugins()
51
- await this.loadProjectPlugins(config.plugins || [])
80
+ await this.loadProjectPlugins((config.plugins as Array<string | PluginSpec>) || [])
52
81
 
53
82
  this.initialized = true
54
83
  }
@@ -56,14 +85,14 @@ class PluginLoader {
56
85
  /**
57
86
  * Load built-in plugins from core/plugins
58
87
  */
59
- async loadBuiltinPlugins() {
88
+ async loadBuiltinPlugins(): Promise<void> {
60
89
  const builtinPath = path.join(__dirname, '..', 'plugins')
61
90
 
62
91
  try {
63
92
  const files = await fs.readdir(builtinPath)
64
93
 
65
94
  for (const file of files) {
66
- if (file.endsWith('.js')) {
95
+ if (file.endsWith('.js') || file.endsWith('.ts')) {
67
96
  const pluginPath = path.join(builtinPath, file)
68
97
  await this.loadPlugin(pluginPath, 'builtin')
69
98
  }
@@ -76,17 +105,18 @@ class PluginLoader {
76
105
  /**
77
106
  * Load global plugins from ~/.prjct-cli/plugins
78
107
  */
79
- async loadGlobalPlugins() {
108
+ async loadGlobalPlugins(): Promise<void> {
80
109
  const globalPath = path.join(pathManager.getGlobalStoragePath(), 'plugins')
81
110
 
82
111
  try {
83
112
  const files = await fs.readdir(globalPath)
84
113
 
85
114
  for (const file of files) {
86
- if (file.endsWith('.js') || (await this.isDirectory(path.join(globalPath, file)))) {
87
- const pluginPath = file.endsWith('.js')
88
- ? path.join(globalPath, file)
89
- : path.join(globalPath, file, 'index.js')
115
+ const filePath = path.join(globalPath, file)
116
+ if (file.endsWith('.js') || file.endsWith('.ts') || (await this.isDirectory(filePath))) {
117
+ const pluginPath = (file.endsWith('.js') || file.endsWith('.ts'))
118
+ ? filePath
119
+ : path.join(filePath, 'index.js')
90
120
  await this.loadPlugin(pluginPath, 'global')
91
121
  }
92
122
  }
@@ -97,9 +127,8 @@ class PluginLoader {
97
127
 
98
128
  /**
99
129
  * Load project-specific plugins from config
100
- * @param {Array<string|Object>} plugins - Plugin specs from config
101
130
  */
102
- async loadProjectPlugins(plugins) {
131
+ async loadProjectPlugins(plugins: Array<string | PluginSpec>): Promise<void> {
103
132
  for (const spec of plugins) {
104
133
  try {
105
134
  if (typeof spec === 'string') {
@@ -125,24 +154,21 @@ class PluginLoader {
125
154
  await this.loadPlugin(fullPath, 'project', spec.config)
126
155
  }
127
156
  } catch (error) {
128
- console.error(`Failed to load plugin: ${spec}`, error.message)
157
+ console.error(`Failed to load plugin: ${spec}`, (error as Error).message)
129
158
  }
130
159
  }
131
160
  }
132
161
 
133
162
  /**
134
163
  * Load a single plugin
135
- * @param {string} pluginPath - Path to plugin file
136
- * @param {string} source - 'builtin', 'global', or 'project'
137
- * @param {Object} config - Plugin-specific config
138
164
  */
139
- async loadPlugin(pluginPath, source, config = {}) {
165
+ async loadPlugin(pluginPath: string, source: PluginSource, config: Record<string, unknown> = {}): Promise<void> {
140
166
  try {
141
167
  // Check if file exists
142
168
  await fs.access(pluginPath)
143
169
 
144
170
  // Require the plugin
145
- const plugin = require(pluginPath)
171
+ const plugin: Plugin = require(pluginPath)
146
172
 
147
173
  // Validate plugin structure
148
174
  if (!plugin.name) {
@@ -158,7 +184,7 @@ class PluginLoader {
158
184
  this.plugins.set(plugin.name, {
159
185
  ...plugin,
160
186
  source,
161
- config: { ...config, ...this.config[plugin.name] }
187
+ config: { ...config, ...(this.config[plugin.name] as Record<string, unknown> || {}) }
162
188
  })
163
189
  this.pluginPaths.set(plugin.name, pluginPath)
164
190
 
@@ -175,7 +201,7 @@ class PluginLoader {
175
201
  // Call activate if exists
176
202
  if (typeof plugin.activate === 'function') {
177
203
  await plugin.activate({
178
- config: this.plugins.get(plugin.name).config,
204
+ config: this.plugins.get(plugin.name)!.config!,
179
205
  eventBus,
180
206
  hookSystem,
181
207
  projectPath: this.projectPath
@@ -183,22 +209,22 @@ class PluginLoader {
183
209
  }
184
210
 
185
211
  } catch (error) {
186
- if (error.code === 'ENOENT') {
212
+ const err = error as NodeJS.ErrnoException
213
+ if (err.code === 'ENOENT') {
187
214
  // File not found - skip silently
188
- } else if (error.code === 'MODULE_NOT_FOUND') {
215
+ } else if (err.code === 'MODULE_NOT_FOUND') {
189
216
  console.error(`Plugin module not found: ${pluginPath}`)
190
217
  } else {
191
- console.error(`Failed to load plugin from ${pluginPath}:`, error.message)
218
+ console.error(`Failed to load plugin from ${pluginPath}:`, err.message)
192
219
  }
193
220
  }
194
221
  }
195
222
 
196
223
  /**
197
224
  * Register plugin hooks
198
- * @param {Plugin} plugin
199
225
  */
200
- registerPluginHooks(plugin) {
201
- for (const [hookPoint, handler] of Object.entries(plugin.hooks)) {
226
+ registerPluginHooks(plugin: Plugin): void {
227
+ for (const [hookPoint, handler] of Object.entries(plugin.hooks || {})) {
202
228
  hookSystem.register(hookPoint, handler, {
203
229
  pluginName: plugin.name,
204
230
  priority: plugin.priority || 10
@@ -208,19 +234,17 @@ class PluginLoader {
208
234
 
209
235
  /**
210
236
  * Register plugin event listeners
211
- * @param {Plugin} plugin
212
237
  */
213
- registerPluginEvents(plugin) {
214
- for (const [eventType, handler] of Object.entries(plugin.events)) {
238
+ registerPluginEvents(plugin: Plugin): void {
239
+ for (const [eventType, handler] of Object.entries(plugin.events || {})) {
215
240
  eventBus.on(eventType, handler)
216
241
  }
217
242
  }
218
243
 
219
244
  /**
220
245
  * Unload a plugin
221
- * @param {string} name - Plugin name
222
246
  */
223
- async unloadPlugin(name) {
247
+ async unloadPlugin(name: string): Promise<void> {
224
248
  const plugin = this.plugins.get(name)
225
249
  if (!plugin) return
226
250
 
@@ -234,20 +258,19 @@ class PluginLoader {
234
258
 
235
259
  // Remove from loaded plugins
236
260
  this.plugins.delete(name)
237
- this.pluginPaths.delete(name)
238
261
 
239
262
  // Clear require cache
240
263
  const pluginPath = this.pluginPaths.get(name)
241
264
  if (pluginPath) {
242
265
  delete require.cache[require.resolve(pluginPath)]
243
266
  }
267
+ this.pluginPaths.delete(name)
244
268
  }
245
269
 
246
270
  /**
247
271
  * Reload a plugin
248
- * @param {string} name - Plugin name
249
272
  */
250
- async reloadPlugin(name) {
273
+ async reloadPlugin(name: string): Promise<void> {
251
274
  const pluginPath = this.pluginPaths.get(name)
252
275
  const plugin = this.plugins.get(name)
253
276
 
@@ -256,47 +279,41 @@ class PluginLoader {
256
279
  }
257
280
 
258
281
  await this.unloadPlugin(name)
259
- await this.loadPlugin(pluginPath, plugin.source, plugin.config)
282
+ await this.loadPlugin(pluginPath, plugin.source!, plugin.config)
260
283
  }
261
284
 
262
285
  /**
263
286
  * Get a loaded plugin
264
- * @param {string} name
265
- * @returns {Plugin|null}
266
287
  */
267
- getPlugin(name) {
288
+ getPlugin(name: string): Plugin | null {
268
289
  return this.plugins.get(name) || null
269
290
  }
270
291
 
271
292
  /**
272
293
  * Get all loaded plugins
273
- * @returns {Plugin[]}
274
294
  */
275
- getAllPlugins() {
295
+ getAllPlugins(): Plugin[] {
276
296
  return Array.from(this.plugins.values())
277
297
  }
278
298
 
279
299
  /**
280
300
  * Get plugins by source
281
- * @param {string} source - 'builtin', 'global', or 'project'
282
- * @returns {Plugin[]}
283
301
  */
284
- getPluginsBySource(source) {
302
+ getPluginsBySource(source: PluginSource): Plugin[] {
285
303
  return this.getAllPlugins().filter(p => p.source === source)
286
304
  }
287
305
 
288
306
  /**
289
307
  * Get custom commands from all plugins
290
- * @returns {Object} Map of command name to handler
291
308
  */
292
- getPluginCommands() {
293
- const commands = {}
309
+ getPluginCommands(): Record<string, CommandInfo> {
310
+ const commands: Record<string, CommandInfo> = {}
294
311
 
295
312
  for (const plugin of this.plugins.values()) {
296
313
  if (plugin.commands) {
297
314
  for (const [name, handler] of Object.entries(plugin.commands)) {
298
315
  commands[name] = {
299
- handler,
316
+ handler: handler.handler,
300
317
  plugin: plugin.name,
301
318
  description: handler.description || `Command from ${plugin.name}`
302
319
  }
@@ -309,10 +326,8 @@ class PluginLoader {
309
326
 
310
327
  /**
311
328
  * Check if path is a directory
312
- * @param {string} p
313
- * @returns {Promise<boolean>}
314
329
  */
315
- async isDirectory(p) {
330
+ async isDirectory(p: string): Promise<boolean> {
316
331
  try {
317
332
  const stat = await fs.stat(p)
318
333
  return stat.isDirectory()
@@ -325,7 +340,10 @@ class PluginLoader {
325
340
  // Singleton instance
326
341
  const pluginLoader = new PluginLoader()
327
342
 
328
- module.exports = {
343
+ export {
329
344
  PluginLoader,
330
- pluginLoader
345
+ pluginLoader,
346
+ Plugin
331
347
  }
348
+
349
+ export default { PluginLoader, pluginLoader }