coding-friend-cli 1.38.4 → 1.39.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/dist/{chunk-32UAW3NX.js → chunk-2EY7VVFT.js} +1 -1
  2. package/dist/{chunk-RCE4OWNX.js → chunk-463QKRBN.js} +1 -1
  3. package/dist/{chunk-ETTZRJ55.js → chunk-4CPUWHIN.js} +1 -1
  4. package/dist/{chunk-6NXZKAOV.js → chunk-7JQZRMOG.js} +37 -4
  5. package/dist/{chunk-5KHZQCZB.js → chunk-FQUIO5BW.js} +1 -1
  6. package/dist/chunk-GTOEIGDM.js +510 -0
  7. package/dist/{chunk-PLSJW7QJ.js → chunk-IV5OPG34.js} +47 -1
  8. package/dist/{chunk-I2DQYPKT.js → chunk-MO4SUPZN.js} +176 -17
  9. package/dist/{chunk-S4ENKXXC.js → chunk-ODW27NAC.js} +8 -8
  10. package/dist/chunk-OFEC6OVI.js +99 -0
  11. package/dist/{chunk-5QCGEPQO.js → chunk-RL3DCID7.js} +11 -1
  12. package/dist/{chunk-GIH6E7GJ.js → chunk-VMODQCSL.js} +4 -53
  13. package/dist/{chunk-VHUU3QDC.js → chunk-YPW67OGP.js} +1 -1
  14. package/dist/{chunk-BXSCYGWE.js → chunk-ZGIUKUL2.js} +51 -6
  15. package/dist/chunk-ZZNTNIM4.js +63 -0
  16. package/dist/{clean-MSRZSOSO.js → clean-LPWEBJJ5.js} +2 -2
  17. package/dist/{config-EX3B3HWO.js → config-VNSC2NAY.js} +15 -13
  18. package/dist/{dev-PTBNMKZT.js → dev-NRTDUQAR.js} +3 -3
  19. package/dist/{disable-MO7AXYYF.js → disable-6L352DMD.js} +19 -4
  20. package/dist/{enable-4GXLQEHD.js → enable-6KXREKRP.js} +24 -4
  21. package/dist/{guide-HCR43LJN.js → guide-HCLEOAGR.js} +1 -1
  22. package/dist/{host-VIQ5YI3V.js → host-2JOPHLN3.js} +4 -3
  23. package/dist/index.js +46 -46
  24. package/dist/{init-S2K4CQO2.js → init-VENKICVP.js} +54 -18
  25. package/dist/{install-LUPE3VTC.js → install-A4TSBGOV.js} +52 -9
  26. package/dist/{learn-A3TP6PLL.js → learn-SSNBBDY3.js} +2 -2
  27. package/dist/{mcp-QNJTCZMS.js → mcp-J5VO3OH7.js} +13 -11
  28. package/dist/{mcp-serve-4VP4KDYG.js → mcp-serve-55DSE2J4.js} +4 -3
  29. package/dist/{mcp-serve-learn-UVXIDOEZ.js → mcp-serve-learn-EDBWNL4I.js} +3 -2
  30. package/dist/{memory-7GKTQSIW.js → memory-CDZKWOFL.js} +9 -7
  31. package/dist/{permission-VISPGMUK.js → permission-DPKPA2HU.js} +11 -3
  32. package/dist/{permissions-2SBACQHV.js → permissions-HZYUVKCY.js} +2 -2
  33. package/dist/{session-VDGNTICO.js → session-YWJDLNBP.js} +2 -2
  34. package/dist/{status-RHSL5MBU.js → status-ZOAYLVH6.js} +18 -16
  35. package/dist/{statusline-AOZHEQSV.js → statusline-R5BNYK3H.js} +2 -2
  36. package/dist/{uninstall-QN6527IR.js → uninstall-TCMK2WNW.js} +52 -8
  37. package/dist/{update-ZQG25VOJ.js → update-6OYI5BAY.js} +10 -7
  38. package/dist/{update-check-7LKJLJPM.js → update-check-EJSGVGO6.js} +1 -1
  39. package/package.json +1 -1
  40. package/dist/chunk-RZRT7NGT.js +0 -18
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  ensureStatusline,
3
3
  getInstalledVersion
4
- } from "./chunk-ETTZRJ55.js";
4
+ } from "./chunk-4CPUWHIN.js";
5
5
  import {
6
6
  ensureShellCompletion
7
7
  } from "./chunk-667NMPN4.js";
@@ -9,15 +9,28 @@ import {
9
9
  isMemoryMcpRegistered,
10
10
  registerMemoryMcp,
11
11
  removeMemoryMcpEntry
12
- } from "./chunk-BXSCYGWE.js";
12
+ } from "./chunk-ZGIUKUL2.js";
13
+ import {
14
+ isPluginInstalled
15
+ } from "./chunk-2EY7VVFT.js";
13
16
  import {
14
17
  CODEX_MARKETPLACE_NAME,
15
- getCodexInstalledVersion
16
- } from "./chunk-5QCGEPQO.js";
18
+ getCodexInstalledVersion,
19
+ isCodexMarketplaceLocal,
20
+ isCodexMarketplaceRegistered
21
+ } from "./chunk-RL3DCID7.js";
22
+ import {
23
+ deployOmpAgents,
24
+ isOmpAgentInstalled,
25
+ writeOmpExtensionEntry
26
+ } from "./chunk-GTOEIGDM.js";
17
27
  import {
18
28
  resolveHostFlags,
19
29
  resolveScope
20
- } from "./chunk-GIH6E7GJ.js";
30
+ } from "./chunk-VMODQCSL.js";
31
+ import {
32
+ detectHostsAvailable
33
+ } from "./chunk-OFEC6OVI.js";
21
34
  import {
22
35
  commandExists,
23
36
  run,
@@ -29,7 +42,7 @@ import {
29
42
  } from "./chunk-5UVDWG5L.js";
30
43
  import {
31
44
  claudeSettingsPath
32
- } from "./chunk-PLSJW7QJ.js";
45
+ } from "./chunk-IV5OPG34.js";
33
46
  import {
34
47
  log,
35
48
  printBanner
@@ -98,14 +111,75 @@ function getStatuslineVersion() {
98
111
  );
99
112
  return match?.[1]?.replace(/^v/, "") ?? null;
100
113
  }
114
+ function argvHasAgentFlag() {
115
+ return process.argv.some((a) => a === "--agent" || a.startsWith("--agent="));
116
+ }
117
+ function hasExplicitHost(opts) {
118
+ if (opts.codex === true || opts.omp === true) return true;
119
+ if (argvHasAgentFlag()) return true;
120
+ const agent = opts.agent?.trim().toLowerCase();
121
+ return agent === "codex" || agent === "omp";
122
+ }
123
+ function flagsForHostResolve(opts) {
124
+ if (!argvHasAgentFlag() && opts.agent === "claude" && (opts.codex === true || opts.omp === true)) {
125
+ return { ...opts, agent: void 0 };
126
+ }
127
+ return opts;
128
+ }
129
+ function isHostInstalled(host) {
130
+ switch (host) {
131
+ case "claude":
132
+ return isPluginInstalled();
133
+ case "codex":
134
+ return isCodexMarketplaceRegistered();
135
+ case "omp":
136
+ return isOmpAgentInstalled("user") || isOmpAgentInstalled("project");
137
+ }
138
+ }
139
+ function hostSectionTitle(host) {
140
+ switch (host) {
141
+ case "claude":
142
+ return "Claude";
143
+ case "codex":
144
+ return "Codex";
145
+ case "omp":
146
+ return "omp";
147
+ }
148
+ }
149
+ async function updateHost(host, opts, mode) {
150
+ if (host === "codex") return updateCodexCommand(opts, mode);
151
+ if (host === "omp") return updateOmpCommand(opts, mode);
152
+ return updateClaudeCommand(opts, mode);
153
+ }
101
154
  async function updateCommand(opts) {
102
- const { host } = resolveHostFlags(opts);
103
- if (host === "codex") {
104
- await updateCodexCommand(opts);
155
+ if (hasExplicitHost(opts)) {
156
+ const { host } = resolveHostFlags(flagsForHostResolve(opts));
157
+ await updateHost(host, opts);
158
+ return;
159
+ }
160
+ const installed = detectHostsAvailable().filter(isHostInstalled);
161
+ if (installed.length === 0) {
162
+ await updateClaudeCommand(opts);
105
163
  return;
106
164
  }
165
+ if (installed.length === 1) {
166
+ await updateHost(installed[0], opts);
167
+ return;
168
+ }
169
+ printBanner("\u2728 Coding Friend Update \u2728");
170
+ console.log();
171
+ for (const [index, host] of installed.entries()) {
172
+ console.log(chalk.bold(`\u2500\u2500 ${hostSectionTitle(host)} \u2500\u2500`));
173
+ console.log();
174
+ await updateHost(host, opts, {
175
+ skipBanner: true,
176
+ skipCli: index > 0
177
+ });
178
+ }
179
+ }
180
+ async function updateClaudeCommand(opts, mode) {
107
181
  const updateAll = !opts.cli && !opts.plugin && !opts.statusline;
108
- const doCli = updateAll || !!opts.cli;
182
+ const doCli = (updateAll || !!opts.cli) && !mode?.skipCli;
109
183
  const doPlugin = updateAll || !!opts.plugin;
110
184
  const doStatusline = updateAll || !!opts.statusline;
111
185
  const hasScopeFlag = !!(opts.user || opts.global || opts.project || opts.local);
@@ -115,8 +189,10 @@ async function updateCommand(opts) {
115
189
  } else if (doPlugin && !hasScopeFlag) {
116
190
  scope = "user";
117
191
  }
118
- printBanner("\u2728 Coding Friend Update \u2728");
119
- console.log();
192
+ if (!mode?.skipBanner) {
193
+ printBanner("\u2728 Coding Friend Update \u2728");
194
+ console.log();
195
+ }
120
196
  const currentVersion = getInstalledVersion();
121
197
  const latestVersion = getLatestVersion();
122
198
  const statuslineVersion = getStatuslineVersion();
@@ -235,7 +311,7 @@ async function updateCommand(opts) {
235
311
  }
236
312
  let refreshMemoryAfterUpdate = null;
237
313
  if (doCli) {
238
- ({ refreshMemoryAfterUpdate } = await import("./memory-7GKTQSIW.js"));
314
+ ({ refreshMemoryAfterUpdate } = await import("./memory-CDZKWOFL.js"));
239
315
  if (!latestCliVersion) {
240
316
  log.warn("Cannot check latest CLI version from npm.");
241
317
  } else {
@@ -293,12 +369,14 @@ async function updateCommand(opts) {
293
369
  console.log();
294
370
  log.dim("Restart Claude Code (or start a new session) to see changes.");
295
371
  }
296
- async function updateCodexCommand(opts) {
372
+ async function updateCodexCommand(opts, mode) {
297
373
  const updateAll = !opts.cli && !opts.plugin && !opts.statusline;
298
- const doCli = updateAll || !!opts.cli;
374
+ const doCli = (updateAll || !!opts.cli) && !mode?.skipCli;
299
375
  const doPlugin = updateAll || !!opts.plugin;
300
- printBanner("\u2728 Coding Friend Codex Update \u2728");
301
- console.log();
376
+ if (!mode?.skipBanner) {
377
+ printBanner("\u2728 Coding Friend Codex Update \u2728");
378
+ console.log();
379
+ }
302
380
  if (doPlugin) {
303
381
  const beforeVersion = getCodexInstalledVersion();
304
382
  console.log(
@@ -306,6 +384,19 @@ async function updateCodexCommand(opts) {
306
384
  );
307
385
  if (!commandExists("codex")) {
308
386
  log.error("Codex CLI not found. Cannot update Codex plugin.");
387
+ } else if (isCodexMarketplaceLocal()) {
388
+ if (beforeVersion) {
389
+ log.info(
390
+ "Codex marketplace is a local dev source \u2014 skipping git upgrade (it only works on git marketplaces)."
391
+ );
392
+ log.dim(
393
+ `Codex runs a cached copy at v${beforeVersion}; to pick up working-tree changes, reinstall via Codex \u2192 /plugins.`
394
+ );
395
+ } else {
396
+ log.warn(
397
+ "Codex marketplace is a local dev source, but coding-friend is not installed yet. Open Codex and run /plugins to install it."
398
+ );
399
+ }
309
400
  } else {
310
401
  log.step("Updating Codex marketplace...");
311
402
  const result = runWithStderr("codex", [
@@ -371,6 +462,74 @@ async function updateCodexCommand(opts) {
371
462
  console.log();
372
463
  log.dim("Restart Codex CLI (or start a new session) to see changes.");
373
464
  }
465
+ function ompUpdateScopes(opts) {
466
+ if (opts.project || opts.local) return ["project"];
467
+ if (opts.user || opts.global) return ["user"];
468
+ const scopes = [];
469
+ if (isOmpAgentInstalled("user")) scopes.push("user");
470
+ if (isOmpAgentInstalled("project")) scopes.push("project");
471
+ return scopes.length > 0 ? scopes : ["user"];
472
+ }
473
+ async function updateOmpCommand(opts, mode) {
474
+ const updateAll = !opts.cli && !opts.plugin && !opts.statusline;
475
+ const doCli = (updateAll || !!opts.cli) && !mode?.skipCli;
476
+ const doPlugin = updateAll || !!opts.plugin;
477
+ const scopes = ompUpdateScopes(opts);
478
+ if (!mode?.skipBanner) {
479
+ printBanner("\u2728 Coding Friend omp Update \u2728");
480
+ console.log();
481
+ }
482
+ if (doPlugin) {
483
+ const cliVersion = getCliVersion();
484
+ console.log(` CLI ${cliVersion}`);
485
+ for (const scope of scopes) {
486
+ log.step(`Updating omp agents (${scope} scope)...`);
487
+ const { deployed, skipped } = deployOmpAgents(scope);
488
+ writeOmpExtensionEntry(scope);
489
+ const fileLabel = deployed.length === 1 ? "file" : "files";
490
+ log.success(
491
+ `omp agents updated (${deployed.length} ${fileLabel}, ${scope} scope).`
492
+ );
493
+ if (skipped.length > 0) {
494
+ log.warn(`Skipped ${skipped.length} agent file(s).`);
495
+ }
496
+ log.success("omp extension entry refreshed.");
497
+ }
498
+ registerMemoryMcp("omp");
499
+ log.success("omp memory MCP entry refreshed.");
500
+ }
501
+ if (doCli) {
502
+ const cliVersion = getCliVersion();
503
+ const latestCliVersion = getLatestCliVersion();
504
+ if (!latestCliVersion) {
505
+ log.warn("Cannot check latest CLI version from npm.");
506
+ } else {
507
+ const cmp = semverCompare(cliVersion, latestCliVersion);
508
+ if (cmp < 0) {
509
+ log.step(
510
+ `CLI update available: ${chalk.yellow(`v${cliVersion}`)} \u2192 ${chalk.green(`v${latestCliVersion}`)}`
511
+ );
512
+ const result = run("npm", [
513
+ "install",
514
+ "-g",
515
+ "coding-friend-cli@latest"
516
+ ]);
517
+ if (result === null) {
518
+ log.error(
519
+ "CLI update failed. Try manually: npm install -g coding-friend-cli@latest"
520
+ );
521
+ } else {
522
+ log.success(`CLI updated to ${chalk.green(`v${latestCliVersion}`)}`);
523
+ }
524
+ }
525
+ }
526
+ }
527
+ if (opts.statusline) {
528
+ log.warn("omp does not use the Claude statusline. Skipping.");
529
+ }
530
+ console.log();
531
+ log.dim("Restart omp (or start a new session) to see changes.");
532
+ }
374
533
 
375
534
  export {
376
535
  semverCompare,
@@ -2,23 +2,23 @@ import {
2
2
  checkMemoryMcpHealth,
3
3
  printHealthSection,
4
4
  warnStaleMcpJson
5
- } from "./chunk-VHUU3QDC.js";
5
+ } from "./chunk-YPW67OGP.js";
6
6
  import {
7
7
  loadConfig,
8
8
  resolveMemoryDir
9
- } from "./chunk-5KHZQCZB.js";
9
+ } from "./chunk-FQUIO5BW.js";
10
10
  import {
11
11
  getMemoryMcpStatus,
12
12
  isMemoryMcpRegistered,
13
13
  memoryConfigMenu,
14
14
  registerMemoryMcp
15
- } from "./chunk-BXSCYGWE.js";
16
- import {
17
- getLibPath
18
- } from "./chunk-RZRT7NGT.js";
15
+ } from "./chunk-ZGIUKUL2.js";
19
16
  import {
20
17
  showConfigHint
21
- } from "./chunk-GIH6E7GJ.js";
18
+ } from "./chunk-VMODQCSL.js";
19
+ import {
20
+ getLibPath
21
+ } from "./chunk-ZZNTNIM4.js";
22
22
  import {
23
23
  run,
24
24
  runWithStderr
@@ -30,7 +30,7 @@ import {
30
30
  import {
31
31
  globalConfigPath,
32
32
  localConfigPath
33
- } from "./chunk-PLSJW7QJ.js";
33
+ } from "./chunk-IV5OPG34.js";
34
34
  import {
35
35
  log,
36
36
  printBanner
@@ -0,0 +1,99 @@
1
+ import {
2
+ commandExists,
3
+ run
4
+ } from "./chunk-EVGXUDX4.js";
5
+
6
+ // src/lib/host.ts
7
+ var CODEX_MIN_VERSION = "0.130.0";
8
+ var OMP_MIN_VERSION = "0.1.0";
9
+ function detectHostsAvailable() {
10
+ const hosts = [];
11
+ if (commandExists("claude")) hosts.push("claude");
12
+ if (commandExists("codex")) hosts.push("codex");
13
+ if (commandExists("omp")) hosts.push("omp");
14
+ return hosts;
15
+ }
16
+ function resolveHost(opts = {}) {
17
+ const agent = opts.agent?.trim().toLowerCase();
18
+ const codexAlias = opts.codex === true;
19
+ const ompAlias = opts.omp === true;
20
+ if (agent && agent !== "claude" && agent !== "codex" && agent !== "omp") {
21
+ throw new Error(
22
+ `Unsupported agent "${opts.agent}". Use "claude", "codex", or "omp".`
23
+ );
24
+ }
25
+ if (codexAlias && ompAlias) {
26
+ throw new Error("Use either --codex or --omp, not both.");
27
+ }
28
+ if (codexAlias && agent === "claude") {
29
+ throw new Error("Use either --agent claude or --codex, not both.");
30
+ }
31
+ if (ompAlias && agent === "claude") {
32
+ throw new Error("Use either --agent claude or --omp, not both.");
33
+ }
34
+ if (ompAlias && agent === "codex") {
35
+ throw new Error("Use either --agent codex or --omp, not both.");
36
+ }
37
+ if (codexAlias && agent === "omp") {
38
+ throw new Error("Use either --agent omp or --codex, not both.");
39
+ }
40
+ if (ompAlias) return "omp";
41
+ if (agent === "omp") return "omp";
42
+ if (codexAlias) return "codex";
43
+ if (agent === "codex") return "codex";
44
+ return "claude";
45
+ }
46
+ function getCodexMinVersion() {
47
+ return CODEX_MIN_VERSION;
48
+ }
49
+ function getOmpMinVersion() {
50
+ return OMP_MIN_VERSION;
51
+ }
52
+ function checkCodexVersion() {
53
+ const min = getCodexMinVersion();
54
+ const output = run("codex", ["--version"]);
55
+ const actual = output ? extractVersion(output) : void 0;
56
+ return {
57
+ ok: actual ? compareVersions(actual, min) >= 0 : false,
58
+ actual,
59
+ min
60
+ };
61
+ }
62
+ function checkOmpVersion() {
63
+ const min = getOmpMinVersion();
64
+ const output = run("omp", ["--version"]);
65
+ const actual = output ? extractVersion(output) : void 0;
66
+ return {
67
+ ok: actual ? compareVersions(actual, min) >= 0 : false,
68
+ actual,
69
+ min
70
+ };
71
+ }
72
+ function extractVersion(input) {
73
+ return input.match(/\b(\d+\.\d+\.\d+)\b/)?.[1];
74
+ }
75
+ function compareVersions(a, b) {
76
+ const left = parseVersion(a);
77
+ const right = parseVersion(b);
78
+ for (let i = 0; i < 3; i += 1) {
79
+ if (left[i] > right[i]) return 1;
80
+ if (left[i] < right[i]) return -1;
81
+ }
82
+ return 0;
83
+ }
84
+ function parseVersion(version) {
85
+ const parts = version.split(".").map((part) => Number.parseInt(part, 10));
86
+ return [
87
+ Number.isFinite(parts[0]) ? parts[0] : 0,
88
+ Number.isFinite(parts[1]) ? parts[1] : 0,
89
+ Number.isFinite(parts[2]) ? parts[2] : 0
90
+ ];
91
+ }
92
+
93
+ export {
94
+ detectHostsAvailable,
95
+ resolveHost,
96
+ checkCodexVersion,
97
+ checkOmpVersion,
98
+ compareVersions
99
+ };
@@ -2,7 +2,7 @@ import {
2
2
  codexAgentsDir,
3
3
  codexConfigTomlPath,
4
4
  codexInstalledPluginsPath
5
- } from "./chunk-PLSJW7QJ.js";
5
+ } from "./chunk-IV5OPG34.js";
6
6
 
7
7
  // src/lib/codex-config.ts
8
8
  import {
@@ -97,6 +97,15 @@ function isCodexMarketplaceRegistered(configPath = codexConfigTomlPath()) {
97
97
  (line) => line.trim() === tableHeader(`marketplaces.${CODEX_MARKETPLACE_NAME}`)
98
98
  );
99
99
  }
100
+ function isCodexMarketplaceLocal(configPath = codexConfigTomlPath()) {
101
+ const table = getTable(
102
+ readToml(configPath),
103
+ `marketplaces.${CODEX_MARKETPLACE_NAME}`
104
+ );
105
+ return table.some(
106
+ (line) => /^\s*source_type\s*=\s*["']local["']\s*(?:#.*)?$/.test(line)
107
+ );
108
+ }
100
109
  function setCodexPluginEnabled(enabled, configPath = codexConfigTomlPath()) {
101
110
  const content = readToml(configPath);
102
111
  writeToml(
@@ -225,6 +234,7 @@ function deployCodexAgents(sourceDir, targetDir = codexAgentsDir()) {
225
234
  export {
226
235
  CODEX_MARKETPLACE_NAME,
227
236
  isCodexMarketplaceRegistered,
237
+ isCodexMarketplaceLocal,
228
238
  setCodexPluginEnabled,
229
239
  isCodexPluginDisabled,
230
240
  removeCodexMemoryMcpConfig,
@@ -1,3 +1,6 @@
1
+ import {
2
+ resolveHost
3
+ } from "./chunk-OFEC6OVI.js";
1
4
  import {
2
5
  run
3
6
  } from "./chunk-EVGXUDX4.js";
@@ -7,62 +10,11 @@ import {
7
10
  import {
8
11
  globalConfigPath,
9
12
  localConfigPath
10
- } from "./chunk-PLSJW7QJ.js";
13
+ } from "./chunk-IV5OPG34.js";
11
14
  import {
12
15
  log
13
16
  } from "./chunk-NREZK463.js";
14
17
 
15
- // src/lib/host.ts
16
- var CODEX_MIN_VERSION = "0.130.0";
17
- function resolveHost(opts = {}) {
18
- const agent = opts.agent?.trim().toLowerCase();
19
- const codexAlias = opts.codex === true;
20
- if (agent && agent !== "claude" && agent !== "codex") {
21
- throw new Error(
22
- `Unsupported agent "${opts.agent}". Use "claude" or "codex".`
23
- );
24
- }
25
- if (codexAlias && agent === "claude") {
26
- throw new Error("Use either --agent claude or --codex, not both.");
27
- }
28
- if (codexAlias) return "codex";
29
- if (agent === "codex") return "codex";
30
- return "claude";
31
- }
32
- function getCodexMinVersion() {
33
- return CODEX_MIN_VERSION;
34
- }
35
- function checkCodexVersion() {
36
- const min = getCodexMinVersion();
37
- const output = run("codex", ["--version"]);
38
- const actual = output ? extractVersion(output) : void 0;
39
- return {
40
- ok: actual ? compareVersions(actual, min) >= 0 : false,
41
- actual,
42
- min
43
- };
44
- }
45
- function extractVersion(input) {
46
- return input.match(/\b(\d+\.\d+\.\d+)\b/)?.[1];
47
- }
48
- function compareVersions(a, b) {
49
- const left = parseVersion(a);
50
- const right = parseVersion(b);
51
- for (let i = 0; i < 3; i += 1) {
52
- if (left[i] > right[i]) return 1;
53
- if (left[i] < right[i]) return -1;
54
- }
55
- return 0;
56
- }
57
- function parseVersion(version) {
58
- const parts = version.split(".").map((part) => Number.parseInt(part, 10));
59
- return [
60
- Number.isFinite(parts[0]) ? parts[0] : 0,
61
- Number.isFinite(parts[1]) ? parts[1] : 0,
62
- Number.isFinite(parts[2]) ? parts[2] : 0
63
- ];
64
- }
65
-
66
18
  // src/lib/prompt-utils.ts
67
19
  import { select, Separator } from "@inquirer/prompts";
68
20
  import { existsSync } from "fs";
@@ -232,7 +184,6 @@ function applyDocsDirChange(newValue, oldValue, scope, subfolders = []) {
232
184
  }
233
185
 
234
186
  export {
235
- checkCodexVersion,
236
187
  BACK,
237
188
  injectBackChoice,
238
189
  askScope,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  isMemoryMcpRegistered
3
- } from "./chunk-BXSCYGWE.js";
3
+ } from "./chunk-ZGIUKUL2.js";
4
4
  import {
5
5
  readJson
6
6
  } from "./chunk-5UVDWG5L.js";
@@ -1,12 +1,17 @@
1
1
  import {
2
- getLibPath
3
- } from "./chunk-RZRT7NGT.js";
2
+ readOmpMcpJson,
3
+ removeOmpMcpEntry,
4
+ writeOmpMcpEntry
5
+ } from "./chunk-GTOEIGDM.js";
4
6
  import {
5
7
  BACK,
6
8
  askScope,
7
9
  formatScopeLabel,
8
10
  injectBackChoice
9
- } from "./chunk-GIH6E7GJ.js";
11
+ } from "./chunk-VMODQCSL.js";
12
+ import {
13
+ getLibPath
14
+ } from "./chunk-ZZNTNIM4.js";
10
15
  import {
11
16
  runWithStderr
12
17
  } from "./chunk-EVGXUDX4.js";
@@ -19,14 +24,32 @@ import {
19
24
  claudeConfigDir,
20
25
  globalConfigPath,
21
26
  localConfigPath
22
- } from "./chunk-PLSJW7QJ.js";
27
+ } from "./chunk-IV5OPG34.js";
23
28
  import {
24
29
  log
25
30
  } from "./chunk-NREZK463.js";
26
31
 
27
32
  // src/lib/memory-mcp-register.ts
28
33
  var MCP_NAME = "coding-friend-memory";
29
- function registerMemoryMcp() {
34
+ var OMP_MEMORY_SERVER = {
35
+ command: "npx",
36
+ args: ["-y", "coding-friend-cli", "mcp-serve"]
37
+ };
38
+ function hasOmpMemoryEntry() {
39
+ const data = readOmpMcpJson();
40
+ return data !== null && MCP_NAME in data.mcpServers;
41
+ }
42
+ function registerMemoryMcp(host = "claude") {
43
+ if (host === "omp") {
44
+ try {
45
+ writeOmpMcpEntry(MCP_NAME, OMP_MEMORY_SERVER);
46
+ return true;
47
+ } catch (error) {
48
+ const detail = error instanceof Error ? error.message : "unknown error";
49
+ log.warn(`Could not register MCP: ${detail}`);
50
+ return false;
51
+ }
52
+ }
30
53
  const result = runWithStderr("claude", [
31
54
  "mcp",
32
55
  "add",
@@ -53,10 +76,31 @@ function registerMemoryMcp() {
53
76
  }
54
77
  return true;
55
78
  }
56
- function isMemoryMcpRegistered() {
79
+ function isMemoryMcpRegistered(host = "claude") {
80
+ if (host === "omp") return hasOmpMemoryEntry();
57
81
  const result = runWithStderr("claude", ["mcp", "get", MCP_NAME]);
58
82
  return result.exitCode === 0;
59
83
  }
84
+ function unregisterMemoryMcp(host = "claude") {
85
+ if (host === "omp") {
86
+ try {
87
+ removeOmpMcpEntry(MCP_NAME);
88
+ return !hasOmpMemoryEntry();
89
+ } catch (error) {
90
+ const detail = error instanceof Error ? error.message : "unknown error";
91
+ log.warn(`Could not unregister MCP: ${detail}`);
92
+ return false;
93
+ }
94
+ }
95
+ const result = runWithStderr("claude", [
96
+ "mcp",
97
+ "remove",
98
+ "--scope",
99
+ "user",
100
+ MCP_NAME
101
+ ]);
102
+ return result.exitCode === 0;
103
+ }
60
104
 
61
105
  // src/lib/memory-prompts.ts
62
106
  import { confirm, input, select } from "@inquirer/prompts";
@@ -402,6 +446,7 @@ async function memoryConfigMenu(opts) {
402
446
  export {
403
447
  registerMemoryMcp,
404
448
  isMemoryMcpRegistered,
449
+ unregisterMemoryMcp,
405
450
  removeMemoryMcpEntry,
406
451
  getMemoryMcpStatus,
407
452
  memoryConfigMenu
@@ -0,0 +1,63 @@
1
+ import {
2
+ compareVersions
3
+ } from "./chunk-OFEC6OVI.js";
4
+ import {
5
+ pluginCachePath
6
+ } from "./chunk-IV5OPG34.js";
7
+
8
+ // src/lib/lib-path.ts
9
+ import { existsSync, readdirSync } from "fs";
10
+ import { dirname, join, resolve } from "path";
11
+ import { fileURLToPath } from "url";
12
+ var __dirname = dirname(fileURLToPath(import.meta.url));
13
+ function getLibPath(name) {
14
+ const bundled = join(__dirname, "..", "lib", name);
15
+ if (existsSync(bundled)) return bundled;
16
+ const dev = join(__dirname, "..", "..", "lib", name);
17
+ if (existsSync(dev)) return dev;
18
+ throw new Error(
19
+ `Could not find lib/${name}. Ensure it exists in the CLI package.`
20
+ );
21
+ }
22
+ function existingOmpExtension(root) {
23
+ const nested = join(root, "plugin", "omp", "extension.ts");
24
+ if (existsSync(nested)) return nested;
25
+ const flat = join(root, "omp", "extension.ts");
26
+ if (existsSync(flat)) return flat;
27
+ return null;
28
+ }
29
+ function cachedOmpExtensionDirs(cacheRoot) {
30
+ let names = [];
31
+ try {
32
+ names = readdirSync(cacheRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name);
33
+ } catch {
34
+ return [];
35
+ }
36
+ const versions = names.filter((name) => /^\d/.test(name)).sort(compareVersions).reverse();
37
+ const rest = names.filter((name) => !/^\d/.test(name));
38
+ return [...versions, ...rest].map((name) => join(cacheRoot, name));
39
+ }
40
+ function cachedOmpExtension() {
41
+ const cacheRoot = pluginCachePath();
42
+ if (!existsSync(cacheRoot)) return null;
43
+ const direct = existingOmpExtension(cacheRoot);
44
+ if (direct) return direct;
45
+ for (const dir of cachedOmpExtensionDirs(cacheRoot)) {
46
+ const found = existingOmpExtension(dir);
47
+ if (found) return found;
48
+ }
49
+ return null;
50
+ }
51
+ function getOmpExtensionPath(repoRoot = process.cwd()) {
52
+ const root = resolve(repoRoot);
53
+ const fromCwd = existingOmpExtension(root);
54
+ if (fromCwd) return fromCwd;
55
+ const fromParent = existingOmpExtension(resolve(root, ".."));
56
+ if (fromParent) return fromParent;
57
+ return cachedOmpExtension();
58
+ }
59
+
60
+ export {
61
+ getLibPath,
62
+ getOmpExtensionPath
63
+ };
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  loadConfig,
3
3
  resolveMemoryDir
4
- } from "./chunk-5KHZQCZB.js";
4
+ } from "./chunk-FQUIO5BW.js";
5
5
  import "./chunk-3WIZA5OZ.js";
6
6
  import "./chunk-EVGXUDX4.js";
7
7
  import "./chunk-5UVDWG5L.js";
8
8
  import {
9
9
  resolvePath
10
- } from "./chunk-PLSJW7QJ.js";
10
+ } from "./chunk-IV5OPG34.js";
11
11
  import {
12
12
  log,
13
13
  printBanner