prjct-cli 0.11.4 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (385) hide show
  1. package/CHANGELOG.md +72 -0
  2. package/README.md +81 -25
  3. package/bin/dev.js +1 -1
  4. package/bin/generate-views.js +209 -0
  5. package/bin/migrate-to-json.js +742 -0
  6. package/bin/prjct +5 -5
  7. package/bin/serve.js +246 -54
  8. package/core/__tests__/agentic/{memory-system.test.js → memory-system.test.ts} +12 -23
  9. package/core/__tests__/agentic/{plan-mode.test.js → plan-mode.test.ts} +26 -24
  10. package/core/__tests__/agentic/{prompt-builder.test.js → prompt-builder.test.ts} +3 -8
  11. package/core/__tests__/utils/date-helper.test.ts +405 -0
  12. package/core/__tests__/utils/{output.test.js → output.test.ts} +12 -24
  13. package/core/agentic/agent-router.ts +137 -0
  14. package/core/agentic/chain-of-thought.ts +228 -0
  15. package/core/agentic/command-executor/command-executor.ts +384 -0
  16. package/core/agentic/command-executor/index.ts +16 -0
  17. package/core/agentic/command-executor/status-signal.ts +38 -0
  18. package/core/agentic/command-executor/types.ts +79 -0
  19. package/core/agentic/command-executor.ts +8 -0
  20. package/core/agentic/{context-builder.js → context-builder.ts} +99 -89
  21. package/core/agentic/context-filter.ts +365 -0
  22. package/core/agentic/ground-truth/index.ts +76 -0
  23. package/core/agentic/ground-truth/types.ts +33 -0
  24. package/core/agentic/ground-truth/utils.ts +48 -0
  25. package/core/agentic/ground-truth/verifiers/analyze.ts +54 -0
  26. package/core/agentic/ground-truth/verifiers/done.ts +75 -0
  27. package/core/agentic/ground-truth/verifiers/feature.ts +70 -0
  28. package/core/agentic/ground-truth/verifiers/index.ts +37 -0
  29. package/core/agentic/ground-truth/verifiers/init.ts +52 -0
  30. package/core/agentic/ground-truth/verifiers/now.ts +57 -0
  31. package/core/agentic/ground-truth/verifiers/ship.ts +85 -0
  32. package/core/agentic/ground-truth/verifiers/spec.ts +45 -0
  33. package/core/agentic/ground-truth/verifiers/sync.ts +47 -0
  34. package/core/agentic/ground-truth/verifiers.ts +6 -0
  35. package/core/agentic/ground-truth.ts +8 -0
  36. package/core/agentic/loop-detector/error-analysis.ts +97 -0
  37. package/core/agentic/loop-detector/hallucination.ts +71 -0
  38. package/core/agentic/loop-detector/index.ts +41 -0
  39. package/core/agentic/loop-detector/loop-detector.ts +222 -0
  40. package/core/agentic/loop-detector/types.ts +66 -0
  41. package/core/agentic/loop-detector.ts +8 -0
  42. package/core/agentic/memory-system/history.ts +53 -0
  43. package/core/agentic/memory-system/index.ts +192 -0
  44. package/core/agentic/memory-system/patterns.ts +156 -0
  45. package/core/agentic/memory-system/semantic-memories.ts +277 -0
  46. package/core/agentic/memory-system/session.ts +21 -0
  47. package/core/agentic/memory-system/types.ts +159 -0
  48. package/core/agentic/memory-system.ts +8 -0
  49. package/core/agentic/parallel-tools.ts +165 -0
  50. package/core/agentic/plan-mode/approval.ts +57 -0
  51. package/core/agentic/plan-mode/constants.ts +44 -0
  52. package/core/agentic/plan-mode/index.ts +28 -0
  53. package/core/agentic/plan-mode/plan-mode.ts +406 -0
  54. package/core/agentic/plan-mode/types.ts +193 -0
  55. package/core/agentic/plan-mode.ts +8 -0
  56. package/core/agentic/prompt-builder.ts +566 -0
  57. package/core/agentic/response-templates.ts +164 -0
  58. package/core/agentic/semantic-compression.ts +273 -0
  59. package/core/agentic/services.ts +206 -0
  60. package/core/agentic/smart-context.ts +476 -0
  61. package/core/agentic/{template-loader.js → template-loader.ts} +35 -18
  62. package/core/agentic/think-blocks.ts +202 -0
  63. package/core/agentic/tool-registry.ts +119 -0
  64. package/core/agentic/validation-rules.ts +313 -0
  65. package/core/agents/index.ts +28 -0
  66. package/core/agents/performance.ts +444 -0
  67. package/core/agents/types.ts +126 -0
  68. package/core/bus/{index.js → index.ts} +57 -61
  69. package/core/command-registry/categories.ts +23 -0
  70. package/core/command-registry/commands.ts +15 -0
  71. package/core/command-registry/core-commands.ts +319 -0
  72. package/core/command-registry/index.ts +158 -0
  73. package/core/command-registry/optional-commands.ts +119 -0
  74. package/core/command-registry/setup-commands.ts +53 -0
  75. package/core/command-registry/types.ts +59 -0
  76. package/core/command-registry.ts +9 -0
  77. package/core/commands/analysis.ts +298 -0
  78. package/core/commands/analytics.ts +288 -0
  79. package/core/commands/base.ts +273 -0
  80. package/core/commands/index.ts +211 -0
  81. package/core/commands/maintenance.ts +226 -0
  82. package/core/commands/planning.ts +311 -0
  83. package/core/commands/setup.ts +309 -0
  84. package/core/commands/shipping.ts +188 -0
  85. package/core/commands/types.ts +183 -0
  86. package/core/commands/workflow.ts +226 -0
  87. package/core/commands.ts +11 -0
  88. package/core/constants/formats.ts +187 -0
  89. package/core/constants/index.ts +7 -0
  90. package/core/{context-sync.js → context-sync.ts} +59 -26
  91. package/core/data/agents-manager.ts +76 -0
  92. package/core/data/analysis-manager.ts +83 -0
  93. package/core/data/base-manager.ts +156 -0
  94. package/core/data/ideas-manager.ts +81 -0
  95. package/core/data/index.ts +32 -0
  96. package/core/data/outcomes-manager.ts +96 -0
  97. package/core/data/project-manager.ts +75 -0
  98. package/core/data/roadmap-manager.ts +118 -0
  99. package/core/data/shipped-manager.ts +65 -0
  100. package/core/data/state-manager.ts +214 -0
  101. package/core/domain/{agent-generator.js → agent-generator.ts} +77 -57
  102. package/core/domain/{agent-loader.js → agent-loader.ts} +65 -56
  103. package/core/domain/{agent-matcher.js → agent-matcher.ts} +51 -24
  104. package/core/domain/{agent-validator.js → agent-validator.ts} +70 -37
  105. package/core/domain/{analyzer.js → analyzer.ts} +91 -85
  106. package/core/domain/{architect-session.js → architect-session.ts} +49 -34
  107. package/core/domain/{architecture-generator.js → architecture-generator.ts} +25 -13
  108. package/core/domain/{context-estimator.js → context-estimator.ts} +57 -36
  109. package/core/domain/{product-standards.js → product-standards.ts} +40 -26
  110. package/core/domain/{smart-cache.js → smart-cache.ts} +39 -30
  111. package/core/domain/{snapshot-manager.js → snapshot-manager.ts} +103 -100
  112. package/core/domain/{task-analyzer.js → task-analyzer.ts} +82 -43
  113. package/core/domain/task-stack/index.ts +19 -0
  114. package/core/domain/task-stack/parser.ts +86 -0
  115. package/core/domain/task-stack/storage.ts +123 -0
  116. package/core/domain/task-stack/task-stack.ts +340 -0
  117. package/core/domain/task-stack/types.ts +51 -0
  118. package/core/domain/task-stack.ts +8 -0
  119. package/core/{index.js → index.ts} +61 -18
  120. package/core/infrastructure/{agent-detector.js → agent-detector.ts} +62 -23
  121. package/core/infrastructure/agents/{claude-agent.js → claude-agent.ts} +61 -21
  122. package/core/infrastructure/{author-detector.js → author-detector.ts} +42 -49
  123. package/core/infrastructure/{capability-installer.js → capability-installer.ts} +51 -27
  124. package/core/infrastructure/{command-installer.js → command-installer/command-installer.ts} +43 -144
  125. package/core/infrastructure/command-installer/global-config.ts +106 -0
  126. package/core/infrastructure/command-installer/index.ts +25 -0
  127. package/core/infrastructure/command-installer/types.ts +41 -0
  128. package/core/infrastructure/command-installer.ts +8 -0
  129. package/core/infrastructure/{config-manager.js → config-manager.ts} +60 -80
  130. package/core/infrastructure/{editors-config.js → editors-config.ts} +33 -31
  131. package/core/infrastructure/legacy-installer-detector/cleanup.ts +216 -0
  132. package/core/infrastructure/legacy-installer-detector/detection.ts +95 -0
  133. package/core/infrastructure/legacy-installer-detector/index.ts +171 -0
  134. package/core/infrastructure/legacy-installer-detector/migration.ts +87 -0
  135. package/core/infrastructure/legacy-installer-detector/types.ts +42 -0
  136. package/core/infrastructure/legacy-installer-detector.ts +7 -0
  137. package/core/infrastructure/migrator/file-operations.ts +125 -0
  138. package/core/infrastructure/migrator/index.ts +288 -0
  139. package/core/infrastructure/migrator/project-scanner.ts +89 -0
  140. package/core/infrastructure/migrator/reports.ts +117 -0
  141. package/core/infrastructure/migrator/types.ts +124 -0
  142. package/core/infrastructure/migrator/validation.ts +94 -0
  143. package/core/infrastructure/migrator/version-migration.ts +117 -0
  144. package/core/infrastructure/migrator.ts +10 -0
  145. package/core/infrastructure/{path-manager.js → path-manager.ts} +51 -91
  146. package/core/infrastructure/session-manager/index.ts +23 -0
  147. package/core/infrastructure/session-manager/migration.ts +88 -0
  148. package/core/infrastructure/session-manager/session-manager.ts +307 -0
  149. package/core/infrastructure/session-manager/types.ts +45 -0
  150. package/core/infrastructure/session-manager.ts +8 -0
  151. package/core/infrastructure/{setup.js → setup.ts} +29 -21
  152. package/core/infrastructure/{update-checker.js → update-checker.ts} +40 -18
  153. package/core/outcomes/analyzer.ts +333 -0
  154. package/core/outcomes/index.ts +34 -0
  155. package/core/outcomes/recorder.ts +194 -0
  156. package/core/outcomes/types.ts +145 -0
  157. package/core/plugin/{hooks.js → hooks.ts} +56 -58
  158. package/core/plugin/{index.js → index.ts} +19 -8
  159. package/core/plugin/{loader.js → loader.ts} +87 -69
  160. package/core/plugin/{registry.js → registry.ts} +49 -45
  161. package/core/plugins/{webhook.js → webhook.ts} +43 -27
  162. package/core/schemas/agents.ts +27 -0
  163. package/core/schemas/analysis.ts +41 -0
  164. package/core/schemas/ideas.ts +83 -0
  165. package/core/schemas/index.ts +73 -0
  166. package/core/schemas/outcomes.ts +22 -0
  167. package/core/schemas/project.ts +26 -0
  168. package/core/schemas/roadmap.ts +90 -0
  169. package/core/schemas/shipped.ts +82 -0
  170. package/core/schemas/state.ts +107 -0
  171. package/core/session/index.ts +17 -0
  172. package/core/session/{metrics.js → metrics.ts} +64 -46
  173. package/core/session/{index.js → session-manager.ts} +51 -117
  174. package/core/session/types.ts +29 -0
  175. package/core/session/utils.ts +57 -0
  176. package/core/state/index.ts +25 -0
  177. package/core/state/manager.ts +376 -0
  178. package/core/state/types.ts +185 -0
  179. package/core/tsconfig.json +22 -0
  180. package/core/types/index.ts +506 -0
  181. package/core/utils/{animations.js → animations.ts} +74 -28
  182. package/core/utils/{branding.js → branding.ts} +29 -4
  183. package/core/utils/{date-helper.js → date-helper.ts} +31 -74
  184. package/core/utils/file-helper.ts +262 -0
  185. package/core/utils/{jsonl-helper.js → jsonl-helper.ts} +71 -107
  186. package/core/utils/{logger.js → logger.ts} +24 -12
  187. package/core/utils/{output.js → output.ts} +25 -13
  188. package/core/utils/{project-capabilities.js → project-capabilities.ts} +31 -18
  189. package/core/utils/{session-helper.js → session-helper.ts} +79 -66
  190. package/core/utils/{version.js → version.ts} +23 -31
  191. package/core/view-generator.ts +536 -0
  192. package/package.json +23 -17
  193. package/packages/shared/.turbo/turbo-build.log +14 -0
  194. package/packages/shared/dist/index.d.ts +8 -613
  195. package/packages/shared/dist/index.d.ts.map +1 -0
  196. package/packages/shared/dist/index.js +4110 -118
  197. package/packages/shared/dist/schemas.d.ts +408 -0
  198. package/packages/shared/dist/schemas.d.ts.map +1 -0
  199. package/packages/shared/dist/types.d.ts +144 -0
  200. package/packages/shared/dist/types.d.ts.map +1 -0
  201. package/packages/shared/dist/unified.d.ts +139 -0
  202. package/packages/shared/dist/unified.d.ts.map +1 -0
  203. package/packages/shared/dist/utils.d.ts +60 -0
  204. package/packages/shared/dist/utils.d.ts.map +1 -0
  205. package/packages/shared/package.json +4 -4
  206. package/packages/shared/src/index.ts +1 -0
  207. package/packages/shared/src/unified.ts +174 -0
  208. package/packages/web/app/api/claude/sessions/route.ts +1 -1
  209. package/packages/web/app/api/claude/status/route.ts +1 -1
  210. package/packages/web/app/api/migrate/route.ts +46 -0
  211. package/packages/web/app/api/projects/[id]/route.ts +1 -1
  212. package/packages/web/app/api/projects/[id]/stats/route.ts +30 -2
  213. package/packages/web/app/api/projects/[id]/status/route.ts +1 -1
  214. package/packages/web/app/api/projects/route.ts +1 -1
  215. package/packages/web/app/api/settings/route.ts +97 -0
  216. package/packages/web/app/api/v2/projects/[id]/unified/route.ts +57 -0
  217. package/packages/web/app/globals.css +38 -0
  218. package/packages/web/app/layout.tsx +10 -2
  219. package/packages/web/app/page.tsx +9 -224
  220. package/packages/web/app/project/[id]/page.tsx +191 -63
  221. package/packages/web/app/project/[id]/stats/loading.tsx +43 -0
  222. package/packages/web/app/project/[id]/stats/page.tsx +203 -403
  223. package/packages/web/app/settings/page.tsx +222 -2
  224. package/packages/web/components/ActivityTimeline/ActivityTimeline.constants.ts +2 -0
  225. package/packages/web/components/ActivityTimeline/ActivityTimeline.tsx +50 -0
  226. package/packages/web/components/ActivityTimeline/ActivityTimeline.types.ts +8 -0
  227. package/packages/web/components/ActivityTimeline/hooks/index.ts +2 -0
  228. package/packages/web/components/ActivityTimeline/hooks/useExpandable.ts +9 -0
  229. package/packages/web/components/ActivityTimeline/hooks/useGroupedEvents.ts +23 -0
  230. package/packages/web/components/ActivityTimeline/index.ts +2 -0
  231. package/packages/web/components/AgentsCard/AgentsCard.tsx +63 -0
  232. package/packages/web/components/AgentsCard/AgentsCard.types.ts +13 -0
  233. package/packages/web/components/AgentsCard/index.ts +2 -0
  234. package/packages/web/components/AppSidebar/AppSidebar.tsx +134 -0
  235. package/packages/web/components/AppSidebar/index.ts +1 -0
  236. package/packages/web/components/BackLink/BackLink.tsx +18 -0
  237. package/packages/web/components/BackLink/BackLink.types.ts +5 -0
  238. package/packages/web/components/BackLink/index.ts +2 -0
  239. package/packages/web/components/BentoCard/BentoCard.constants.ts +16 -0
  240. package/packages/web/components/BentoCard/BentoCard.tsx +47 -0
  241. package/packages/web/components/BentoCard/BentoCard.types.ts +15 -0
  242. package/packages/web/components/BentoCard/index.ts +2 -0
  243. package/packages/web/components/BentoCardSkeleton/BentoCardSkeleton.constants.ts +9 -0
  244. package/packages/web/components/BentoCardSkeleton/BentoCardSkeleton.tsx +18 -0
  245. package/packages/web/components/BentoCardSkeleton/BentoCardSkeleton.types.ts +5 -0
  246. package/packages/web/components/BentoCardSkeleton/index.ts +2 -0
  247. package/packages/web/components/BentoGrid/BentoGrid.tsx +18 -0
  248. package/packages/web/components/BentoGrid/BentoGrid.types.ts +4 -0
  249. package/packages/web/components/BentoGrid/index.ts +2 -0
  250. package/packages/web/components/CommandButton/index.ts +1 -0
  251. package/packages/web/components/ConnectionStatus/index.ts +1 -0
  252. package/packages/web/components/DashboardContent/DashboardContent.tsx +254 -0
  253. package/packages/web/components/DashboardContent/index.ts +1 -0
  254. package/packages/web/components/DateGroup/DateGroup.tsx +18 -0
  255. package/packages/web/components/DateGroup/DateGroup.types.ts +6 -0
  256. package/packages/web/components/DateGroup/DateGroup.utils.ts +11 -0
  257. package/packages/web/components/DateGroup/index.ts +2 -0
  258. package/packages/web/components/EmptyState/EmptyState.tsx +58 -0
  259. package/packages/web/components/EmptyState/EmptyState.types.ts +10 -0
  260. package/packages/web/components/EmptyState/index.ts +2 -0
  261. package/packages/web/components/EventRow/EventRow.constants.ts +10 -0
  262. package/packages/web/components/EventRow/EventRow.tsx +49 -0
  263. package/packages/web/components/EventRow/EventRow.types.ts +7 -0
  264. package/packages/web/components/EventRow/EventRow.utils.ts +49 -0
  265. package/packages/web/components/EventRow/index.ts +2 -0
  266. package/packages/web/components/ExpandButton/ExpandButton.tsx +18 -0
  267. package/packages/web/components/ExpandButton/ExpandButton.types.ts +6 -0
  268. package/packages/web/components/ExpandButton/index.ts +2 -0
  269. package/packages/web/components/HealthGradientBackground/HealthGradientBackground.tsx +14 -0
  270. package/packages/web/components/HealthGradientBackground/HealthGradientBackground.types.ts +5 -0
  271. package/packages/web/components/HealthGradientBackground/HealthGradientBackground.utils.ts +13 -0
  272. package/packages/web/components/HealthGradientBackground/index.ts +2 -0
  273. package/packages/web/components/HeroSection/HeroSection.tsx +55 -0
  274. package/packages/web/components/HeroSection/HeroSection.types.ts +14 -0
  275. package/packages/web/components/HeroSection/HeroSection.utils.ts +7 -0
  276. package/packages/web/components/HeroSection/hooks/index.ts +2 -0
  277. package/packages/web/components/HeroSection/hooks/useCountUp.ts +45 -0
  278. package/packages/web/components/HeroSection/hooks/useWeeklyActivity.ts +18 -0
  279. package/packages/web/components/HeroSection/index.ts +2 -0
  280. package/packages/web/components/IdeasCard/IdeasCard.tsx +48 -0
  281. package/packages/web/components/IdeasCard/IdeasCard.types.ts +9 -0
  282. package/packages/web/components/IdeasCard/index.ts +2 -0
  283. package/packages/web/components/InsightMessage/InsightMessage.tsx +9 -0
  284. package/packages/web/components/InsightMessage/InsightMessage.types.ts +3 -0
  285. package/packages/web/components/InsightMessage/index.ts +2 -0
  286. package/packages/web/components/Logo/index.ts +1 -0
  287. package/packages/web/components/MarkdownContent/index.ts +1 -0
  288. package/packages/web/components/NowCard/NowCard.tsx +93 -0
  289. package/packages/web/components/NowCard/NowCard.types.ts +15 -0
  290. package/packages/web/components/NowCard/index.ts +2 -0
  291. package/packages/web/components/ProgressRing/ProgressRing.constants.ts +20 -0
  292. package/packages/web/components/ProgressRing/ProgressRing.tsx +51 -0
  293. package/packages/web/components/ProgressRing/ProgressRing.types.ts +11 -0
  294. package/packages/web/components/ProgressRing/index.ts +2 -0
  295. package/packages/web/components/ProjectAvatar/index.ts +1 -0
  296. package/packages/web/components/Providers/index.ts +1 -0
  297. package/packages/web/components/QueueCard/QueueCard.tsx +72 -0
  298. package/packages/web/components/QueueCard/QueueCard.types.ts +11 -0
  299. package/packages/web/components/QueueCard/QueueCard.utils.ts +12 -0
  300. package/packages/web/components/QueueCard/index.ts +2 -0
  301. package/packages/web/components/RoadmapCard/RoadmapCard.tsx +77 -0
  302. package/packages/web/components/RoadmapCard/RoadmapCard.types.ts +15 -0
  303. package/packages/web/components/RoadmapCard/index.ts +2 -0
  304. package/packages/web/components/ShipsCard/ShipsCard.tsx +52 -0
  305. package/packages/web/components/ShipsCard/ShipsCard.types.ts +12 -0
  306. package/packages/web/components/ShipsCard/ShipsCard.utils.ts +4 -0
  307. package/packages/web/components/ShipsCard/index.ts +2 -0
  308. package/packages/web/components/SparklineChart/SparklineChart.tsx +38 -0
  309. package/packages/web/components/SparklineChart/SparklineChart.types.ts +6 -0
  310. package/packages/web/components/SparklineChart/index.ts +2 -0
  311. package/packages/web/components/StreakCard/StreakCard.constants.ts +2 -0
  312. package/packages/web/components/StreakCard/StreakCard.tsx +53 -0
  313. package/packages/web/components/StreakCard/StreakCard.types.ts +4 -0
  314. package/packages/web/components/StreakCard/index.ts +2 -0
  315. package/packages/web/components/TasksCounter/TasksCounter.tsx +14 -0
  316. package/packages/web/components/TasksCounter/TasksCounter.types.ts +3 -0
  317. package/packages/web/components/TasksCounter/index.ts +2 -0
  318. package/packages/web/components/TechStackBadges/index.ts +1 -0
  319. package/packages/web/components/{TerminalTab.tsx → TerminalTabs/TerminalTab.tsx} +11 -0
  320. package/packages/web/components/{TerminalTabs.tsx → TerminalTabs/TerminalTabs.tsx} +29 -28
  321. package/packages/web/components/TerminalTabs/index.ts +1 -0
  322. package/packages/web/components/VelocityBadge/VelocityBadge.tsx +27 -0
  323. package/packages/web/components/VelocityBadge/VelocityBadge.types.ts +3 -0
  324. package/packages/web/components/VelocityBadge/index.ts +2 -0
  325. package/packages/web/components/VelocityCard/VelocityCard.tsx +71 -0
  326. package/packages/web/components/VelocityCard/VelocityCard.types.ts +7 -0
  327. package/packages/web/components/VelocityCard/index.ts +2 -0
  328. package/packages/web/components/WeeklySparkline/WeeklySparkline.tsx +13 -0
  329. package/packages/web/components/WeeklySparkline/WeeklySparkline.types.ts +3 -0
  330. package/packages/web/components/WeeklySparkline/index.ts +2 -0
  331. package/packages/web/components/ui/input.tsx +21 -0
  332. package/packages/web/components/ui/tooltip.tsx +2 -2
  333. package/packages/web/context/TerminalTabsContext.tsx +46 -1
  334. package/packages/web/hooks/useClaudeTerminal.ts +71 -21
  335. package/packages/web/hooks/useProjectStats.ts +55 -0
  336. package/packages/web/hooks/useProjects.ts +6 -6
  337. package/packages/web/lib/actions/projects.ts +15 -0
  338. package/packages/web/lib/json-loader.ts +630 -0
  339. package/packages/web/lib/services/index.ts +9 -0
  340. package/packages/web/lib/services/migration.server.ts +598 -0
  341. package/packages/web/lib/services/projects.server.ts +52 -0
  342. package/packages/web/lib/services/stats.server.ts +264 -0
  343. package/packages/web/lib/unified-loader.ts +396 -0
  344. package/packages/web/next-env.d.ts +1 -1
  345. package/packages/web/package.json +10 -6
  346. package/packages/web/server.ts +36 -6
  347. package/templates/commands/done.md +76 -32
  348. package/templates/commands/feature.md +121 -47
  349. package/templates/commands/idea.md +81 -8
  350. package/templates/commands/now.md +41 -17
  351. package/templates/commands/ship.md +64 -25
  352. package/templates/commands/sync.md +28 -3
  353. package/core/agentic/agent-router.js +0 -128
  354. package/core/agentic/chain-of-thought.js +0 -578
  355. package/core/agentic/command-executor.js +0 -421
  356. package/core/agentic/context-filter.js +0 -354
  357. package/core/agentic/ground-truth.js +0 -591
  358. package/core/agentic/loop-detector.js +0 -406
  359. package/core/agentic/memory-system.js +0 -850
  360. package/core/agentic/parallel-tools.js +0 -366
  361. package/core/agentic/plan-mode.js +0 -572
  362. package/core/agentic/prompt-builder.js +0 -338
  363. package/core/agentic/response-templates.js +0 -290
  364. package/core/agentic/semantic-compression.js +0 -517
  365. package/core/agentic/think-blocks.js +0 -657
  366. package/core/agentic/tool-registry.js +0 -184
  367. package/core/agentic/validation-rules.js +0 -380
  368. package/core/command-registry.js +0 -698
  369. package/core/commands.js +0 -2237
  370. package/core/domain/task-stack.js +0 -497
  371. package/core/infrastructure/legacy-installer-detector.js +0 -546
  372. package/core/infrastructure/migrator.js +0 -799
  373. package/core/infrastructure/session-manager.js +0 -390
  374. package/core/utils/file-helper.js +0 -329
  375. package/packages/web/app/api/projects/[id]/delete/route.ts +0 -21
  376. package/packages/web/app/api/stats/route.ts +0 -38
  377. package/packages/web/components/AppSidebar.tsx +0 -113
  378. package/packages/web/hooks/useStats.ts +0 -28
  379. /package/packages/web/components/{CommandButton.tsx → CommandButton/CommandButton.tsx} +0 -0
  380. /package/packages/web/components/{ConnectionStatus.tsx → ConnectionStatus/ConnectionStatus.tsx} +0 -0
  381. /package/packages/web/components/{Logo.tsx → Logo/Logo.tsx} +0 -0
  382. /package/packages/web/components/{MarkdownContent.tsx → MarkdownContent/MarkdownContent.tsx} +0 -0
  383. /package/packages/web/components/{ProjectAvatar.tsx → ProjectAvatar/ProjectAvatar.tsx} +0 -0
  384. /package/packages/web/components/{providers.tsx → Providers/Providers.tsx} +0 -0
  385. /package/packages/web/components/{TechStackBadges.tsx → TechStackBadges/TechStackBadges.tsx} +0 -0
@@ -0,0 +1,307 @@
1
+ /**
2
+ * SessionManager Class
3
+ * Manages temporal fragmentation of logs and progress data.
4
+ */
5
+
6
+ import path from 'path'
7
+ import pathManager from '../path-manager'
8
+ import { VERSION } from '../../utils/version'
9
+ import * as dateHelper from '../../utils/date-helper'
10
+ import * as jsonlHelper from '../../utils/jsonl-helper'
11
+ import * as fileHelper from '../../utils/file-helper'
12
+ import { migrateLegacyJsonl, migrateLegacyMarkdown } from './migration'
13
+ import type { SessionEntry, SessionMetadata, SessionStats, MigrationResult } from './types'
14
+
15
+ export class SessionManager {
16
+ private currentSessionCache: Map<string, string>
17
+ private sessionMetadataCache: Map<string, SessionMetadata>
18
+
19
+ constructor() {
20
+ this.currentSessionCache = new Map()
21
+ this.sessionMetadataCache = new Map()
22
+ }
23
+
24
+ /**
25
+ * Get or create current session directory for a project
26
+ */
27
+ async getCurrentSession(projectId: string): Promise<string> {
28
+ const cacheKey = `${projectId}-${this._getTodayKey()}`
29
+
30
+ if (this.currentSessionCache.has(cacheKey)) {
31
+ return this.currentSessionCache.get(cacheKey)!
32
+ }
33
+
34
+ const sessionPath = await pathManager.ensureSessionPath(projectId)
35
+ this.currentSessionCache.set(cacheKey, sessionPath)
36
+
37
+ await this._ensureSessionMetadata(sessionPath)
38
+
39
+ return sessionPath
40
+ }
41
+
42
+ /**
43
+ * Write log entry to current session
44
+ */
45
+ async writeToSession(
46
+ projectId: string,
47
+ entry: SessionEntry,
48
+ filename: string = 'context.jsonl'
49
+ ): Promise<void> {
50
+ const sessionPath = await this.getCurrentSession(projectId)
51
+ const filePath = path.join(sessionPath, filename)
52
+
53
+ // Use automatic rotation to prevent large files (>10MB)
54
+ await jsonlHelper.appendJsonLineWithRotation(filePath, entry, 10)
55
+
56
+ await this._updateSessionMetadata(sessionPath, {
57
+ lastActivity: dateHelper.getTimestamp(),
58
+ entryCount: await jsonlHelper.countJsonLines(filePath),
59
+ })
60
+ }
61
+
62
+ /**
63
+ * Append content to a session file (for markdown files like shipped.md)
64
+ */
65
+ async appendToSession(projectId: string, content: string, filename: string): Promise<void> {
66
+ const sessionPath = await this.getCurrentSession(projectId)
67
+ const filePath = path.join(sessionPath, filename)
68
+
69
+ const exists = await fileHelper.fileExists(filePath)
70
+ if (!exists && filename === 'shipped.md') {
71
+ await fileHelper.writeFile(filePath, '# SHIPPED 🚀\n\n' + content)
72
+ } else {
73
+ await fileHelper.appendToFile(filePath, content)
74
+ }
75
+
76
+ await this._updateSessionMetadata(sessionPath, {
77
+ lastActivity: dateHelper.getTimestamp(),
78
+ })
79
+ }
80
+
81
+ /**
82
+ * Read logs from current session
83
+ * Uses streaming for large files (>50MB)
84
+ */
85
+ async readCurrentSession<T = SessionEntry>(
86
+ projectId: string,
87
+ filename: string = 'context.jsonl',
88
+ maxLines: number = 1000
89
+ ): Promise<T[]> {
90
+ const sessionPath = await this.getCurrentSession(projectId)
91
+ const filePath = path.join(sessionPath, filename)
92
+
93
+ // Check file size and warn if large
94
+ const { isLarge } = await jsonlHelper.checkFileSizeWarning(filePath, 50)
95
+
96
+ if (isLarge) {
97
+ // Use streaming for large files
98
+ return (await jsonlHelper.readJsonLinesStreaming(filePath, maxLines)) as T[]
99
+ }
100
+
101
+ // Use normal read for small files
102
+ return (await jsonlHelper.readJsonLines(filePath)) as T[]
103
+ }
104
+
105
+ /**
106
+ * Read logs from a specific date range
107
+ */
108
+ async readSessionRange<T = SessionEntry>(
109
+ projectId: string,
110
+ fromDate: Date,
111
+ toDate: Date = new Date(),
112
+ filename: string = 'context.jsonl'
113
+ ): Promise<T[]> {
114
+ const sessions = await pathManager.getSessionsInRange(projectId, fromDate, toDate)
115
+ const allEntries: T[] = []
116
+
117
+ for (const session of sessions) {
118
+ const filePath = path.join(session.path, filename)
119
+ const entries = (await jsonlHelper.readJsonLines(filePath)) as (T & { _sessionDate?: Date })[]
120
+
121
+ entries.forEach((entry) => {
122
+ entry._sessionDate = session.date
123
+ })
124
+
125
+ allEntries.push(...entries)
126
+ }
127
+
128
+ return allEntries
129
+ }
130
+
131
+ /**
132
+ * Read markdown content from sessions in date range
133
+ */
134
+ async readMarkdownRange(
135
+ projectId: string,
136
+ fromDate: Date,
137
+ toDate: Date,
138
+ filename: string
139
+ ): Promise<string> {
140
+ const sessions = await pathManager.getSessionsInRange(projectId, fromDate, toDate)
141
+ const allContent: string[] = []
142
+
143
+ for (const session of sessions) {
144
+ const filePath = path.join(session.path, filename)
145
+ const content = await fileHelper.readFile(filePath, '')
146
+
147
+ if (content.trim()) {
148
+ allContent.push(`## Session: ${session.year}-${session.month}-${session.day}\n\n${content}`)
149
+ }
150
+ }
151
+
152
+ return allContent.join('\n---\n\n')
153
+ }
154
+
155
+ /**
156
+ * Get recent logs (last N days)
157
+ */
158
+ async getRecentLogs<T = SessionEntry>(
159
+ projectId: string,
160
+ days: number = 7,
161
+ filename: string = 'context.jsonl'
162
+ ): Promise<T[]> {
163
+ const toDate = new Date()
164
+ const fromDate = dateHelper.getDaysAgo(days)
165
+
166
+ return await this.readSessionRange<T>(projectId, fromDate, toDate, filename)
167
+ }
168
+
169
+ /**
170
+ * Get session statistics
171
+ */
172
+ async getSessionStats(projectId: string, fromDate: Date, toDate: Date): Promise<SessionStats> {
173
+ const sessions = await pathManager.getSessionsInRange(projectId, fromDate, toDate)
174
+
175
+ let totalEntries = 0
176
+ let totalShips = 0
177
+ let activeDays = 0
178
+
179
+ for (const session of sessions) {
180
+ const metadata = await this._getSessionMetadata(session.path)
181
+ if (metadata) {
182
+ totalEntries += metadata.entryCount || 0
183
+ totalShips += metadata.shipCount || 0
184
+ if (metadata.entryCount && metadata.entryCount > 0) {
185
+ activeDays++
186
+ }
187
+ }
188
+ }
189
+
190
+ return {
191
+ totalSessions: sessions.length,
192
+ activeDays,
193
+ totalEntries,
194
+ totalShips,
195
+ averageEntriesPerDay: activeDays > 0 ? Math.round(totalEntries / activeDays) : 0,
196
+ }
197
+ }
198
+
199
+ /**
200
+ * Migrate legacy single-file logs to session structure
201
+ */
202
+ async migrateLegacyLogs(
203
+ projectId: string,
204
+ legacyFilePath: string,
205
+ sessionFilename: string
206
+ ): Promise<MigrationResult> {
207
+ try {
208
+ const content = await fileHelper.readFile(legacyFilePath)
209
+
210
+ if (sessionFilename.endsWith('.jsonl')) {
211
+ return await migrateLegacyJsonl(
212
+ projectId,
213
+ content,
214
+ sessionFilename,
215
+ (sp, u) => this._updateSessionMetadata(sp, u),
216
+ (sp) => this._ensureSessionMetadata(sp)
217
+ )
218
+ } else {
219
+ const sessionPath = await this.getCurrentSession(projectId)
220
+ return await migrateLegacyMarkdown(
221
+ sessionPath,
222
+ content,
223
+ sessionFilename,
224
+ (sp, u) => this._updateSessionMetadata(sp, u)
225
+ )
226
+ }
227
+ } catch (error) {
228
+ return {
229
+ success: false,
230
+ message: `Migration failed: ${(error as Error).message}`,
231
+ entriesMigrated: 0,
232
+ }
233
+ }
234
+ }
235
+
236
+ /**
237
+ * Get session metadata
238
+ */
239
+ private async _getSessionMetadata(sessionPath: string): Promise<SessionMetadata | null> {
240
+ const metadataPath = path.join(sessionPath, 'session-meta.json')
241
+
242
+ if (this.sessionMetadataCache.has(sessionPath)) {
243
+ return this.sessionMetadataCache.get(sessionPath)!
244
+ }
245
+
246
+ const metadata = await fileHelper.readJson<SessionMetadata>(metadataPath, null)
247
+ if (metadata) {
248
+ this.sessionMetadataCache.set(sessionPath, metadata)
249
+ }
250
+ return metadata
251
+ }
252
+
253
+ /**
254
+ * Ensure session metadata exists
255
+ */
256
+ private async _ensureSessionMetadata(sessionPath: string): Promise<void> {
257
+ const metadataPath = path.join(sessionPath, 'session-meta.json')
258
+
259
+ const exists = await fileHelper.fileExists(metadataPath)
260
+ if (!exists) {
261
+ const metadata: SessionMetadata = {
262
+ created: dateHelper.getTimestamp(),
263
+ lastActivity: dateHelper.getTimestamp(),
264
+ entryCount: 0,
265
+ shipCount: 0,
266
+ version: VERSION,
267
+ }
268
+ await fileHelper.writeJson(metadataPath, metadata)
269
+ this.sessionMetadataCache.set(sessionPath, metadata)
270
+ }
271
+ }
272
+
273
+ /**
274
+ * Update session metadata
275
+ */
276
+ private async _updateSessionMetadata(
277
+ sessionPath: string,
278
+ updates: Partial<SessionMetadata>
279
+ ): Promise<void> {
280
+ const metadata = (await this._getSessionMetadata(sessionPath)) || {}
281
+ Object.assign(metadata, updates)
282
+
283
+ const metadataPath = path.join(sessionPath, 'session-meta.json')
284
+ await fileHelper.writeJson(metadataPath, metadata)
285
+
286
+ this.sessionMetadataCache.set(sessionPath, metadata)
287
+ }
288
+
289
+ /**
290
+ * Get today's date key (YYYY-MM-DD)
291
+ */
292
+ private _getTodayKey(): string {
293
+ return dateHelper.getTodayKey()
294
+ }
295
+
296
+ /**
297
+ * Get date key for any date (YYYY-MM-DD)
298
+ */
299
+ private _getDateKey(date: Date): string {
300
+ return dateHelper.getDateKey(date)
301
+ }
302
+
303
+ clearCache(): void {
304
+ this.currentSessionCache.clear()
305
+ this.sessionMetadataCache.clear()
306
+ }
307
+ }
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Session Manager Types
3
+ */
4
+
5
+ export interface SessionEntry {
6
+ timestamp?: string
7
+ data?: {
8
+ timestamp?: string
9
+ }
10
+ _sessionDate?: Date
11
+ [key: string]: unknown
12
+ }
13
+
14
+ export interface SessionMetadata {
15
+ created?: string
16
+ lastActivity?: string
17
+ entryCount?: number
18
+ shipCount?: number
19
+ version?: string
20
+ migrated?: boolean
21
+ migratedAt?: string
22
+ }
23
+
24
+ export interface SessionStats {
25
+ totalSessions: number
26
+ activeDays: number
27
+ totalEntries: number
28
+ totalShips: number
29
+ averageEntriesPerDay: number
30
+ }
31
+
32
+ export interface MigrationResult {
33
+ success: boolean
34
+ message: string
35
+ entriesMigrated: number
36
+ sessionsCreated?: number
37
+ }
38
+
39
+ export interface SessionInfo {
40
+ path: string
41
+ date: Date
42
+ year: string
43
+ month: string
44
+ day: string
45
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Session Manager
3
+ * Re-exports from session-manager/index.ts for backwards compatibility.
4
+ */
5
+
6
+ import sessionManager from './session-manager/index'
7
+ export * from './session-manager/index'
8
+ export default sessionManager
@@ -1,10 +1,3 @@
1
- const { execSync } = require('child_process')
2
- const installer = require('./command-installer')
3
- const migrator = require('./migrator')
4
- const legacyDetector = require('./legacy-installer-detector')
5
- const editorsConfig = require('./editors-config')
6
- const { VERSION } = require('../utils/version')
7
-
8
1
  /**
9
2
  * Setup Module - Core installation logic
10
3
  *
@@ -23,18 +16,33 @@ const { VERSION } = require('../utils/version')
23
16
  * @version 0.8.8
24
17
  */
25
18
 
19
+ import { execSync } from 'child_process'
20
+ import installer from './command-installer'
21
+ import migrator from './migrator'
22
+ import legacyDetector from './legacy-installer-detector'
23
+ import editorsConfig from './editors-config'
24
+ import { VERSION } from '../utils/version'
25
+
26
26
  // Colors
27
27
  const GREEN = '\x1b[32m'
28
28
  const YELLOW = '\x1b[33m'
29
- const MAGENTA = '\x1b[35m'
30
- const BOLD = '\x1b[1m'
31
29
  const DIM = '\x1b[2m'
32
30
  const NC = '\x1b[0m'
33
31
 
32
+ interface SetupResults {
33
+ legacyCleaned: boolean
34
+ legacyProjectsMigrated: number
35
+ claudeInstalled: boolean
36
+ commandsAdded: number
37
+ commandsUpdated: number
38
+ configAction: string | null
39
+ projectsMigrated: number
40
+ }
41
+
34
42
  /**
35
43
  * Check if Claude Code CLI is installed
36
44
  */
37
- async function hasClaudeCodeCLI() {
45
+ async function hasClaudeCodeCLI(): Promise<boolean> {
38
46
  try {
39
47
  execSync('which claude', { stdio: 'ignore' })
40
48
  return true
@@ -46,7 +54,7 @@ async function hasClaudeCodeCLI() {
46
54
  /**
47
55
  * Install Claude Code CLI
48
56
  */
49
- async function installClaudeCode() {
57
+ async function installClaudeCode(): Promise<boolean> {
50
58
  try {
51
59
  console.log(`${YELLOW}📦 Claude Code not found. Installing...${NC}`)
52
60
  console.log('')
@@ -56,7 +64,7 @@ async function installClaudeCode() {
56
64
  console.log('')
57
65
  return true
58
66
  } catch (error) {
59
- console.log(`${YELLOW}⚠️ Failed to install Claude Code: ${error.message}${NC}`)
67
+ console.log(`${YELLOW}⚠️ Failed to install Claude Code: ${(error as Error).message}${NC}`)
60
68
  console.log(`${DIM}Please install manually: npm install -g @anthropic-ai/claude-code${NC}`)
61
69
  console.log('')
62
70
  return false
@@ -66,15 +74,15 @@ async function installClaudeCode() {
66
74
  /**
67
75
  * Main setup function
68
76
  */
69
- async function run() {
70
- const results = {
77
+ export async function run(): Promise<SetupResults> {
78
+ const results: SetupResults = {
71
79
  legacyCleaned: false,
72
80
  legacyProjectsMigrated: 0,
73
81
  claudeInstalled: false,
74
82
  commandsAdded: 0,
75
83
  commandsUpdated: 0,
76
84
  configAction: null,
77
- projectsMigrated: 0
85
+ projectsMigrated: 0,
78
86
  }
79
87
 
80
88
  // Step 0: Detect and clean legacy curl installation
@@ -120,7 +128,7 @@ async function run() {
120
128
  const migrationResult = await migrator.migrateAll({
121
129
  deepScan: false,
122
130
  cleanupLegacy: true,
123
- dryRun: false
131
+ dryRun: false,
124
132
  })
125
133
 
126
134
  if (migrationResult.successfullyMigrated > 0) {
@@ -140,14 +148,16 @@ async function run() {
140
148
  /**
141
149
  * Show setup results
142
150
  */
143
- function showResults(results) {
151
+ function showResults(results: SetupResults): void {
144
152
  console.log('')
145
153
 
146
154
  // Show what was done
147
155
  if (results.legacyCleaned) {
148
156
  console.log(` ${GREEN}✓${NC} Legacy curl installation cleaned up`)
149
157
  if (results.legacyProjectsMigrated > 0) {
150
- console.log(` ${GREEN}✓${NC} ${results.legacyProjectsMigrated} project(s) migrated from legacy`)
158
+ console.log(
159
+ ` ${GREEN}✓${NC} ${results.legacyProjectsMigrated} project(s) migrated from legacy`
160
+ )
151
161
  }
152
162
  }
153
163
 
@@ -159,7 +169,7 @@ function showResults(results) {
159
169
 
160
170
  const totalCommands = results.commandsAdded + results.commandsUpdated
161
171
  if (totalCommands > 0) {
162
- const parts = []
172
+ const parts: string[] = []
163
173
  if (results.commandsAdded > 0) parts.push(`${results.commandsAdded} new`)
164
174
  if (results.commandsUpdated > 0) parts.push(`${results.commandsUpdated} updated`)
165
175
  console.log(` ${GREEN}✓${NC} Commands synced (${parts.join(', ')})`)
@@ -181,5 +191,3 @@ function showResults(results) {
181
191
 
182
192
  console.log('')
183
193
  }
184
-
185
- module.exports = { run }
@@ -1,9 +1,32 @@
1
- const https = require('https')
2
- const fs = require('fs')
3
- const path = require('path')
4
- const os = require('os')
1
+ /**
2
+ * UpdateChecker - Checks for package updates from npm registry
3
+ *
4
+ * @version 0.5.0
5
+ */
6
+
7
+ import https from 'https'
8
+ import fs from 'fs'
9
+ import path from 'path'
10
+ import os from 'os'
11
+ import chalk from 'chalk'
12
+
13
+ interface UpdateCache {
14
+ lastCheck: number
15
+ latestVersion: string
16
+ }
17
+
18
+ interface UpdateResult {
19
+ updateAvailable: boolean
20
+ currentVersion: string
21
+ latestVersion: string
22
+ }
5
23
 
6
24
  class UpdateChecker {
25
+ packageName: string
26
+ cacheDir: string
27
+ cacheFile: string
28
+ checkInterval: number
29
+
7
30
  constructor() {
8
31
  this.packageName = 'prjct-cli'
9
32
  this.cacheDir = path.join(os.homedir(), '.prjct-cli', 'config')
@@ -14,13 +37,13 @@ class UpdateChecker {
14
37
  /**
15
38
  * Get current installed version from package.json
16
39
  */
17
- getCurrentVersion() {
40
+ getCurrentVersion(): string | null {
18
41
  try {
19
42
  const packageJsonPath = path.join(__dirname, '..', '..', 'package.json')
20
43
  const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'))
21
44
  return packageJson.version
22
45
  } catch (error) {
23
- console.error('Error reading package version:', error.message)
46
+ console.error('Error reading package version:', (error as Error).message)
24
47
  return null
25
48
  }
26
49
  }
@@ -28,7 +51,7 @@ class UpdateChecker {
28
51
  /**
29
52
  * Fetch latest version from npm registry
30
53
  */
31
- async getLatestVersion() {
54
+ async getLatestVersion(): Promise<string> {
32
55
  return new Promise((resolve, reject) => {
33
56
  const options = {
34
57
  hostname: 'registry.npmjs.org',
@@ -78,7 +101,7 @@ class UpdateChecker {
78
101
  * Compare two semantic versions
79
102
  * Returns: 1 if v1 > v2, -1 if v1 < v2, 0 if equal
80
103
  */
81
- compareVersions(v1, v2) {
104
+ compareVersions(v1: string, v2: string): number {
82
105
  const parts1 = v1.split('.').map(Number)
83
106
  const parts2 = v2.split('.').map(Number)
84
107
 
@@ -96,13 +119,13 @@ class UpdateChecker {
96
119
  /**
97
120
  * Read cache file
98
121
  */
99
- readCache() {
122
+ readCache(): UpdateCache | null {
100
123
  try {
101
124
  if (fs.existsSync(this.cacheFile)) {
102
125
  const cache = JSON.parse(fs.readFileSync(this.cacheFile, 'utf8'))
103
126
  return cache
104
127
  }
105
- } catch (error) {
128
+ } catch {
106
129
  // Cache file doesn't exist or is corrupted, ignore
107
130
  }
108
131
  return null
@@ -111,7 +134,7 @@ class UpdateChecker {
111
134
  /**
112
135
  * Write cache file
113
136
  */
114
- writeCache(data) {
137
+ writeCache(data: UpdateCache): void {
115
138
  try {
116
139
  // Ensure cache directory exists
117
140
  if (!fs.existsSync(this.cacheDir)) {
@@ -119,7 +142,7 @@ class UpdateChecker {
119
142
  }
120
143
 
121
144
  fs.writeFileSync(this.cacheFile, JSON.stringify(data, null, 2), 'utf8')
122
- } catch (error) {
145
+ } catch {
123
146
  // Fail silently - cache is not critical
124
147
  }
125
148
  }
@@ -128,7 +151,7 @@ class UpdateChecker {
128
151
  * Check if update is available (respects 24-hour cache)
129
152
  * Returns: { updateAvailable: boolean, currentVersion: string, latestVersion: string } or null
130
153
  */
131
- async checkForUpdates() {
154
+ async checkForUpdates(): Promise<UpdateResult | null> {
132
155
  try {
133
156
  const currentVersion = this.getCurrentVersion()
134
157
  if (!currentVersion) {
@@ -172,7 +195,7 @@ class UpdateChecker {
172
195
  currentVersion,
173
196
  latestVersion,
174
197
  }
175
- } catch (error) {
198
+ } catch {
176
199
  // Network error or other issue - fail silently
177
200
  // Return null to indicate check couldn't be performed
178
201
  return null
@@ -182,15 +205,13 @@ class UpdateChecker {
182
205
  /**
183
206
  * Get formatted update notification message
184
207
  */
185
- async getUpdateNotification() {
208
+ async getUpdateNotification(): Promise<string | null> {
186
209
  const result = await this.checkForUpdates()
187
210
 
188
211
  if (!result || !result.updateAvailable) {
189
212
  return null
190
213
  }
191
214
 
192
- const chalk = require('chalk')
193
-
194
215
  return (
195
216
  '\n' +
196
217
  chalk.yellow('┌───────────────────────────────────────────────────────────┐') +
@@ -219,4 +240,5 @@ class UpdateChecker {
219
240
  }
220
241
  }
221
242
 
222
- module.exports = UpdateChecker
243
+ export default UpdateChecker
244
+ export { UpdateChecker }