coding-friend-cli 1.38.3 → 1.39.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-32UAW3NX.js → chunk-2EY7VVFT.js} +1 -1
- package/dist/{chunk-RCE4OWNX.js → chunk-463QKRBN.js} +1 -1
- package/dist/{chunk-ETTZRJ55.js → chunk-4CPUWHIN.js} +1 -1
- package/dist/{chunk-6NXZKAOV.js → chunk-7JQZRMOG.js} +37 -4
- package/dist/{chunk-5KHZQCZB.js → chunk-FQUIO5BW.js} +1 -1
- package/dist/chunk-GTOEIGDM.js +510 -0
- package/dist/{chunk-PLSJW7QJ.js → chunk-IV5OPG34.js} +47 -1
- package/dist/{chunk-5QCGEPQO.js → chunk-JSH6BMVZ.js} +1 -1
- package/dist/{chunk-S4ENKXXC.js → chunk-ODW27NAC.js} +8 -8
- package/dist/chunk-OFEC6OVI.js +99 -0
- package/dist/{chunk-GIH6E7GJ.js → chunk-VMODQCSL.js} +4 -53
- package/dist/{chunk-I2DQYPKT.js → chunk-WJHQUCOF.js} +162 -17
- package/dist/{chunk-VHUU3QDC.js → chunk-YPW67OGP.js} +1 -1
- package/dist/{chunk-BXSCYGWE.js → chunk-ZGIUKUL2.js} +51 -6
- package/dist/chunk-ZZNTNIM4.js +63 -0
- package/dist/{clean-BJSNDUPN.js → clean-LPWEBJJ5.js} +45 -7
- package/dist/{config-EX3B3HWO.js → config-VNSC2NAY.js} +15 -13
- package/dist/{dev-PTBNMKZT.js → dev-NRTDUQAR.js} +3 -3
- package/dist/{disable-MO7AXYYF.js → disable-NROSQUHR.js} +19 -4
- package/dist/{enable-4GXLQEHD.js → enable-26FFJGX5.js} +24 -4
- package/dist/{guide-HCR43LJN.js → guide-HCLEOAGR.js} +1 -1
- package/dist/{host-VIQ5YI3V.js → host-2JOPHLN3.js} +4 -3
- package/dist/index.js +46 -46
- package/dist/{init-S2K4CQO2.js → init-MHHII5EP.js} +54 -18
- package/dist/{install-LUPE3VTC.js → install-OEFJLAWA.js} +52 -9
- package/dist/{learn-A3TP6PLL.js → learn-SSNBBDY3.js} +2 -2
- package/dist/{mcp-QNJTCZMS.js → mcp-J5VO3OH7.js} +13 -11
- package/dist/{mcp-serve-4VP4KDYG.js → mcp-serve-55DSE2J4.js} +4 -3
- package/dist/{mcp-serve-learn-UVXIDOEZ.js → mcp-serve-learn-EDBWNL4I.js} +3 -2
- package/dist/{memory-7GKTQSIW.js → memory-CDZKWOFL.js} +9 -7
- package/dist/{permission-VISPGMUK.js → permission-DPKPA2HU.js} +11 -3
- package/dist/{permissions-2SBACQHV.js → permissions-HZYUVKCY.js} +2 -2
- package/dist/{session-VDGNTICO.js → session-YWJDLNBP.js} +2 -2
- package/dist/{status-RHSL5MBU.js → status-4WMIQL7L.js} +18 -16
- package/dist/{statusline-AOZHEQSV.js → statusline-R5BNYK3H.js} +2 -2
- package/dist/{uninstall-QN6527IR.js → uninstall-EV7362NK.js} +52 -8
- package/dist/{update-ZQG25VOJ.js → update-YQBBAIIF.js} +10 -7
- package/dist/{update-check-7LKJLJPM.js → update-check-EJSGVGO6.js} +1 -1
- package/package.json +1 -1
- package/dist/chunk-RZRT7NGT.js +0 -18
|
@@ -2,23 +2,23 @@ import {
|
|
|
2
2
|
checkMemoryMcpHealth,
|
|
3
3
|
printHealthSection,
|
|
4
4
|
warnStaleMcpJson
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-YPW67OGP.js";
|
|
6
6
|
import {
|
|
7
7
|
loadConfig,
|
|
8
8
|
resolveMemoryDir
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-FQUIO5BW.js";
|
|
10
10
|
import {
|
|
11
11
|
getMemoryMcpStatus,
|
|
12
12
|
isMemoryMcpRegistered,
|
|
13
13
|
memoryConfigMenu,
|
|
14
14
|
registerMemoryMcp
|
|
15
|
-
} from "./chunk-
|
|
16
|
-
import {
|
|
17
|
-
getLibPath
|
|
18
|
-
} from "./chunk-RZRT7NGT.js";
|
|
15
|
+
} from "./chunk-ZGIUKUL2.js";
|
|
19
16
|
import {
|
|
20
17
|
showConfigHint
|
|
21
|
-
} from "./chunk-
|
|
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-
|
|
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
|
+
};
|
|
@@ -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-
|
|
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,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ensureStatusline,
|
|
3
3
|
getInstalledVersion
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-4CPUWHIN.js";
|
|
5
5
|
import {
|
|
6
6
|
ensureShellCompletion
|
|
7
7
|
} from "./chunk-667NMPN4.js";
|
|
@@ -9,15 +9,27 @@ import {
|
|
|
9
9
|
isMemoryMcpRegistered,
|
|
10
10
|
registerMemoryMcp,
|
|
11
11
|
removeMemoryMcpEntry
|
|
12
|
-
} from "./chunk-
|
|
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
|
-
|
|
18
|
+
getCodexInstalledVersion,
|
|
19
|
+
isCodexMarketplaceRegistered
|
|
20
|
+
} from "./chunk-JSH6BMVZ.js";
|
|
21
|
+
import {
|
|
22
|
+
deployOmpAgents,
|
|
23
|
+
isOmpAgentInstalled,
|
|
24
|
+
writeOmpExtensionEntry
|
|
25
|
+
} from "./chunk-GTOEIGDM.js";
|
|
17
26
|
import {
|
|
18
27
|
resolveHostFlags,
|
|
19
28
|
resolveScope
|
|
20
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-VMODQCSL.js";
|
|
30
|
+
import {
|
|
31
|
+
detectHostsAvailable
|
|
32
|
+
} from "./chunk-OFEC6OVI.js";
|
|
21
33
|
import {
|
|
22
34
|
commandExists,
|
|
23
35
|
run,
|
|
@@ -29,7 +41,7 @@ import {
|
|
|
29
41
|
} from "./chunk-5UVDWG5L.js";
|
|
30
42
|
import {
|
|
31
43
|
claudeSettingsPath
|
|
32
|
-
} from "./chunk-
|
|
44
|
+
} from "./chunk-IV5OPG34.js";
|
|
33
45
|
import {
|
|
34
46
|
log,
|
|
35
47
|
printBanner
|
|
@@ -98,14 +110,75 @@ function getStatuslineVersion() {
|
|
|
98
110
|
);
|
|
99
111
|
return match?.[1]?.replace(/^v/, "") ?? null;
|
|
100
112
|
}
|
|
113
|
+
function argvHasAgentFlag() {
|
|
114
|
+
return process.argv.some((a) => a === "--agent" || a.startsWith("--agent="));
|
|
115
|
+
}
|
|
116
|
+
function hasExplicitHost(opts) {
|
|
117
|
+
if (opts.codex === true || opts.omp === true) return true;
|
|
118
|
+
if (argvHasAgentFlag()) return true;
|
|
119
|
+
const agent = opts.agent?.trim().toLowerCase();
|
|
120
|
+
return agent === "codex" || agent === "omp";
|
|
121
|
+
}
|
|
122
|
+
function flagsForHostResolve(opts) {
|
|
123
|
+
if (!argvHasAgentFlag() && opts.agent === "claude" && (opts.codex === true || opts.omp === true)) {
|
|
124
|
+
return { ...opts, agent: void 0 };
|
|
125
|
+
}
|
|
126
|
+
return opts;
|
|
127
|
+
}
|
|
128
|
+
function isHostInstalled(host) {
|
|
129
|
+
switch (host) {
|
|
130
|
+
case "claude":
|
|
131
|
+
return isPluginInstalled();
|
|
132
|
+
case "codex":
|
|
133
|
+
return isCodexMarketplaceRegistered();
|
|
134
|
+
case "omp":
|
|
135
|
+
return isOmpAgentInstalled("user") || isOmpAgentInstalled("project");
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
function hostSectionTitle(host) {
|
|
139
|
+
switch (host) {
|
|
140
|
+
case "claude":
|
|
141
|
+
return "Claude";
|
|
142
|
+
case "codex":
|
|
143
|
+
return "Codex";
|
|
144
|
+
case "omp":
|
|
145
|
+
return "omp";
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
async function updateHost(host, opts, mode) {
|
|
149
|
+
if (host === "codex") return updateCodexCommand(opts, mode);
|
|
150
|
+
if (host === "omp") return updateOmpCommand(opts, mode);
|
|
151
|
+
return updateClaudeCommand(opts, mode);
|
|
152
|
+
}
|
|
101
153
|
async function updateCommand(opts) {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
await
|
|
154
|
+
if (hasExplicitHost(opts)) {
|
|
155
|
+
const { host } = resolveHostFlags(flagsForHostResolve(opts));
|
|
156
|
+
await updateHost(host, opts);
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
const installed = detectHostsAvailable().filter(isHostInstalled);
|
|
160
|
+
if (installed.length === 0) {
|
|
161
|
+
await updateClaudeCommand(opts);
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
if (installed.length === 1) {
|
|
165
|
+
await updateHost(installed[0], opts);
|
|
105
166
|
return;
|
|
106
167
|
}
|
|
168
|
+
printBanner("\u2728 Coding Friend Update \u2728");
|
|
169
|
+
console.log();
|
|
170
|
+
for (const [index, host] of installed.entries()) {
|
|
171
|
+
console.log(chalk.bold(`\u2500\u2500 ${hostSectionTitle(host)} \u2500\u2500`));
|
|
172
|
+
console.log();
|
|
173
|
+
await updateHost(host, opts, {
|
|
174
|
+
skipBanner: true,
|
|
175
|
+
skipCli: index > 0
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
async function updateClaudeCommand(opts, mode) {
|
|
107
180
|
const updateAll = !opts.cli && !opts.plugin && !opts.statusline;
|
|
108
|
-
const doCli = updateAll || !!opts.cli;
|
|
181
|
+
const doCli = (updateAll || !!opts.cli) && !mode?.skipCli;
|
|
109
182
|
const doPlugin = updateAll || !!opts.plugin;
|
|
110
183
|
const doStatusline = updateAll || !!opts.statusline;
|
|
111
184
|
const hasScopeFlag = !!(opts.user || opts.global || opts.project || opts.local);
|
|
@@ -115,8 +188,10 @@ async function updateCommand(opts) {
|
|
|
115
188
|
} else if (doPlugin && !hasScopeFlag) {
|
|
116
189
|
scope = "user";
|
|
117
190
|
}
|
|
118
|
-
|
|
119
|
-
|
|
191
|
+
if (!mode?.skipBanner) {
|
|
192
|
+
printBanner("\u2728 Coding Friend Update \u2728");
|
|
193
|
+
console.log();
|
|
194
|
+
}
|
|
120
195
|
const currentVersion = getInstalledVersion();
|
|
121
196
|
const latestVersion = getLatestVersion();
|
|
122
197
|
const statuslineVersion = getStatuslineVersion();
|
|
@@ -235,7 +310,7 @@ async function updateCommand(opts) {
|
|
|
235
310
|
}
|
|
236
311
|
let refreshMemoryAfterUpdate = null;
|
|
237
312
|
if (doCli) {
|
|
238
|
-
({ refreshMemoryAfterUpdate } = await import("./memory-
|
|
313
|
+
({ refreshMemoryAfterUpdate } = await import("./memory-CDZKWOFL.js"));
|
|
239
314
|
if (!latestCliVersion) {
|
|
240
315
|
log.warn("Cannot check latest CLI version from npm.");
|
|
241
316
|
} else {
|
|
@@ -293,12 +368,14 @@ async function updateCommand(opts) {
|
|
|
293
368
|
console.log();
|
|
294
369
|
log.dim("Restart Claude Code (or start a new session) to see changes.");
|
|
295
370
|
}
|
|
296
|
-
async function updateCodexCommand(opts) {
|
|
371
|
+
async function updateCodexCommand(opts, mode) {
|
|
297
372
|
const updateAll = !opts.cli && !opts.plugin && !opts.statusline;
|
|
298
|
-
const doCli = updateAll || !!opts.cli;
|
|
373
|
+
const doCli = (updateAll || !!opts.cli) && !mode?.skipCli;
|
|
299
374
|
const doPlugin = updateAll || !!opts.plugin;
|
|
300
|
-
|
|
301
|
-
|
|
375
|
+
if (!mode?.skipBanner) {
|
|
376
|
+
printBanner("\u2728 Coding Friend Codex Update \u2728");
|
|
377
|
+
console.log();
|
|
378
|
+
}
|
|
302
379
|
if (doPlugin) {
|
|
303
380
|
const beforeVersion = getCodexInstalledVersion();
|
|
304
381
|
console.log(
|
|
@@ -371,6 +448,74 @@ async function updateCodexCommand(opts) {
|
|
|
371
448
|
console.log();
|
|
372
449
|
log.dim("Restart Codex CLI (or start a new session) to see changes.");
|
|
373
450
|
}
|
|
451
|
+
function ompUpdateScopes(opts) {
|
|
452
|
+
if (opts.project || opts.local) return ["project"];
|
|
453
|
+
if (opts.user || opts.global) return ["user"];
|
|
454
|
+
const scopes = [];
|
|
455
|
+
if (isOmpAgentInstalled("user")) scopes.push("user");
|
|
456
|
+
if (isOmpAgentInstalled("project")) scopes.push("project");
|
|
457
|
+
return scopes.length > 0 ? scopes : ["user"];
|
|
458
|
+
}
|
|
459
|
+
async function updateOmpCommand(opts, mode) {
|
|
460
|
+
const updateAll = !opts.cli && !opts.plugin && !opts.statusline;
|
|
461
|
+
const doCli = (updateAll || !!opts.cli) && !mode?.skipCli;
|
|
462
|
+
const doPlugin = updateAll || !!opts.plugin;
|
|
463
|
+
const scopes = ompUpdateScopes(opts);
|
|
464
|
+
if (!mode?.skipBanner) {
|
|
465
|
+
printBanner("\u2728 Coding Friend omp Update \u2728");
|
|
466
|
+
console.log();
|
|
467
|
+
}
|
|
468
|
+
if (doPlugin) {
|
|
469
|
+
const cliVersion = getCliVersion();
|
|
470
|
+
console.log(` CLI ${cliVersion}`);
|
|
471
|
+
for (const scope of scopes) {
|
|
472
|
+
log.step(`Updating omp agents (${scope} scope)...`);
|
|
473
|
+
const { deployed, skipped } = deployOmpAgents(scope);
|
|
474
|
+
writeOmpExtensionEntry(scope);
|
|
475
|
+
const fileLabel = deployed.length === 1 ? "file" : "files";
|
|
476
|
+
log.success(
|
|
477
|
+
`omp agents updated (${deployed.length} ${fileLabel}, ${scope} scope).`
|
|
478
|
+
);
|
|
479
|
+
if (skipped.length > 0) {
|
|
480
|
+
log.warn(`Skipped ${skipped.length} agent file(s).`);
|
|
481
|
+
}
|
|
482
|
+
log.success("omp extension entry refreshed.");
|
|
483
|
+
}
|
|
484
|
+
registerMemoryMcp("omp");
|
|
485
|
+
log.success("omp memory MCP entry refreshed.");
|
|
486
|
+
}
|
|
487
|
+
if (doCli) {
|
|
488
|
+
const cliVersion = getCliVersion();
|
|
489
|
+
const latestCliVersion = getLatestCliVersion();
|
|
490
|
+
if (!latestCliVersion) {
|
|
491
|
+
log.warn("Cannot check latest CLI version from npm.");
|
|
492
|
+
} else {
|
|
493
|
+
const cmp = semverCompare(cliVersion, latestCliVersion);
|
|
494
|
+
if (cmp < 0) {
|
|
495
|
+
log.step(
|
|
496
|
+
`CLI update available: ${chalk.yellow(`v${cliVersion}`)} \u2192 ${chalk.green(`v${latestCliVersion}`)}`
|
|
497
|
+
);
|
|
498
|
+
const result = run("npm", [
|
|
499
|
+
"install",
|
|
500
|
+
"-g",
|
|
501
|
+
"coding-friend-cli@latest"
|
|
502
|
+
]);
|
|
503
|
+
if (result === null) {
|
|
504
|
+
log.error(
|
|
505
|
+
"CLI update failed. Try manually: npm install -g coding-friend-cli@latest"
|
|
506
|
+
);
|
|
507
|
+
} else {
|
|
508
|
+
log.success(`CLI updated to ${chalk.green(`v${latestCliVersion}`)}`);
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
if (opts.statusline) {
|
|
514
|
+
log.warn("omp does not use the Claude statusline. Skipping.");
|
|
515
|
+
}
|
|
516
|
+
console.log();
|
|
517
|
+
log.dim("Restart omp (or start a new session) to see changes.");
|
|
518
|
+
}
|
|
374
519
|
|
|
375
520
|
export {
|
|
376
521
|
semverCompare,
|
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
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-
|
|
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-
|
|
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
|
-
|
|
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
|
+
};
|