@codexhost/cli-darwin-x64 0.11.0 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/app/codexhost-distribution.json +1 -1
- package/app/console-server.mjs +44 -2
- package/app/console-web.js +2216 -492
- package/app/desktop-controller.mjs +391 -189
- package/app/host-runtime.mjs +3917 -625
- package/app/plugins/antigravity/plugin.mjs +15634 -15526
- package/app/plugins/claude-code/plugin.mjs +215 -70
- package/app/plugins/codebuddy/plugin.mjs +1260 -827
- package/app/plugins/cursor-cli/plugin.mjs +529 -370
- package/app/plugins/deepseek-harness/plugin.mjs +25467 -26242
- package/app/plugins/enabled.json +2 -1
- package/app/plugins/grok/plugin.mjs +936 -505
- package/app/plugins/hermes/plugin.mjs +18659 -23012
- package/app/plugins/kimi-code/plugin.mjs +1046 -703
- package/app/plugins/kiro-cli/plugin.mjs +959 -590
- package/app/plugins/omp/plugin.mjs +1038 -576
- package/app/plugins/opencode/plugin.mjs +961 -700
- package/app/plugins/pi/plugin.mjs +15911 -15724
- package/app/plugins/qoder/plugin.mjs +679 -375
- package/app/plugins/qoder-cn/plugin.mjs +345 -39
- package/app/plugins/workbuddy/plugin.mjs +417 -40
- package/app/plugins/zcode/assets/icon.svg +8 -0
- package/app/plugins/zcode/manifest.json +14 -0
- package/app/plugins/zcode/plugin.mjs +19202 -0
- package/app/renderer-extension.js +2495 -486
- package/bin/codexhost +0 -0
- package/libexec/codexhost-shim +0 -0
- package/libexec/codexhost-updater +0 -0
- package/package.json +1 -1
|
@@ -5,6 +5,409 @@ var __export = (target, all) => {
|
|
|
5
5
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
6
6
|
};
|
|
7
7
|
|
|
8
|
+
// ../../harness-discovery/dist/environment.js
|
|
9
|
+
import fs from "node:fs";
|
|
10
|
+
import path from "node:path";
|
|
11
|
+
function targetPath(platform) {
|
|
12
|
+
return platform === "win32" ? path.win32 : path.posix;
|
|
13
|
+
}
|
|
14
|
+
function environmentValue(environment, name) {
|
|
15
|
+
const lowered = name.toLowerCase();
|
|
16
|
+
for (const [key, value] of Object.entries(environment)) {
|
|
17
|
+
if (key.toLowerCase() === lowered)
|
|
18
|
+
return value;
|
|
19
|
+
}
|
|
20
|
+
return void 0;
|
|
21
|
+
}
|
|
22
|
+
function pathDelimiter(platform) {
|
|
23
|
+
return platform === "win32" ? ";" : ":";
|
|
24
|
+
}
|
|
25
|
+
function pathDirectories(environment, platform) {
|
|
26
|
+
return (environmentValue(environment, "PATH") ?? "").split(pathDelimiter(platform)).map((directory) => directory.trim().replace(/^"|"$/gu, "")).filter(Boolean);
|
|
27
|
+
}
|
|
28
|
+
function executableExtensions(command, platform, environment) {
|
|
29
|
+
if (platform !== "win32")
|
|
30
|
+
return [""];
|
|
31
|
+
if (targetPath(platform).extname(command) !== "")
|
|
32
|
+
return [""];
|
|
33
|
+
return (environmentValue(environment, "PATHEXT") ?? ".COM;.EXE;.BAT;.CMD").split(";").map((extension) => extension.trim()).filter(Boolean);
|
|
34
|
+
}
|
|
35
|
+
function isExecutableFile(filePath, platform) {
|
|
36
|
+
try {
|
|
37
|
+
fs.accessSync(filePath, platform === "win32" ? fs.constants.F_OK : fs.constants.X_OK);
|
|
38
|
+
return fs.statSync(filePath).isFile();
|
|
39
|
+
} catch {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function subdirectoryNames(directory) {
|
|
44
|
+
try {
|
|
45
|
+
return fs.readdirSync(directory, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name);
|
|
46
|
+
} catch {
|
|
47
|
+
return [];
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function newestFirst(names) {
|
|
51
|
+
return [...names].sort((left, right) => right.localeCompare(left, void 0, { numeric: true }));
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// ../../harness-discovery/dist/invocation.js
|
|
55
|
+
import path2 from "node:path";
|
|
56
|
+
function commandInvocation(command, arguments_, environment, platform = process.platform) {
|
|
57
|
+
const extension = path2.win32.extname(command).toLowerCase();
|
|
58
|
+
if (platform !== "win32" || ![".cmd", ".bat"].includes(extension)) {
|
|
59
|
+
return { command, arguments: [...arguments_], windowsVerbatimArguments: false };
|
|
60
|
+
}
|
|
61
|
+
const quote = (value) => `"${value.replaceAll("%", "%%").replaceAll('"', '""')}"`;
|
|
62
|
+
const commandLine = [command, ...arguments_].map(quote).join(" ");
|
|
63
|
+
return {
|
|
64
|
+
command: environmentValue(environment, "ComSpec") ?? "cmd.exe",
|
|
65
|
+
arguments: ["/d", "/v:off", "/s", "/c", `"${commandLine}"`],
|
|
66
|
+
windowsVerbatimArguments: true
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// ../../harness-discovery/dist/node-runtime.js
|
|
71
|
+
import path3 from "node:path";
|
|
72
|
+
function withNodeRuntimeOnPath(environment, runtimeExecutable = process.execPath, platform = process.platform) {
|
|
73
|
+
const pathKey = Object.keys(environment).find((name) => name.toLowerCase() === "path") ?? "PATH";
|
|
74
|
+
const delimiter = platform === "win32" ? ";" : ":";
|
|
75
|
+
const runtimeDirectory = path3.dirname(runtimeExecutable);
|
|
76
|
+
const directories = (environment[pathKey] ?? "").split(delimiter).filter(Boolean);
|
|
77
|
+
const equal = platform === "win32" ? (value) => value.toLowerCase() : (value) => value;
|
|
78
|
+
if (!directories.some((directory) => equal(directory) === equal(runtimeDirectory))) {
|
|
79
|
+
directories.push(runtimeDirectory);
|
|
80
|
+
}
|
|
81
|
+
return { ...environment, [pathKey]: directories.join(delimiter) };
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// ../../harness-discovery/dist/resolve.js
|
|
85
|
+
import os from "node:os";
|
|
86
|
+
|
|
87
|
+
// ../../harness-discovery/dist/version-managers.js
|
|
88
|
+
function versionManagerBinaryDirectories(context) {
|
|
89
|
+
const { platform, environment, home } = context;
|
|
90
|
+
const list = context.subdirectories ?? subdirectoryNames;
|
|
91
|
+
const pathFlavor = targetPath(platform);
|
|
92
|
+
const value = (name) => environmentValue(environment, name);
|
|
93
|
+
const directories = [];
|
|
94
|
+
const versioned = (root, ...tail) => {
|
|
95
|
+
for (const version2 of newestFirst(list(root))) {
|
|
96
|
+
directories.push(pathFlavor.join(root, version2, ...tail));
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
if (platform === "win32") {
|
|
100
|
+
const appData = value("APPDATA") ?? pathFlavor.join(home, "AppData", "Roaming");
|
|
101
|
+
const localAppData = value("LOCALAPPDATA") ?? pathFlavor.join(home, "AppData", "Local");
|
|
102
|
+
versioned(pathFlavor.join(appData, "nvm"));
|
|
103
|
+
versioned(value("FNM_DIR") ?? pathFlavor.join(appData, "fnm", "node-versions"), "installation");
|
|
104
|
+
directories.push(pathFlavor.join(localAppData, "Volta", "bin"));
|
|
105
|
+
directories.push(pathFlavor.join(home, ".bun", "bin"));
|
|
106
|
+
const pnpmHome2 = value("PNPM_HOME");
|
|
107
|
+
if (pnpmHome2)
|
|
108
|
+
directories.push(pnpmHome2);
|
|
109
|
+
directories.push(pathFlavor.join(localAppData, "pnpm"));
|
|
110
|
+
return directories;
|
|
111
|
+
}
|
|
112
|
+
versioned(pathFlavor.join(value("NVM_DIR") ?? pathFlavor.join(home, ".nvm"), "versions", "node"), "bin");
|
|
113
|
+
const fnmRoots = [
|
|
114
|
+
value("FNM_DIR"),
|
|
115
|
+
pathFlavor.join(home, ".local", "share", "fnm"),
|
|
116
|
+
pathFlavor.join(home, "Library", "Application Support", "fnm")
|
|
117
|
+
].filter((root) => root !== void 0);
|
|
118
|
+
for (const root of fnmRoots) {
|
|
119
|
+
versioned(pathFlavor.join(root, "node-versions"), "installation", "bin");
|
|
120
|
+
}
|
|
121
|
+
const voltaHome = value("VOLTA_HOME") ?? pathFlavor.join(home, ".volta");
|
|
122
|
+
versioned(pathFlavor.join(voltaHome, "tools", "image", "node"), "bin");
|
|
123
|
+
directories.push(pathFlavor.join(voltaHome, "bin"));
|
|
124
|
+
const asdfHome = value("ASDF_DATA_DIR") ?? pathFlavor.join(home, ".asdf");
|
|
125
|
+
versioned(pathFlavor.join(asdfHome, "installs", "nodejs"), "bin");
|
|
126
|
+
directories.push(pathFlavor.join(asdfHome, "shims"));
|
|
127
|
+
const nodenvHome = value("NODENV_ROOT") ?? pathFlavor.join(home, ".nodenv");
|
|
128
|
+
versioned(pathFlavor.join(nodenvHome, "versions"), "bin");
|
|
129
|
+
directories.push(pathFlavor.join(nodenvHome, "shims"));
|
|
130
|
+
versioned(pathFlavor.join(value("N_PREFIX") ?? "/usr/local", "n", "versions", "node"), "bin");
|
|
131
|
+
directories.push(pathFlavor.join(home, ".bun", "bin"));
|
|
132
|
+
const pnpmHome = value("PNPM_HOME");
|
|
133
|
+
if (pnpmHome)
|
|
134
|
+
directories.push(pnpmHome);
|
|
135
|
+
directories.push(pathFlavor.join(home, "Library", "pnpm"));
|
|
136
|
+
directories.push(pathFlavor.join(home, ".local", "share", "pnpm"));
|
|
137
|
+
for (const prefix of ["/opt/homebrew/opt", "/usr/local/opt"]) {
|
|
138
|
+
for (const formula of newestFirst(list(prefix).filter((name) => name.startsWith("node@")))) {
|
|
139
|
+
directories.push(pathFlavor.join(prefix, formula, "bin"));
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return directories;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// ../../harness-discovery/dist/resolve.js
|
|
146
|
+
var VERSION_MANAGER_ROOTS = "<version-managers>";
|
|
147
|
+
function installRootExtensions(platform) {
|
|
148
|
+
return platform === "win32" ? [".exe", ".cmd"] : [""];
|
|
149
|
+
}
|
|
150
|
+
function resolveHomeDirectory(input) {
|
|
151
|
+
return input.homeDirectory ?? environmentValue(input.environment, "HOME") ?? environmentValue(input.environment, "USERPROFILE") ?? os.homedir();
|
|
152
|
+
}
|
|
153
|
+
function templateVariables(environment, platform, home) {
|
|
154
|
+
const pathFlavor = targetPath(platform);
|
|
155
|
+
return {
|
|
156
|
+
HOME: home,
|
|
157
|
+
USERPROFILE: home,
|
|
158
|
+
APPDATA: environmentValue(environment, "APPDATA") ?? pathFlavor.join(home, "AppData", "Roaming"),
|
|
159
|
+
LOCALAPPDATA: environmentValue(environment, "LOCALAPPDATA") ?? pathFlavor.join(home, "AppData", "Local")
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
function joinTemplate(platform, value) {
|
|
163
|
+
const pathFlavor = targetPath(platform);
|
|
164
|
+
const segments = value.split("/");
|
|
165
|
+
const head = segments[0] ?? "";
|
|
166
|
+
const tail = segments.slice(1);
|
|
167
|
+
if (head === "")
|
|
168
|
+
return pathFlavor.join(pathFlavor.sep, ...tail);
|
|
169
|
+
return tail.length === 0 ? head : pathFlavor.join(head, ...tail);
|
|
170
|
+
}
|
|
171
|
+
function expandInstallRoot(template, environment, platform, home) {
|
|
172
|
+
const variables = templateVariables(environment, platform, home);
|
|
173
|
+
let unresolved = false;
|
|
174
|
+
const substituted = template.replace(/^~(?=\/|$)/u, home).replace(/\$\{(\w+)\}/gu, (_match, name) => {
|
|
175
|
+
const value = variables[name] ?? environmentValue(environment, name);
|
|
176
|
+
if (value === void 0 || value === "") {
|
|
177
|
+
unresolved = true;
|
|
178
|
+
return "";
|
|
179
|
+
}
|
|
180
|
+
return value;
|
|
181
|
+
});
|
|
182
|
+
return unresolved ? void 0 : joinTemplate(platform, substituted);
|
|
183
|
+
}
|
|
184
|
+
function installRootDirectories(spec, input, dependencies, platform, home) {
|
|
185
|
+
const templates = (platform === "win32" ? spec.installRoots?.windows : spec.installRoots?.posix) ?? [];
|
|
186
|
+
const directories = [];
|
|
187
|
+
for (const template of templates) {
|
|
188
|
+
if (template === VERSION_MANAGER_ROOTS) {
|
|
189
|
+
directories.push(...versionManagerBinaryDirectories({
|
|
190
|
+
platform,
|
|
191
|
+
environment: input.environment,
|
|
192
|
+
home,
|
|
193
|
+
...dependencies.subdirectories ? { subdirectories: dependencies.subdirectories } : {}
|
|
194
|
+
}));
|
|
195
|
+
continue;
|
|
196
|
+
}
|
|
197
|
+
const directory = expandInstallRoot(template, input.environment, platform, home);
|
|
198
|
+
if (directory !== void 0)
|
|
199
|
+
directories.push(directory);
|
|
200
|
+
}
|
|
201
|
+
return directories;
|
|
202
|
+
}
|
|
203
|
+
function harnessCandidates(spec, input, dependencies = {}) {
|
|
204
|
+
const platform = input.platform ?? process.platform;
|
|
205
|
+
const pathFlavor = targetPath(platform);
|
|
206
|
+
const configured = input.command ?? (spec.commandEnvironmentVariable ? environmentValue(input.environment, spec.commandEnvironmentVariable) : void 0);
|
|
207
|
+
const command = configured ?? spec.command;
|
|
208
|
+
if (pathFlavor.isAbsolute(command) || command.includes("/") || command.includes("\\")) {
|
|
209
|
+
return [{ candidate: command, source: "configured" }];
|
|
210
|
+
}
|
|
211
|
+
const candidates = [];
|
|
212
|
+
const extensions = executableExtensions(command, platform, input.environment);
|
|
213
|
+
for (const directory of pathDirectories(input.environment, platform)) {
|
|
214
|
+
for (const extension of extensions) {
|
|
215
|
+
candidates.push({
|
|
216
|
+
candidate: pathFlavor.join(directory, command + extension),
|
|
217
|
+
source: "path"
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
if (configured !== void 0)
|
|
222
|
+
return candidates;
|
|
223
|
+
const home = resolveHomeDirectory(input);
|
|
224
|
+
for (const directory of installRootDirectories(spec, input, dependencies, platform, home)) {
|
|
225
|
+
for (const extension of installRootExtensions(platform)) {
|
|
226
|
+
candidates.push({
|
|
227
|
+
candidate: pathFlavor.join(directory, spec.command + extension),
|
|
228
|
+
source: "install-root"
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
return candidates;
|
|
233
|
+
}
|
|
234
|
+
function resolveHarnessExecutable(spec, input, dependencies = {}) {
|
|
235
|
+
const platform = input.platform ?? process.platform;
|
|
236
|
+
const isExecutable = dependencies.isExecutable ?? ((candidate) => isExecutableFile(candidate, platform));
|
|
237
|
+
const runnable = spec.runnableCandidate ?? ((candidate) => candidate);
|
|
238
|
+
const context = { platform, isExecutable };
|
|
239
|
+
for (const { candidate, source } of harnessCandidates(spec, input, dependencies)) {
|
|
240
|
+
const executable = runnable(candidate, context);
|
|
241
|
+
if (executable !== void 0 && isExecutable(executable))
|
|
242
|
+
return { executable, source };
|
|
243
|
+
}
|
|
244
|
+
return void 0;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
// ../../harness-discovery/dist/installation.js
|
|
248
|
+
import { execFile } from "node:child_process";
|
|
249
|
+
import { homedir } from "node:os";
|
|
250
|
+
function runInstallationCommand(command, args, environment, timeout = 3e4) {
|
|
251
|
+
const env = withNodeRuntimeOnPath(environment);
|
|
252
|
+
const invocation = /\.[cm]?js$/i.test(command) ? commandInvocation(process.execPath, [command, ...args], env) : commandInvocation(command, args, env);
|
|
253
|
+
return new Promise((resolve, reject) => {
|
|
254
|
+
const child = execFile(invocation.command, invocation.arguments, {
|
|
255
|
+
env,
|
|
256
|
+
cwd: env.HOME ?? env.USERPROFILE ?? homedir(),
|
|
257
|
+
encoding: "utf8",
|
|
258
|
+
timeout,
|
|
259
|
+
killSignal: "SIGKILL",
|
|
260
|
+
maxBuffer: 1024 * 1024,
|
|
261
|
+
windowsHide: true,
|
|
262
|
+
windowsVerbatimArguments: invocation.windowsVerbatimArguments
|
|
263
|
+
}, (error51, stdout, stderr) => {
|
|
264
|
+
if (error51)
|
|
265
|
+
reject(new Error(error51.killed ? "Harness command timed out" : "Harness command failed; check the native installation and retry"));
|
|
266
|
+
else
|
|
267
|
+
resolve((stdout || stderr).trim());
|
|
268
|
+
});
|
|
269
|
+
child.stdin?.end();
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
function installationVersion(value) {
|
|
273
|
+
if (typeof value !== "string" || !/^v?\d+(?:\.\d+){1,3}(?:-[\w.-]+)?(?:\+[\w.-]+)?$/.test(value.trim()))
|
|
274
|
+
throw new Error("Harness returned an invalid version");
|
|
275
|
+
return value.trim().replace(/^v/, "");
|
|
276
|
+
}
|
|
277
|
+
function versionFromOutput(output) {
|
|
278
|
+
return installationVersion(output.match(/\b\d+(?:\.\d+){1,3}(?:-[\w.-]+)?(?:\+[\w.-]+)?\b/)?.[0]);
|
|
279
|
+
}
|
|
280
|
+
function newerInstallationVersion(current, latest) {
|
|
281
|
+
const a = installationVersion(current).replace(/\+.*/, "");
|
|
282
|
+
const b = installationVersion(latest).replace(/\+.*/, "");
|
|
283
|
+
const coreA = a.replace(/-.*/, "").split(".").map(BigInt);
|
|
284
|
+
const coreB = b.replace(/-.*/, "").split(".").map(BigInt);
|
|
285
|
+
for (let i = 0; i < Math.max(coreA.length, coreB.length); i++) {
|
|
286
|
+
if ((coreA[i] ?? 0n) !== (coreB[i] ?? 0n))
|
|
287
|
+
return (coreB[i] ?? 0n) > (coreA[i] ?? 0n);
|
|
288
|
+
}
|
|
289
|
+
const preA = a.includes("-") ? a.slice(a.indexOf("-") + 1).split(".") : [];
|
|
290
|
+
const preB = b.includes("-") ? b.slice(b.indexOf("-") + 1).split(".") : [];
|
|
291
|
+
if (!preA.length || !preB.length)
|
|
292
|
+
return !!preA.length && !preB.length;
|
|
293
|
+
for (let i = 0; i < Math.max(preA.length, preB.length); i++) {
|
|
294
|
+
const x = preA[i];
|
|
295
|
+
const y = preB[i];
|
|
296
|
+
if (x === y)
|
|
297
|
+
continue;
|
|
298
|
+
if (x === void 0 || y === void 0)
|
|
299
|
+
return x === void 0;
|
|
300
|
+
const numericX = /^\d+$/.test(x);
|
|
301
|
+
const numericY = /^\d+$/.test(y);
|
|
302
|
+
if (numericX && numericY) {
|
|
303
|
+
if (BigInt(x) === BigInt(y))
|
|
304
|
+
continue;
|
|
305
|
+
return BigInt(y) > BigInt(x);
|
|
306
|
+
}
|
|
307
|
+
if (numericX !== numericY)
|
|
308
|
+
return numericX;
|
|
309
|
+
return y > x;
|
|
310
|
+
}
|
|
311
|
+
return false;
|
|
312
|
+
}
|
|
313
|
+
function createInstallationManager(options) {
|
|
314
|
+
let checking;
|
|
315
|
+
let updating;
|
|
316
|
+
const check2 = () => checking ??= options.check().finally(() => {
|
|
317
|
+
checking = void 0;
|
|
318
|
+
});
|
|
319
|
+
return (action) => {
|
|
320
|
+
if (updating)
|
|
321
|
+
return updating;
|
|
322
|
+
if (action === "check")
|
|
323
|
+
return check2();
|
|
324
|
+
updating = (async () => {
|
|
325
|
+
const before = await check2();
|
|
326
|
+
if (!before.updateAvailable)
|
|
327
|
+
return before;
|
|
328
|
+
if (!before.canUpdate)
|
|
329
|
+
throw new Error(before.message ?? "This installation cannot be updated automatically");
|
|
330
|
+
await options.update(before);
|
|
331
|
+
const after = await check2();
|
|
332
|
+
if (after.currentVersion === before.currentVersion)
|
|
333
|
+
throw new Error("The Harness version did not change; check the native updater and retry");
|
|
334
|
+
return after;
|
|
335
|
+
})().finally(() => {
|
|
336
|
+
updating = void 0;
|
|
337
|
+
});
|
|
338
|
+
return updating;
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
async function fetchInstallationText(url2) {
|
|
342
|
+
const request = async () => {
|
|
343
|
+
const response = await fetch(url2, { signal: AbortSignal.timeout(15e3) });
|
|
344
|
+
if (!response.ok)
|
|
345
|
+
throw new Error("Could not check the latest Harness version");
|
|
346
|
+
return response.text();
|
|
347
|
+
};
|
|
348
|
+
try {
|
|
349
|
+
return await request();
|
|
350
|
+
} catch (error51) {
|
|
351
|
+
if (error51 instanceof DOMException && (error51.name === "AbortError" || error51.name === "TimeoutError"))
|
|
352
|
+
throw error51;
|
|
353
|
+
return request();
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
// ../../harness-discovery/dist/installer.js
|
|
358
|
+
import { mkdtemp, rm, writeFile } from "node:fs/promises";
|
|
359
|
+
import { tmpdir } from "node:os";
|
|
360
|
+
import { join } from "node:path";
|
|
361
|
+
function createHarnessInstaller(environment, source) {
|
|
362
|
+
return async () => {
|
|
363
|
+
if (!["darwin", "linux", "win32"].includes(process.platform))
|
|
364
|
+
throw new Error("Unsupported installation platform");
|
|
365
|
+
const env = withNodeRuntimeOnPath(environment);
|
|
366
|
+
if ("npm" in source) {
|
|
367
|
+
const npm = resolveHarnessExecutable({
|
|
368
|
+
id: "npm",
|
|
369
|
+
command: "npm",
|
|
370
|
+
installRoots: {
|
|
371
|
+
posix: [
|
|
372
|
+
"~/.npm-global/bin",
|
|
373
|
+
"~/.local/bin",
|
|
374
|
+
VERSION_MANAGER_ROOTS,
|
|
375
|
+
"/opt/homebrew/bin",
|
|
376
|
+
"/usr/local/bin",
|
|
377
|
+
"/usr/bin"
|
|
378
|
+
],
|
|
379
|
+
windows: [
|
|
380
|
+
"${APPDATA}/npm",
|
|
381
|
+
VERSION_MANAGER_ROOTS,
|
|
382
|
+
"${ProgramFiles}/nodejs",
|
|
383
|
+
"${LOCALAPPDATA}/Programs/nodejs"
|
|
384
|
+
]
|
|
385
|
+
}
|
|
386
|
+
}, { environment: env });
|
|
387
|
+
if (!npm)
|
|
388
|
+
throw new Error("Install Node.js and npm first");
|
|
389
|
+
await runInstallationCommand(npm.executable, ["install", "--global", source.npm], {
|
|
390
|
+
...env,
|
|
391
|
+
...source.allowScripts ? { npm_config_allow_scripts: source.allowScripts } : {}
|
|
392
|
+
}, 6e5);
|
|
393
|
+
return;
|
|
394
|
+
}
|
|
395
|
+
const windows = process.platform === "win32";
|
|
396
|
+
const url2 = windows ? source.windows : source.posix;
|
|
397
|
+
if (new URL(url2).protocol !== "https:")
|
|
398
|
+
throw new Error("Installer requires HTTPS");
|
|
399
|
+
const script = await fetchInstallationText(url2);
|
|
400
|
+
const directory = await mkdtemp(join(tmpdir(), "codexhost-installer-"));
|
|
401
|
+
try {
|
|
402
|
+
const file2 = join(directory, windows ? "install.ps1" : "install.sh");
|
|
403
|
+
await writeFile(file2, script, { mode: 384 });
|
|
404
|
+
await runInstallationCommand(windows ? "powershell.exe" : source.shell ?? "bash", windows ? ["-NoProfile", "-NonInteractive", "-ExecutionPolicy", "Bypass", "-File", file2] : [file2], env, 6e5);
|
|
405
|
+
} finally {
|
|
406
|
+
await rm(directory, { recursive: true, force: true });
|
|
407
|
+
}
|
|
408
|
+
};
|
|
409
|
+
}
|
|
410
|
+
|
|
8
411
|
// ../../../node_modules/diff/libesm/diff/base.js
|
|
9
412
|
var Diff = class {
|
|
10
413
|
diff(oldStr, newStr, options = {}) {
|
|
@@ -105,16 +508,16 @@ var Diff = class {
|
|
|
105
508
|
}
|
|
106
509
|
}
|
|
107
510
|
}
|
|
108
|
-
addToPath(
|
|
109
|
-
const last =
|
|
511
|
+
addToPath(path8, added, removed, oldPosInc, options) {
|
|
512
|
+
const last = path8.lastComponent;
|
|
110
513
|
if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
|
|
111
514
|
return {
|
|
112
|
-
oldPos:
|
|
515
|
+
oldPos: path8.oldPos + oldPosInc,
|
|
113
516
|
lastComponent: { count: last.count + 1, added, removed, previousComponent: last.previousComponent }
|
|
114
517
|
};
|
|
115
518
|
} else {
|
|
116
519
|
return {
|
|
117
|
-
oldPos:
|
|
520
|
+
oldPos: path8.oldPos + oldPosInc,
|
|
118
521
|
lastComponent: { count: 1, added, removed, previousComponent: last }
|
|
119
522
|
};
|
|
120
523
|
}
|
|
@@ -527,8 +930,8 @@ function splitLines(text) {
|
|
|
527
930
|
|
|
528
931
|
// dist/omp-adapter.js
|
|
529
932
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
530
|
-
import { realpath as
|
|
531
|
-
import
|
|
933
|
+
import { realpath as realpath3, stat as stat2 } from "node:fs/promises";
|
|
934
|
+
import path6 from "node:path";
|
|
532
935
|
|
|
533
936
|
// ../../../node_modules/zod/v4/classic/external.js
|
|
534
937
|
var external_exports = {};
|
|
@@ -1296,10 +1699,10 @@ function mergeDefs(...defs) {
|
|
|
1296
1699
|
function cloneDef(schema) {
|
|
1297
1700
|
return mergeDefs(schema._zod.def);
|
|
1298
1701
|
}
|
|
1299
|
-
function getElementAtPath(obj,
|
|
1300
|
-
if (!
|
|
1702
|
+
function getElementAtPath(obj, path8) {
|
|
1703
|
+
if (!path8)
|
|
1301
1704
|
return obj;
|
|
1302
|
-
return
|
|
1705
|
+
return path8.reduce((acc, key) => acc?.[key], obj);
|
|
1303
1706
|
}
|
|
1304
1707
|
function promiseAllObject(promisesObj) {
|
|
1305
1708
|
const keys = Object.keys(promisesObj);
|
|
@@ -1708,11 +2111,11 @@ function explicitlyAborted(x, startIndex = 0) {
|
|
|
1708
2111
|
}
|
|
1709
2112
|
return false;
|
|
1710
2113
|
}
|
|
1711
|
-
function prefixIssues(
|
|
2114
|
+
function prefixIssues(path8, issues) {
|
|
1712
2115
|
return issues.map((iss) => {
|
|
1713
2116
|
var _a3;
|
|
1714
2117
|
(_a3 = iss).path ?? (_a3.path = []);
|
|
1715
|
-
iss.path.unshift(
|
|
2118
|
+
iss.path.unshift(path8);
|
|
1716
2119
|
return iss;
|
|
1717
2120
|
});
|
|
1718
2121
|
}
|
|
@@ -1859,16 +2262,16 @@ function flattenError(error51, mapper = (issue2) => issue2.message) {
|
|
|
1859
2262
|
}
|
|
1860
2263
|
function formatError(error51, mapper = (issue2) => issue2.message) {
|
|
1861
2264
|
const fieldErrors = { _errors: [] };
|
|
1862
|
-
const processError = (error52,
|
|
2265
|
+
const processError = (error52, path8 = []) => {
|
|
1863
2266
|
for (const issue2 of error52.issues) {
|
|
1864
2267
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
1865
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
2268
|
+
issue2.errors.map((issues) => processError({ issues }, [...path8, ...issue2.path]));
|
|
1866
2269
|
} else if (issue2.code === "invalid_key") {
|
|
1867
|
-
processError({ issues: issue2.issues }, [...
|
|
2270
|
+
processError({ issues: issue2.issues }, [...path8, ...issue2.path]);
|
|
1868
2271
|
} else if (issue2.code === "invalid_element") {
|
|
1869
|
-
processError({ issues: issue2.issues }, [...
|
|
2272
|
+
processError({ issues: issue2.issues }, [...path8, ...issue2.path]);
|
|
1870
2273
|
} else {
|
|
1871
|
-
const fullpath = [...
|
|
2274
|
+
const fullpath = [...path8, ...issue2.path];
|
|
1872
2275
|
if (fullpath.length === 0) {
|
|
1873
2276
|
fieldErrors._errors.push(mapper(issue2));
|
|
1874
2277
|
} else {
|
|
@@ -1895,17 +2298,17 @@ function formatError(error51, mapper = (issue2) => issue2.message) {
|
|
|
1895
2298
|
}
|
|
1896
2299
|
function treeifyError(error51, mapper = (issue2) => issue2.message) {
|
|
1897
2300
|
const result = { errors: [] };
|
|
1898
|
-
const processError = (error52,
|
|
2301
|
+
const processError = (error52, path8 = []) => {
|
|
1899
2302
|
var _a3, _b;
|
|
1900
2303
|
for (const issue2 of error52.issues) {
|
|
1901
2304
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
1902
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
2305
|
+
issue2.errors.map((issues) => processError({ issues }, [...path8, ...issue2.path]));
|
|
1903
2306
|
} else if (issue2.code === "invalid_key") {
|
|
1904
|
-
processError({ issues: issue2.issues }, [...
|
|
2307
|
+
processError({ issues: issue2.issues }, [...path8, ...issue2.path]);
|
|
1905
2308
|
} else if (issue2.code === "invalid_element") {
|
|
1906
|
-
processError({ issues: issue2.issues }, [...
|
|
2309
|
+
processError({ issues: issue2.issues }, [...path8, ...issue2.path]);
|
|
1907
2310
|
} else {
|
|
1908
|
-
const fullpath = [...
|
|
2311
|
+
const fullpath = [...path8, ...issue2.path];
|
|
1909
2312
|
if (fullpath.length === 0) {
|
|
1910
2313
|
result.errors.push(mapper(issue2));
|
|
1911
2314
|
continue;
|
|
@@ -1937,8 +2340,8 @@ function treeifyError(error51, mapper = (issue2) => issue2.message) {
|
|
|
1937
2340
|
}
|
|
1938
2341
|
function toDotPath(_path) {
|
|
1939
2342
|
const segs = [];
|
|
1940
|
-
const
|
|
1941
|
-
for (const seg of
|
|
2343
|
+
const path8 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
2344
|
+
for (const seg of path8) {
|
|
1942
2345
|
if (typeof seg === "number")
|
|
1943
2346
|
segs.push(`[${seg}]`);
|
|
1944
2347
|
else if (typeof seg === "symbol")
|
|
@@ -14630,13 +15033,13 @@ function resolveRef(ref, ctx) {
|
|
|
14630
15033
|
if (!ref.startsWith("#")) {
|
|
14631
15034
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
14632
15035
|
}
|
|
14633
|
-
const
|
|
14634
|
-
if (
|
|
15036
|
+
const path8 = ref.slice(1).split("/").filter(Boolean);
|
|
15037
|
+
if (path8.length === 0) {
|
|
14635
15038
|
return ctx.rootSchema;
|
|
14636
15039
|
}
|
|
14637
15040
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
14638
|
-
if (
|
|
14639
|
-
const key =
|
|
15041
|
+
if (path8[0] === defsKey) {
|
|
15042
|
+
const key = path8[1];
|
|
14640
15043
|
if (!key || !ctx.defs[key]) {
|
|
14641
15044
|
throw new Error(`Reference not found: ${ref}`);
|
|
14642
15045
|
}
|
|
@@ -15130,6 +15533,7 @@ var CONSOLE_HOST_METHODS = Object.freeze([
|
|
|
15130
15533
|
"codexhost/harness/display-settings/get",
|
|
15131
15534
|
"codexhost/harness/display-settings/set",
|
|
15132
15535
|
"codexhost/harness/inspect",
|
|
15536
|
+
"codexhost/harness/installation",
|
|
15133
15537
|
"codexhost/harness/launch-settings/get",
|
|
15134
15538
|
"codexhost/harness/launch-settings/set",
|
|
15135
15539
|
"codexhost/harness/web-ui/open",
|
|
@@ -15776,14 +16180,17 @@ var harnessLaunchSettingsSchema = external_exports.object({
|
|
|
15776
16180
|
// ../../shared-contracts/dist/harness-installation.js
|
|
15777
16181
|
var harnessInstallationParamsSchema = external_exports.object({
|
|
15778
16182
|
harnessId: harnessIdSchema,
|
|
15779
|
-
action: external_exports.enum(["check", "update"])
|
|
16183
|
+
action: external_exports.enum(["check", "update", "install"])
|
|
15780
16184
|
}).strict();
|
|
15781
16185
|
var harnessInstallationStateSchema = external_exports.object({
|
|
15782
16186
|
currentVersion: external_exports.string().min(1).max(128),
|
|
15783
16187
|
latestVersion: external_exports.string().min(1).max(128),
|
|
15784
16188
|
updateAvailable: external_exports.boolean(),
|
|
15785
16189
|
canUpdate: external_exports.boolean(),
|
|
15786
|
-
|
|
16190
|
+
// Adapter-owned diagnostic text; UI uses messageCode rather than displaying it verbatim.
|
|
16191
|
+
message: external_exports.string().max(2048).optional(),
|
|
16192
|
+
messageCode: external_exports.string().min(1).max(128).optional(),
|
|
16193
|
+
latestVersionKind: external_exports.enum(["unknown", "tracking-branch"]).optional()
|
|
15787
16194
|
}).strict();
|
|
15788
16195
|
|
|
15789
16196
|
// ../../shared-contracts/dist/codex-accounts.js
|
|
@@ -16085,6 +16492,38 @@ var updateStatusResultSchema = external_exports.strictObject({
|
|
|
16085
16492
|
status: updateStatusSchema.nullable()
|
|
16086
16493
|
});
|
|
16087
16494
|
|
|
16495
|
+
// ../../shared-contracts/dist/remote-runtime.js
|
|
16496
|
+
var remoteUpdatePhaseSchema = external_exports.enum([
|
|
16497
|
+
"idle",
|
|
16498
|
+
"installing",
|
|
16499
|
+
"restarting",
|
|
16500
|
+
"succeeded",
|
|
16501
|
+
"failed"
|
|
16502
|
+
]);
|
|
16503
|
+
var runtimeStatusSchema = external_exports.object({
|
|
16504
|
+
runningVersion: external_exports.string().nullable(),
|
|
16505
|
+
installedVersion: external_exports.string().nullable(),
|
|
16506
|
+
restartRequired: external_exports.boolean(),
|
|
16507
|
+
remote: external_exports.boolean(),
|
|
16508
|
+
updateSupported: external_exports.boolean(),
|
|
16509
|
+
update: external_exports.object({
|
|
16510
|
+
phase: remoteUpdatePhaseSchema,
|
|
16511
|
+
targetVersion: external_exports.string().nullable(),
|
|
16512
|
+
error: external_exports.string().nullable()
|
|
16513
|
+
})
|
|
16514
|
+
});
|
|
16515
|
+
var remoteUpdateParamsSchema = external_exports.object({
|
|
16516
|
+
version: external_exports.string().regex(/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/u)
|
|
16517
|
+
}).strict();
|
|
16518
|
+
var remoteSshSetupParamsSchema = external_exports.object({
|
|
16519
|
+
hostname: external_exports.string().min(1).max(1024).refine((value) => !value.startsWith("-") && !/\s/u.test(value)),
|
|
16520
|
+
port: external_exports.number().int().min(1).max(65535).nullable(),
|
|
16521
|
+
identity: external_exports.string().max(4096).nullable(),
|
|
16522
|
+
action: external_exports.enum(["inspect", "install", "update", "repair"]),
|
|
16523
|
+
version: external_exports.string().regex(/^\d+\.\d+\.\d+$/u).nullable()
|
|
16524
|
+
}).strict();
|
|
16525
|
+
var remoteSshSetupResultSchema = external_exports.object({ state: external_exports.enum(["installed", "not-installed"]) }).strict();
|
|
16526
|
+
|
|
16088
16527
|
// ../../shared-contracts/dist/index.js
|
|
16089
16528
|
var workspaceContractVersionSchema = external_exports.literal(WORKSPACE_CONTRACT_VERSION);
|
|
16090
16529
|
|
|
@@ -16792,512 +17231,502 @@ function mapOmpSnapshot(history, state) {
|
|
|
16792
17231
|
const changed = modelChange(entry);
|
|
16793
17232
|
if (changed)
|
|
16794
17233
|
effectiveModel = changed;
|
|
16795
|
-
}
|
|
16796
|
-
index = end;
|
|
16797
|
-
}
|
|
16798
|
-
return { turns };
|
|
16799
|
-
}
|
|
16800
|
-
function resolveOmpLastTurnBoundary(history) {
|
|
16801
|
-
const users = activeOmpEntries(history).filter((entry) => messageRole(entry) === "user");
|
|
16802
|
-
const last = users.at(-1);
|
|
16803
|
-
return last ? { lastUserEntryId: last.id, sourceTurnCount: users.length } : null;
|
|
16804
|
-
}
|
|
16805
|
-
function resolveOmpForkBoundary(history, checkpointId) {
|
|
16806
|
-
const active = activeOmpEntries(history);
|
|
16807
|
-
const users = active.filter((entry) => messageRole(entry) === "user");
|
|
16808
|
-
const targetTurnIndex = users.findIndex((entry) => entry.id === checkpointId);
|
|
16809
|
-
if (targetTurnIndex < 0)
|
|
16810
|
-
throw new Error("Omp Checkpoint is not on the active branch");
|
|
16811
|
-
return {
|
|
16812
|
-
targetTurnIndex,
|
|
16813
|
-
nextUserEntryId: users[targetTurnIndex + 1]?.id ?? null
|
|
16814
|
-
};
|
|
16815
|
-
}
|
|
16816
|
-
|
|
16817
|
-
// dist/omp-session-file.js
|
|
16818
|
-
import { createReadStream } from "node:fs";
|
|
16819
|
-
import { open, realpath } from "node:fs/promises";
|
|
16820
|
-
import readline from "node:readline";
|
|
16821
|
-
var MAX_SESSION_HEADER_BYTES = 64 * 1024;
|
|
16822
|
-
var utf8Decoder = new TextDecoder("utf-8", { fatal: true });
|
|
16823
|
-
function isRecord5(value) {
|
|
16824
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
16825
|
-
}
|
|
16826
|
-
function historyEntry(value) {
|
|
16827
|
-
if (!isRecord5(value) || value.type === "title" || value.type === "session" || typeof value.id !== "string" || value.id.length === 0 || value.parentId !== null && typeof value.parentId !== "string" || typeof value.type !== "string") {
|
|
16828
|
-
return null;
|
|
16829
|
-
}
|
|
16830
|
-
return value;
|
|
16831
|
-
}
|
|
16832
|
-
async function readOmpSessionHistory(sessionFile, maxBytes) {
|
|
16833
|
-
const entries = [];
|
|
16834
|
-
let leafId = null;
|
|
16835
|
-
const lines = readline.createInterface({
|
|
16836
|
-
input: createReadStream(sessionFile, {
|
|
16837
|
-
encoding: "utf8",
|
|
16838
|
-
...maxBytes === void 0 ? {} : { end: maxBytes - 1 }
|
|
16839
|
-
}),
|
|
16840
|
-
crlfDelay: Number.POSITIVE_INFINITY
|
|
16841
|
-
});
|
|
16842
|
-
try {
|
|
16843
|
-
for await (const line of lines) {
|
|
16844
|
-
if (line.length === 0)
|
|
16845
|
-
continue;
|
|
16846
|
-
let parsed;
|
|
16847
|
-
try {
|
|
16848
|
-
parsed = JSON.parse(line);
|
|
16849
|
-
} catch {
|
|
16850
|
-
continue;
|
|
16851
|
-
}
|
|
16852
|
-
const entry = historyEntry(parsed);
|
|
16853
|
-
if (!entry)
|
|
16854
|
-
continue;
|
|
16855
|
-
entries.push(entry);
|
|
16856
|
-
leafId = entry.id;
|
|
16857
|
-
}
|
|
16858
|
-
} finally {
|
|
16859
|
-
lines.close();
|
|
16860
|
-
}
|
|
16861
|
-
return { entries, leafId };
|
|
16862
|
-
}
|
|
16863
|
-
async function readOmpSessionHeader(sessionFile) {
|
|
16864
|
-
const handle = await open(sessionFile, "r");
|
|
16865
|
-
try {
|
|
16866
|
-
const buffer = Buffer.allocUnsafe(MAX_SESSION_HEADER_BYTES);
|
|
16867
|
-
const { bytesRead } = await handle.read(buffer, 0, buffer.length, 0);
|
|
16868
|
-
const contents = buffer.subarray(0, bytesRead);
|
|
16869
|
-
const newline = contents.indexOf(10);
|
|
16870
|
-
if (newline < 0 && bytesRead === buffer.length) {
|
|
16871
|
-
throw new Error("Omp Session header exceeds the supported size");
|
|
16872
|
-
}
|
|
16873
|
-
const contentsText = utf8Decoder.decode(contents);
|
|
16874
|
-
for (const line of contentsText.split("\n")) {
|
|
16875
|
-
if (line.length === 0)
|
|
16876
|
-
continue;
|
|
16877
|
-
let parsed;
|
|
16878
|
-
try {
|
|
16879
|
-
parsed = JSON.parse(line);
|
|
16880
|
-
} catch {
|
|
16881
|
-
continue;
|
|
16882
|
-
}
|
|
16883
|
-
if (!isRecord5(parsed) || parsed.type !== "session")
|
|
16884
|
-
continue;
|
|
16885
|
-
if (typeof parsed.id !== "string" || parsed.id.length === 0 || typeof parsed.cwd !== "string" || parsed.cwd.length === 0) {
|
|
16886
|
-
throw new Error("Omp Session header is invalid");
|
|
16887
|
-
}
|
|
16888
|
-
return { type: "session", id: parsed.id, cwd: parsed.cwd };
|
|
16889
|
-
}
|
|
16890
|
-
throw new Error("Omp Session header is invalid");
|
|
16891
|
-
} finally {
|
|
16892
|
-
await handle.close();
|
|
16893
|
-
}
|
|
16894
|
-
}
|
|
16895
|
-
async function verifyOmpSessionCwd(input) {
|
|
16896
|
-
if (!input.sessionFile)
|
|
16897
|
-
throw new Error("Omp Fork Session has no persisted Session file");
|
|
16898
|
-
const header = await readOmpSessionHeader(input.sessionFile);
|
|
16899
|
-
if (header.id !== input.sessionId) {
|
|
16900
|
-
throw new Error("Omp Fork Session header identity does not match RPC state");
|
|
16901
|
-
}
|
|
16902
|
-
const [actualCwd, expectedCwd] = await Promise.all([
|
|
16903
|
-
realpath(header.cwd),
|
|
16904
|
-
realpath(input.expectedCwd)
|
|
16905
|
-
]);
|
|
16906
|
-
if (actualCwd !== expectedCwd) {
|
|
16907
|
-
throw new Error("Omp Fork Session did not bind the requested cwd");
|
|
16908
|
-
}
|
|
16909
|
-
}
|
|
16910
|
-
|
|
16911
|
-
// dist/omp-last-turn-rollback.js
|
|
16912
|
-
function modelFromState(state) {
|
|
16913
|
-
if (state.provider === null && state.modelId === null)
|
|
16914
|
-
return null;
|
|
16915
|
-
if (state.provider === null || state.modelId === null) {
|
|
16916
|
-
throw new Error("Omp state contains a partial Model identity");
|
|
16917
|
-
}
|
|
16918
|
-
return { provider: state.provider, id: state.modelId };
|
|
16919
|
-
}
|
|
16920
|
-
async function rollbackOmpLastTurn(transport, sourceSessionId, cwd) {
|
|
16921
|
-
const startupState = transport.state;
|
|
16922
|
-
const startupSessionId = startupState.sessionId;
|
|
16923
|
-
const currentModel = modelFromState(startupState);
|
|
16924
|
-
const currentThinking = startupState.thinkingLevel;
|
|
16925
|
-
const copiedHistory = await transport.getEntries();
|
|
16926
|
-
const boundary = resolveOmpLastTurnBoundary(copiedHistory);
|
|
16927
|
-
if (!boundary)
|
|
16928
|
-
return { ok: false, reason: "empty" };
|
|
16929
|
-
const sourceSnapshot = mapOmpSnapshot(copiedHistory, {
|
|
16930
|
-
sessionId: startupSessionId,
|
|
16931
|
-
model: currentModel
|
|
16932
|
-
});
|
|
16933
|
-
let state = await transport.fork(boundary.lastUserEntryId);
|
|
16934
|
-
if (state.sessionId === sourceSessionId || state.sessionId === startupSessionId) {
|
|
16935
|
-
throw new Error("Omp last-Turn rollback did not create a distinct Native Session");
|
|
16936
|
-
}
|
|
16937
|
-
if (!sameOmpModel(modelFromState(state), currentModel)) {
|
|
16938
|
-
if (!currentModel)
|
|
16939
|
-
throw new Error("Omp last-Turn rollback changed the current Model");
|
|
16940
|
-
state = await transport.selectModel(currentModel);
|
|
16941
|
-
}
|
|
16942
|
-
if (state.thinkingLevel !== currentThinking) {
|
|
16943
|
-
if (!currentThinking)
|
|
16944
|
-
throw new Error("Omp last-Turn rollback changed current Thinking");
|
|
16945
|
-
state = await transport.selectThinkingOption(currentThinking);
|
|
16946
|
-
}
|
|
16947
|
-
if (!sameOmpModel(modelFromState(state), currentModel) || state.thinkingLevel !== currentThinking) {
|
|
16948
|
-
throw new Error("Omp last-Turn rollback could not restore current Model and Thinking");
|
|
16949
|
-
}
|
|
16950
|
-
const snapshot = mapOmpSnapshot(await transport.getEntries(), {
|
|
16951
|
-
sessionId: state.sessionId,
|
|
16952
|
-
model: modelFromState(state)
|
|
16953
|
-
});
|
|
16954
|
-
const expectedTurnKeys = sourceSnapshot.turns.slice(0, -1).map((turn) => turn.nativeTurnRef.nativeTurnKey);
|
|
16955
|
-
const actualTurnKeys = snapshot.turns.map((turn) => turn.nativeTurnRef.nativeTurnKey);
|
|
16956
|
-
if (snapshot.turns.length !== boundary.sourceTurnCount - 1 || actualTurnKeys.some((key, index) => key !== expectedTurnKeys[index])) {
|
|
16957
|
-
throw new Error("Omp last-Turn rollback did not produce the exact retained history prefix");
|
|
16958
|
-
}
|
|
16959
|
-
await transport.verifySessionCwd(cwd);
|
|
16960
|
-
return { ok: true };
|
|
16961
|
-
}
|
|
16962
|
-
|
|
16963
|
-
// dist/omp-rpc-session.js
|
|
16964
|
-
import { spawn, spawnSync } from "node:child_process";
|
|
16965
|
-
import { randomUUID } from "node:crypto";
|
|
16966
|
-
import path4 from "node:path";
|
|
16967
|
-
|
|
16968
|
-
// ../../harness-discovery/dist/environment.js
|
|
16969
|
-
import fs from "node:fs";
|
|
16970
|
-
import path from "node:path";
|
|
16971
|
-
function targetPath(platform) {
|
|
16972
|
-
return platform === "win32" ? path.win32 : path.posix;
|
|
16973
|
-
}
|
|
16974
|
-
function environmentValue(environment, name) {
|
|
16975
|
-
const lowered = name.toLowerCase();
|
|
16976
|
-
for (const [key, value] of Object.entries(environment)) {
|
|
16977
|
-
if (key.toLowerCase() === lowered)
|
|
16978
|
-
return value;
|
|
16979
|
-
}
|
|
16980
|
-
return void 0;
|
|
16981
|
-
}
|
|
16982
|
-
function pathDelimiter(platform) {
|
|
16983
|
-
return platform === "win32" ? ";" : ":";
|
|
16984
|
-
}
|
|
16985
|
-
function pathDirectories(environment, platform) {
|
|
16986
|
-
return (environmentValue(environment, "PATH") ?? "").split(pathDelimiter(platform)).map((directory) => directory.trim().replace(/^"|"$/gu, "")).filter(Boolean);
|
|
16987
|
-
}
|
|
16988
|
-
function executableExtensions(command, platform, environment) {
|
|
16989
|
-
if (platform !== "win32")
|
|
16990
|
-
return [""];
|
|
16991
|
-
if (targetPath(platform).extname(command) !== "")
|
|
16992
|
-
return [""];
|
|
16993
|
-
return (environmentValue(environment, "PATHEXT") ?? ".COM;.EXE;.BAT;.CMD").split(";").map((extension) => extension.trim()).filter(Boolean);
|
|
16994
|
-
}
|
|
16995
|
-
function isExecutableFile(filePath, platform) {
|
|
16996
|
-
try {
|
|
16997
|
-
fs.accessSync(filePath, platform === "win32" ? fs.constants.F_OK : fs.constants.X_OK);
|
|
16998
|
-
return fs.statSync(filePath).isFile();
|
|
16999
|
-
} catch {
|
|
17000
|
-
return false;
|
|
17001
|
-
}
|
|
17002
|
-
}
|
|
17003
|
-
function subdirectoryNames(directory) {
|
|
17004
|
-
try {
|
|
17005
|
-
return fs.readdirSync(directory, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name);
|
|
17006
|
-
} catch {
|
|
17007
|
-
return [];
|
|
17234
|
+
}
|
|
17235
|
+
index = end;
|
|
17008
17236
|
}
|
|
17237
|
+
return { turns };
|
|
17009
17238
|
}
|
|
17010
|
-
function
|
|
17011
|
-
|
|
17239
|
+
function resolveOmpLastTurnBoundary(history) {
|
|
17240
|
+
const users = activeOmpEntries(history).filter((entry) => messageRole(entry) === "user");
|
|
17241
|
+
const last = users.at(-1);
|
|
17242
|
+
return last ? { lastUserEntryId: last.id, sourceTurnCount: users.length } : null;
|
|
17012
17243
|
}
|
|
17013
|
-
|
|
17014
|
-
|
|
17015
|
-
|
|
17016
|
-
|
|
17017
|
-
|
|
17018
|
-
|
|
17019
|
-
return { command, arguments: [...arguments_], windowsVerbatimArguments: false };
|
|
17020
|
-
}
|
|
17021
|
-
const quote = (value) => `"${value.replaceAll("%", "%%").replaceAll('"', '""')}"`;
|
|
17022
|
-
const commandLine = [command, ...arguments_].map(quote).join(" ");
|
|
17244
|
+
function resolveOmpForkBoundary(history, checkpointId) {
|
|
17245
|
+
const active = activeOmpEntries(history);
|
|
17246
|
+
const users = active.filter((entry) => messageRole(entry) === "user");
|
|
17247
|
+
const targetTurnIndex = users.findIndex((entry) => entry.id === checkpointId);
|
|
17248
|
+
if (targetTurnIndex < 0)
|
|
17249
|
+
throw new Error("Omp Checkpoint is not on the active branch");
|
|
17023
17250
|
return {
|
|
17024
|
-
|
|
17025
|
-
|
|
17026
|
-
windowsVerbatimArguments: true
|
|
17251
|
+
targetTurnIndex,
|
|
17252
|
+
nextUserEntryId: users[targetTurnIndex + 1]?.id ?? null
|
|
17027
17253
|
};
|
|
17028
17254
|
}
|
|
17029
17255
|
|
|
17030
|
-
//
|
|
17031
|
-
import
|
|
17032
|
-
|
|
17033
|
-
|
|
17034
|
-
|
|
17035
|
-
|
|
17036
|
-
|
|
17037
|
-
|
|
17038
|
-
|
|
17039
|
-
|
|
17256
|
+
// dist/omp-session-file.js
|
|
17257
|
+
import { createReadStream } from "node:fs";
|
|
17258
|
+
import { open, realpath } from "node:fs/promises";
|
|
17259
|
+
import readline from "node:readline";
|
|
17260
|
+
var MAX_SESSION_HEADER_BYTES = 64 * 1024;
|
|
17261
|
+
var utf8Decoder = new TextDecoder("utf-8", { fatal: true });
|
|
17262
|
+
function isRecord5(value) {
|
|
17263
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
17264
|
+
}
|
|
17265
|
+
function historyEntry(value) {
|
|
17266
|
+
if (!isRecord5(value) || value.type === "title" || value.type === "session" || typeof value.id !== "string" || value.id.length === 0 || value.parentId !== null && typeof value.parentId !== "string" || typeof value.type !== "string") {
|
|
17267
|
+
return null;
|
|
17040
17268
|
}
|
|
17041
|
-
return
|
|
17269
|
+
return value;
|
|
17042
17270
|
}
|
|
17043
|
-
|
|
17044
|
-
|
|
17045
|
-
|
|
17046
|
-
|
|
17047
|
-
|
|
17048
|
-
|
|
17049
|
-
|
|
17050
|
-
|
|
17051
|
-
|
|
17052
|
-
|
|
17053
|
-
|
|
17054
|
-
|
|
17055
|
-
|
|
17056
|
-
|
|
17271
|
+
async function readOmpSessionHistory(sessionFile, maxBytes) {
|
|
17272
|
+
const entries = [];
|
|
17273
|
+
let leafId = null;
|
|
17274
|
+
const lines = readline.createInterface({
|
|
17275
|
+
input: createReadStream(sessionFile, {
|
|
17276
|
+
encoding: "utf8",
|
|
17277
|
+
...maxBytes === void 0 ? {} : { end: maxBytes - 1 }
|
|
17278
|
+
}),
|
|
17279
|
+
crlfDelay: Number.POSITIVE_INFINITY
|
|
17280
|
+
});
|
|
17281
|
+
try {
|
|
17282
|
+
for await (const line of lines) {
|
|
17283
|
+
if (line.length === 0)
|
|
17284
|
+
continue;
|
|
17285
|
+
let parsed;
|
|
17286
|
+
try {
|
|
17287
|
+
parsed = JSON.parse(line);
|
|
17288
|
+
} catch {
|
|
17289
|
+
continue;
|
|
17290
|
+
}
|
|
17291
|
+
const entry = historyEntry(parsed);
|
|
17292
|
+
if (!entry)
|
|
17293
|
+
continue;
|
|
17294
|
+
entries.push(entry);
|
|
17295
|
+
leafId = entry.id;
|
|
17057
17296
|
}
|
|
17058
|
-
}
|
|
17059
|
-
|
|
17060
|
-
const appData = value("APPDATA") ?? pathFlavor.join(home, "AppData", "Roaming");
|
|
17061
|
-
const localAppData = value("LOCALAPPDATA") ?? pathFlavor.join(home, "AppData", "Local");
|
|
17062
|
-
versioned(pathFlavor.join(appData, "nvm"));
|
|
17063
|
-
versioned(value("FNM_DIR") ?? pathFlavor.join(appData, "fnm", "node-versions"), "installation");
|
|
17064
|
-
directories.push(pathFlavor.join(localAppData, "Volta", "bin"));
|
|
17065
|
-
directories.push(pathFlavor.join(home, ".bun", "bin"));
|
|
17066
|
-
const pnpmHome2 = value("PNPM_HOME");
|
|
17067
|
-
if (pnpmHome2)
|
|
17068
|
-
directories.push(pnpmHome2);
|
|
17069
|
-
directories.push(pathFlavor.join(localAppData, "pnpm"));
|
|
17070
|
-
return directories;
|
|
17071
|
-
}
|
|
17072
|
-
versioned(pathFlavor.join(value("NVM_DIR") ?? pathFlavor.join(home, ".nvm"), "versions", "node"), "bin");
|
|
17073
|
-
const fnmRoots = [
|
|
17074
|
-
value("FNM_DIR"),
|
|
17075
|
-
pathFlavor.join(home, ".local", "share", "fnm"),
|
|
17076
|
-
pathFlavor.join(home, "Library", "Application Support", "fnm")
|
|
17077
|
-
].filter((root) => root !== void 0);
|
|
17078
|
-
for (const root of fnmRoots) {
|
|
17079
|
-
versioned(pathFlavor.join(root, "node-versions"), "installation", "bin");
|
|
17297
|
+
} finally {
|
|
17298
|
+
lines.close();
|
|
17080
17299
|
}
|
|
17081
|
-
|
|
17082
|
-
|
|
17083
|
-
|
|
17084
|
-
const
|
|
17085
|
-
|
|
17086
|
-
|
|
17087
|
-
|
|
17088
|
-
|
|
17089
|
-
|
|
17090
|
-
|
|
17091
|
-
|
|
17092
|
-
|
|
17093
|
-
|
|
17094
|
-
|
|
17095
|
-
|
|
17096
|
-
|
|
17097
|
-
|
|
17098
|
-
|
|
17099
|
-
|
|
17300
|
+
return { entries, leafId };
|
|
17301
|
+
}
|
|
17302
|
+
async function readOmpSessionHeader(sessionFile) {
|
|
17303
|
+
const handle = await open(sessionFile, "r");
|
|
17304
|
+
try {
|
|
17305
|
+
const buffer = Buffer.allocUnsafe(MAX_SESSION_HEADER_BYTES);
|
|
17306
|
+
const { bytesRead } = await handle.read(buffer, 0, buffer.length, 0);
|
|
17307
|
+
const contents = buffer.subarray(0, bytesRead);
|
|
17308
|
+
const newline = contents.indexOf(10);
|
|
17309
|
+
if (newline < 0 && bytesRead === buffer.length) {
|
|
17310
|
+
throw new Error("Omp Session header exceeds the supported size");
|
|
17311
|
+
}
|
|
17312
|
+
const contentsText = utf8Decoder.decode(contents);
|
|
17313
|
+
for (const line of contentsText.split("\n")) {
|
|
17314
|
+
if (line.length === 0)
|
|
17315
|
+
continue;
|
|
17316
|
+
let parsed;
|
|
17317
|
+
try {
|
|
17318
|
+
parsed = JSON.parse(line);
|
|
17319
|
+
} catch {
|
|
17320
|
+
continue;
|
|
17321
|
+
}
|
|
17322
|
+
if (!isRecord5(parsed) || parsed.type !== "session")
|
|
17323
|
+
continue;
|
|
17324
|
+
if (typeof parsed.id !== "string" || parsed.id.length === 0 || typeof parsed.cwd !== "string" || parsed.cwd.length === 0) {
|
|
17325
|
+
throw new Error("Omp Session header is invalid");
|
|
17326
|
+
}
|
|
17327
|
+
return { type: "session", id: parsed.id, cwd: parsed.cwd };
|
|
17100
17328
|
}
|
|
17329
|
+
throw new Error("Omp Session header is invalid");
|
|
17330
|
+
} finally {
|
|
17331
|
+
await handle.close();
|
|
17101
17332
|
}
|
|
17102
|
-
return directories;
|
|
17103
17333
|
}
|
|
17104
|
-
|
|
17105
|
-
|
|
17106
|
-
|
|
17107
|
-
|
|
17108
|
-
|
|
17109
|
-
|
|
17110
|
-
|
|
17111
|
-
|
|
17334
|
+
async function verifyOmpSessionCwd(input) {
|
|
17335
|
+
if (!input.sessionFile)
|
|
17336
|
+
throw new Error("Omp Fork Session has no persisted Session file");
|
|
17337
|
+
const header = await readOmpSessionHeader(input.sessionFile);
|
|
17338
|
+
if (header.id !== input.sessionId) {
|
|
17339
|
+
throw new Error("Omp Fork Session header identity does not match RPC state");
|
|
17340
|
+
}
|
|
17341
|
+
const [actualCwd, expectedCwd] = await Promise.all([
|
|
17342
|
+
realpath(header.cwd),
|
|
17343
|
+
realpath(input.expectedCwd)
|
|
17344
|
+
]);
|
|
17345
|
+
if (actualCwd !== expectedCwd) {
|
|
17346
|
+
throw new Error("Omp Fork Session did not bind the requested cwd");
|
|
17347
|
+
}
|
|
17112
17348
|
}
|
|
17113
|
-
|
|
17114
|
-
|
|
17115
|
-
|
|
17116
|
-
|
|
17117
|
-
|
|
17118
|
-
|
|
17119
|
-
|
|
17120
|
-
|
|
17349
|
+
|
|
17350
|
+
// dist/session-import.js
|
|
17351
|
+
import { createReadStream as createReadStream2 } from "node:fs";
|
|
17352
|
+
import { opendir, realpath as realpath2, stat } from "node:fs/promises";
|
|
17353
|
+
import os2 from "node:os";
|
|
17354
|
+
import path4 from "node:path";
|
|
17355
|
+
import { createInterface } from "node:readline";
|
|
17356
|
+
|
|
17357
|
+
// ../../harness-adapter/dist/session-import.js
|
|
17358
|
+
import { lstat } from "node:fs/promises";
|
|
17359
|
+
var SessionImportChangedError = class extends Error {
|
|
17360
|
+
constructor(message3 = "Native Session changed during discovery; refresh and retry") {
|
|
17361
|
+
super(message3);
|
|
17362
|
+
this.name = "SessionImportChangedError";
|
|
17363
|
+
}
|
|
17364
|
+
};
|
|
17365
|
+
function isMissingFileError(error51) {
|
|
17366
|
+
return typeof error51 === "object" && error51 !== null && "code" in error51 && error51.code === "ENOENT";
|
|
17121
17367
|
}
|
|
17122
|
-
function
|
|
17123
|
-
|
|
17124
|
-
const segments = value.split("/");
|
|
17125
|
-
const head = segments[0] ?? "";
|
|
17126
|
-
const tail = segments.slice(1);
|
|
17127
|
-
if (head === "")
|
|
17128
|
-
return pathFlavor.join(pathFlavor.sep, ...tail);
|
|
17129
|
-
return tail.length === 0 ? head : pathFlavor.join(head, ...tail);
|
|
17368
|
+
function sameFileFingerprint(left, right) {
|
|
17369
|
+
return left === null || right === null ? left === right : left.dev === right.dev && left.ino === right.ino && left.size === right.size && left.mtimeMs === right.mtimeMs && left.ctimeMs === right.ctimeMs;
|
|
17130
17370
|
}
|
|
17131
|
-
|
|
17132
|
-
|
|
17133
|
-
|
|
17134
|
-
const substituted = template.replace(/^~(?=\/|$)/u, home).replace(/\$\{(\w+)\}/gu, (_match, name) => {
|
|
17135
|
-
const value = variables[name] ?? environmentValue(environment, name);
|
|
17136
|
-
if (value === void 0 || value === "") {
|
|
17137
|
-
unresolved = true;
|
|
17138
|
-
return "";
|
|
17139
|
-
}
|
|
17140
|
-
return value;
|
|
17141
|
-
});
|
|
17142
|
-
return unresolved ? void 0 : joinTemplate(platform, substituted);
|
|
17371
|
+
var STORAGE_ACCESS_ERRORS = /* @__PURE__ */ new Set(["EACCES", "EPERM", "EIO", "EMFILE", "ENFILE"]);
|
|
17372
|
+
function isStorageAccessError(error51) {
|
|
17373
|
+
return typeof error51 === "object" && error51 !== null && "code" in error51 && typeof error51.code === "string" && STORAGE_ACCESS_ERRORS.has(error51.code);
|
|
17143
17374
|
}
|
|
17144
|
-
function
|
|
17145
|
-
|
|
17146
|
-
|
|
17147
|
-
|
|
17148
|
-
if (
|
|
17149
|
-
|
|
17150
|
-
|
|
17151
|
-
environment: input.environment,
|
|
17152
|
-
home,
|
|
17153
|
-
...dependencies.subdirectories ? { subdirectories: dependencies.subdirectories } : {}
|
|
17154
|
-
}));
|
|
17155
|
-
continue;
|
|
17156
|
-
}
|
|
17157
|
-
const directory = expandInstallRoot(template, input.environment, platform, home);
|
|
17158
|
-
if (directory !== void 0)
|
|
17159
|
-
directories.push(directory);
|
|
17375
|
+
async function optionalLstat(file2) {
|
|
17376
|
+
try {
|
|
17377
|
+
return await lstat(file2);
|
|
17378
|
+
} catch (error51) {
|
|
17379
|
+
if (isMissingFileError(error51))
|
|
17380
|
+
return null;
|
|
17381
|
+
throw error51;
|
|
17160
17382
|
}
|
|
17161
|
-
return directories;
|
|
17162
17383
|
}
|
|
17163
|
-
function
|
|
17164
|
-
const
|
|
17165
|
-
const
|
|
17166
|
-
const
|
|
17167
|
-
|
|
17168
|
-
|
|
17169
|
-
|
|
17384
|
+
async function readStableFiles(files, read) {
|
|
17385
|
+
const before = await Promise.all(files.map(optionalLstat));
|
|
17386
|
+
const value = await read(before);
|
|
17387
|
+
const after = await Promise.all(files.map(optionalLstat));
|
|
17388
|
+
if (before.some((info, index) => !sameFileFingerprint(info, after[index] ?? null)))
|
|
17389
|
+
throw new SessionImportChangedError();
|
|
17390
|
+
return value;
|
|
17391
|
+
}
|
|
17392
|
+
function sessionImportTitle(value, maxLength = HARNESS_SESSION_IMPORT_TITLE_MAX_LENGTH) {
|
|
17393
|
+
if (typeof value !== "string")
|
|
17394
|
+
return null;
|
|
17395
|
+
const normalized = value.replaceAll("\0", "").replaceAll(/\s+/gu, " ").trim();
|
|
17396
|
+
if (!normalized)
|
|
17397
|
+
return null;
|
|
17398
|
+
if (normalized.length <= maxLength)
|
|
17399
|
+
return normalized;
|
|
17400
|
+
const characters = [...normalized];
|
|
17401
|
+
if (characters.length <= maxLength)
|
|
17402
|
+
return normalized;
|
|
17403
|
+
return `${characters.slice(0, maxLength - 1).join("").trimEnd()}…`;
|
|
17404
|
+
}
|
|
17405
|
+
function sessionImportCandidate(input) {
|
|
17406
|
+
const time3 = typeof input.updatedAt === "number" ? input.updatedAt : typeof input.updatedAt === "string" ? Date.parse(input.updatedAt) : Number.NaN;
|
|
17407
|
+
const parsed = harnessSessionImportCandidateSchema.safeParse({
|
|
17408
|
+
nativeSessionId: input.nativeSessionId,
|
|
17409
|
+
cwd: input.cwd,
|
|
17410
|
+
title: typeof input.title === "string" && input.title.trim().length > 0 ? input.title : null,
|
|
17411
|
+
updatedAt: Math.floor(time3),
|
|
17412
|
+
// Unknown must stay unknown; only an explicit boolean is a native statement.
|
|
17413
|
+
running: typeof input.running === "boolean" ? input.running : null
|
|
17414
|
+
});
|
|
17415
|
+
return parsed.success ? parsed.data : null;
|
|
17416
|
+
}
|
|
17417
|
+
var SessionImportScope = class {
|
|
17418
|
+
#abort = new AbortController();
|
|
17419
|
+
#options;
|
|
17420
|
+
#pending = /* @__PURE__ */ new Set();
|
|
17421
|
+
constructor(options) {
|
|
17422
|
+
this.#options = options;
|
|
17170
17423
|
}
|
|
17171
|
-
|
|
17172
|
-
|
|
17173
|
-
|
|
17174
|
-
|
|
17175
|
-
|
|
17176
|
-
candidate: pathFlavor.join(directory, command + extension),
|
|
17177
|
-
source: "path"
|
|
17178
|
-
});
|
|
17179
|
-
}
|
|
17424
|
+
#closed() {
|
|
17425
|
+
return {
|
|
17426
|
+
ok: false,
|
|
17427
|
+
error: { code: "invalidState", message: this.#options.closedMessage, retryable: false }
|
|
17428
|
+
};
|
|
17180
17429
|
}
|
|
17181
|
-
|
|
17182
|
-
|
|
17183
|
-
|
|
17184
|
-
|
|
17185
|
-
|
|
17186
|
-
|
|
17187
|
-
|
|
17188
|
-
|
|
17189
|
-
|
|
17430
|
+
read(operation) {
|
|
17431
|
+
const signal = this.#abort.signal;
|
|
17432
|
+
if (signal.aborted)
|
|
17433
|
+
return Promise.resolve(this.#closed());
|
|
17434
|
+
let started;
|
|
17435
|
+
try {
|
|
17436
|
+
started = operation(signal);
|
|
17437
|
+
} catch (error51) {
|
|
17438
|
+
started = Promise.reject(error51 instanceof Error ? error51 : new Error("Session read failed"));
|
|
17190
17439
|
}
|
|
17440
|
+
const request = started.then((value) => signal.aborted ? this.#closed() : { ok: true, value }).catch(() => signal.aborted ? this.#closed() : {
|
|
17441
|
+
ok: false,
|
|
17442
|
+
error: {
|
|
17443
|
+
code: "unavailable",
|
|
17444
|
+
message: this.#options.unavailableMessage,
|
|
17445
|
+
retryable: true
|
|
17446
|
+
}
|
|
17447
|
+
}).finally(() => this.#pending.delete(request));
|
|
17448
|
+
this.#pending.add(request);
|
|
17449
|
+
return request;
|
|
17191
17450
|
}
|
|
17192
|
-
|
|
17193
|
-
|
|
17194
|
-
|
|
17195
|
-
|
|
17196
|
-
|
|
17197
|
-
|
|
17198
|
-
|
|
17199
|
-
|
|
17200
|
-
|
|
17201
|
-
|
|
17202
|
-
|
|
17451
|
+
/** `read` for `resolveCandidate`: a null source is the selected Session having disappeared. */
|
|
17452
|
+
async resolve(operation) {
|
|
17453
|
+
const result = await this.read(operation);
|
|
17454
|
+
if (!result.ok)
|
|
17455
|
+
return result;
|
|
17456
|
+
return result.value ? { ok: true, value: result.value } : {
|
|
17457
|
+
ok: false,
|
|
17458
|
+
error: {
|
|
17459
|
+
code: "sessionNotFound",
|
|
17460
|
+
message: this.#options.notFoundMessage,
|
|
17461
|
+
retryable: false
|
|
17462
|
+
}
|
|
17463
|
+
};
|
|
17203
17464
|
}
|
|
17204
|
-
|
|
17205
|
-
|
|
17465
|
+
/** Idempotent. Resolves after every started read has settled. */
|
|
17466
|
+
async close() {
|
|
17467
|
+
this.#abort.abort();
|
|
17468
|
+
await Promise.allSettled(this.#pending);
|
|
17469
|
+
}
|
|
17470
|
+
};
|
|
17206
17471
|
|
|
17207
|
-
//
|
|
17208
|
-
|
|
17209
|
-
|
|
17210
|
-
function runInstallationCommand(command, args, environment, timeout = 3e4) {
|
|
17211
|
-
const env = withNodeRuntimeOnPath(environment);
|
|
17212
|
-
const invocation = /\.[cm]?js$/i.test(command) ? commandInvocation(process.execPath, [command, ...args], env) : commandInvocation(command, args, env);
|
|
17213
|
-
return new Promise((resolve, reject) => {
|
|
17214
|
-
const child = execFile(invocation.command, invocation.arguments, {
|
|
17215
|
-
env,
|
|
17216
|
-
cwd: env.HOME ?? env.USERPROFILE ?? homedir(),
|
|
17217
|
-
encoding: "utf8",
|
|
17218
|
-
timeout,
|
|
17219
|
-
killSignal: "SIGKILL",
|
|
17220
|
-
maxBuffer: 1024 * 1024,
|
|
17221
|
-
windowsHide: true,
|
|
17222
|
-
windowsVerbatimArguments: invocation.windowsVerbatimArguments
|
|
17223
|
-
}, (error51, stdout, stderr) => {
|
|
17224
|
-
if (error51)
|
|
17225
|
-
reject(new Error(error51.killed ? "Harness command timed out" : "Harness command failed; check the native installation and retry"));
|
|
17226
|
-
else
|
|
17227
|
-
resolve((stdout || stderr).trim());
|
|
17228
|
-
});
|
|
17229
|
-
child.stdin?.end();
|
|
17230
|
-
});
|
|
17472
|
+
// dist/session-import.js
|
|
17473
|
+
function isRecord6(value) {
|
|
17474
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
17231
17475
|
}
|
|
17232
|
-
function
|
|
17233
|
-
|
|
17234
|
-
throw new Error("Harness returned an invalid version");
|
|
17235
|
-
return value.trim().replace(/^v/, "");
|
|
17476
|
+
function expandDirectory(value, home) {
|
|
17477
|
+
return path4.resolve(value === "~" ? home : value.startsWith(`~${path4.sep}`) || value.startsWith("~/") ? path4.join(home, value.slice(2)) : value);
|
|
17236
17478
|
}
|
|
17237
|
-
function
|
|
17238
|
-
|
|
17479
|
+
function ompSessionImportDirectory(environment) {
|
|
17480
|
+
const home = (process.platform === "win32" ? environment.USERPROFILE : environment.HOME) || os2.homedir();
|
|
17481
|
+
const custom2 = environment.PI_CODING_AGENT_SESSION_DIR;
|
|
17482
|
+
if (custom2)
|
|
17483
|
+
return { directory: expandDirectory(custom2, home), flat: true };
|
|
17484
|
+
const agent = environment.PI_CODING_AGENT_DIR;
|
|
17485
|
+
return {
|
|
17486
|
+
directory: path4.join(agent ? expandDirectory(agent, home) : path4.join(home, ".omp", "agent"), "sessions"),
|
|
17487
|
+
flat: false
|
|
17488
|
+
};
|
|
17239
17489
|
}
|
|
17240
|
-
function
|
|
17241
|
-
|
|
17242
|
-
|
|
17243
|
-
|
|
17244
|
-
|
|
17245
|
-
|
|
17246
|
-
|
|
17247
|
-
|
|
17248
|
-
}
|
|
17249
|
-
const
|
|
17250
|
-
|
|
17251
|
-
|
|
17252
|
-
|
|
17253
|
-
|
|
17254
|
-
|
|
17255
|
-
|
|
17256
|
-
|
|
17257
|
-
|
|
17258
|
-
|
|
17259
|
-
|
|
17260
|
-
const numericX = /^\d+$/.test(x);
|
|
17261
|
-
const numericY = /^\d+$/.test(y);
|
|
17262
|
-
if (numericX && numericY) {
|
|
17263
|
-
if (BigInt(x) === BigInt(y))
|
|
17490
|
+
function messageText(content) {
|
|
17491
|
+
if (typeof content === "string")
|
|
17492
|
+
return content;
|
|
17493
|
+
if (!Array.isArray(content))
|
|
17494
|
+
return "";
|
|
17495
|
+
return content.filter((part) => isRecord6(part) && part.type === "text" && typeof part.text === "string").map((part) => String(part.text)).join(" ");
|
|
17496
|
+
}
|
|
17497
|
+
async function readFacts(file2, signal) {
|
|
17498
|
+
const stream = createReadStream2(file2, { encoding: "utf8", signal });
|
|
17499
|
+
const lines = createInterface({ input: stream, crlfDelay: Infinity });
|
|
17500
|
+
let header = null;
|
|
17501
|
+
let nativeTitle = null;
|
|
17502
|
+
let firstPrompt = null;
|
|
17503
|
+
let updatedAt = null;
|
|
17504
|
+
let leafHasUser = false;
|
|
17505
|
+
const hasUserAncestry = /* @__PURE__ */ new Map();
|
|
17506
|
+
try {
|
|
17507
|
+
for await (const line of lines) {
|
|
17508
|
+
signal.throwIfAborted();
|
|
17509
|
+
if (!line.trim())
|
|
17264
17510
|
continue;
|
|
17265
|
-
|
|
17511
|
+
let entry;
|
|
17512
|
+
try {
|
|
17513
|
+
entry = JSON.parse(line);
|
|
17514
|
+
} catch {
|
|
17515
|
+
continue;
|
|
17516
|
+
}
|
|
17517
|
+
if (!isRecord6(entry))
|
|
17518
|
+
continue;
|
|
17519
|
+
if (entry.type === "title") {
|
|
17520
|
+
nativeTitle = sessionImportTitle(entry.title);
|
|
17521
|
+
continue;
|
|
17522
|
+
}
|
|
17523
|
+
if (entry.type === "session") {
|
|
17524
|
+
if (header)
|
|
17525
|
+
return null;
|
|
17526
|
+
if (typeof entry.id !== "string" || entry.id.length === 0 || typeof entry.cwd !== "string" || !path4.isAbsolute(entry.cwd))
|
|
17527
|
+
return null;
|
|
17528
|
+
header = { id: entry.id, cwd: entry.cwd };
|
|
17529
|
+
continue;
|
|
17530
|
+
}
|
|
17531
|
+
if (typeof entry.id !== "string" || entry.id.length === 0)
|
|
17532
|
+
continue;
|
|
17533
|
+
const message3 = isRecord6(entry.message) ? entry.message : null;
|
|
17534
|
+
const isUser = entry.type === "message" && message3?.role === "user";
|
|
17535
|
+
if (isUser)
|
|
17536
|
+
firstPrompt ??= sessionImportTitle(messageText(message3?.content));
|
|
17537
|
+
leafHasUser = isUser || typeof entry.parentId === "string" && hasUserAncestry.get(entry.parentId) === true;
|
|
17538
|
+
hasUserAncestry.set(entry.id, leafHasUser);
|
|
17539
|
+
if (entry.type === "message" && (message3?.role === "user" || message3?.role === "assistant")) {
|
|
17540
|
+
const time3 = typeof message3.timestamp === "number" ? message3.timestamp : typeof entry.timestamp === "string" ? Date.parse(entry.timestamp) : Number.NaN;
|
|
17541
|
+
if (Number.isFinite(time3) && time3 >= 0)
|
|
17542
|
+
updatedAt = time3;
|
|
17543
|
+
}
|
|
17266
17544
|
}
|
|
17267
|
-
|
|
17268
|
-
|
|
17269
|
-
|
|
17545
|
+
} finally {
|
|
17546
|
+
lines.close();
|
|
17547
|
+
stream.destroy();
|
|
17270
17548
|
}
|
|
17271
|
-
|
|
17272
|
-
|
|
17273
|
-
|
|
17274
|
-
|
|
17275
|
-
|
|
17276
|
-
|
|
17277
|
-
|
|
17549
|
+
if (!header || !leafHasUser)
|
|
17550
|
+
return null;
|
|
17551
|
+
return {
|
|
17552
|
+
nativeSessionId: header.id,
|
|
17553
|
+
cwd: header.cwd,
|
|
17554
|
+
title: nativeTitle ?? firstPrompt,
|
|
17555
|
+
updatedAt
|
|
17556
|
+
};
|
|
17557
|
+
}
|
|
17558
|
+
var OmpSessionImport = class {
|
|
17559
|
+
#location;
|
|
17560
|
+
#scope = new SessionImportScope({
|
|
17561
|
+
closedMessage: "Omp Session import is closed",
|
|
17562
|
+
unavailableMessage: "Omp sessions could not be read; close native clients, check storage access and retry",
|
|
17563
|
+
notFoundMessage: "Omp Session is no longer importable"
|
|
17278
17564
|
});
|
|
17279
|
-
|
|
17280
|
-
|
|
17281
|
-
|
|
17282
|
-
|
|
17283
|
-
|
|
17284
|
-
|
|
17285
|
-
|
|
17286
|
-
|
|
17287
|
-
|
|
17288
|
-
|
|
17289
|
-
|
|
17290
|
-
await
|
|
17291
|
-
|
|
17292
|
-
|
|
17293
|
-
|
|
17294
|
-
return
|
|
17295
|
-
})().finally(() => {
|
|
17296
|
-
updating = void 0;
|
|
17565
|
+
constructor(environment) {
|
|
17566
|
+
this.#location = ompSessionImportDirectory(environment);
|
|
17567
|
+
}
|
|
17568
|
+
listCandidates() {
|
|
17569
|
+
return this.#scope.read(async (signal) => [...(await this.#sources(signal)).values()].flatMap((sources) => (
|
|
17570
|
+
// One identity in two files cannot be resumed unambiguously.
|
|
17571
|
+
sources.length === 1 && sources[0] ? [sources[0].candidate] : []
|
|
17572
|
+
)));
|
|
17573
|
+
}
|
|
17574
|
+
resolveCandidate(nativeSessionId) {
|
|
17575
|
+
return this.#scope.resolve(async (signal) => {
|
|
17576
|
+
const sources = (await this.#sources(signal)).get(nativeSessionId);
|
|
17577
|
+
if (sources?.length !== 1 || !sources[0])
|
|
17578
|
+
return null;
|
|
17579
|
+
const source = await this.#source(sources[0].file, signal);
|
|
17580
|
+
return source?.nativeRef.nativeSessionId === nativeSessionId ? { candidate: source.candidate, nativeRef: source.nativeRef } : null;
|
|
17297
17581
|
});
|
|
17298
|
-
|
|
17299
|
-
|
|
17582
|
+
}
|
|
17583
|
+
close() {
|
|
17584
|
+
return this.#scope.close();
|
|
17585
|
+
}
|
|
17586
|
+
async #sessionFiles(signal) {
|
|
17587
|
+
const { directory, flat } = this.#location;
|
|
17588
|
+
const info = await optionalLstat(directory);
|
|
17589
|
+
if (!info)
|
|
17590
|
+
return [];
|
|
17591
|
+
if (!info.isDirectory())
|
|
17592
|
+
throw new Error("Omp Session store is not a directory");
|
|
17593
|
+
const files = [];
|
|
17594
|
+
const visit = async (current, projectLevel) => {
|
|
17595
|
+
const entries = await opendir(current).catch((error51) => {
|
|
17596
|
+
if (isMissingFileError(error51))
|
|
17597
|
+
return null;
|
|
17598
|
+
throw error51;
|
|
17599
|
+
});
|
|
17600
|
+
if (!entries)
|
|
17601
|
+
return;
|
|
17602
|
+
for await (const entry of entries) {
|
|
17603
|
+
signal.throwIfAborted();
|
|
17604
|
+
if (projectLevel && entry.isDirectory())
|
|
17605
|
+
await visit(path4.join(current, entry.name), false);
|
|
17606
|
+
else if (!projectLevel && entry.isFile() && entry.name.endsWith(".jsonl"))
|
|
17607
|
+
files.push(path4.join(current, entry.name));
|
|
17608
|
+
}
|
|
17609
|
+
};
|
|
17610
|
+
await visit(directory, !flat);
|
|
17611
|
+
return files;
|
|
17612
|
+
}
|
|
17613
|
+
/** Session ID to every readable file claiming it. Files changing under the read are skipped. */
|
|
17614
|
+
async #sources(signal) {
|
|
17615
|
+
const found = /* @__PURE__ */ new Map();
|
|
17616
|
+
for (const file2 of await this.#sessionFiles(signal)) {
|
|
17617
|
+
signal.throwIfAborted();
|
|
17618
|
+
try {
|
|
17619
|
+
const source = await this.#source(file2, signal);
|
|
17620
|
+
if (!source)
|
|
17621
|
+
continue;
|
|
17622
|
+
const sources = found.get(source.nativeRef.nativeSessionId) ?? [];
|
|
17623
|
+
sources.push(source);
|
|
17624
|
+
found.set(source.nativeRef.nativeSessionId, sources);
|
|
17625
|
+
} catch (error51) {
|
|
17626
|
+
if (!(error51 instanceof SessionImportChangedError))
|
|
17627
|
+
throw error51;
|
|
17628
|
+
}
|
|
17629
|
+
}
|
|
17630
|
+
return found;
|
|
17631
|
+
}
|
|
17632
|
+
async #source(file2, signal) {
|
|
17633
|
+
signal.throwIfAborted();
|
|
17634
|
+
return readStableFiles([file2], async ([info]) => {
|
|
17635
|
+
if (!info?.isFile() || info.size === 0)
|
|
17636
|
+
return null;
|
|
17637
|
+
try {
|
|
17638
|
+
const facts = await readFacts(file2, signal);
|
|
17639
|
+
if (!facts)
|
|
17640
|
+
return null;
|
|
17641
|
+
const cwd = await realpath2(facts.cwd);
|
|
17642
|
+
if (!(await stat(cwd)).isDirectory())
|
|
17643
|
+
return null;
|
|
17644
|
+
const candidate = sessionImportCandidate({
|
|
17645
|
+
nativeSessionId: facts.nativeSessionId,
|
|
17646
|
+
cwd,
|
|
17647
|
+
title: facts.title,
|
|
17648
|
+
updatedAt: facts.updatedAt ?? info.mtimeMs
|
|
17649
|
+
// OMP has no cross-process activity marker: idleness cannot be established.
|
|
17650
|
+
});
|
|
17651
|
+
if (!candidate)
|
|
17652
|
+
return null;
|
|
17653
|
+
return {
|
|
17654
|
+
file: file2,
|
|
17655
|
+
candidate,
|
|
17656
|
+
// Resume needs the file itself: OMP is started with `--session <file>`.
|
|
17657
|
+
nativeRef: nativeSessionRefSchema.parse({
|
|
17658
|
+
harnessId: "omp",
|
|
17659
|
+
nativeSessionId: facts.nativeSessionId,
|
|
17660
|
+
locator: { sessionFile: await realpath2(file2) },
|
|
17661
|
+
formatVersion: 1
|
|
17662
|
+
})
|
|
17663
|
+
};
|
|
17664
|
+
} catch (error51) {
|
|
17665
|
+
signal.throwIfAborted();
|
|
17666
|
+
if (isStorageAccessError(error51))
|
|
17667
|
+
throw error51;
|
|
17668
|
+
return null;
|
|
17669
|
+
}
|
|
17670
|
+
});
|
|
17671
|
+
}
|
|
17672
|
+
};
|
|
17673
|
+
|
|
17674
|
+
// dist/omp-last-turn-rollback.js
|
|
17675
|
+
function modelFromState(state) {
|
|
17676
|
+
if (state.provider === null && state.modelId === null)
|
|
17677
|
+
return null;
|
|
17678
|
+
if (state.provider === null || state.modelId === null) {
|
|
17679
|
+
throw new Error("Omp state contains a partial Model identity");
|
|
17680
|
+
}
|
|
17681
|
+
return { provider: state.provider, id: state.modelId };
|
|
17300
17682
|
}
|
|
17683
|
+
async function rollbackOmpLastTurn(transport, sourceSessionId, cwd) {
|
|
17684
|
+
const startupState = transport.state;
|
|
17685
|
+
const startupSessionId = startupState.sessionId;
|
|
17686
|
+
const currentModel = modelFromState(startupState);
|
|
17687
|
+
const currentThinking = startupState.thinkingLevel;
|
|
17688
|
+
const copiedHistory = await transport.getEntries();
|
|
17689
|
+
const boundary = resolveOmpLastTurnBoundary(copiedHistory);
|
|
17690
|
+
if (!boundary)
|
|
17691
|
+
return { ok: false, reason: "empty" };
|
|
17692
|
+
const sourceSnapshot = mapOmpSnapshot(copiedHistory, {
|
|
17693
|
+
sessionId: startupSessionId,
|
|
17694
|
+
model: currentModel
|
|
17695
|
+
});
|
|
17696
|
+
let state = await transport.fork(boundary.lastUserEntryId);
|
|
17697
|
+
if (state.sessionId === sourceSessionId || state.sessionId === startupSessionId) {
|
|
17698
|
+
throw new Error("Omp last-Turn rollback did not create a distinct Native Session");
|
|
17699
|
+
}
|
|
17700
|
+
if (!sameOmpModel(modelFromState(state), currentModel)) {
|
|
17701
|
+
if (!currentModel)
|
|
17702
|
+
throw new Error("Omp last-Turn rollback changed the current Model");
|
|
17703
|
+
state = await transport.selectModel(currentModel);
|
|
17704
|
+
}
|
|
17705
|
+
if (state.thinkingLevel !== currentThinking) {
|
|
17706
|
+
if (!currentThinking)
|
|
17707
|
+
throw new Error("Omp last-Turn rollback changed current Thinking");
|
|
17708
|
+
state = await transport.selectThinkingOption(currentThinking);
|
|
17709
|
+
}
|
|
17710
|
+
if (!sameOmpModel(modelFromState(state), currentModel) || state.thinkingLevel !== currentThinking) {
|
|
17711
|
+
throw new Error("Omp last-Turn rollback could not restore current Model and Thinking");
|
|
17712
|
+
}
|
|
17713
|
+
const snapshot = mapOmpSnapshot(await transport.getEntries(), {
|
|
17714
|
+
sessionId: state.sessionId,
|
|
17715
|
+
model: modelFromState(state)
|
|
17716
|
+
});
|
|
17717
|
+
const expectedTurnKeys = sourceSnapshot.turns.slice(0, -1).map((turn) => turn.nativeTurnRef.nativeTurnKey);
|
|
17718
|
+
const actualTurnKeys = snapshot.turns.map((turn) => turn.nativeTurnRef.nativeTurnKey);
|
|
17719
|
+
if (snapshot.turns.length !== boundary.sourceTurnCount - 1 || actualTurnKeys.some((key, index) => key !== expectedTurnKeys[index])) {
|
|
17720
|
+
throw new Error("Omp last-Turn rollback did not produce the exact retained history prefix");
|
|
17721
|
+
}
|
|
17722
|
+
await transport.verifySessionCwd(cwd);
|
|
17723
|
+
return { ok: true };
|
|
17724
|
+
}
|
|
17725
|
+
|
|
17726
|
+
// dist/omp-rpc-session.js
|
|
17727
|
+
import { spawn, spawnSync } from "node:child_process";
|
|
17728
|
+
import { randomUUID } from "node:crypto";
|
|
17729
|
+
import path5 from "node:path";
|
|
17301
17730
|
|
|
17302
17731
|
// dist/command.js
|
|
17303
17732
|
var ompDiscoverySpec = {
|
|
@@ -17326,14 +17755,14 @@ function resolveOmpExecutable(input, dependencies = {}) {
|
|
|
17326
17755
|
}
|
|
17327
17756
|
|
|
17328
17757
|
// dist/omp-usage.js
|
|
17329
|
-
function
|
|
17758
|
+
function isRecord7(value) {
|
|
17330
17759
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
17331
17760
|
}
|
|
17332
17761
|
function nonNegativeSafeInteger(value) {
|
|
17333
17762
|
return typeof value === "number" && Number.isSafeInteger(value) && value >= 0 ? value : null;
|
|
17334
17763
|
}
|
|
17335
17764
|
function optionalOmpCacheHitRatePercent(value) {
|
|
17336
|
-
if (!
|
|
17765
|
+
if (!isRecord7(value) || value.role !== "assistant" || !isRecord7(value.usage))
|
|
17337
17766
|
return null;
|
|
17338
17767
|
const input = nonNegativeSafeInteger(value.usage.input);
|
|
17339
17768
|
const cacheRead = nonNegativeSafeInteger(value.usage.cacheRead);
|
|
@@ -17346,20 +17775,20 @@ function optionalOmpCacheHitRatePercent(value) {
|
|
|
17346
17775
|
function latestOmpCacheHitRatePercent(history) {
|
|
17347
17776
|
let latest = null;
|
|
17348
17777
|
for (const entry of activeOmpEntries(history)) {
|
|
17349
|
-
if (entry.type === "message" &&
|
|
17778
|
+
if (entry.type === "message" && isRecord7(entry.message) && entry.message.role === "assistant") {
|
|
17350
17779
|
latest = optionalOmpCacheHitRatePercent(entry.message);
|
|
17351
17780
|
}
|
|
17352
17781
|
}
|
|
17353
17782
|
return latest;
|
|
17354
17783
|
}
|
|
17355
17784
|
function responseData(response, operation) {
|
|
17356
|
-
if (!
|
|
17785
|
+
if (!isRecord7(response.data)) {
|
|
17357
17786
|
throw new Error(`Omp RPC ${operation} response has no data`);
|
|
17358
17787
|
}
|
|
17359
17788
|
return response.data;
|
|
17360
17789
|
}
|
|
17361
17790
|
function contextUsage(value) {
|
|
17362
|
-
if (!
|
|
17791
|
+
if (!isRecord7(value))
|
|
17363
17792
|
throw new Error("Omp RPC context Usage is invalid");
|
|
17364
17793
|
return parseHostUsage({
|
|
17365
17794
|
contextUsedTokens: value.tokens,
|
|
@@ -17369,15 +17798,15 @@ function contextUsage(value) {
|
|
|
17369
17798
|
function parseOmpSessionUsage(response) {
|
|
17370
17799
|
const data = responseData(response, "Session stats");
|
|
17371
17800
|
const tokens = data.tokens;
|
|
17372
|
-
if (tokens !== void 0 && !
|
|
17801
|
+
if (tokens !== void 0 && !isRecord7(tokens)) {
|
|
17373
17802
|
throw new Error("Omp RPC Session stats tokens are invalid");
|
|
17374
17803
|
}
|
|
17375
17804
|
return parseHostUsage({
|
|
17376
|
-
...
|
|
17377
|
-
...
|
|
17378
|
-
...
|
|
17379
|
-
...
|
|
17380
|
-
...
|
|
17805
|
+
...isRecord7(tokens) && tokens.input !== void 0 ? { inputTokens: tokens.input } : {},
|
|
17806
|
+
...isRecord7(tokens) && tokens.cacheRead !== void 0 ? { cachedInputTokens: tokens.cacheRead } : {},
|
|
17807
|
+
...isRecord7(tokens) && tokens.cacheWrite !== void 0 ? { cacheWriteInputTokens: tokens.cacheWrite } : {},
|
|
17808
|
+
...isRecord7(tokens) && tokens.output !== void 0 ? { outputTokens: tokens.output } : {},
|
|
17809
|
+
...isRecord7(tokens) && tokens.total !== void 0 ? { totalTokens: tokens.total } : {},
|
|
17381
17810
|
...data.cost !== void 0 ? { totalCostUsd: data.cost } : {},
|
|
17382
17811
|
...data.contextUsage !== void 0 ? contextUsage(data.contextUsage) : {}
|
|
17383
17812
|
});
|
|
@@ -17492,7 +17921,7 @@ var OmpRpcUnsupportedCommandError = class extends Error {
|
|
|
17492
17921
|
}
|
|
17493
17922
|
};
|
|
17494
17923
|
var textDecoder = new TextDecoder("utf-8", { fatal: true });
|
|
17495
|
-
function
|
|
17924
|
+
function isRecord8(value) {
|
|
17496
17925
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
17497
17926
|
}
|
|
17498
17927
|
function message2(value) {
|
|
@@ -17504,13 +17933,13 @@ function nonBlankString(value) {
|
|
|
17504
17933
|
function parseNativeModel(value, context) {
|
|
17505
17934
|
if (value === null || value === void 0)
|
|
17506
17935
|
return null;
|
|
17507
|
-
if (!
|
|
17936
|
+
if (!isRecord8(value) || !nonBlankString(value.provider) || !nonBlankString(value.id)) {
|
|
17508
17937
|
throw new OmpRpcFaultError("protocolError", `Omp RPC returned an invalid ${context} Model`);
|
|
17509
17938
|
}
|
|
17510
17939
|
return { provider: value.provider, id: value.id };
|
|
17511
17940
|
}
|
|
17512
17941
|
function sessionStateData(response) {
|
|
17513
|
-
const data =
|
|
17942
|
+
const data = isRecord8(response.data) ? response.data : null;
|
|
17514
17943
|
if (!data)
|
|
17515
17944
|
throw new OmpRpcFaultError("protocolError", "Omp RPC state response has no data");
|
|
17516
17945
|
return data;
|
|
@@ -17525,7 +17954,7 @@ function parseSessionState(response) {
|
|
|
17525
17954
|
if (thinkingLevel !== null && !thinkingLevel.success) {
|
|
17526
17955
|
throw new OmpRpcFaultError("protocolError", "Omp RPC state has an invalid Thinking level");
|
|
17527
17956
|
}
|
|
17528
|
-
const thinking =
|
|
17957
|
+
const thinking = isRecord8(data.model) && isRecord8(data.model.thinking) ? data.model.thinking : null;
|
|
17529
17958
|
const availableThinkingLevels = thinking && Array.isArray(thinking.efforts) ? thinking.efforts.flatMap((level) => {
|
|
17530
17959
|
const parsed = harnessThinkingOptionIdSchema.safeParse(level);
|
|
17531
17960
|
return parsed.success ? [parsed.data] : [];
|
|
@@ -17548,25 +17977,25 @@ function parseSessionStreaming(response) {
|
|
|
17548
17977
|
return isStreaming;
|
|
17549
17978
|
}
|
|
17550
17979
|
function parseAvailableModels(response) {
|
|
17551
|
-
const data =
|
|
17980
|
+
const data = isRecord8(response.data) ? response.data : null;
|
|
17552
17981
|
if (!data || !Array.isArray(data.models)) {
|
|
17553
17982
|
throw new OmpRpcFaultError("protocolError", "Omp RPC Model catalog response has no models");
|
|
17554
17983
|
}
|
|
17555
17984
|
return data.models.map((model) => {
|
|
17556
17985
|
const parsed = parseNativeModel(model, "catalog");
|
|
17557
|
-
if (!parsed || !
|
|
17986
|
+
if (!parsed || !isRecord8(model) || typeof model.reasoning !== "boolean") {
|
|
17558
17987
|
throw new OmpRpcFaultError("protocolError", "Omp RPC catalog contains a Model without reasoning capability");
|
|
17559
17988
|
}
|
|
17560
17989
|
return { ...parsed, reasoning: model.reasoning };
|
|
17561
17990
|
});
|
|
17562
17991
|
}
|
|
17563
17992
|
function parseSubagentMessages(response) {
|
|
17564
|
-
const data =
|
|
17993
|
+
const data = isRecord8(response.data) ? response.data : null;
|
|
17565
17994
|
if (!data || !nonBlankString(data.sessionFile) || !Number.isSafeInteger(data.fromByte) || !Number.isSafeInteger(data.nextByte) || data.fromByte < 0 || data.nextByte < data.fromByte || typeof data.reset !== "boolean" || !Array.isArray(data.entries) || !Array.isArray(data.messages)) {
|
|
17566
17995
|
throw new OmpRpcFaultError("protocolError", "Omp RPC Subagent transcript response is invalid");
|
|
17567
17996
|
}
|
|
17568
|
-
const entries = data.entries.flatMap((value) =>
|
|
17569
|
-
const messages = data.messages.flatMap((value) =>
|
|
17997
|
+
const entries = data.entries.flatMap((value) => isRecord8(value) ? [value] : []);
|
|
17998
|
+
const messages = data.messages.flatMap((value) => isRecord8(value) ? [value] : []);
|
|
17570
17999
|
if (entries.length !== data.entries.length || messages.length !== data.messages.length) {
|
|
17571
18000
|
throw new OmpRpcFaultError("protocolError", "Omp RPC Subagent transcript contains invalid data");
|
|
17572
18001
|
}
|
|
@@ -17587,17 +18016,17 @@ function subagentStatus(value) {
|
|
|
17587
18016
|
throw new OmpRpcFaultError("protocolError", "Omp RPC Subagent status is invalid");
|
|
17588
18017
|
}
|
|
17589
18018
|
function assistantText(value) {
|
|
17590
|
-
if (!
|
|
18019
|
+
if (!isRecord8(value) || value.role !== "assistant" || !Array.isArray(value.content))
|
|
17591
18020
|
return null;
|
|
17592
|
-
return value.content.filter((content) =>
|
|
18021
|
+
return value.content.filter((content) => isRecord8(content) && content.type === "text" && typeof content.text === "string").map((content) => content.text).join("");
|
|
17593
18022
|
}
|
|
17594
18023
|
function assistantMessageId(value) {
|
|
17595
|
-
if (!
|
|
18024
|
+
if (!isRecord8(value) || value.role !== "assistant")
|
|
17596
18025
|
return null;
|
|
17597
18026
|
return nonBlankString(value.responseId) ? value.responseId : null;
|
|
17598
18027
|
}
|
|
17599
18028
|
function extractReasoningText(content) {
|
|
17600
|
-
if (!
|
|
18029
|
+
if (!isRecord8(content))
|
|
17601
18030
|
return null;
|
|
17602
18031
|
const type = String(content.type ?? "");
|
|
17603
18032
|
if (type === "thinking" || type === "reasoning" || type === "thought") {
|
|
@@ -17607,12 +18036,12 @@ function extractReasoningText(content) {
|
|
|
17607
18036
|
return null;
|
|
17608
18037
|
}
|
|
17609
18038
|
function assistantReasoning(value) {
|
|
17610
|
-
if (!
|
|
18039
|
+
if (!isRecord8(value) || value.role !== "assistant" || !Array.isArray(value.content))
|
|
17611
18040
|
return null;
|
|
17612
18041
|
return value.content.map(extractReasoningText).filter((text) => typeof text === "string").join("");
|
|
17613
18042
|
}
|
|
17614
18043
|
function assistantFailure(value) {
|
|
17615
|
-
if (!
|
|
18044
|
+
if (!isRecord8(value) || value.role !== "assistant")
|
|
17616
18045
|
return void 0;
|
|
17617
18046
|
if (value.stopReason !== "error" && value.stopReason !== "aborted")
|
|
17618
18047
|
return null;
|
|
@@ -17632,7 +18061,7 @@ function signalProcessTree(child, signal) {
|
|
|
17632
18061
|
try {
|
|
17633
18062
|
process.kill(-child.pid, signal);
|
|
17634
18063
|
} catch (error51) {
|
|
17635
|
-
if (!
|
|
18064
|
+
if (!isRecord8(error51) || error51.code !== "ESRCH")
|
|
17636
18065
|
throw error51;
|
|
17637
18066
|
}
|
|
17638
18067
|
}
|
|
@@ -17671,7 +18100,7 @@ function ompRpcProcessCommand(options, dependencies = {}) {
|
|
|
17671
18100
|
...modelArguments,
|
|
17672
18101
|
...sessionArguments
|
|
17673
18102
|
];
|
|
17674
|
-
const extension =
|
|
18103
|
+
const extension = path5.win32.extname(command).toLowerCase();
|
|
17675
18104
|
if (platform !== "win32" || ![".cmd", ".bat"].includes(extension)) {
|
|
17676
18105
|
return { command, arguments: arguments_, windowsVerbatimArguments: false };
|
|
17677
18106
|
}
|
|
@@ -17714,6 +18143,10 @@ var OmpRpcSession = class {
|
|
|
17714
18143
|
#manualCompaction = null;
|
|
17715
18144
|
#stderrTail = "";
|
|
17716
18145
|
#frameDecoder = new OmpFrameDecoder();
|
|
18146
|
+
#startupFaultResolve = null;
|
|
18147
|
+
#startupFault = new Promise((resolve) => {
|
|
18148
|
+
this.#startupFaultResolve = resolve;
|
|
18149
|
+
});
|
|
17717
18150
|
#readyResolve = null;
|
|
17718
18151
|
#ready = new Promise((resolve) => {
|
|
17719
18152
|
this.#readyResolve = resolve;
|
|
@@ -17770,7 +18203,7 @@ var OmpRpcSession = class {
|
|
|
17770
18203
|
this.#stderrTail = sanitizeDiagnosticTail(`${this.#stderrTail}${chunk.toString()}`);
|
|
17771
18204
|
});
|
|
17772
18205
|
child.once("error", (error51) => {
|
|
17773
|
-
const kind =
|
|
18206
|
+
const kind = isRecord8(error51) && error51.code === "ENOENT" ? "notInstalled" : "unavailable";
|
|
17774
18207
|
this.#fail(new OmpRpcFaultError(kind, `Omp RPC failed to start: ${error51.message}`, this.stderrTail));
|
|
17775
18208
|
});
|
|
17776
18209
|
child.once("exit", (code, signal) => {
|
|
@@ -17785,10 +18218,20 @@ var OmpRpcSession = class {
|
|
|
17785
18218
|
}),
|
|
17786
18219
|
new Promise((_resolve, reject) => setTimeout(() => reject(new Error("Omp RPC start timed out")), this.#options.commandTimeoutMs))
|
|
17787
18220
|
]);
|
|
17788
|
-
|
|
17789
|
-
|
|
17790
|
-
|
|
17791
|
-
|
|
18221
|
+
let readyTimeout;
|
|
18222
|
+
try {
|
|
18223
|
+
await Promise.race([
|
|
18224
|
+
this.#ready,
|
|
18225
|
+
this.#startupFault.then((error51) => {
|
|
18226
|
+
throw error51;
|
|
18227
|
+
}),
|
|
18228
|
+
new Promise((_resolve, reject) => {
|
|
18229
|
+
readyTimeout = setTimeout(() => reject(new Error("Omp RPC ready signal timed out")), this.#options.commandTimeoutMs);
|
|
18230
|
+
})
|
|
18231
|
+
]);
|
|
18232
|
+
} finally {
|
|
18233
|
+
clearTimeout(readyTimeout);
|
|
18234
|
+
}
|
|
17792
18235
|
await this.#send("negotiate_protocol", { protocolVersion: 2 }).catch(() => void 0);
|
|
17793
18236
|
if (this.#options.subscribeSubagentEvents !== false) {
|
|
17794
18237
|
await this.#send("set_subagent_subscription", { level: "events" }).catch(() => void 0);
|
|
@@ -17808,17 +18251,17 @@ var OmpRpcSession = class {
|
|
|
17808
18251
|
return await readOmpSessionHistory(this.state.sessionFile);
|
|
17809
18252
|
}
|
|
17810
18253
|
const response = await this.#send("get_messages", {});
|
|
17811
|
-
const data =
|
|
18254
|
+
const data = isRecord8(response.data) ? response.data : null;
|
|
17812
18255
|
if (!data || !Array.isArray(data.messages)) {
|
|
17813
18256
|
throw new OmpRpcFaultError("protocolError", "Omp RPC messages response has no messages");
|
|
17814
18257
|
}
|
|
17815
18258
|
let branchEntryIds = null;
|
|
17816
18259
|
try {
|
|
17817
18260
|
const branchResponse = await this.#send("get_branch_messages", {});
|
|
17818
|
-
const branchData =
|
|
18261
|
+
const branchData = isRecord8(branchResponse.data) ? branchResponse.data : null;
|
|
17819
18262
|
if (branchData && Array.isArray(branchData.messages)) {
|
|
17820
18263
|
const parsed = branchData.messages.flatMap((entry) => {
|
|
17821
|
-
if (!
|
|
18264
|
+
if (!isRecord8(entry) || !nonBlankString(entry.entryId))
|
|
17822
18265
|
return [];
|
|
17823
18266
|
return [entry.entryId];
|
|
17824
18267
|
});
|
|
@@ -17832,11 +18275,11 @@ var OmpRpcSession = class {
|
|
|
17832
18275
|
let userIndex = 0;
|
|
17833
18276
|
let parentId = null;
|
|
17834
18277
|
const entries = data.messages.map((nativeMessage, index) => {
|
|
17835
|
-
const role =
|
|
18278
|
+
const role = isRecord8(nativeMessage) ? nativeMessage.role : void 0;
|
|
17836
18279
|
const branchId = role === "user" ? branchEntryIds?.[userIndex] : void 0;
|
|
17837
18280
|
if (branchId)
|
|
17838
18281
|
userIndex += 1;
|
|
17839
|
-
const id = branchId ?? (
|
|
18282
|
+
const id = branchId ?? (isRecord8(nativeMessage) && nonBlankString(nativeMessage.id) ? nativeMessage.id : `omp-message-${index}`);
|
|
17840
18283
|
const entry = { id, parentId, type: "message", message: nativeMessage };
|
|
17841
18284
|
parentId = id;
|
|
17842
18285
|
return entry;
|
|
@@ -17916,7 +18359,7 @@ var OmpRpcSession = class {
|
|
|
17916
18359
|
throw new Error("Omp RPC Fork requires an Entry identity");
|
|
17917
18360
|
try {
|
|
17918
18361
|
const response = await this.#send("branch", { entryId });
|
|
17919
|
-
const data =
|
|
18362
|
+
const data = isRecord8(response.data) ? response.data : null;
|
|
17920
18363
|
if (!data || data.cancelled === true) {
|
|
17921
18364
|
throw new OmpRpcFaultError("unavailable", "Omp RPC Fork was cancelled");
|
|
17922
18365
|
}
|
|
@@ -18109,7 +18552,7 @@ var OmpRpcSession = class {
|
|
|
18109
18552
|
continue;
|
|
18110
18553
|
}
|
|
18111
18554
|
const value = decoded;
|
|
18112
|
-
if (!
|
|
18555
|
+
if (!isRecord8(value) || typeof value.type !== "string") {
|
|
18113
18556
|
throw new OmpRpcFaultError("protocolError", "Omp RPC returned an invalid envelope");
|
|
18114
18557
|
}
|
|
18115
18558
|
this.#handle(value);
|
|
@@ -18168,7 +18611,7 @@ var OmpRpcSession = class {
|
|
|
18168
18611
|
this.#armCommandTimeout(id, pending);
|
|
18169
18612
|
}
|
|
18170
18613
|
}
|
|
18171
|
-
const outcome = value.aborted === true ? "cancelled" :
|
|
18614
|
+
const outcome = value.aborted === true ? "cancelled" : isRecord8(value.result) ? "succeeded" : "failed";
|
|
18172
18615
|
const event = {
|
|
18173
18616
|
type: "compaction.completed",
|
|
18174
18617
|
outcome,
|
|
@@ -18201,12 +18644,12 @@ var OmpRpcSession = class {
|
|
|
18201
18644
|
this.#startAssistantMessage(active, value.message);
|
|
18202
18645
|
return;
|
|
18203
18646
|
}
|
|
18204
|
-
if (value.type === "message_update" &&
|
|
18647
|
+
if (value.type === "message_update" && isRecord8(value.assistantMessageEvent)) {
|
|
18205
18648
|
const event = value.assistantMessageEvent;
|
|
18206
18649
|
const eventType = String(event.type ?? "");
|
|
18207
18650
|
const isThinking = eventType === "thinking_delta" || eventType === "reasoning_delta" || eventType === "thought_delta" || eventType === "thinking" || eventType === "reasoning";
|
|
18208
18651
|
const isText = eventType === "text_delta" || eventType === "text" || eventType === "content_block_delta";
|
|
18209
|
-
const delta = typeof event.delta === "string" ? event.delta : typeof event.thinking === "string" ? event.thinking : typeof event.reasoning === "string" ? event.reasoning : typeof event.text === "string" ? event.text :
|
|
18652
|
+
const delta = typeof event.delta === "string" ? event.delta : typeof event.thinking === "string" ? event.thinking : typeof event.reasoning === "string" ? event.reasoning : typeof event.text === "string" ? event.text : isRecord8(event.delta) && typeof event.delta.thinking === "string" ? event.delta.thinking : isRecord8(event.delta) && typeof event.delta.text === "string" ? event.delta.text : null;
|
|
18210
18653
|
if (isThinking && delta !== null && delta.length > 0) {
|
|
18211
18654
|
const messageId = this.#ensureAssistantMessage(active, value.message);
|
|
18212
18655
|
active.reasoningMessageOpen = true;
|
|
@@ -18246,7 +18689,7 @@ var OmpRpcSession = class {
|
|
|
18246
18689
|
if (value.type === "agent_end" && Array.isArray(value.messages)) {
|
|
18247
18690
|
for (let index = value.messages.length - 1; index >= 0; index -= 1) {
|
|
18248
18691
|
const message3 = value.messages[index];
|
|
18249
|
-
if (!
|
|
18692
|
+
if (!isRecord8(message3) || message3.role !== "assistant")
|
|
18250
18693
|
continue;
|
|
18251
18694
|
this.#finalizeAssistantMessage(active, message3);
|
|
18252
18695
|
break;
|
|
@@ -18263,8 +18706,8 @@ var OmpRpcSession = class {
|
|
|
18263
18706
|
if (value.type !== "subagent_lifecycle" && value.type !== "subagent_progress" && value.type !== "subagent_event") {
|
|
18264
18707
|
return false;
|
|
18265
18708
|
}
|
|
18266
|
-
const payload =
|
|
18267
|
-
const progressPayload = value.type === "subagent_progress" && payload &&
|
|
18709
|
+
const payload = isRecord8(value.payload) ? value.payload : null;
|
|
18710
|
+
const progressPayload = value.type === "subagent_progress" && payload && isRecord8(payload.progress) ? payload.progress : null;
|
|
18268
18711
|
const nativeIdValue = progressPayload?.id ?? payload?.id;
|
|
18269
18712
|
if (!payload || !nonBlankString(nativeIdValue)) {
|
|
18270
18713
|
throw new OmpRpcFaultError("protocolError", "Omp RPC Subagent frame has no stable ID");
|
|
@@ -18681,6 +19124,8 @@ var OmpRpcSession = class {
|
|
|
18681
19124
|
if (this.#closed || this.#failed)
|
|
18682
19125
|
return;
|
|
18683
19126
|
this.#failed = true;
|
|
19127
|
+
this.#startupFaultResolve?.(error51);
|
|
19128
|
+
this.#startupFaultResolve = null;
|
|
18684
19129
|
this.#rejectAll(error51);
|
|
18685
19130
|
this.#options.onFault?.(error51);
|
|
18686
19131
|
}
|
|
@@ -18841,7 +19286,7 @@ var ompCommandCatalog = harnessCommandCatalogSchema.parse({
|
|
|
18841
19286
|
]
|
|
18842
19287
|
});
|
|
18843
19288
|
var DEFAULT_TOOL_OUTPUT_LIMIT = 64e3;
|
|
18844
|
-
function
|
|
19289
|
+
function isRecord9(value) {
|
|
18845
19290
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
18846
19291
|
}
|
|
18847
19292
|
function errorMessage(error51) {
|
|
@@ -18856,7 +19301,7 @@ var OmpAdapterFaultError = class extends Error {
|
|
|
18856
19301
|
}
|
|
18857
19302
|
};
|
|
18858
19303
|
function normalizedError(error51, fallbackCode) {
|
|
18859
|
-
if (
|
|
19304
|
+
if (isRecord9(error51) && error51.code === "ENOENT") {
|
|
18860
19305
|
return { code: "notInstalled", message: errorMessage(error51), retryable: false };
|
|
18861
19306
|
}
|
|
18862
19307
|
if (error51 instanceof OmpAdapterFaultError)
|
|
@@ -18933,7 +19378,7 @@ function nativeModelForHistory(state) {
|
|
|
18933
19378
|
return nativeModelFromState(state);
|
|
18934
19379
|
}
|
|
18935
19380
|
function sessionFileFromRef(ref) {
|
|
18936
|
-
if (ref.harnessId !== ompHarnessId2 || !
|
|
19381
|
+
if (ref.harnessId !== ompHarnessId2 || !isRecord9(ref.locator) || typeof ref.locator.sessionFile !== "string" || ref.locator.sessionFile.length === 0) {
|
|
18937
19382
|
throw new Error("Omp Native Session Ref has no resumable Session file");
|
|
18938
19383
|
}
|
|
18939
19384
|
return ref.locator.sessionFile;
|
|
@@ -18943,7 +19388,7 @@ function subagentTranscriptPath(parentSessionFile, nativeSubagentId) {
|
|
|
18943
19388
|
if (nativeSubagentId.includes("/") || nativeSubagentId.includes("\\") || nativeSubagentId.includes("\0") || nativeSubagentId === "." || nativeSubagentId === "..") {
|
|
18944
19389
|
throw new Error("Omp Subagent ID is not a plain transcript file name");
|
|
18945
19390
|
}
|
|
18946
|
-
if (!parentSessionFile.endsWith(".jsonl") || !
|
|
19391
|
+
if (!parentSessionFile.endsWith(".jsonl") || !path6.isAbsolute(parentSessionFile)) {
|
|
18947
19392
|
return null;
|
|
18948
19393
|
}
|
|
18949
19394
|
return `${parentSessionFile.slice(0, -".jsonl".length)}/${nativeSubagentId}.jsonl`;
|
|
@@ -18952,10 +19397,10 @@ async function readSubagentTranscriptFile(parentSessionFile, nativeSubagentId) {
|
|
|
18952
19397
|
const transcriptFile = subagentTranscriptPath(parentSessionFile, nativeSubagentId);
|
|
18953
19398
|
if (transcriptFile === null)
|
|
18954
19399
|
return { status: "missing" };
|
|
18955
|
-
const parentDirectory =
|
|
19400
|
+
const parentDirectory = path6.dirname(transcriptFile);
|
|
18956
19401
|
let metadata;
|
|
18957
19402
|
try {
|
|
18958
|
-
metadata = await
|
|
19403
|
+
metadata = await stat2(transcriptFile);
|
|
18959
19404
|
} catch (error51) {
|
|
18960
19405
|
if (error51.code === "ENOENT")
|
|
18961
19406
|
return { status: "missing" };
|
|
@@ -18967,10 +19412,10 @@ async function readSubagentTranscriptFile(parentSessionFile, nativeSubagentId) {
|
|
|
18967
19412
|
throw new Error("Omp Subagent transcript exceeds the supported size");
|
|
18968
19413
|
}
|
|
18969
19414
|
const [resolvedTranscript, resolvedParentDirectory] = await Promise.all([
|
|
18970
|
-
|
|
18971
|
-
|
|
19415
|
+
realpath3(transcriptFile),
|
|
19416
|
+
realpath3(parentDirectory)
|
|
18972
19417
|
]);
|
|
18973
|
-
if (
|
|
19418
|
+
if (path6.dirname(resolvedTranscript) !== resolvedParentDirectory) {
|
|
18974
19419
|
throw new Error("Omp Subagent transcript resolves outside its parent Session directory");
|
|
18975
19420
|
}
|
|
18976
19421
|
return {
|
|
@@ -18988,9 +19433,9 @@ function toolFailure(toolName) {
|
|
|
18988
19433
|
function nativeText(value) {
|
|
18989
19434
|
if (typeof value === "string")
|
|
18990
19435
|
return value;
|
|
18991
|
-
if (!
|
|
19436
|
+
if (!isRecord9(value) || !Array.isArray(value.content))
|
|
18992
19437
|
return "";
|
|
18993
|
-
return value.content.filter((content) =>
|
|
19438
|
+
return value.content.filter((content) => isRecord9(content) && content.type === "text" && typeof content.text === "string").map(({ text }) => text).join("");
|
|
18994
19439
|
}
|
|
18995
19440
|
function boundedOutput(value, limit) {
|
|
18996
19441
|
const text = nativeText(value);
|
|
@@ -19006,17 +19451,17 @@ function outputText(output) {
|
|
|
19006
19451
|
return output?.content.filter((content) => content.type === "text").map(({ text }) => text).join("") ?? "";
|
|
19007
19452
|
}
|
|
19008
19453
|
function stringField2(value, key) {
|
|
19009
|
-
if (!
|
|
19454
|
+
if (!isRecord9(value))
|
|
19010
19455
|
return void 0;
|
|
19011
19456
|
const field = value[key];
|
|
19012
19457
|
if (typeof field === "string" && field.length > 0)
|
|
19013
19458
|
return field;
|
|
19014
|
-
if (
|
|
19459
|
+
if (isRecord9(value.input)) {
|
|
19015
19460
|
const nested = value.input[key];
|
|
19016
19461
|
if (typeof nested === "string" && nested.length > 0)
|
|
19017
19462
|
return nested;
|
|
19018
19463
|
}
|
|
19019
|
-
if (
|
|
19464
|
+
if (isRecord9(value.arguments)) {
|
|
19020
19465
|
const nested = value.arguments[key];
|
|
19021
19466
|
if (typeof nested === "string" && nested.length > 0)
|
|
19022
19467
|
return nested;
|
|
@@ -19024,7 +19469,7 @@ function stringField2(value, key) {
|
|
|
19024
19469
|
return void 0;
|
|
19025
19470
|
}
|
|
19026
19471
|
function numberField(value, key) {
|
|
19027
|
-
if (!
|
|
19472
|
+
if (!isRecord9(value))
|
|
19028
19473
|
return void 0;
|
|
19029
19474
|
const field = value[key];
|
|
19030
19475
|
return typeof field === "number" || field === null ? field : void 0;
|
|
@@ -19035,10 +19480,10 @@ function stripDiffPrefix(pathString) {
|
|
|
19035
19480
|
return pathString.startsWith("a/") || pathString.startsWith("b/") ? pathString.slice(2) : pathString;
|
|
19036
19481
|
}
|
|
19037
19482
|
function displayPath(nativePath, cwd) {
|
|
19038
|
-
const resolvedCwd =
|
|
19039
|
-
const resolvedPath =
|
|
19040
|
-
const relative =
|
|
19041
|
-
const inside = relative.length > 0 && relative !== ".." && !relative.startsWith(`..${
|
|
19483
|
+
const resolvedCwd = path6.resolve(cwd);
|
|
19484
|
+
const resolvedPath = path6.isAbsolute(nativePath) ? path6.resolve(nativePath) : path6.resolve(cwd, nativePath);
|
|
19485
|
+
const relative = path6.relative(resolvedCwd, resolvedPath);
|
|
19486
|
+
const inside = relative.length > 0 && relative !== ".." && !relative.startsWith(`..${path6.sep}`);
|
|
19042
19487
|
const selected = inside ? relative : resolvedPath;
|
|
19043
19488
|
const normalized = selected.replaceAll("\\", "/");
|
|
19044
19489
|
if (normalized.length === 0 || normalized === ".")
|
|
@@ -19063,7 +19508,7 @@ function fileMutatingKind(toolName) {
|
|
|
19063
19508
|
return null;
|
|
19064
19509
|
}
|
|
19065
19510
|
function nestedToolString(value, keys) {
|
|
19066
|
-
if (!
|
|
19511
|
+
if (!isRecord9(value))
|
|
19067
19512
|
return void 0;
|
|
19068
19513
|
for (const key of keys) {
|
|
19069
19514
|
const field = value[key];
|
|
@@ -19078,14 +19523,14 @@ function nestedToolString(value, keys) {
|
|
|
19078
19523
|
return void 0;
|
|
19079
19524
|
}
|
|
19080
19525
|
function patchFromResult(result) {
|
|
19081
|
-
if (!
|
|
19526
|
+
if (!isRecord9(result))
|
|
19082
19527
|
return void 0;
|
|
19083
19528
|
for (const key of ["patch", "diff", "unifiedDiff"]) {
|
|
19084
19529
|
const field = result[key];
|
|
19085
19530
|
if (typeof field === "string" && field.length > 0)
|
|
19086
19531
|
return field;
|
|
19087
19532
|
}
|
|
19088
|
-
if (
|
|
19533
|
+
if (isRecord9(result.details)) {
|
|
19089
19534
|
for (const key of ["patch", "diff", "unifiedDiff"]) {
|
|
19090
19535
|
const field = result.details[key];
|
|
19091
19536
|
if (typeof field === "string" && field.length > 0)
|
|
@@ -20567,6 +21012,7 @@ var OmpAdapter = class {
|
|
|
20567
21012
|
commandCatalog = ompCommandCatalog;
|
|
20568
21013
|
liveCommandCatalog = true;
|
|
20569
21014
|
harnessId = ompHarnessId2;
|
|
21015
|
+
sessionImport;
|
|
20570
21016
|
subagents = {
|
|
20571
21017
|
readSnapshot: async (input) => {
|
|
20572
21018
|
if (input.parent.harnessId !== this.harnessId || input.nativeSubagentId.trim().length === 0 || input.cwd.length === 0) {
|
|
@@ -20626,6 +21072,7 @@ var OmpAdapter = class {
|
|
|
20626
21072
|
createTransport: (sessionOptions) => new OmpRpcSession({ ...options, ...sessionOptions })
|
|
20627
21073
|
}) {
|
|
20628
21074
|
this.#createTransport = dependencies.createTransport;
|
|
21075
|
+
this.sessionImport = new OmpSessionImport({ ...process.env, ...options.environment });
|
|
20629
21076
|
this.#closeTimeoutMs = options.closeTimeoutMs ?? 2e3;
|
|
20630
21077
|
this.#toolOutputLimit = options.toolOutputLimit ?? DEFAULT_TOOL_OUTPUT_LIMIT;
|
|
20631
21078
|
}
|
|
@@ -20697,7 +21144,11 @@ var OmpAdapter = class {
|
|
|
20697
21144
|
};
|
|
20698
21145
|
} catch (error51) {
|
|
20699
21146
|
await transport.close().catch(() => void 0);
|
|
20700
|
-
const normalized =
|
|
21147
|
+
const normalized = stage === "startup" && /No models available\.\s*Use \/login or set an API key environment variable\./i.test(transport.stderrTail ?? "") ? {
|
|
21148
|
+
code: "configurationRequired",
|
|
21149
|
+
message: "No models are configured for use in Oh My Pi. Configure a Provider and its API key or models.yml, then run `omp` and use `/model` to select a model. For Providers that support it, `/login` configures Provider authentication, not an Oh My Pi account.",
|
|
21150
|
+
retryable: false
|
|
21151
|
+
} : normalizedError(error51, "unavailable");
|
|
20701
21152
|
return {
|
|
20702
21153
|
status: normalized.code === "notInstalled" ? "notInstalled" : "error",
|
|
20703
21154
|
error: {
|
|
@@ -20887,6 +21338,7 @@ var OmpAdapter = class {
|
|
|
20887
21338
|
close() {
|
|
20888
21339
|
if (!this.#closePromise) {
|
|
20889
21340
|
this.#closePromise = Promise.all([
|
|
21341
|
+
this.sessionImport.close(),
|
|
20890
21342
|
...[...this.#inspections].map((transport) => transport.close()),
|
|
20891
21343
|
...[...this.#sessions].map((session) => session.close())
|
|
20892
21344
|
]).then(() => void 0);
|
|
@@ -20896,22 +21348,22 @@ var OmpAdapter = class {
|
|
|
20896
21348
|
};
|
|
20897
21349
|
|
|
20898
21350
|
// dist/installation.js
|
|
20899
|
-
import { realpath as
|
|
20900
|
-
import
|
|
21351
|
+
import { realpath as realpath4 } from "node:fs/promises";
|
|
21352
|
+
import path7 from "node:path";
|
|
20901
21353
|
function createOmpInstallation(environment, command) {
|
|
20902
21354
|
let executable;
|
|
20903
21355
|
let env;
|
|
20904
21356
|
return createInstallationManager({
|
|
20905
21357
|
async check() {
|
|
20906
21358
|
executable = resolveOmpExecutable({ environment, ...command ? { command } : {} });
|
|
20907
|
-
const selected = await
|
|
21359
|
+
const selected = await realpath4(executable);
|
|
20908
21360
|
const pathKey = Object.keys(environment).find((key) => key.toLowerCase() === "path") ?? "PATH";
|
|
20909
21361
|
env = {
|
|
20910
21362
|
...environment,
|
|
20911
|
-
[pathKey]: `${
|
|
21363
|
+
[pathKey]: `${path7.dirname(executable)}${path7.delimiter}${environment[pathKey] ?? ""}`
|
|
20912
21364
|
};
|
|
20913
21365
|
const target = resolveHarnessExecutable({ id: "omp", command: "omp", installRoots: { posix: [], windows: [] } }, { environment: env });
|
|
20914
|
-
const canUpdate = !selected.includes("/nix/store/") && !!target && await
|
|
21366
|
+
const canUpdate = !selected.includes("/nix/store/") && !!target && await realpath4(target.executable) === selected;
|
|
20915
21367
|
const output = await runInstallationCommand(executable, ["update", "--check"], env);
|
|
20916
21368
|
const currentVersion = versionFromOutput(output);
|
|
20917
21369
|
const available = output.match(/New version available:\s*(\S+)/i);
|
|
@@ -20923,7 +21375,10 @@ function createOmpInstallation(environment, command) {
|
|
|
20923
21375
|
latestVersion,
|
|
20924
21376
|
updateAvailable: newerInstallationVersion(currentVersion, latestVersion),
|
|
20925
21377
|
canUpdate,
|
|
20926
|
-
...!canUpdate ? {
|
|
21378
|
+
...!canUpdate ? {
|
|
21379
|
+
messageCode: "original-installer",
|
|
21380
|
+
message: "Update this installation with its original package manager or launcher."
|
|
21381
|
+
} : {}
|
|
20927
21382
|
};
|
|
20928
21383
|
},
|
|
20929
21384
|
async update() {
|
|
@@ -20939,7 +21394,14 @@ function createHarnessAdapter(context) {
|
|
|
20939
21394
|
return Object.assign(new OmpAdapter({
|
|
20940
21395
|
...environment[OMP_COMMAND_ENV] ? { command: environment[OMP_COMMAND_ENV] } : {},
|
|
20941
21396
|
environment
|
|
20942
|
-
}), {
|
|
21397
|
+
}), {
|
|
21398
|
+
installation: createOmpInstallation(environment, environment[OMP_COMMAND_ENV]),
|
|
21399
|
+
install: createHarnessInstaller(environment, {
|
|
21400
|
+
posix: "https://omp.sh/install",
|
|
21401
|
+
windows: "https://omp.sh/install.ps1",
|
|
21402
|
+
shell: "sh"
|
|
21403
|
+
})
|
|
21404
|
+
});
|
|
20943
21405
|
}
|
|
20944
21406
|
export {
|
|
20945
21407
|
OMP_COMMAND_ENV,
|