@codemieai/code 0.15.1 → 0.15.2

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 (202) 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.map +1 -1
  26. package/dist/agents/plugins/claude/claude.session.js +27 -1
  27. package/dist/agents/plugins/claude/claude.session.js.map +1 -1
  28. package/dist/agents/plugins/claude/plugin/.claude-plugin/plugin.json +1 -1
  29. package/dist/agents/plugins/claude/plugin/hooks/hooks.json +7 -7
  30. package/dist/agents/plugins/codex/codex.plugin.d.ts.map +1 -1
  31. package/dist/agents/plugins/codex/codex.plugin.js +7 -6
  32. package/dist/agents/plugins/codex/codex.plugin.js.map +1 -1
  33. package/dist/agents/plugins/copilot-cli/copilot-cli.plugin.d.ts.map +1 -1
  34. package/dist/agents/plugins/copilot-cli/copilot-cli.plugin.js +5 -2
  35. package/dist/agents/plugins/copilot-cli/copilot-cli.plugin.js.map +1 -1
  36. package/dist/agents/plugins/gemini/extension/gemini-extension.json +1 -1
  37. package/dist/agents/plugins/gemini/extension/hooks/hooks.json +7 -7
  38. package/dist/agents/plugins/gemini/gemini.plugin.d.ts.map +1 -1
  39. package/dist/agents/plugins/gemini/gemini.plugin.js +7 -6
  40. package/dist/agents/plugins/gemini/gemini.plugin.js.map +1 -1
  41. package/dist/agents/plugins/kimi/kimi.hook-config-injector.d.ts.map +1 -1
  42. package/dist/agents/plugins/kimi/kimi.hook-config-injector.js +26 -5
  43. package/dist/agents/plugins/kimi/kimi.hook-config-injector.js.map +1 -1
  44. package/dist/agents/plugins/kimi/kimi.plugin.d.ts.map +1 -1
  45. package/dist/agents/plugins/kimi/kimi.plugin.js +5 -2
  46. package/dist/agents/plugins/kimi/kimi.plugin.js.map +1 -1
  47. package/dist/cli/commands/analytics/cost/claude-dispatch-allocation.d.ts +6 -0
  48. package/dist/cli/commands/analytics/cost/claude-dispatch-allocation.d.ts.map +1 -0
  49. package/dist/cli/commands/analytics/cost/claude-dispatch-allocation.js +115 -0
  50. package/dist/cli/commands/analytics/cost/claude-dispatch-allocation.js.map +1 -0
  51. package/dist/cli/commands/analytics/cost/claude-lifecycle.d.ts +6 -0
  52. package/dist/cli/commands/analytics/cost/claude-lifecycle.d.ts.map +1 -0
  53. package/dist/cli/commands/analytics/cost/claude-lifecycle.js +107 -0
  54. package/dist/cli/commands/analytics/cost/claude-lifecycle.js.map +1 -0
  55. package/dist/cli/commands/analytics/cost/claude-native.d.ts +54 -0
  56. package/dist/cli/commands/analytics/cost/claude-native.d.ts.map +1 -0
  57. package/dist/cli/commands/analytics/cost/claude-native.js +14 -0
  58. package/dist/cli/commands/analytics/cost/claude-native.js.map +1 -0
  59. package/dist/cli/commands/analytics/cost/claude-ownership.d.ts +23 -0
  60. package/dist/cli/commands/analytics/cost/claude-ownership.d.ts.map +1 -0
  61. package/dist/cli/commands/analytics/cost/claude-ownership.js +99 -0
  62. package/dist/cli/commands/analytics/cost/claude-ownership.js.map +1 -0
  63. package/dist/cli/commands/analytics/cost/claude-trace.d.ts +28 -0
  64. package/dist/cli/commands/analytics/cost/claude-trace.d.ts.map +1 -0
  65. package/dist/cli/commands/analytics/cost/claude-trace.js +120 -0
  66. package/dist/cli/commands/analytics/cost/claude-trace.js.map +1 -0
  67. package/dist/cli/commands/analytics/cost/cost-enricher.d.ts +1 -1
  68. package/dist/cli/commands/analytics/cost/cost-enricher.d.ts.map +1 -1
  69. package/dist/cli/commands/analytics/cost/cost-enricher.js +34 -43
  70. package/dist/cli/commands/analytics/cost/cost-enricher.js.map +1 -1
  71. package/dist/cli/commands/analytics/cost/dispatch-allocation.d.ts +18 -0
  72. package/dist/cli/commands/analytics/cost/dispatch-allocation.d.ts.map +1 -0
  73. package/dist/cli/commands/analytics/cost/dispatch-allocation.js +53 -0
  74. package/dist/cli/commands/analytics/cost/dispatch-allocation.js.map +1 -0
  75. package/dist/cli/commands/analytics/cost/dispatch-extractor.d.ts +8 -13
  76. package/dist/cli/commands/analytics/cost/dispatch-extractor.d.ts.map +1 -1
  77. package/dist/cli/commands/analytics/cost/dispatch-extractor.js +131 -69
  78. package/dist/cli/commands/analytics/cost/dispatch-extractor.js.map +1 -1
  79. package/dist/cli/commands/analytics/cost/types.d.ts +39 -0
  80. package/dist/cli/commands/analytics/cost/types.d.ts.map +1 -1
  81. package/dist/cli/commands/analytics/cost/types.js.map +1 -1
  82. package/dist/cli/commands/analytics/cost/usage-readers.d.ts +2 -0
  83. package/dist/cli/commands/analytics/cost/usage-readers.d.ts.map +1 -1
  84. package/dist/cli/commands/analytics/cost/usage-readers.js +14 -3
  85. package/dist/cli/commands/analytics/cost/usage-readers.js.map +1 -1
  86. package/dist/cli/commands/analytics/data-loader.d.ts +13 -0
  87. package/dist/cli/commands/analytics/data-loader.d.ts.map +1 -1
  88. package/dist/cli/commands/analytics/data-loader.js +6 -0
  89. package/dist/cli/commands/analytics/data-loader.js.map +1 -1
  90. package/dist/cli/commands/analytics/native-loader.d.ts +1 -1
  91. package/dist/cli/commands/analytics/native-loader.d.ts.map +1 -1
  92. package/dist/cli/commands/analytics/native-loader.js +25 -3
  93. package/dist/cli/commands/analytics/native-loader.js.map +1 -1
  94. package/dist/cli/commands/analytics/otel-loader.d.ts.map +1 -1
  95. package/dist/cli/commands/analytics/otel-loader.js +5 -0
  96. package/dist/cli/commands/analytics/otel-loader.js.map +1 -1
  97. package/dist/cli/commands/analytics/report/client/app.js +302 -125
  98. package/dist/cli/commands/analytics/report/payload-builder.d.ts.map +1 -1
  99. package/dist/cli/commands/analytics/report/payload-builder.js +64 -13
  100. package/dist/cli/commands/analytics/report/payload-builder.js.map +1 -1
  101. package/dist/cli/commands/analytics/report/template.html +50 -2
  102. package/dist/cli/commands/analytics/report/types.d.ts +16 -0
  103. package/dist/cli/commands/analytics/report/types.d.ts.map +1 -1
  104. package/dist/cli/commands/doctor/checks/AgentsCheck.d.ts +6 -0
  105. package/dist/cli/commands/doctor/checks/AgentsCheck.d.ts.map +1 -1
  106. package/dist/cli/commands/doctor/checks/AgentsCheck.js +37 -33
  107. package/dist/cli/commands/doctor/checks/AgentsCheck.js.map +1 -1
  108. package/dist/cli/commands/doctor/index.d.ts.map +1 -1
  109. package/dist/cli/commands/doctor/index.js +11 -0
  110. package/dist/cli/commands/doctor/index.js.map +1 -1
  111. package/dist/cli/commands/hook.d.ts.map +1 -1
  112. package/dist/cli/commands/hook.js +72 -12
  113. package/dist/cli/commands/hook.js.map +1 -1
  114. package/dist/cli/commands/install.d.ts.map +1 -1
  115. package/dist/cli/commands/install.js +5 -9
  116. package/dist/cli/commands/install.js.map +1 -1
  117. package/dist/cli/commands/mcp/index.d.ts.map +1 -1
  118. package/dist/cli/commands/mcp/index.js +68 -17
  119. package/dist/cli/commands/mcp/index.js.map +1 -1
  120. package/dist/cli/commands/proxy/connectors/desktop.d.ts +13 -9
  121. package/dist/cli/commands/proxy/connectors/desktop.d.ts.map +1 -1
  122. package/dist/cli/commands/proxy/connectors/desktop.js +27 -13
  123. package/dist/cli/commands/proxy/connectors/desktop.js.map +1 -1
  124. package/dist/cli/commands/setup.d.ts.map +1 -1
  125. package/dist/cli/commands/setup.js +72 -24
  126. package/dist/cli/commands/setup.js.map +1 -1
  127. package/dist/cli/commands/tips.d.ts +10 -0
  128. package/dist/cli/commands/tips.d.ts.map +1 -0
  129. package/dist/cli/commands/tips.js +142 -0
  130. package/dist/cli/commands/tips.js.map +1 -0
  131. package/dist/cli/commands/update.d.ts.map +1 -1
  132. package/dist/cli/commands/update.js +12 -10
  133. package/dist/cli/commands/update.js.map +1 -1
  134. package/dist/cli/commands/whatsnew.d.ts +6 -0
  135. package/dist/cli/commands/whatsnew.d.ts.map +1 -0
  136. package/dist/cli/commands/whatsnew.js +37 -0
  137. package/dist/cli/commands/whatsnew.js.map +1 -0
  138. package/dist/cli/first-time.d.ts.map +1 -1
  139. package/dist/cli/first-time.js +4 -0
  140. package/dist/cli/first-time.js.map +1 -1
  141. package/dist/cli/index.js +4 -0
  142. package/dist/cli/index.js.map +1 -1
  143. package/dist/providers/core/types.d.ts +15 -0
  144. package/dist/providers/core/types.d.ts.map +1 -1
  145. package/dist/providers/core/types.js.map +1 -1
  146. package/dist/providers/integration/setup-ui.d.ts +5 -3
  147. package/dist/providers/integration/setup-ui.d.ts.map +1 -1
  148. package/dist/providers/integration/setup-ui.js +6 -4
  149. package/dist/providers/integration/setup-ui.js.map +1 -1
  150. package/dist/providers/plugins/ollama/ollama.library.d.ts +37 -0
  151. package/dist/providers/plugins/ollama/ollama.library.d.ts.map +1 -0
  152. package/dist/providers/plugins/ollama/ollama.library.js +105 -0
  153. package/dist/providers/plugins/ollama/ollama.library.js.map +1 -0
  154. package/dist/providers/plugins/ollama/ollama.models.d.ts +3 -1
  155. package/dist/providers/plugins/ollama/ollama.models.d.ts.map +1 -1
  156. package/dist/providers/plugins/ollama/ollama.models.js +5 -39
  157. package/dist/providers/plugins/ollama/ollama.models.js.map +1 -1
  158. package/dist/providers/plugins/ollama/ollama.setup-steps.d.ts.map +1 -1
  159. package/dist/providers/plugins/ollama/ollama.setup-steps.js +196 -6
  160. package/dist/providers/plugins/ollama/ollama.setup-steps.js.map +1 -1
  161. package/dist/providers/plugins/ollama/ollama.template.d.ts.map +1 -1
  162. package/dist/providers/plugins/ollama/ollama.template.js +12 -32
  163. package/dist/providers/plugins/ollama/ollama.template.js.map +1 -1
  164. package/dist/providers/plugins/sso/session/BaseProcessor.d.ts +4 -0
  165. package/dist/providers/plugins/sso/session/BaseProcessor.d.ts.map +1 -1
  166. package/dist/providers/plugins/sso/session/SessionSyncer.d.ts +12 -0
  167. package/dist/providers/plugins/sso/session/SessionSyncer.d.ts.map +1 -1
  168. package/dist/providers/plugins/sso/session/SessionSyncer.js +89 -0
  169. package/dist/providers/plugins/sso/session/SessionSyncer.js.map +1 -1
  170. package/dist/providers/plugins/sso/session/processors/conversations/syncProcessor.d.ts.map +1 -1
  171. package/dist/providers/plugins/sso/session/processors/conversations/syncProcessor.js +75 -41
  172. package/dist/providers/plugins/sso/session/processors/conversations/syncProcessor.js.map +1 -1
  173. package/dist/providers/plugins/sso/session/processors/metrics/metrics-sync-processor.d.ts.map +1 -1
  174. package/dist/providers/plugins/sso/session/processors/metrics/metrics-sync-processor.js +23 -4
  175. package/dist/providers/plugins/sso/session/processors/metrics/metrics-sync-processor.js.map +1 -1
  176. package/dist/utils/cli-updater.d.ts.map +1 -1
  177. package/dist/utils/cli-updater.js +2 -8
  178. package/dist/utils/cli-updater.js.map +1 -1
  179. package/dist/utils/env.d.ts +12 -0
  180. package/dist/utils/env.d.ts.map +1 -0
  181. package/dist/utils/env.js +18 -0
  182. package/dist/utils/env.js.map +1 -0
  183. package/dist/utils/hook-command.d.ts +6 -0
  184. package/dist/utils/hook-command.d.ts.map +1 -1
  185. package/dist/utils/hook-command.js +40 -1
  186. package/dist/utils/hook-command.js.map +1 -1
  187. package/dist/utils/pricing.json +14 -6
  188. package/dist/utils/tips.d.ts +103 -0
  189. package/dist/utils/tips.d.ts.map +1 -0
  190. package/dist/utils/tips.js +221 -0
  191. package/dist/utils/tips.js.map +1 -0
  192. package/dist/utils/version-warnings.d.ts +41 -0
  193. package/dist/utils/version-warnings.d.ts.map +1 -0
  194. package/dist/utils/version-warnings.js +93 -0
  195. package/dist/utils/version-warnings.js.map +1 -0
  196. package/dist/utils/whatsnew.d.ts +83 -0
  197. package/dist/utils/whatsnew.d.ts.map +1 -0
  198. package/dist/utils/whatsnew.js +200 -0
  199. package/dist/utils/whatsnew.js.map +1 -0
  200. package/package.json +3 -1
  201. package/scripts/release.sh +6 -0
  202. package/src/utils/tips.json +806 -0
@@ -1,3 +1,9 @@
1
+ /**
2
+ * Detect whether a `codemie` command path actually resolves to the bundled agent
3
+ * binary instead of this CLI. Checks both the raw path and its symlink target;
4
+ * never throws (unresolvable paths are treated as not shadowed).
5
+ */
6
+ export declare function isShadowedCodemieShim(commandPath: string): boolean;
1
7
  export declare function resolveCodemieBinary(): Promise<string>;
2
8
  export declare function resolveHookCommand(command: string, binary: string): string;
3
9
  export declare function rewriteHooksCommandTree(node: unknown, binary: string): boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"hook-command.d.ts","sourceRoot":"","sources":["../../src/utils/hook-command.ts"],"names":[],"mappings":"AA2BA,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,MAAM,CAAC,CAoB5D;AAGD,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAI1E;AAID,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CA2B9E"}
1
+ {"version":3,"file":"hook-command.d.ts","sourceRoot":"","sources":["../../src/utils/hook-command.ts"],"names":[],"mappings":"AAoBA;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAWlE;AAsBD,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,MAAM,CAAC,CAoB5D;AAKD,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAc1E;AAID,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CA2B9E"}
@@ -3,9 +3,34 @@
3
3
  * bare `codemie hook` no longer fails with `command not found` when the hook
4
4
  * shell's PATH lacks the codemie bin dir. See EPMCDME-14035.
5
5
  */
6
+ import { realpathSync } from 'fs';
6
7
  import { getCommandPath } from './processes.js';
7
8
  // Shell-special chars that force the command path to be quoted; mirrors BaseAgentAdapter.
8
9
  const NEEDS_QUOTING = /[ \t,;=()&|<>^%[\]{}]/;
10
+ // The bundled agent package (@codemieai/codemie-opencode) registers `codemie` as
11
+ // its own bin name, so in dev checkouts node_modules/.bin/codemie symlinks to the
12
+ // agent binary, not to this CLI. Hooks pointed at that shim silently run the
13
+ // wrong program: `codemie hook` is parsed as a project path, and
14
+ // `codemie sound X` prints the agent's CLI help to stdout and exits 1 with empty
15
+ // stderr (surfacing in agents as "Failed with non-blocking status code: No
16
+ // stderr output").
17
+ const SHADOWING_PACKAGE_SEGMENT = '/@codemieai/codemie-opencode/';
18
+ /**
19
+ * Detect whether a `codemie` command path actually resolves to the bundled agent
20
+ * binary instead of this CLI. Checks both the raw path and its symlink target;
21
+ * never throws (unresolvable paths are treated as not shadowed).
22
+ */
23
+ export function isShadowedCodemieShim(commandPath) {
24
+ const unquoted = commandPath.replace(/^"|"$/g, '');
25
+ const candidates = [unquoted];
26
+ try {
27
+ candidates.push(realpathSync(unquoted));
28
+ }
29
+ catch {
30
+ // Unresolvable path — judge by the raw path alone.
31
+ }
32
+ return candidates.some((candidate) => candidate.replace(/\\/g, '/').includes(SHADOWING_PACKAGE_SEGMENT));
33
+ }
9
34
  function quoteIfNeeded(p) {
10
35
  return NEEDS_QUOTING.test(p) && !p.startsWith('"') ? `"${p}"` : p;
11
36
  }
@@ -20,10 +45,13 @@ function toForwardSlash(p) {
20
45
  }
21
46
  // Prefer the PATH-resolved shim, then the running entry (argv[1]), then bare `codemie`.
22
47
  // Never throws — it runs in launch-critical hook paths, so errors degrade to the next fallback.
48
+ // A PATH shim that resolves to the bundled agent binary (dev checkouts where
49
+ // node_modules/.bin precedes the global bin dir) is rejected: hooks would run the
50
+ // agent, not this CLI.
23
51
  export async function resolveCodemieBinary() {
24
52
  try {
25
53
  const resolved = await getCommandPath('codemie');
26
- if (resolved)
54
+ if (resolved && !isShadowedCodemieShim(resolved))
27
55
  return quoteIfNeeded(toForwardSlash(resolved));
28
56
  }
29
57
  catch {
@@ -42,11 +70,22 @@ export async function resolveCodemieBinary() {
42
70
  return 'codemie';
43
71
  }
44
72
  // Rewrite a leading `codemie` token to `binary`; other commands pass through.
73
+ // Also rewrites absolute paths baked in by older resolvers that point at the
74
+ // bundled agent shim, so already-installed hooks get repaired on rewrite.
45
75
  export function resolveHookCommand(command, binary) {
46
76
  if (command === 'codemie')
47
77
  return binary;
48
78
  if (command.startsWith('codemie '))
49
79
  return binary + command.slice('codemie'.length);
80
+ const firstTokenEnd = command.startsWith('"')
81
+ ? command.indexOf('"', 1) + 1
82
+ : command.indexOf(' ');
83
+ if (firstTokenEnd > 0) {
84
+ const firstToken = command.slice(0, firstTokenEnd);
85
+ if (isShadowedCodemieShim(firstToken)) {
86
+ return binary + command.slice(firstTokenEnd);
87
+ }
88
+ }
50
89
  return command;
51
90
  }
52
91
  // Recursively rewrite every string `command` field anywhere in a hooks structure.
@@ -1 +1 @@
1
- {"version":3,"file":"hook-command.js","sourceRoot":"","sources":["../../src/utils/hook-command.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"hook-command.js","sourceRoot":"","sources":["../../src/utils/hook-command.ts"],"names":[],"mappings":"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"}
@@ -15,16 +15,24 @@
15
15
  "notes": {
16
16
  "keys": "All keys use dashes instead of dots (e.g. gpt-5-4 not gpt-5.4) so normalizeModelName dots→dashes works",
17
17
  "cacheRead": "cache hit price (Anthropic: 0.1x input, OpenAI: varies, Google: ~0.1x input)",
18
- "cacheWrite": "cache write price (Anthropic: 1.25x input, OpenAI: ~same as input)"
18
+ "cacheWrite": "cache write price (Anthropic: 1.25x input, OpenAI: ~same as input)",
19
+ "claude5": "Sonnet 5 and Opus 5 standard API-equivalent token rates verified 2026-09-15 at https://platform.claude.com/docs/en/about-claude/pricing; excludes additional tool charges. Sonnet 5's planned September 1 price increase was cancelled."
19
20
  },
20
21
  "note": "codemie: added claude 4-7/4-8 tier estimates 2026-06-08; added kimi-for-coding alias and normalized kimi-k2-5 key 2026-06-15; added claude-sonnet-5 pinned entry 2026-07-01 (pricing table lookup also has a generic same-tier fallback now, see pricing.ts)"
21
22
  },
22
23
  "claude-sonnet-5": {
23
- "input": 3,
24
- "output": 15,
25
- "cacheRead": 0.3,
26
- "cacheWrite": 3.75,
27
- "cacheWrite1h": 6.0
24
+ "input": 2,
25
+ "output": 10,
26
+ "cacheRead": 0.2,
27
+ "cacheWrite": 2.5,
28
+ "cacheWrite1h": 4.0
29
+ },
30
+ "claude-opus-5": {
31
+ "input": 5,
32
+ "output": 25,
33
+ "cacheRead": 0.5,
34
+ "cacheWrite": 6.25,
35
+ "cacheWrite1h": 10.0
28
36
  },
29
37
  "claude-opus-4-6": {
30
38
  "input": 5,
@@ -0,0 +1,103 @@
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
+ /**
30
+ * A single feature tip.
31
+ */
32
+ export interface Tip {
33
+ /** Stable unique id, kebab-case, e.g. 'cmd-skill'. Never reused. */
34
+ id: string;
35
+ /** Short category for grouping in `codemie tips`, e.g. 'Commands'. */
36
+ category: string;
37
+ /** Full sentence shown to the user. May embed the command inline. */
38
+ message: string;
39
+ /**
40
+ * Optional top-level command name used for validation and display,
41
+ * e.g. 'skill' or 'proxy'. When the referenced command is retired,
42
+ * `codemie tips` drops/flags this tip automatically.
43
+ */
44
+ command?: string;
45
+ /** Concrete invocation variations taught by this tip. */
46
+ commands?: string[];
47
+ }
48
+ /**
49
+ * Curated tip catalog, loaded eagerly from src/utils/tips.json. Every
50
+ * `command` value references a top-level command registered in
51
+ * src/cli/index.ts; `codemie tips` re-validates these at runtime.
52
+ */
53
+ export declare const TIPS: readonly Tip[];
54
+ /**
55
+ * Check if session tips are enabled (default: true).
56
+ * Reads the CODEMIE_TIPS environment variable.
57
+ *
58
+ * @returns true unless CODEMIE_TIPS is set to a falsy value ('false', '0', 'no')
59
+ */
60
+ export declare function isTipsEnabled(): boolean;
61
+ /**
62
+ * Return the full tip catalog (used by `codemie tips`).
63
+ */
64
+ export declare function listTips(): readonly Tip[];
65
+ /**
66
+ * Pick the tip to show at a session lifecycle point.
67
+ *
68
+ * Randomly selects a tip that has not been shown yet (per the rotation state
69
+ * file), records the pick, and resets the shown list once every tip has been
70
+ * shown. Both contexts share one catalog and one rotation for now; the context
71
+ * is recorded in the debug log so future per-context catalogs can reuse it.
72
+ *
73
+ * Best-effort: unreadable/corrupt state is treated as empty, write failures
74
+ * are swallowed — a tip must never block or break a session.
75
+ *
76
+ * @param context - Where the tip is rendered ('start' or 'end' of session)
77
+ * @returns A tip, or null when tips are disabled or the catalog is empty
78
+ */
79
+ export declare function getSessionTip(context: 'start' | 'end'): Tip | null;
80
+ /**
81
+ * Format a tip for terminal display: a gold ✨ prefix followed by the message
82
+ * in the same warm gold, bold. Yellow is the CLI's established accent color
83
+ * (matches the Kimi-style prompt echo) — deliberately no background bars or
84
+ * badge, just plain foreground styling.
85
+ * Shared by session lifecycle rendering (BaseAgentAdapter), renderTip(), and
86
+ * `codemie tips --random` so tips look identical everywhere.
87
+ */
88
+ export declare function formatTipLine(tip: Tip): string;
89
+ /**
90
+ * Print a single random tip to the console for CLI surfaces (doctor,
91
+ * first-run and post-setup screens, ...). Unlike getSessionTip(), this does
92
+ * not read or update the rotation state — rotation stays exclusive to session
93
+ * start/end.
94
+ *
95
+ * Best-effort: never throws, and is a no-op when tips are disabled.
96
+ *
97
+ * @param options.category - Restrict the pick to one category; falls back to
98
+ * the full catalog when the category has no tips
99
+ */
100
+ export declare function renderTip(options?: {
101
+ category?: string;
102
+ }): void;
103
+ //# sourceMappingURL=tips.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tips.d.ts","sourceRoot":"","sources":["../../src/utils/tips.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAUH;;GAEG;AACH,MAAM,WAAW,GAAG;IAClB,oEAAoE;IACpE,EAAE,EAAE,MAAM,CAAC;IACX,sEAAsE;IACtE,QAAQ,EAAE,MAAM,CAAC;IACjB,qEAAqE;IACrE,OAAO,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,yDAAyD;IACzD,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAqDD;;;;GAIG;AACH,eAAO,MAAM,IAAI,EAAE,SAAS,GAAG,EAAsB,CAAC;AAYtD;;;;;GAKG;AACH,wBAAgB,aAAa,IAAI,OAAO,CAEvC;AAED;;GAEG;AACH,wBAAgB,QAAQ,IAAI,SAAS,GAAG,EAAE,CAEzC;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,KAAK,GAAG,GAAG,GAAG,IAAI,CAwBlE;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,GAAG,GAAG,MAAM,CAE9C;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,SAAS,CAAC,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAoB/D"}
@@ -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":"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"}