@codemieai/code 0.15.1 → 0.15.3

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 (336) hide show
  1. package/CHANGELOG.md +75 -0
  2. package/bin/codemie.js +52 -0
  3. package/dist/agents/core/AgentCLI.d.ts.map +1 -1
  4. package/dist/agents/core/AgentCLI.js +6 -0
  5. package/dist/agents/core/AgentCLI.js.map +1 -1
  6. package/dist/agents/core/BaseAgentAdapter.d.ts +25 -0
  7. package/dist/agents/core/BaseAgentAdapter.d.ts.map +1 -1
  8. package/dist/agents/core/BaseAgentAdapter.js +137 -127
  9. package/dist/agents/core/BaseAgentAdapter.js.map +1 -1
  10. package/dist/agents/core/session/BaseProcessor.d.ts +10 -0
  11. package/dist/agents/core/session/BaseProcessor.d.ts.map +1 -1
  12. package/dist/agents/core/session/BaseProcessor.js +11 -1
  13. package/dist/agents/core/session/BaseProcessor.js.map +1 -1
  14. package/dist/agents/core/session/BaseSessionAdapter.d.ts +4 -0
  15. package/dist/agents/core/session/BaseSessionAdapter.d.ts.map +1 -1
  16. package/dist/agents/core/types.d.ts +11 -5
  17. package/dist/agents/core/types.d.ts.map +1 -1
  18. package/dist/agents/plugins/claude/claude.models.d.ts.map +1 -1
  19. package/dist/agents/plugins/claude/claude.models.js +12 -11
  20. package/dist/agents/plugins/claude/claude.models.js.map +1 -1
  21. package/dist/agents/plugins/claude/claude.plugin.d.ts +3 -3
  22. package/dist/agents/plugins/claude/claude.plugin.d.ts.map +1 -1
  23. package/dist/agents/plugins/claude/claude.plugin.js +14 -13
  24. package/dist/agents/plugins/claude/claude.plugin.js.map +1 -1
  25. package/dist/agents/plugins/claude/claude.session.d.ts +17 -1
  26. package/dist/agents/plugins/claude/claude.session.d.ts.map +1 -1
  27. package/dist/agents/plugins/claude/claude.session.js +31 -1
  28. package/dist/agents/plugins/claude/claude.session.js.map +1 -1
  29. package/dist/agents/plugins/claude/plugin/.claude-plugin/plugin.json +1 -1
  30. package/dist/agents/plugins/claude/plugin/hooks/hooks.json +7 -7
  31. package/dist/agents/plugins/codex/codex.plugin.d.ts.map +1 -1
  32. package/dist/agents/plugins/codex/codex.plugin.js +7 -6
  33. package/dist/agents/plugins/codex/codex.plugin.js.map +1 -1
  34. package/dist/agents/plugins/copilot-cli/copilot-cli.plugin.d.ts.map +1 -1
  35. package/dist/agents/plugins/copilot-cli/copilot-cli.plugin.js +5 -2
  36. package/dist/agents/plugins/copilot-cli/copilot-cli.plugin.js.map +1 -1
  37. package/dist/agents/plugins/gemini/extension/gemini-extension.json +1 -1
  38. package/dist/agents/plugins/gemini/extension/hooks/hooks.json +7 -7
  39. package/dist/agents/plugins/gemini/gemini.plugin.d.ts.map +1 -1
  40. package/dist/agents/plugins/gemini/gemini.plugin.js +7 -6
  41. package/dist/agents/plugins/gemini/gemini.plugin.js.map +1 -1
  42. package/dist/agents/plugins/kimi/kimi.hook-config-injector.d.ts.map +1 -1
  43. package/dist/agents/plugins/kimi/kimi.hook-config-injector.js +26 -5
  44. package/dist/agents/plugins/kimi/kimi.hook-config-injector.js.map +1 -1
  45. package/dist/agents/plugins/kimi/kimi.plugin.d.ts.map +1 -1
  46. package/dist/agents/plugins/kimi/kimi.plugin.js +5 -2
  47. package/dist/agents/plugins/kimi/kimi.plugin.js.map +1 -1
  48. package/dist/agents/plugins/opencode/opencode-dynamic-models.d.ts.map +1 -1
  49. package/dist/agents/plugins/opencode/opencode-dynamic-models.js +3 -4
  50. package/dist/agents/plugins/opencode/opencode-dynamic-models.js.map +1 -1
  51. package/dist/agents/plugins/pi/pi.models.d.ts.map +1 -1
  52. package/dist/agents/plugins/pi/pi.models.js +3 -3
  53. package/dist/agents/plugins/pi/pi.models.js.map +1 -1
  54. package/dist/bin/proxy-daemon.js +8 -1
  55. package/dist/bin/proxy-daemon.js.map +1 -1
  56. package/dist/cli/commands/analytics/cost/claude-dispatch-allocation.d.ts +6 -0
  57. package/dist/cli/commands/analytics/cost/claude-dispatch-allocation.d.ts.map +1 -0
  58. package/dist/cli/commands/analytics/cost/claude-dispatch-allocation.js +115 -0
  59. package/dist/cli/commands/analytics/cost/claude-dispatch-allocation.js.map +1 -0
  60. package/dist/cli/commands/analytics/cost/claude-lifecycle.d.ts +6 -0
  61. package/dist/cli/commands/analytics/cost/claude-lifecycle.d.ts.map +1 -0
  62. package/dist/cli/commands/analytics/cost/claude-lifecycle.js +107 -0
  63. package/dist/cli/commands/analytics/cost/claude-lifecycle.js.map +1 -0
  64. package/dist/cli/commands/analytics/cost/claude-native.d.ts +54 -0
  65. package/dist/cli/commands/analytics/cost/claude-native.d.ts.map +1 -0
  66. package/dist/cli/commands/analytics/cost/claude-native.js +14 -0
  67. package/dist/cli/commands/analytics/cost/claude-native.js.map +1 -0
  68. package/dist/cli/commands/analytics/cost/claude-ownership.d.ts +23 -0
  69. package/dist/cli/commands/analytics/cost/claude-ownership.d.ts.map +1 -0
  70. package/dist/cli/commands/analytics/cost/claude-ownership.js +99 -0
  71. package/dist/cli/commands/analytics/cost/claude-ownership.js.map +1 -0
  72. package/dist/cli/commands/analytics/cost/claude-trace.d.ts +28 -0
  73. package/dist/cli/commands/analytics/cost/claude-trace.d.ts.map +1 -0
  74. package/dist/cli/commands/analytics/cost/claude-trace.js +120 -0
  75. package/dist/cli/commands/analytics/cost/claude-trace.js.map +1 -0
  76. package/dist/cli/commands/analytics/cost/cost-enricher.d.ts +1 -1
  77. package/dist/cli/commands/analytics/cost/cost-enricher.d.ts.map +1 -1
  78. package/dist/cli/commands/analytics/cost/cost-enricher.js +34 -43
  79. package/dist/cli/commands/analytics/cost/cost-enricher.js.map +1 -1
  80. package/dist/cli/commands/analytics/cost/dispatch-allocation.d.ts +18 -0
  81. package/dist/cli/commands/analytics/cost/dispatch-allocation.d.ts.map +1 -0
  82. package/dist/cli/commands/analytics/cost/dispatch-allocation.js +53 -0
  83. package/dist/cli/commands/analytics/cost/dispatch-allocation.js.map +1 -0
  84. package/dist/cli/commands/analytics/cost/dispatch-extractor.d.ts +8 -13
  85. package/dist/cli/commands/analytics/cost/dispatch-extractor.d.ts.map +1 -1
  86. package/dist/cli/commands/analytics/cost/dispatch-extractor.js +131 -69
  87. package/dist/cli/commands/analytics/cost/dispatch-extractor.js.map +1 -1
  88. package/dist/cli/commands/analytics/cost/types.d.ts +39 -0
  89. package/dist/cli/commands/analytics/cost/types.d.ts.map +1 -1
  90. package/dist/cli/commands/analytics/cost/types.js.map +1 -1
  91. package/dist/cli/commands/analytics/cost/usage-readers.d.ts +2 -0
  92. package/dist/cli/commands/analytics/cost/usage-readers.d.ts.map +1 -1
  93. package/dist/cli/commands/analytics/cost/usage-readers.js +14 -3
  94. package/dist/cli/commands/analytics/cost/usage-readers.js.map +1 -1
  95. package/dist/cli/commands/analytics/data-loader.d.ts +13 -0
  96. package/dist/cli/commands/analytics/data-loader.d.ts.map +1 -1
  97. package/dist/cli/commands/analytics/data-loader.js +6 -0
  98. package/dist/cli/commands/analytics/data-loader.js.map +1 -1
  99. package/dist/cli/commands/analytics/native-loader.d.ts +1 -1
  100. package/dist/cli/commands/analytics/native-loader.d.ts.map +1 -1
  101. package/dist/cli/commands/analytics/native-loader.js +25 -3
  102. package/dist/cli/commands/analytics/native-loader.js.map +1 -1
  103. package/dist/cli/commands/analytics/otel-loader.d.ts.map +1 -1
  104. package/dist/cli/commands/analytics/otel-loader.js +5 -0
  105. package/dist/cli/commands/analytics/otel-loader.js.map +1 -1
  106. package/dist/cli/commands/analytics/report/client/app.js +302 -125
  107. package/dist/cli/commands/analytics/report/payload-builder.d.ts.map +1 -1
  108. package/dist/cli/commands/analytics/report/payload-builder.js +64 -13
  109. package/dist/cli/commands/analytics/report/payload-builder.js.map +1 -1
  110. package/dist/cli/commands/analytics/report/template.html +50 -2
  111. package/dist/cli/commands/analytics/report/types.d.ts +16 -0
  112. package/dist/cli/commands/analytics/report/types.d.ts.map +1 -1
  113. package/dist/cli/commands/assistants/constants.d.ts +4 -0
  114. package/dist/cli/commands/assistants/constants.d.ts.map +1 -1
  115. package/dist/cli/commands/assistants/constants.js +4 -0
  116. package/dist/cli/commands/assistants/constants.js.map +1 -1
  117. package/dist/cli/commands/assistants/setup/data.d.ts +1 -0
  118. package/dist/cli/commands/assistants/setup/data.d.ts.map +1 -1
  119. package/dist/cli/commands/assistants/setup/data.js +55 -10
  120. package/dist/cli/commands/assistants/setup/data.js.map +1 -1
  121. package/dist/cli/commands/assistants/setup/helpers.d.ts +1 -1
  122. package/dist/cli/commands/assistants/setup/helpers.d.ts.map +1 -1
  123. package/dist/cli/commands/assistants/setup/helpers.js +2 -5
  124. package/dist/cli/commands/assistants/setup/helpers.js.map +1 -1
  125. package/dist/cli/commands/assistants/setup/index.d.ts +12 -0
  126. package/dist/cli/commands/assistants/setup/index.d.ts.map +1 -1
  127. package/dist/cli/commands/assistants/setup/index.js +148 -20
  128. package/dist/cli/commands/assistants/setup/index.js.map +1 -1
  129. package/dist/cli/commands/doctor/checks/AgentsCheck.d.ts +6 -0
  130. package/dist/cli/commands/doctor/checks/AgentsCheck.d.ts.map +1 -1
  131. package/dist/cli/commands/doctor/checks/AgentsCheck.js +37 -33
  132. package/dist/cli/commands/doctor/checks/AgentsCheck.js.map +1 -1
  133. package/dist/cli/commands/doctor/index.d.ts.map +1 -1
  134. package/dist/cli/commands/doctor/index.js +11 -0
  135. package/dist/cli/commands/doctor/index.js.map +1 -1
  136. package/dist/cli/commands/hook.d.ts.map +1 -1
  137. package/dist/cli/commands/hook.js +72 -12
  138. package/dist/cli/commands/hook.js.map +1 -1
  139. package/dist/cli/commands/install.d.ts.map +1 -1
  140. package/dist/cli/commands/install.js +5 -9
  141. package/dist/cli/commands/install.js.map +1 -1
  142. package/dist/cli/commands/mcp/index.d.ts.map +1 -1
  143. package/dist/cli/commands/mcp/index.js +68 -17
  144. package/dist/cli/commands/mcp/index.js.map +1 -1
  145. package/dist/cli/commands/profile/display.d.ts +5 -1
  146. package/dist/cli/commands/profile/display.d.ts.map +1 -1
  147. package/dist/cli/commands/profile/display.js +5 -1
  148. package/dist/cli/commands/profile/display.js.map +1 -1
  149. package/dist/cli/commands/profile/index.d.ts.map +1 -1
  150. package/dist/cli/commands/profile/index.js +7 -4
  151. package/dist/cli/commands/profile/index.js.map +1 -1
  152. package/dist/cli/commands/proxy/connect-orchestrator.d.ts.map +1 -1
  153. package/dist/cli/commands/proxy/connect-orchestrator.js +3 -4
  154. package/dist/cli/commands/proxy/connect-orchestrator.js.map +1 -1
  155. package/dist/cli/commands/proxy/connectors/desktop.d.ts +15 -12
  156. package/dist/cli/commands/proxy/connectors/desktop.d.ts.map +1 -1
  157. package/dist/cli/commands/proxy/connectors/desktop.js +36 -38
  158. package/dist/cli/commands/proxy/connectors/desktop.js.map +1 -1
  159. package/dist/cli/commands/proxy/connectors/model-name-resolver.d.ts +19 -0
  160. package/dist/cli/commands/proxy/connectors/model-name-resolver.d.ts.map +1 -0
  161. package/dist/cli/commands/proxy/connectors/model-name-resolver.js +126 -0
  162. package/dist/cli/commands/proxy/connectors/model-name-resolver.js.map +1 -0
  163. package/dist/cli/commands/proxy/connectors/tenant-catalog.d.ts +11 -0
  164. package/dist/cli/commands/proxy/connectors/tenant-catalog.d.ts.map +1 -0
  165. package/dist/cli/commands/proxy/connectors/tenant-catalog.js +108 -0
  166. package/dist/cli/commands/proxy/connectors/tenant-catalog.js.map +1 -0
  167. package/dist/cli/commands/proxy/connectors/vscode-claude-code.d.ts.map +1 -1
  168. package/dist/cli/commands/proxy/connectors/vscode-claude-code.js +49 -19
  169. package/dist/cli/commands/proxy/connectors/vscode-claude-code.js.map +1 -1
  170. package/dist/cli/commands/proxy/connectors/vscode-models.d.ts +3 -3
  171. package/dist/cli/commands/proxy/connectors/vscode-models.d.ts.map +1 -1
  172. package/dist/cli/commands/proxy/connectors/vscode-models.js +28 -28
  173. package/dist/cli/commands/proxy/connectors/vscode-models.js.map +1 -1
  174. package/dist/cli/commands/proxy/connectors/vscode.d.ts +3 -2
  175. package/dist/cli/commands/proxy/connectors/vscode.d.ts.map +1 -1
  176. package/dist/cli/commands/proxy/connectors/vscode.js +78 -39
  177. package/dist/cli/commands/proxy/connectors/vscode.js.map +1 -1
  178. package/dist/cli/commands/setup.d.ts.map +1 -1
  179. package/dist/cli/commands/setup.js +72 -24
  180. package/dist/cli/commands/setup.js.map +1 -1
  181. package/dist/cli/commands/shared/headless.d.ts +69 -0
  182. package/dist/cli/commands/shared/headless.d.ts.map +1 -0
  183. package/dist/cli/commands/shared/headless.js +83 -0
  184. package/dist/cli/commands/shared/headless.js.map +1 -0
  185. package/dist/cli/commands/shared/helpers.d.ts +21 -0
  186. package/dist/cli/commands/shared/helpers.d.ts.map +1 -1
  187. package/dist/cli/commands/shared/helpers.js +73 -1
  188. package/dist/cli/commands/shared/helpers.js.map +1 -1
  189. package/dist/cli/commands/shared/identifier-resolution.d.ts +23 -0
  190. package/dist/cli/commands/shared/identifier-resolution.d.ts.map +1 -0
  191. package/dist/cli/commands/shared/identifier-resolution.js +55 -0
  192. package/dist/cli/commands/shared/identifier-resolution.js.map +1 -0
  193. package/dist/cli/commands/skills/setup/data.d.ts +3 -2
  194. package/dist/cli/commands/skills/setup/data.d.ts.map +1 -1
  195. package/dist/cli/commands/skills/setup/data.js +75 -13
  196. package/dist/cli/commands/skills/setup/data.js.map +1 -1
  197. package/dist/cli/commands/skills/setup/helpers.d.ts +1 -1
  198. package/dist/cli/commands/skills/setup/helpers.d.ts.map +1 -1
  199. package/dist/cli/commands/skills/setup/helpers.js +2 -5
  200. package/dist/cli/commands/skills/setup/helpers.js.map +1 -1
  201. package/dist/cli/commands/skills/setup/index.d.ts +17 -1
  202. package/dist/cli/commands/skills/setup/index.d.ts.map +1 -1
  203. package/dist/cli/commands/skills/setup/index.js +190 -19
  204. package/dist/cli/commands/skills/setup/index.js.map +1 -1
  205. package/dist/cli/commands/tips.d.ts +10 -0
  206. package/dist/cli/commands/tips.d.ts.map +1 -0
  207. package/dist/cli/commands/tips.js +142 -0
  208. package/dist/cli/commands/tips.js.map +1 -0
  209. package/dist/cli/commands/update.d.ts.map +1 -1
  210. package/dist/cli/commands/update.js +12 -10
  211. package/dist/cli/commands/update.js.map +1 -1
  212. package/dist/cli/commands/whatsnew.d.ts +6 -0
  213. package/dist/cli/commands/whatsnew.d.ts.map +1 -0
  214. package/dist/cli/commands/whatsnew.js +37 -0
  215. package/dist/cli/commands/whatsnew.js.map +1 -0
  216. package/dist/cli/first-time.d.ts.map +1 -1
  217. package/dist/cli/first-time.js +4 -0
  218. package/dist/cli/first-time.js.map +1 -1
  219. package/dist/cli/index.js +4 -0
  220. package/dist/cli/index.js.map +1 -1
  221. package/dist/providers/core/types.d.ts +15 -0
  222. package/dist/providers/core/types.d.ts.map +1 -1
  223. package/dist/providers/core/types.js.map +1 -1
  224. package/dist/providers/integration/setup-ui.d.ts +5 -3
  225. package/dist/providers/integration/setup-ui.d.ts.map +1 -1
  226. package/dist/providers/integration/setup-ui.js +6 -4
  227. package/dist/providers/integration/setup-ui.js.map +1 -1
  228. package/dist/providers/plugins/ollama/ollama.library.d.ts +37 -0
  229. package/dist/providers/plugins/ollama/ollama.library.d.ts.map +1 -0
  230. package/dist/providers/plugins/ollama/ollama.library.js +105 -0
  231. package/dist/providers/plugins/ollama/ollama.library.js.map +1 -0
  232. package/dist/providers/plugins/ollama/ollama.models.d.ts +3 -1
  233. package/dist/providers/plugins/ollama/ollama.models.d.ts.map +1 -1
  234. package/dist/providers/plugins/ollama/ollama.models.js +5 -39
  235. package/dist/providers/plugins/ollama/ollama.models.js.map +1 -1
  236. package/dist/providers/plugins/ollama/ollama.setup-steps.d.ts.map +1 -1
  237. package/dist/providers/plugins/ollama/ollama.setup-steps.js +196 -6
  238. package/dist/providers/plugins/ollama/ollama.setup-steps.js.map +1 -1
  239. package/dist/providers/plugins/ollama/ollama.template.d.ts.map +1 -1
  240. package/dist/providers/plugins/ollama/ollama.template.js +12 -32
  241. package/dist/providers/plugins/ollama/ollama.template.js.map +1 -1
  242. package/dist/providers/plugins/sso/proxy/plugins/claude-model-resolver.d.ts +41 -0
  243. package/dist/providers/plugins/sso/proxy/plugins/claude-model-resolver.d.ts.map +1 -0
  244. package/dist/providers/plugins/sso/proxy/plugins/claude-model-resolver.js +115 -0
  245. package/dist/providers/plugins/sso/proxy/plugins/claude-model-resolver.js.map +1 -0
  246. package/dist/providers/plugins/sso/proxy/plugins/claude-request-normalizer.plugin.d.ts.map +1 -1
  247. package/dist/providers/plugins/sso/proxy/plugins/claude-request-normalizer.plugin.js +101 -7
  248. package/dist/providers/plugins/sso/proxy/plugins/claude-request-normalizer.plugin.js.map +1 -1
  249. package/dist/providers/plugins/sso/proxy/plugins/header-injection.plugin.d.ts +4 -0
  250. package/dist/providers/plugins/sso/proxy/plugins/header-injection.plugin.d.ts.map +1 -1
  251. package/dist/providers/plugins/sso/proxy/plugins/header-injection.plugin.js +28 -3
  252. package/dist/providers/plugins/sso/proxy/plugins/header-injection.plugin.js.map +1 -1
  253. package/dist/providers/plugins/sso/proxy/proxy-types.d.ts +5 -0
  254. package/dist/providers/plugins/sso/proxy/proxy-types.d.ts.map +1 -1
  255. package/dist/providers/plugins/sso/proxy/sso.proxy.d.ts.map +1 -1
  256. package/dist/providers/plugins/sso/proxy/sso.proxy.js +1 -0
  257. package/dist/providers/plugins/sso/proxy/sso.proxy.js.map +1 -1
  258. package/dist/providers/plugins/sso/session/BaseProcessor.d.ts +4 -0
  259. package/dist/providers/plugins/sso/session/BaseProcessor.d.ts.map +1 -1
  260. package/dist/providers/plugins/sso/session/SessionSyncer.d.ts +12 -0
  261. package/dist/providers/plugins/sso/session/SessionSyncer.d.ts.map +1 -1
  262. package/dist/providers/plugins/sso/session/SessionSyncer.js +89 -0
  263. package/dist/providers/plugins/sso/session/SessionSyncer.js.map +1 -1
  264. package/dist/providers/plugins/sso/session/processors/conversations/syncProcessor.d.ts.map +1 -1
  265. package/dist/providers/plugins/sso/session/processors/conversations/syncProcessor.js +75 -41
  266. package/dist/providers/plugins/sso/session/processors/conversations/syncProcessor.js.map +1 -1
  267. package/dist/providers/plugins/sso/session/processors/metrics/metrics-aggregator.d.ts.map +1 -1
  268. package/dist/providers/plugins/sso/session/processors/metrics/metrics-aggregator.js +11 -2
  269. package/dist/providers/plugins/sso/session/processors/metrics/metrics-aggregator.js.map +1 -1
  270. package/dist/providers/plugins/sso/session/processors/metrics/metrics-sync-processor.d.ts.map +1 -1
  271. package/dist/providers/plugins/sso/session/processors/metrics/metrics-sync-processor.js +25 -5
  272. package/dist/providers/plugins/sso/session/processors/metrics/metrics-sync-processor.js.map +1 -1
  273. package/dist/telemetry/clients/claude-desktop/claude-desktop.discovery.d.ts +1 -0
  274. package/dist/telemetry/clients/claude-desktop/claude-desktop.discovery.d.ts.map +1 -1
  275. package/dist/telemetry/clients/claude-desktop/claude-desktop.discovery.js +30 -6
  276. package/dist/telemetry/clients/claude-desktop/claude-desktop.discovery.js.map +1 -1
  277. package/dist/telemetry/clients/claude-desktop/claude-desktop.parser.d.ts.map +1 -1
  278. package/dist/telemetry/clients/claude-desktop/claude-desktop.parser.js +33 -3
  279. package/dist/telemetry/clients/claude-desktop/claude-desktop.parser.js.map +1 -1
  280. package/dist/telemetry/runtime/DesktopRepositoryResolver.d.ts +58 -0
  281. package/dist/telemetry/runtime/DesktopRepositoryResolver.d.ts.map +1 -0
  282. package/dist/telemetry/runtime/DesktopRepositoryResolver.js +370 -0
  283. package/dist/telemetry/runtime/DesktopRepositoryResolver.js.map +1 -0
  284. package/dist/telemetry/runtime/DesktopTelemetryRuntime.d.ts +1 -0
  285. package/dist/telemetry/runtime/DesktopTelemetryRuntime.d.ts.map +1 -1
  286. package/dist/telemetry/runtime/DesktopTelemetryRuntime.js +89 -6
  287. package/dist/telemetry/runtime/DesktopTelemetryRuntime.js.map +1 -1
  288. package/dist/telemetry/runtime/types.d.ts +2 -0
  289. package/dist/telemetry/runtime/types.d.ts.map +1 -1
  290. package/dist/utils/auth.d.ts +13 -2
  291. package/dist/utils/auth.d.ts.map +1 -1
  292. package/dist/utils/auth.js +7 -3
  293. package/dist/utils/auth.js.map +1 -1
  294. package/dist/utils/cli-updater.d.ts.map +1 -1
  295. package/dist/utils/cli-updater.js +2 -8
  296. package/dist/utils/cli-updater.js.map +1 -1
  297. package/dist/utils/config.d.ts +21 -0
  298. package/dist/utils/config.d.ts.map +1 -1
  299. package/dist/utils/config.js +69 -7
  300. package/dist/utils/config.js.map +1 -1
  301. package/dist/utils/env.d.ts +12 -0
  302. package/dist/utils/env.d.ts.map +1 -0
  303. package/dist/utils/env.js +18 -0
  304. package/dist/utils/env.js.map +1 -0
  305. package/dist/utils/errors.d.ts +14 -0
  306. package/dist/utils/errors.d.ts.map +1 -1
  307. package/dist/utils/errors.js +25 -0
  308. package/dist/utils/errors.js.map +1 -1
  309. package/dist/utils/hook-command.d.ts +6 -0
  310. package/dist/utils/hook-command.d.ts.map +1 -1
  311. package/dist/utils/hook-command.js +40 -1
  312. package/dist/utils/hook-command.js.map +1 -1
  313. package/dist/utils/paths.d.ts +2 -2
  314. package/dist/utils/paths.d.ts.map +1 -1
  315. package/dist/utils/paths.js +11 -9
  316. package/dist/utils/paths.js.map +1 -1
  317. package/dist/utils/pricing.json +14 -6
  318. package/dist/utils/processes.d.ts +12 -0
  319. package/dist/utils/processes.d.ts.map +1 -1
  320. package/dist/utils/processes.js +15 -0
  321. package/dist/utils/processes.js.map +1 -1
  322. package/dist/utils/tips.d.ts +103 -0
  323. package/dist/utils/tips.d.ts.map +1 -0
  324. package/dist/utils/tips.js +221 -0
  325. package/dist/utils/tips.js.map +1 -0
  326. package/dist/utils/version-warnings.d.ts +41 -0
  327. package/dist/utils/version-warnings.d.ts.map +1 -0
  328. package/dist/utils/version-warnings.js +93 -0
  329. package/dist/utils/version-warnings.js.map +1 -0
  330. package/dist/utils/whatsnew.d.ts +83 -0
  331. package/dist/utils/whatsnew.d.ts.map +1 -0
  332. package/dist/utils/whatsnew.js +200 -0
  333. package/dist/utils/whatsnew.js.map +1 -0
  334. package/package.json +4 -1
  335. package/scripts/release.sh +6 -0
  336. package/src/utils/tips.json +806 -0
@@ -0,0 +1,221 @@
1
+ /**
2
+ * Feature Tips ("Did you know?") — selection, rotation and rendering logic.
3
+ *
4
+ * The curated catalog lives in src/utils/tips.json (pure data — edit tips
5
+ * there); this module loads it once at startup and exposes it as TIPS.
6
+ * Tips are shown at session start and end, browseable on demand via
7
+ * `codemie tips`, and sprinkled onto selected CLI surfaces (doctor, first-run
8
+ * screens) via renderTip().
9
+ *
10
+ * Catalog maintenance workflow (edit src/utils/tips.json):
11
+ * - Add a tip: append one `{ "id", "category", "message", "command"? }` object
12
+ * to the array. Use a fresh kebab-case id — ids are never reused, because
13
+ * the rotation state (~/.codemie/.tips-state.json) remembers them.
14
+ * - Retire a command: delete its tip in the same PR. If the tip is missed,
15
+ * `codemie tips` validates `command` references against the live CLI command
16
+ * tree and silently drops (plus debug-logs) tips pointing at retired
17
+ * commands — session rendering never validates and never breaks.
18
+ * - Reword a tip: edit `message` in place and keep `id` stable so the rotation
19
+ * history stays meaningful.
20
+ *
21
+ * This module must stay safe to import from the agent runtime, so it depends
22
+ * only on fs/path, chalk, the logger and the paths utility — never on
23
+ * commander or the CLI layer.
24
+ *
25
+ * Environment Variables:
26
+ * - CODEMIE_TIPS=true (default): show tips at session start/end
27
+ * - CODEMIE_TIPS=false|0|no: disable session tips (`codemie tips` still works)
28
+ */
29
+ import { readFileSync, writeFileSync, mkdirSync, renameSync } from 'fs';
30
+ import path from 'path';
31
+ import { fileURLToPath } from 'url';
32
+ import chalk from 'chalk';
33
+ import { logger } from './logger.js';
34
+ import { getCodemiePath } from './paths.js';
35
+ import { parseBooleanEnv } from './env.js';
36
+ const isStringArray = (value) => Array.isArray(value) && value.every(item => typeof item === 'string');
37
+ /**
38
+ * Load the tip catalog from src/utils/tips.json at the package root (resolved
39
+ * relative to this module, so it works from src/utils in dev and dist/utils in
40
+ * the installed package, where the JSON ships via the package.json files list).
41
+ *
42
+ * Best-effort: any failure — missing file, malformed JSON, wrong shape — is
43
+ * debug-logged and yields an empty catalog. Tips must never break a session.
44
+ */
45
+ function loadTipsCatalog() {
46
+ try {
47
+ // Resolve via import.meta.url, not paths.js: tests legitimately mock
48
+ // ./paths.js without declaring every export, and this module is loaded
49
+ // eagerly through BaseAgentAdapter — a mocked-out helper must never break
50
+ // module evaluation. Resolves identically from src/utils (dev) and
51
+ // dist/utils (built/installed package, where tips.json ships in src/utils).
52
+ const catalogPath = fileURLToPath(new URL('../../src/utils/tips.json', import.meta.url));
53
+ const parsed = JSON.parse(readFileSync(catalogPath, 'utf-8'));
54
+ if (!Array.isArray(parsed)) {
55
+ logger.debug('[tips] tips.json is not an array — using empty catalog', { catalogPath });
56
+ return [];
57
+ }
58
+ const tips = parsed
59
+ .filter((entry) => typeof entry === 'object' &&
60
+ entry !== null &&
61
+ typeof entry.id === 'string' &&
62
+ typeof entry.category === 'string' &&
63
+ typeof entry.message === 'string')
64
+ .map(entry => {
65
+ // Tolerate a malformed optional `commands` field by dropping just it
66
+ if (entry.commands !== undefined && !isStringArray(entry.commands)) {
67
+ logger.debug(`[tips] tips.json: ignoring malformed 'commands' on tip '${entry.id}'`);
68
+ return { ...entry, commands: undefined };
69
+ }
70
+ return entry;
71
+ });
72
+ if (tips.length !== parsed.length) {
73
+ logger.debug(`[tips] tips.json: dropped ${parsed.length - tips.length} malformed entrie(s)`, { catalogPath });
74
+ }
75
+ return tips;
76
+ }
77
+ catch (error) {
78
+ logger.debug('[tips] Failed to load tips.json — using empty catalog:', error);
79
+ return [];
80
+ }
81
+ }
82
+ /**
83
+ * Curated tip catalog, loaded eagerly from src/utils/tips.json. Every
84
+ * `command` value references a top-level command registered in
85
+ * src/cli/index.ts; `codemie tips` re-validates these at runtime.
86
+ */
87
+ export const TIPS = loadTipsCatalog();
88
+ const stateFilePath = () => getCodemiePath('.tips-state.json');
89
+ /**
90
+ * Check if session tips are enabled (default: true).
91
+ * Reads the CODEMIE_TIPS environment variable.
92
+ *
93
+ * @returns true unless CODEMIE_TIPS is set to a falsy value ('false', '0', 'no')
94
+ */
95
+ export function isTipsEnabled() {
96
+ return parseBooleanEnv(process.env.CODEMIE_TIPS, true);
97
+ }
98
+ /**
99
+ * Return the full tip catalog (used by `codemie tips`).
100
+ */
101
+ export function listTips() {
102
+ return TIPS;
103
+ }
104
+ /**
105
+ * Pick the tip to show at a session lifecycle point.
106
+ *
107
+ * Randomly selects a tip that has not been shown yet (per the rotation state
108
+ * file), records the pick, and resets the shown list once every tip has been
109
+ * shown. Both contexts share one catalog and one rotation for now; the context
110
+ * is recorded in the debug log so future per-context catalogs can reuse it.
111
+ *
112
+ * Best-effort: unreadable/corrupt state is treated as empty, write failures
113
+ * are swallowed — a tip must never block or break a session.
114
+ *
115
+ * @param context - Where the tip is rendered ('start' or 'end' of session)
116
+ * @returns A tip, or null when tips are disabled or the catalog is empty
117
+ */
118
+ export function getSessionTip(context) {
119
+ if (!isTipsEnabled() || TIPS.length === 0) {
120
+ return null;
121
+ }
122
+ const state = loadRotationState();
123
+ // Prune ids of retired tips so the rotation can still complete and reset.
124
+ const catalogIds = new Set(TIPS.map(tip => tip.id));
125
+ state.shownTipIds = state.shownTipIds.filter(id => catalogIds.has(id));
126
+ let candidates = TIPS.filter(tip => !state.shownTipIds.includes(tip.id));
127
+ if (candidates.length === 0) {
128
+ // Full rotation complete — start a fresh cycle.
129
+ state.shownTipIds = [];
130
+ candidates = [...TIPS];
131
+ }
132
+ const tip = candidates[Math.floor(Math.random() * candidates.length)];
133
+ state.shownTipIds.push(tip.id);
134
+ saveRotationState(state);
135
+ logger.debug('[tips] Selected session tip', { context, id: tip.id });
136
+ return tip;
137
+ }
138
+ /**
139
+ * Format a tip for terminal display: a gold ✨ prefix followed by the message
140
+ * in the same warm gold, bold. Yellow is the CLI's established accent color
141
+ * (matches the Kimi-style prompt echo) — deliberately no background bars or
142
+ * badge, just plain foreground styling.
143
+ * Shared by session lifecycle rendering (BaseAgentAdapter), renderTip(), and
144
+ * `codemie tips --random` so tips look identical everywhere.
145
+ */
146
+ export function formatTipLine(tip) {
147
+ return chalk.bold.yellow(`✨ ${tip.message}`);
148
+ }
149
+ /**
150
+ * Print a single random tip to the console for CLI surfaces (doctor,
151
+ * first-run and post-setup screens, ...). Unlike getSessionTip(), this does
152
+ * not read or update the rotation state — rotation stays exclusive to session
153
+ * start/end.
154
+ *
155
+ * Best-effort: never throws, and is a no-op when tips are disabled.
156
+ *
157
+ * @param options.category - Restrict the pick to one category; falls back to
158
+ * the full catalog when the category has no tips
159
+ */
160
+ export function renderTip(options) {
161
+ try {
162
+ if (!isTipsEnabled() || TIPS.length === 0) {
163
+ return;
164
+ }
165
+ let pool = TIPS;
166
+ if (options?.category) {
167
+ const filtered = TIPS.filter(tip => tip.category === options.category);
168
+ if (filtered.length > 0) {
169
+ pool = filtered;
170
+ }
171
+ }
172
+ const tip = pool[Math.floor(Math.random() * pool.length)];
173
+ console.log();
174
+ console.log(formatTipLine(tip));
175
+ }
176
+ catch (error) {
177
+ logger.debug('[tips] renderTip failed (non-fatal):', error);
178
+ }
179
+ }
180
+ function loadRotationState() {
181
+ const file = stateFilePath();
182
+ try {
183
+ const content = readFileSync(file, 'utf-8');
184
+ const parsed = JSON.parse(content);
185
+ if (typeof parsed === 'object' &&
186
+ parsed !== null &&
187
+ Array.isArray(parsed.shownTipIds)) {
188
+ const shownTipIds = parsed.shownTipIds
189
+ .filter((id) => typeof id === 'string');
190
+ return { shownTipIds };
191
+ }
192
+ return { shownTipIds: [] };
193
+ }
194
+ catch (error) {
195
+ const code = error.code;
196
+ if (code !== 'ENOENT') {
197
+ logger.debug('[tips] Rotation state unreadable — treating as empty', { file });
198
+ }
199
+ return { shownTipIds: [] };
200
+ }
201
+ }
202
+ /**
203
+ * Persist rotation state. The write goes through a same-directory temp file
204
+ * plus rename, so a concurrent reader never sees a truncated file (rename is
205
+ * atomic on POSIX and Windows for same-dir renames). Read-modify-write races
206
+ * between concurrent sessions remain theoretically possible — accepted as
207
+ * low-harm (worst case: a tip repeats); deliberately no locking.
208
+ */
209
+ function saveRotationState(state) {
210
+ const file = stateFilePath();
211
+ try {
212
+ mkdirSync(path.dirname(file), { recursive: true });
213
+ const tmpFile = `${file}.tmp`;
214
+ writeFileSync(tmpFile, JSON.stringify(state, null, 2), 'utf-8');
215
+ renameSync(tmpFile, file);
216
+ }
217
+ catch (error) {
218
+ logger.debug('[tips] Failed to persist rotation state (non-fatal):', error);
219
+ }
220
+ }
221
+ //# sourceMappingURL=tips.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tips.js","sourceRoot":"","sources":["../../src/utils/tips.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * VersionWarningStore
3
+ *
4
+ * Records one-time "untested version" markers at user scope.
5
+ * Backing file: `~/.codemie/version-warnings.json`.
6
+ *
7
+ * A marker is keyed by (agent, installed agent version) and additionally stores
8
+ * the `supportedVersion` baseline it was acknowledged against. The marker is
9
+ * honoured only while that baseline still matches: a CodeMie release that moves
10
+ * the recommended version forward invalidates old markers and buys exactly one
11
+ * re-notice, while CodeMie releases that leave the baseline alone never re-nag.
12
+ *
13
+ * See EPMCDME-13734.
14
+ */
15
+ export interface VersionWarningRecord {
16
+ agentName: string;
17
+ agentVersion: string;
18
+ /** Recommended version at the time the notice was acknowledged. */
19
+ supportedVersion: string;
20
+ /** CodeMie version that emitted the notice (context for `codemie doctor`). */
21
+ codemieVersion: string;
22
+ warnedAt: string;
23
+ }
24
+ export interface VersionWarningHistory {
25
+ version: 1;
26
+ warnings: VersionWarningRecord[];
27
+ }
28
+ export declare class VersionWarningStore {
29
+ static loadHistory(): Promise<VersionWarningHistory>;
30
+ static saveHistory(history: VersionWarningHistory): Promise<void>;
31
+ /**
32
+ * True when this agent version was already acknowledged against the same
33
+ * recommended baseline. A moved baseline makes the stored marker stale.
34
+ */
35
+ static hasWarned(agentName: string, agentVersion: string, supportedVersion: string): Promise<boolean>;
36
+ static recordWarning(agentName: string, agentVersion: string, supportedVersion: string, codemieVersion: string): Promise<void>;
37
+ static clear(): Promise<{
38
+ removed: number;
39
+ }>;
40
+ }
41
+ //# sourceMappingURL=version-warnings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version-warnings.d.ts","sourceRoot":"","sources":["../../src/utils/version-warnings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAOH,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,mEAAmE;IACnE,gBAAgB,EAAE,MAAM,CAAC;IACzB,8EAA8E;IAC9E,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,CAAC,CAAC;IACX,QAAQ,EAAE,oBAAoB,EAAE,CAAC;CAClC;AAMD,qBAAa,mBAAmB;WACjB,WAAW,IAAI,OAAO,CAAC,qBAAqB,CAAC;WA0B7C,WAAW,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC;IAMvE;;;OAGG;WACU,SAAS,CACpB,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,EACpB,gBAAgB,EAAE,MAAM,GACvB,OAAO,CAAC,OAAO,CAAC;WAUN,aAAa,CACxB,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,EACpB,gBAAgB,EAAE,MAAM,EACxB,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,IAAI,CAAC;WAeH,KAAK,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;CAkBnD"}
@@ -0,0 +1,93 @@
1
+ /**
2
+ * VersionWarningStore
3
+ *
4
+ * Records one-time "untested version" markers at user scope.
5
+ * Backing file: `~/.codemie/version-warnings.json`.
6
+ *
7
+ * A marker is keyed by (agent, installed agent version) and additionally stores
8
+ * the `supportedVersion` baseline it was acknowledged against. The marker is
9
+ * honoured only while that baseline still matches: a CodeMie release that moves
10
+ * the recommended version forward invalidates old markers and buys exactly one
11
+ * re-notice, while CodeMie releases that leave the baseline alone never re-nag.
12
+ *
13
+ * See EPMCDME-13734.
14
+ */
15
+ import * as fs from 'fs/promises';
16
+ import * as path from 'path';
17
+ import { logger } from './logger.js';
18
+ import { getCodemiePath } from './paths.js';
19
+ const filePath = () => getCodemiePath('version-warnings.json');
20
+ const emptyHistory = () => ({ version: 1, warnings: [] });
21
+ export class VersionWarningStore {
22
+ static async loadHistory() {
23
+ const file = filePath();
24
+ try {
25
+ const content = await fs.readFile(file, 'utf-8');
26
+ const parsed = JSON.parse(content);
27
+ if (typeof parsed === 'object' &&
28
+ parsed !== null &&
29
+ Array.isArray(parsed.warnings)) {
30
+ return {
31
+ version: 1,
32
+ warnings: parsed.warnings,
33
+ };
34
+ }
35
+ return emptyHistory();
36
+ }
37
+ catch (error) {
38
+ const code = error.code;
39
+ if (code === 'ENOENT') {
40
+ return emptyHistory();
41
+ }
42
+ logger.warn('[VersionWarningStore] Corrupt or unreadable file — treating as empty', { file });
43
+ return emptyHistory();
44
+ }
45
+ }
46
+ static async saveHistory(history) {
47
+ const file = filePath();
48
+ await fs.mkdir(path.dirname(file), { recursive: true });
49
+ await fs.writeFile(file, JSON.stringify(history, null, 2), 'utf-8');
50
+ }
51
+ /**
52
+ * True when this agent version was already acknowledged against the same
53
+ * recommended baseline. A moved baseline makes the stored marker stale.
54
+ */
55
+ static async hasWarned(agentName, agentVersion, supportedVersion) {
56
+ const history = await this.loadHistory();
57
+ return history.warnings.some((warning) => warning.agentName === agentName &&
58
+ warning.agentVersion === agentVersion &&
59
+ warning.supportedVersion === supportedVersion);
60
+ }
61
+ static async recordWarning(agentName, agentVersion, supportedVersion, codemieVersion) {
62
+ const history = await this.loadHistory();
63
+ const others = history.warnings.filter((warning) => !(warning.agentName === agentName && warning.agentVersion === agentVersion));
64
+ others.push({
65
+ agentName,
66
+ agentVersion,
67
+ supportedVersion,
68
+ codemieVersion,
69
+ warnedAt: new Date().toISOString(),
70
+ });
71
+ await this.saveHistory({ version: 1, warnings: others });
72
+ }
73
+ static async clear() {
74
+ const file = filePath();
75
+ const history = await this.loadHistory();
76
+ const removed = history.warnings.length;
77
+ try {
78
+ await fs.unlink(file);
79
+ return { removed };
80
+ }
81
+ catch (error) {
82
+ const code = error.code;
83
+ if (code === 'ENOENT') {
84
+ return { removed: 0 };
85
+ }
86
+ // The user ran the reset intentionally — failing `codemie doctor` here
87
+ // would be worse than reporting "0 removed" and continuing the checks.
88
+ logger.warn('[VersionWarningStore] clear() failed; markers left in place', { file, code });
89
+ return { removed: 0 };
90
+ }
91
+ }
92
+ }
93
+ //# sourceMappingURL=version-warnings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version-warnings.js","sourceRoot":"","sources":["../../src/utils/version-warnings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAiB5C,MAAM,QAAQ,GAAG,GAAW,EAAE,CAAC,cAAc,CAAC,uBAAuB,CAAC,CAAC;AAEvE,MAAM,YAAY,GAAG,GAA0B,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;AAEjF,MAAM,OAAO,mBAAmB;IAC9B,MAAM,CAAC,KAAK,CAAC,WAAW;QACtB,MAAM,IAAI,GAAG,QAAQ,EAAE,CAAC;QACxB,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YACjD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAY,CAAC;YAC9C,IACE,OAAO,MAAM,KAAK,QAAQ;gBAC1B,MAAM,KAAK,IAAI;gBACf,KAAK,CAAC,OAAO,CAAE,MAAiC,CAAC,QAAQ,CAAC,EAC1D,CAAC;gBACD,OAAO;oBACL,OAAO,EAAE,CAAC;oBACV,QAAQ,EAAG,MAA+C,CAAC,QAAQ;iBACpE,CAAC;YACJ,CAAC;YACD,OAAO,YAAY,EAAE,CAAC;QACxB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,GAAI,KAA+B,CAAC,IAAI,CAAC;YACnD,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACtB,OAAO,YAAY,EAAE,CAAC;YACxB,CAAC;YACD,MAAM,CAAC,IAAI,CAAC,sEAAsE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;YAC9F,OAAO,YAAY,EAAE,CAAC;QACxB,CAAC;IACH,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,OAA8B;QACrD,MAAM,IAAI,GAAG,QAAQ,EAAE,CAAC;QACxB,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACxD,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;IACtE,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,KAAK,CAAC,SAAS,CACpB,SAAiB,EACjB,YAAoB,EACpB,gBAAwB;QAExB,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;QACzC,OAAO,OAAO,CAAC,QAAQ,CAAC,IAAI,CAC1B,CAAC,OAAO,EAAE,EAAE,CACV,OAAO,CAAC,SAAS,KAAK,SAAS;YAC/B,OAAO,CAAC,YAAY,KAAK,YAAY;YACrC,OAAO,CAAC,gBAAgB,KAAK,gBAAgB,CAChD,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,aAAa,CACxB,SAAiB,EACjB,YAAoB,EACpB,gBAAwB,EACxB,cAAsB;QAEtB,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;QACzC,MAAM,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,MAAM,CACpC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,KAAK,SAAS,IAAI,OAAO,CAAC,YAAY,KAAK,YAAY,CAAC,CACzF,CAAC;QACF,MAAM,CAAC,IAAI,CAAC;YACV,SAAS;YACT,YAAY;YACZ,gBAAgB;YAChB,cAAc;YACd,QAAQ,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACnC,CAAC,CAAC;QACH,MAAM,IAAI,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;IAC3D,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,KAAK;QAChB,MAAM,IAAI,GAAG,QAAQ,EAAE,CAAC;QACxB,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;QACzC,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;QACxC,IAAI,CAAC;YACH,MAAM,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YACtB,OAAO,EAAE,OAAO,EAAE,CAAC;QACrB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,GAAI,KAA+B,CAAC,IAAI,CAAC;YACnD,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACtB,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;YACxB,CAAC;YACD,uEAAuE;YACvE,uEAAuE;YACvE,MAAM,CAAC,IAAI,CAAC,6DAA6D,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YAC3F,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;QACxB,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * What's New — release notes from CHANGELOG.md
3
+ *
4
+ * CHANGELOG.md (Keep a Changelog format) is the curated source of truth for
5
+ * release notes. It ships inside the npm package and is consumed by:
6
+ * - `codemie whatsnew` — browse notes for the current, one, or all versions
7
+ * - the once-per-upgrade startup notice in bin/codemie.js, which shows the
8
+ * current version's notes once and records a `.last-seen-version` marker
9
+ * under the CodeMie home directory
10
+ *
11
+ * This module must stay safe to import from the bin entry point, so its
12
+ * dependencies are limited to fs/path/chalk plus the logger, paths, and tips
13
+ * utilities — never commander or the CLI layer.
14
+ *
15
+ * Environment Variables:
16
+ * - CODEMIE_TIPS=false|0|no: also suppresses the upgrade notice. The "reduce
17
+ * chatter" switch is shared with feature tips on purpose — see tips.ts.
18
+ */
19
+ /**
20
+ * One `### Section` block inside a release entry.
21
+ */
22
+ export interface ReleaseSection {
23
+ title: string;
24
+ items: string[];
25
+ }
26
+ /**
27
+ * One `## [version]` release entry from the changelog.
28
+ */
29
+ export interface ReleaseEntry {
30
+ version: string;
31
+ date?: string;
32
+ sections: ReleaseSection[];
33
+ }
34
+ /**
35
+ * Tolerant Keep-a-Changelog parser. Recognizes `## [x.y.z] - date` headings,
36
+ * `### Section` subheadings, and `- item` bullets; everything else is skipped.
37
+ */
38
+ export declare function parseChangelog(content: string): ReleaseEntry[];
39
+ /**
40
+ * Locate CHANGELOG.md at the package root. Works both from src/utils (dev
41
+ * repo) and dist/utils (built/installed package) — the root is two levels up
42
+ * in both layouts.
43
+ *
44
+ * @returns Absolute path to CHANGELOG.md, or null when it is not shipped
45
+ */
46
+ export declare function getChangelogPath(): string | null;
47
+ /**
48
+ * Read release notes from the changelog.
49
+ *
50
+ * @param version - When given, the entry for this exact version; if there is
51
+ * no matching heading, falls back to the newest versioned entry (or
52
+ * Unreleased when that is all there is) so the once-per-upgrade notice
53
+ * always has something to show
54
+ * @returns Parsed entries (newest first, as written), or an empty array when
55
+ * the changelog is missing or unparseable
56
+ */
57
+ export declare function getReleaseNotes(version?: string): ReleaseEntry[];
58
+ /**
59
+ * Version for which the upgrade notice was last shown, or null if never.
60
+ * Best-effort: an unreadable marker is treated as "never seen".
61
+ */
62
+ export declare function getLastSeenVersion(): string | null;
63
+ /**
64
+ * Record that the upgrade notice was shown for a version. Best-effort: write
65
+ * failures are swallowed — worst case the notice shows once more.
66
+ */
67
+ export declare function markVersionSeen(version: string): void;
68
+ /**
69
+ * Render release notes to the console. Never throws.
70
+ *
71
+ * @param options.maxItems - Cap on the total number of bullets printed across
72
+ * all entries; when truncated, a pointer to `codemie whatsnew` is appended
73
+ */
74
+ export declare function renderReleaseNotes(entries: ReleaseEntry[], options?: {
75
+ maxItems?: number;
76
+ }): void;
77
+ /**
78
+ * Whether the once-per-upgrade notice may print. Deliberately shares the
79
+ * CODEMIE_TIPS switch with feature tips — one "reduce chatter" toggle for all
80
+ * informational CLI output.
81
+ */
82
+ export declare function isWhatsNewEnabled(): boolean;
83
+ //# sourceMappingURL=whatsnew.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"whatsnew.d.ts","sourceRoot":"","sources":["../../src/utils/whatsnew.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AASH;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,cAAc,EAAE,CAAC;CAC5B;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,EAAE,CAoC9D;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,GAAG,IAAI,CAGhD;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,YAAY,EAAE,CAkChE;AAID;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,GAAG,IAAI,CAMlD;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAQrD;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,YAAY,EAAE,EAAE,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAgDjG;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAE3C"}
@@ -0,0 +1,200 @@
1
+ /**
2
+ * What's New — release notes from CHANGELOG.md
3
+ *
4
+ * CHANGELOG.md (Keep a Changelog format) is the curated source of truth for
5
+ * release notes. It ships inside the npm package and is consumed by:
6
+ * - `codemie whatsnew` — browse notes for the current, one, or all versions
7
+ * - the once-per-upgrade startup notice in bin/codemie.js, which shows the
8
+ * current version's notes once and records a `.last-seen-version` marker
9
+ * under the CodeMie home directory
10
+ *
11
+ * This module must stay safe to import from the bin entry point, so its
12
+ * dependencies are limited to fs/path/chalk plus the logger, paths, and tips
13
+ * utilities — never commander or the CLI layer.
14
+ *
15
+ * Environment Variables:
16
+ * - CODEMIE_TIPS=false|0|no: also suppresses the upgrade notice. The "reduce
17
+ * chatter" switch is shared with feature tips on purpose — see tips.ts.
18
+ */
19
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
20
+ import path from 'path';
21
+ import chalk from 'chalk';
22
+ import { logger } from './logger.js';
23
+ import { getCodemiePath, getDirname } from './paths.js';
24
+ import { isTipsEnabled } from './tips.js';
25
+ /**
26
+ * Tolerant Keep-a-Changelog parser. Recognizes `## [x.y.z] - date` headings,
27
+ * `### Section` subheadings, and `- item` bullets; everything else is skipped.
28
+ */
29
+ export function parseChangelog(content) {
30
+ const entries = [];
31
+ let currentEntry = null;
32
+ let currentSection = null;
33
+ for (const line of content.split(/\r?\n/)) {
34
+ const versionMatch = line.match(/^##\s+\[([^\]]+)\](?:\s*-\s*(.+?))?\s*$/);
35
+ if (versionMatch) {
36
+ currentEntry = {
37
+ version: versionMatch[1].trim(),
38
+ date: versionMatch[2]?.trim(),
39
+ sections: []
40
+ };
41
+ entries.push(currentEntry);
42
+ currentSection = null;
43
+ continue;
44
+ }
45
+ if (!currentEntry) {
46
+ continue;
47
+ }
48
+ const sectionMatch = line.match(/^###\s+(.+?)\s*$/);
49
+ if (sectionMatch) {
50
+ currentSection = { title: sectionMatch[1].trim(), items: [] };
51
+ currentEntry.sections.push(currentSection);
52
+ continue;
53
+ }
54
+ const itemMatch = line.match(/^\s*[-*]\s+(.+?)\s*$/);
55
+ if (itemMatch && currentSection) {
56
+ currentSection.items.push(itemMatch[1].trim());
57
+ }
58
+ }
59
+ return entries;
60
+ }
61
+ /**
62
+ * Locate CHANGELOG.md at the package root. Works both from src/utils (dev
63
+ * repo) and dist/utils (built/installed package) — the root is two levels up
64
+ * in both layouts.
65
+ *
66
+ * @returns Absolute path to CHANGELOG.md, or null when it is not shipped
67
+ */
68
+ export function getChangelogPath() {
69
+ const changelogPath = path.resolve(getDirname(import.meta.url), '../../CHANGELOG.md');
70
+ return existsSync(changelogPath) ? changelogPath : null;
71
+ }
72
+ /**
73
+ * Read release notes from the changelog.
74
+ *
75
+ * @param version - When given, the entry for this exact version; if there is
76
+ * no matching heading, falls back to the newest versioned entry (or
77
+ * Unreleased when that is all there is) so the once-per-upgrade notice
78
+ * always has something to show
79
+ * @returns Parsed entries (newest first, as written), or an empty array when
80
+ * the changelog is missing or unparseable
81
+ */
82
+ export function getReleaseNotes(version) {
83
+ const changelogPath = getChangelogPath();
84
+ if (!changelogPath) {
85
+ logger.debug('[whatsnew] CHANGELOG.md not found at package root');
86
+ return [];
87
+ }
88
+ try {
89
+ const entries = parseChangelog(readFileSync(changelogPath, 'utf-8'));
90
+ if (entries.length === 0) {
91
+ logger.debug('[whatsnew] CHANGELOG.md parsed to zero release entries', { changelogPath });
92
+ }
93
+ if (!version) {
94
+ return entries;
95
+ }
96
+ const exact = entries.filter(entry => entry.version === version);
97
+ if (exact.length > 0) {
98
+ return exact;
99
+ }
100
+ // No heading for this exact version (changelog not updated for the
101
+ // release) — fall back to the newest versioned entry so the once-per-
102
+ // upgrade notice still shows something before the version is marked seen.
103
+ const fallback = entries.find(entry => entry.version !== 'Unreleased') ?? entries[0];
104
+ if (fallback) {
105
+ logger.debug(`[whatsnew] No changelog entry for ${version} — falling back to ${fallback.version}`);
106
+ return [fallback];
107
+ }
108
+ return [];
109
+ }
110
+ catch (error) {
111
+ logger.debug('[whatsnew] Failed to read changelog:', error);
112
+ return [];
113
+ }
114
+ }
115
+ const lastSeenFilePath = () => getCodemiePath('.last-seen-version');
116
+ /**
117
+ * Version for which the upgrade notice was last shown, or null if never.
118
+ * Best-effort: an unreadable marker is treated as "never seen".
119
+ */
120
+ export function getLastSeenVersion() {
121
+ try {
122
+ return readFileSync(lastSeenFilePath(), 'utf-8').trim() || null;
123
+ }
124
+ catch {
125
+ return null;
126
+ }
127
+ }
128
+ /**
129
+ * Record that the upgrade notice was shown for a version. Best-effort: write
130
+ * failures are swallowed — worst case the notice shows once more.
131
+ */
132
+ export function markVersionSeen(version) {
133
+ try {
134
+ const file = lastSeenFilePath();
135
+ mkdirSync(path.dirname(file), { recursive: true });
136
+ writeFileSync(file, version, 'utf-8');
137
+ }
138
+ catch (error) {
139
+ logger.debug('[whatsnew] Failed to persist last-seen version (non-fatal):', error);
140
+ }
141
+ }
142
+ /**
143
+ * Render release notes to the console. Never throws.
144
+ *
145
+ * @param options.maxItems - Cap on the total number of bullets printed across
146
+ * all entries; when truncated, a pointer to `codemie whatsnew` is appended
147
+ */
148
+ export function renderReleaseNotes(entries, options) {
149
+ try {
150
+ if (entries.length === 0) {
151
+ return;
152
+ }
153
+ let remaining = options?.maxItems ?? Number.POSITIVE_INFINITY;
154
+ let truncated = false;
155
+ console.log();
156
+ for (const entry of entries) {
157
+ if (remaining <= 0) {
158
+ truncated = true;
159
+ break;
160
+ }
161
+ const dateSuffix = entry.date ? ` (${entry.date})` : '';
162
+ console.log(chalk.bold.cyan(`## What's new in ${entry.version}${dateSuffix}`));
163
+ for (const section of entry.sections) {
164
+ if (remaining <= 0) {
165
+ truncated = true;
166
+ break;
167
+ }
168
+ if (section.items.length === 0) {
169
+ continue;
170
+ }
171
+ console.log(chalk.dim(` ${section.title}`));
172
+ for (const item of section.items) {
173
+ if (remaining <= 0) {
174
+ truncated = true;
175
+ break;
176
+ }
177
+ console.log(` • ${item}`);
178
+ remaining--;
179
+ }
180
+ }
181
+ console.log();
182
+ }
183
+ if (truncated) {
184
+ console.log(chalk.dim(' … run `codemie whatsnew` for the full notes'));
185
+ console.log();
186
+ }
187
+ }
188
+ catch (error) {
189
+ logger.debug('[whatsnew] renderReleaseNotes failed (non-fatal):', error);
190
+ }
191
+ }
192
+ /**
193
+ * Whether the once-per-upgrade notice may print. Deliberately shares the
194
+ * CODEMIE_TIPS switch with feature tips — one "reduce chatter" toggle for all
195
+ * informational CLI output.
196
+ */
197
+ export function isWhatsNewEnabled() {
198
+ return isTipsEnabled();
199
+ }
200
+ //# sourceMappingURL=whatsnew.js.map