@codexhost/cli-darwin-x64 0.10.2 → 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/THIRD_PARTY_NOTICES.txt +4 -0
- package/app/codexhost-distribution.json +1 -1
- package/app/console-server.mjs +18001 -0
- package/app/console-web.js +27674 -0
- package/app/desktop-controller.mjs +452 -110
- package/app/host-runtime.mjs +6670 -1272
- package/app/plugins/antigravity/plugin.mjs +686 -305
- package/app/plugins/claude-code/plugin.mjs +2283 -1450
- package/app/plugins/codebuddy/plugin.mjs +1272 -506
- package/app/plugins/cursor-cli/manifest.json +1 -1
- package/app/plugins/cursor-cli/plugin.mjs +1295 -497
- package/app/plugins/deepseek-harness/plugin.mjs +4718 -4925
- package/app/plugins/enabled.json +2 -1
- package/app/plugins/grok/plugin.mjs +1012 -369
- package/app/plugins/hermes/plugin.mjs +18587 -22714
- package/app/plugins/kimi-code/plugin.mjs +1283 -355
- package/app/plugins/kiro-cli/plugin.mjs +840 -299
- package/app/plugins/omp/plugin.mjs +1045 -328
- package/app/plugins/opencode/plugin.mjs +5341 -1686
- package/app/plugins/pi/plugin.mjs +1343 -534
- package/app/plugins/qoder/plugin.mjs +913 -258
- package/app/plugins/qoder-cn/plugin.mjs +712 -49
- package/app/plugins/workbuddy/plugin.mjs +531 -44
- 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 +5011 -1899
- package/bin/codexhost +0 -0
- package/libexec/codexhost-shim +0 -0
- package/libexec/codexhost-updater +0 -0
- package/licenses/OpenCode-v2-Client-LICENSE.txt +21 -0
- package/package.json +1 -1
|
@@ -5,15 +5,413 @@ var __export = (target, all) => {
|
|
|
5
5
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
6
6
|
};
|
|
7
7
|
|
|
8
|
-
// dist/
|
|
9
|
-
import
|
|
10
|
-
import
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
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
|
|
15
71
|
import path3 from "node:path";
|
|
16
|
-
|
|
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
|
+
|
|
411
|
+
// dist/account-balance.js
|
|
412
|
+
import { readFile } from "node:fs/promises";
|
|
413
|
+
import { homedir as homedir2 } from "node:os";
|
|
414
|
+
import path4 from "node:path";
|
|
17
415
|
|
|
18
416
|
// ../../../node_modules/zod/v4/classic/external.js
|
|
19
417
|
var external_exports = {};
|
|
@@ -781,10 +1179,10 @@ function mergeDefs(...defs) {
|
|
|
781
1179
|
function cloneDef(schema) {
|
|
782
1180
|
return mergeDefs(schema._zod.def);
|
|
783
1181
|
}
|
|
784
|
-
function getElementAtPath(obj,
|
|
785
|
-
if (!
|
|
1182
|
+
function getElementAtPath(obj, path14) {
|
|
1183
|
+
if (!path14)
|
|
786
1184
|
return obj;
|
|
787
|
-
return
|
|
1185
|
+
return path14.reduce((acc, key) => acc?.[key], obj);
|
|
788
1186
|
}
|
|
789
1187
|
function promiseAllObject(promisesObj) {
|
|
790
1188
|
const keys = Object.keys(promisesObj);
|
|
@@ -1193,11 +1591,11 @@ function explicitlyAborted(x, startIndex = 0) {
|
|
|
1193
1591
|
}
|
|
1194
1592
|
return false;
|
|
1195
1593
|
}
|
|
1196
|
-
function prefixIssues(
|
|
1594
|
+
function prefixIssues(path14, issues) {
|
|
1197
1595
|
return issues.map((iss) => {
|
|
1198
1596
|
var _a3;
|
|
1199
1597
|
(_a3 = iss).path ?? (_a3.path = []);
|
|
1200
|
-
iss.path.unshift(
|
|
1598
|
+
iss.path.unshift(path14);
|
|
1201
1599
|
return iss;
|
|
1202
1600
|
});
|
|
1203
1601
|
}
|
|
@@ -1344,16 +1742,16 @@ function flattenError(error51, mapper = (issue2) => issue2.message) {
|
|
|
1344
1742
|
}
|
|
1345
1743
|
function formatError(error51, mapper = (issue2) => issue2.message) {
|
|
1346
1744
|
const fieldErrors = { _errors: [] };
|
|
1347
|
-
const processError = (error52,
|
|
1745
|
+
const processError = (error52, path14 = []) => {
|
|
1348
1746
|
for (const issue2 of error52.issues) {
|
|
1349
1747
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
1350
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
1748
|
+
issue2.errors.map((issues) => processError({ issues }, [...path14, ...issue2.path]));
|
|
1351
1749
|
} else if (issue2.code === "invalid_key") {
|
|
1352
|
-
processError({ issues: issue2.issues }, [...
|
|
1750
|
+
processError({ issues: issue2.issues }, [...path14, ...issue2.path]);
|
|
1353
1751
|
} else if (issue2.code === "invalid_element") {
|
|
1354
|
-
processError({ issues: issue2.issues }, [...
|
|
1752
|
+
processError({ issues: issue2.issues }, [...path14, ...issue2.path]);
|
|
1355
1753
|
} else {
|
|
1356
|
-
const fullpath = [...
|
|
1754
|
+
const fullpath = [...path14, ...issue2.path];
|
|
1357
1755
|
if (fullpath.length === 0) {
|
|
1358
1756
|
fieldErrors._errors.push(mapper(issue2));
|
|
1359
1757
|
} else {
|
|
@@ -1380,17 +1778,17 @@ function formatError(error51, mapper = (issue2) => issue2.message) {
|
|
|
1380
1778
|
}
|
|
1381
1779
|
function treeifyError(error51, mapper = (issue2) => issue2.message) {
|
|
1382
1780
|
const result = { errors: [] };
|
|
1383
|
-
const processError = (error52,
|
|
1781
|
+
const processError = (error52, path14 = []) => {
|
|
1384
1782
|
var _a3, _b;
|
|
1385
1783
|
for (const issue2 of error52.issues) {
|
|
1386
1784
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
1387
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
1785
|
+
issue2.errors.map((issues) => processError({ issues }, [...path14, ...issue2.path]));
|
|
1388
1786
|
} else if (issue2.code === "invalid_key") {
|
|
1389
|
-
processError({ issues: issue2.issues }, [...
|
|
1787
|
+
processError({ issues: issue2.issues }, [...path14, ...issue2.path]);
|
|
1390
1788
|
} else if (issue2.code === "invalid_element") {
|
|
1391
|
-
processError({ issues: issue2.issues }, [...
|
|
1789
|
+
processError({ issues: issue2.issues }, [...path14, ...issue2.path]);
|
|
1392
1790
|
} else {
|
|
1393
|
-
const fullpath = [...
|
|
1791
|
+
const fullpath = [...path14, ...issue2.path];
|
|
1394
1792
|
if (fullpath.length === 0) {
|
|
1395
1793
|
result.errors.push(mapper(issue2));
|
|
1396
1794
|
continue;
|
|
@@ -1422,8 +1820,8 @@ function treeifyError(error51, mapper = (issue2) => issue2.message) {
|
|
|
1422
1820
|
}
|
|
1423
1821
|
function toDotPath(_path) {
|
|
1424
1822
|
const segs = [];
|
|
1425
|
-
const
|
|
1426
|
-
for (const seg of
|
|
1823
|
+
const path14 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
1824
|
+
for (const seg of path14) {
|
|
1427
1825
|
if (typeof seg === "number")
|
|
1428
1826
|
segs.push(`[${seg}]`);
|
|
1429
1827
|
else if (typeof seg === "symbol")
|
|
@@ -14115,13 +14513,13 @@ function resolveRef(ref, ctx) {
|
|
|
14115
14513
|
if (!ref.startsWith("#")) {
|
|
14116
14514
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
14117
14515
|
}
|
|
14118
|
-
const
|
|
14119
|
-
if (
|
|
14516
|
+
const path14 = ref.slice(1).split("/").filter(Boolean);
|
|
14517
|
+
if (path14.length === 0) {
|
|
14120
14518
|
return ctx.rootSchema;
|
|
14121
14519
|
}
|
|
14122
14520
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
14123
|
-
if (
|
|
14124
|
-
const key =
|
|
14521
|
+
if (path14[0] === defsKey) {
|
|
14522
|
+
const key = path14[1];
|
|
14125
14523
|
if (!key || !ctx.defs[key]) {
|
|
14126
14524
|
throw new Error(`Reference not found: ${ref}`);
|
|
14127
14525
|
}
|
|
@@ -14584,6 +14982,56 @@ var credentialImportsParamsSchema = external_exports.object({
|
|
|
14584
14982
|
request: credentialImportsRequestSchema
|
|
14585
14983
|
}).strict();
|
|
14586
14984
|
|
|
14985
|
+
// ../../shared-contracts/dist/harness-display-settings.js
|
|
14986
|
+
var harnessDisplayEntriesSchema = external_exports.array(external_exports.strictObject({
|
|
14987
|
+
agent: external_exports.string().min(1).max(128),
|
|
14988
|
+
section: external_exports.enum(["main", "more", "auto"])
|
|
14989
|
+
})).max(256).refine((entries) => new Set(entries.map((entry) => entry.agent)).size === entries.length, "Duplicate Harness IDs");
|
|
14990
|
+
var harnessDisplaySettingsSchema = external_exports.strictObject({
|
|
14991
|
+
entries: harnessDisplayEntriesSchema.nullable()
|
|
14992
|
+
});
|
|
14993
|
+
var harnessDisplayGetSchema = external_exports.strictObject({});
|
|
14994
|
+
var harnessDisplaySetSchema = external_exports.strictObject({
|
|
14995
|
+
entries: harnessDisplayEntriesSchema,
|
|
14996
|
+
/** Import legacy Desktop preferences only if no shared settings exist yet. */
|
|
14997
|
+
initializeOnly: external_exports.boolean().optional()
|
|
14998
|
+
});
|
|
14999
|
+
|
|
15000
|
+
// ../../shared-contracts/dist/console.js
|
|
15001
|
+
var consoleAnnouncementSchema = external_exports.strictObject({
|
|
15002
|
+
title: external_exports.string().trim().min(1).max(200),
|
|
15003
|
+
type: external_exports.enum(["info", "warning", "danger"]),
|
|
15004
|
+
body: external_exports.string().trim().min(1).max(16 * 1024)
|
|
15005
|
+
});
|
|
15006
|
+
var consoleOpenParamsSchema = external_exports.strictObject({});
|
|
15007
|
+
var consoleOpenResultSchema = external_exports.strictObject({
|
|
15008
|
+
/** The console address. */
|
|
15009
|
+
url: external_exports.string().max(2048).regex(/^http:\/\/(?:127\.0\.0\.1|localhost):\d{1,5}\/(?:\?.*)?$/u)
|
|
15010
|
+
});
|
|
15011
|
+
var CONSOLE_HOST_METHODS = Object.freeze([
|
|
15012
|
+
"codexhost/harness/plugins/list",
|
|
15013
|
+
"codexhost/harness/display-settings/get",
|
|
15014
|
+
"codexhost/harness/display-settings/set",
|
|
15015
|
+
"codexhost/harness/inspect",
|
|
15016
|
+
"codexhost/harness/installation",
|
|
15017
|
+
"codexhost/harness/launch-settings/get",
|
|
15018
|
+
"codexhost/harness/launch-settings/set",
|
|
15019
|
+
"codexhost/harness/web-ui/open",
|
|
15020
|
+
"codexhost/harness/accounts/sources",
|
|
15021
|
+
"codexhost/harness/accounts/list",
|
|
15022
|
+
"codexhost/harness/accounts/inspect",
|
|
15023
|
+
"codexhost/harness/credential-imports",
|
|
15024
|
+
"codexhost/harness/session-import/sources",
|
|
15025
|
+
"codexhost/harness/session-import/list",
|
|
15026
|
+
"codexhost/harness/session-import/import",
|
|
15027
|
+
"codexhost/account/list",
|
|
15028
|
+
"codexhost/account/refresh",
|
|
15029
|
+
"codexhost/account/usage/inspect",
|
|
15030
|
+
"codexhost/update/check",
|
|
15031
|
+
"codexhost/update/start",
|
|
15032
|
+
"codexhost/update/status"
|
|
15033
|
+
]);
|
|
15034
|
+
|
|
14587
15035
|
// ../../shared-contracts/dist/version.js
|
|
14588
15036
|
var WORKSPACE_CONTRACT_VERSION = 1;
|
|
14589
15037
|
|
|
@@ -14637,6 +15085,12 @@ var hostTurnIdSchema = opaqueIdSchema.brand();
|
|
|
14637
15085
|
var hostItemIdSchema = opaqueIdSchema.brand();
|
|
14638
15086
|
var hostInteractionIdSchema = opaqueIdSchema.brand();
|
|
14639
15087
|
|
|
15088
|
+
// ../../shared-contracts/dist/manual-compaction.js
|
|
15089
|
+
var threadManualCompactionStartedSchema = external_exports.strictObject({
|
|
15090
|
+
threadId: hostThreadIdSchema,
|
|
15091
|
+
turnId: hostTurnIdSchema
|
|
15092
|
+
});
|
|
15093
|
+
|
|
14640
15094
|
// ../../shared-contracts/dist/thread-usage.js
|
|
14641
15095
|
var nonNegativeSafeIntegerSchema = external_exports.number().int().safe().nonnegative();
|
|
14642
15096
|
var finiteNonNegativeNumberSchema = external_exports.number().finite().nonnegative();
|
|
@@ -14697,6 +15151,10 @@ var threadUsageSnapshotSchema = external_exports.object({
|
|
|
14697
15151
|
var usagePercentSchema = external_exports.number().finite().min(0).max(100);
|
|
14698
15152
|
var accountCreditsProductUsageSchema = external_exports.object({
|
|
14699
15153
|
product: external_exports.string().min(1),
|
|
15154
|
+
used: external_exports.number().finite().nonnegative().optional(),
|
|
15155
|
+
// Zero is a real empty cap, not an absent field.
|
|
15156
|
+
limit: external_exports.number().finite().nonnegative().optional(),
|
|
15157
|
+
unit: external_exports.string().min(1).max(32).optional(),
|
|
14700
15158
|
usagePercent: usagePercentSchema,
|
|
14701
15159
|
resetsAt: external_exports.string().min(1).optional()
|
|
14702
15160
|
}).strict();
|
|
@@ -14706,6 +15164,10 @@ var accountResetCreditsSchema = external_exports.object({
|
|
|
14706
15164
|
expiresAt: external_exports.array(external_exports.string().min(1)).min(1).max(32).optional()
|
|
14707
15165
|
}).strict();
|
|
14708
15166
|
var accountCreditsSnapshotSchema = external_exports.object({
|
|
15167
|
+
used: external_exports.number().finite().nonnegative().optional(),
|
|
15168
|
+
// Zero is a real empty cap, not an absent field.
|
|
15169
|
+
limit: external_exports.number().finite().nonnegative().optional(),
|
|
15170
|
+
unit: external_exports.string().min(1).max(32).optional(),
|
|
14709
15171
|
/** Native label when the primary limit is scoped to a model or product group. */
|
|
14710
15172
|
label: external_exports.string().min(1).optional(),
|
|
14711
15173
|
usedPercent: usagePercentSchema,
|
|
@@ -14725,12 +15187,27 @@ var threadUsageInspectionSchema = external_exports.object({
|
|
|
14725
15187
|
}).strict();
|
|
14726
15188
|
|
|
14727
15189
|
// ../../shared-contracts/dist/harness-accounts.js
|
|
14728
|
-
var
|
|
15190
|
+
var accountBalanceSnapshotSchema = external_exports.object({
|
|
15191
|
+
amount: external_exports.number().finite().nonnegative(),
|
|
15192
|
+
/** ISO 4217 code as reported by the Provider, for example `CNY`. */
|
|
15193
|
+
currency: external_exports.string().trim().min(1).max(8),
|
|
15194
|
+
/** Native label when the Harness exposes several Billing Sources. */
|
|
15195
|
+
label: external_exports.string().trim().min(1).max(128).optional()
|
|
15196
|
+
}).strict();
|
|
15197
|
+
var harnessAccountSnapshotObject = external_exports.object({
|
|
14729
15198
|
email: external_exports.string().trim().min(1).max(320).optional(),
|
|
14730
15199
|
label: external_exports.string().trim().min(1).max(256).optional(),
|
|
14731
15200
|
plan: external_exports.string().trim().min(1).max(128).optional(),
|
|
14732
|
-
credits: accountCreditsSnapshotSchema
|
|
15201
|
+
credits: accountCreditsSnapshotSchema.optional(),
|
|
15202
|
+
balance: accountBalanceSnapshotSchema.optional()
|
|
14733
15203
|
}).strict();
|
|
15204
|
+
function requireReportedQuota(schema) {
|
|
15205
|
+
return schema.refine((value) => {
|
|
15206
|
+
const reported = value;
|
|
15207
|
+
return reported.credits !== void 0 || reported.balance !== void 0;
|
|
15208
|
+
}, { message: "Account must report either credits or a balance" });
|
|
15209
|
+
}
|
|
15210
|
+
var harnessAccountSnapshotSchema = requireReportedQuota(harnessAccountSnapshotObject);
|
|
14734
15211
|
var harnessAccountIdentityShape = {
|
|
14735
15212
|
harnessId: harnessIdSchema,
|
|
14736
15213
|
harnessName: external_exports.string().trim().min(1).max(128)
|
|
@@ -14741,11 +15218,13 @@ var harnessAccountSourceListResultSchema = external_exports.object({ sources: ex
|
|
|
14741
15218
|
var harnessAccountInspectParamsSchema = external_exports.object({ harnessId: harnessIdSchema, refresh: external_exports.boolean().optional() }).strict();
|
|
14742
15219
|
var harnessAccountInspectResultSchema = external_exports.object({
|
|
14743
15220
|
...harnessAccountIdentityShape,
|
|
14744
|
-
account: harnessAccountSnapshotSchema.nullable()
|
|
15221
|
+
account: harnessAccountSnapshotSchema.nullable(),
|
|
15222
|
+
/** Every Billing Source from one Harness; `account` remains the first for older clients. */
|
|
15223
|
+
accounts: external_exports.array(harnessAccountSnapshotSchema).max(8).optional()
|
|
14745
15224
|
}).strict();
|
|
14746
15225
|
var harnessAccountListParamsSchema = external_exports.object({ refresh: external_exports.boolean().optional() }).strict();
|
|
14747
15226
|
var harnessAccountListResultSchema = external_exports.object({
|
|
14748
|
-
accounts: external_exports.array(
|
|
15227
|
+
accounts: external_exports.array(requireReportedQuota(harnessAccountSnapshotObject.extend(harnessAccountIdentityShape))).max(128)
|
|
14749
15228
|
}).strict();
|
|
14750
15229
|
|
|
14751
15230
|
// ../../shared-contracts/dist/json-value.js
|
|
@@ -14883,6 +15362,8 @@ var harnessModelSchema = external_exports.object({
|
|
|
14883
15362
|
ref: harnessModelRefSchema,
|
|
14884
15363
|
label: nonBlankTextSchema2.max(HARNESS_MODEL_LABEL_MAX_LENGTH),
|
|
14885
15364
|
resolvedModelLabel: harnessResolvedModelLabelSchema.optional(),
|
|
15365
|
+
/** Optional opaque selection for this same Model with priority processing enabled. */
|
|
15366
|
+
fastModel: harnessModelRefSchema.optional(),
|
|
14886
15367
|
supportedThinkingOptionIds: external_exports.array(harnessThinkingOptionIdSchema).optional()
|
|
14887
15368
|
}).strict();
|
|
14888
15369
|
var harnessThinkingOptionsSchema = external_exports.array(harnessThinkingOptionSchema).superRefine((options, context) => {
|
|
@@ -14915,6 +15396,16 @@ var harnessModelCatalogSchema = external_exports.object({
|
|
|
14915
15396
|
});
|
|
14916
15397
|
}
|
|
14917
15398
|
refs.add(model.ref.id);
|
|
15399
|
+
if (model.fastModel) {
|
|
15400
|
+
if (refs.has(model.fastModel.id) || catalog.models.some((entry) => entry.ref.id === model.fastModel?.id)) {
|
|
15401
|
+
context.addIssue({
|
|
15402
|
+
code: "custom",
|
|
15403
|
+
message: "Fast Model refs must be distinct and unique",
|
|
15404
|
+
path: ["models", index, "fastModel"]
|
|
15405
|
+
});
|
|
15406
|
+
}
|
|
15407
|
+
refs.add(model.fastModel.id);
|
|
15408
|
+
}
|
|
14918
15409
|
const supportedThinkingIds = /* @__PURE__ */ new Set();
|
|
14919
15410
|
for (const [optionIndex, optionId] of (model.supportedThinkingOptionIds ?? []).entries()) {
|
|
14920
15411
|
if (supportedThinkingIds.has(optionId)) {
|
|
@@ -15034,11 +15525,13 @@ var threadThinkingSelectParamsSchema = external_exports.object({
|
|
|
15034
15525
|
thinkingOptionId: harnessThinkingOptionIdSchema
|
|
15035
15526
|
}).strict();
|
|
15036
15527
|
var threadInspectionParamsSchema = external_exports.object({
|
|
15037
|
-
threadId: hostThreadIdSchema
|
|
15528
|
+
threadId: hostThreadIdSchema,
|
|
15529
|
+
includeReferenceCapability: external_exports.boolean().optional()
|
|
15038
15530
|
}).strict();
|
|
15039
15531
|
var codexThreadInspectionSchema = external_exports.object({
|
|
15040
15532
|
owner: external_exports.literal("codex"),
|
|
15041
|
-
locked: external_exports.literal(true)
|
|
15533
|
+
locked: external_exports.literal(true),
|
|
15534
|
+
supportsThreadReferences: external_exports.literal(true).optional()
|
|
15042
15535
|
}).strict();
|
|
15043
15536
|
var externalThreadInspectionSchema = external_exports.object({
|
|
15044
15537
|
owner: external_exports.literal("external"),
|
|
@@ -15164,6 +15657,22 @@ var harnessLaunchSettingsSchema = external_exports.object({
|
|
|
15164
15657
|
restartRequired: external_exports.boolean()
|
|
15165
15658
|
}).strict();
|
|
15166
15659
|
|
|
15660
|
+
// ../../shared-contracts/dist/harness-installation.js
|
|
15661
|
+
var harnessInstallationParamsSchema = external_exports.object({
|
|
15662
|
+
harnessId: harnessIdSchema,
|
|
15663
|
+
action: external_exports.enum(["check", "update", "install"])
|
|
15664
|
+
}).strict();
|
|
15665
|
+
var harnessInstallationStateSchema = external_exports.object({
|
|
15666
|
+
currentVersion: external_exports.string().min(1).max(128),
|
|
15667
|
+
latestVersion: external_exports.string().min(1).max(128),
|
|
15668
|
+
updateAvailable: external_exports.boolean(),
|
|
15669
|
+
canUpdate: external_exports.boolean(),
|
|
15670
|
+
// Adapter-owned diagnostic text; UI uses messageCode rather than displaying it verbatim.
|
|
15671
|
+
message: external_exports.string().max(2048).optional(),
|
|
15672
|
+
messageCode: external_exports.string().min(1).max(128).optional(),
|
|
15673
|
+
latestVersionKind: external_exports.enum(["unknown", "tracking-branch"]).optional()
|
|
15674
|
+
}).strict();
|
|
15675
|
+
|
|
15167
15676
|
// ../../shared-contracts/dist/codex-accounts.js
|
|
15168
15677
|
var accountIdSchema = external_exports.string().min(1).max(256).regex(/^[A-Za-z0-9._~-]+$/u);
|
|
15169
15678
|
var nonBlankTextSchema3 = external_exports.string().trim().min(1);
|
|
@@ -15463,233 +15972,198 @@ var updateStatusResultSchema = external_exports.strictObject({
|
|
|
15463
15972
|
status: updateStatusSchema.nullable()
|
|
15464
15973
|
});
|
|
15465
15974
|
|
|
15975
|
+
// ../../shared-contracts/dist/remote-runtime.js
|
|
15976
|
+
var remoteUpdatePhaseSchema = external_exports.enum([
|
|
15977
|
+
"idle",
|
|
15978
|
+
"installing",
|
|
15979
|
+
"restarting",
|
|
15980
|
+
"succeeded",
|
|
15981
|
+
"failed"
|
|
15982
|
+
]);
|
|
15983
|
+
var runtimeStatusSchema = external_exports.object({
|
|
15984
|
+
runningVersion: external_exports.string().nullable(),
|
|
15985
|
+
installedVersion: external_exports.string().nullable(),
|
|
15986
|
+
restartRequired: external_exports.boolean(),
|
|
15987
|
+
remote: external_exports.boolean(),
|
|
15988
|
+
updateSupported: external_exports.boolean(),
|
|
15989
|
+
update: external_exports.object({
|
|
15990
|
+
phase: remoteUpdatePhaseSchema,
|
|
15991
|
+
targetVersion: external_exports.string().nullable(),
|
|
15992
|
+
error: external_exports.string().nullable()
|
|
15993
|
+
})
|
|
15994
|
+
});
|
|
15995
|
+
var remoteUpdateParamsSchema = external_exports.object({
|
|
15996
|
+
version: external_exports.string().regex(/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/u)
|
|
15997
|
+
}).strict();
|
|
15998
|
+
var remoteSshSetupParamsSchema = external_exports.object({
|
|
15999
|
+
hostname: external_exports.string().min(1).max(1024).refine((value) => !value.startsWith("-") && !/\s/u.test(value)),
|
|
16000
|
+
port: external_exports.number().int().min(1).max(65535).nullable(),
|
|
16001
|
+
identity: external_exports.string().max(4096).nullable(),
|
|
16002
|
+
action: external_exports.enum(["inspect", "install", "update", "repair"]),
|
|
16003
|
+
version: external_exports.string().regex(/^\d+\.\d+\.\d+$/u).nullable()
|
|
16004
|
+
}).strict();
|
|
16005
|
+
var remoteSshSetupResultSchema = external_exports.object({ state: external_exports.enum(["installed", "not-installed"]) }).strict();
|
|
16006
|
+
|
|
15466
16007
|
// ../../shared-contracts/dist/index.js
|
|
15467
16008
|
var workspaceContractVersionSchema = external_exports.literal(WORKSPACE_CONTRACT_VERSION);
|
|
15468
16009
|
|
|
15469
|
-
//
|
|
15470
|
-
|
|
15471
|
-
|
|
15472
|
-
|
|
15473
|
-
|
|
15474
|
-
|
|
15475
|
-
|
|
15476
|
-
|
|
15477
|
-
|
|
15478
|
-
|
|
15479
|
-
|
|
15480
|
-
|
|
15481
|
-
|
|
15482
|
-
|
|
15483
|
-
|
|
15484
|
-
|
|
15485
|
-
|
|
15486
|
-
|
|
15487
|
-
return (environmentValue(environment, "PATH") ?? "").split(pathDelimiter(platform)).map((directory) => directory.trim().replace(/^"|"$/gu, "")).filter(Boolean);
|
|
15488
|
-
}
|
|
15489
|
-
function executableExtensions(command, platform, environment) {
|
|
15490
|
-
if (platform !== "win32")
|
|
15491
|
-
return [""];
|
|
15492
|
-
if (targetPath(platform).extname(command) !== "")
|
|
15493
|
-
return [""];
|
|
15494
|
-
return (environmentValue(environment, "PATHEXT") ?? ".COM;.EXE;.BAT;.CMD").split(";").map((extension) => extension.trim()).filter(Boolean);
|
|
15495
|
-
}
|
|
15496
|
-
function isExecutableFile(filePath, platform) {
|
|
15497
|
-
try {
|
|
15498
|
-
fs.accessSync(filePath, platform === "win32" ? fs.constants.F_OK : fs.constants.X_OK);
|
|
15499
|
-
return fs.statSync(filePath).isFile();
|
|
15500
|
-
} catch {
|
|
15501
|
-
return false;
|
|
15502
|
-
}
|
|
15503
|
-
}
|
|
15504
|
-
function subdirectoryNames(directory) {
|
|
15505
|
-
try {
|
|
15506
|
-
return fs.readdirSync(directory, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name);
|
|
15507
|
-
} catch {
|
|
15508
|
-
return [];
|
|
15509
|
-
}
|
|
15510
|
-
}
|
|
15511
|
-
function newestFirst(names) {
|
|
15512
|
-
return [...names].sort((left, right) => right.localeCompare(left, void 0, { numeric: true }));
|
|
15513
|
-
}
|
|
15514
|
-
|
|
15515
|
-
// ../../harness-discovery/dist/node-runtime.js
|
|
15516
|
-
import path2 from "node:path";
|
|
15517
|
-
function withNodeRuntimeOnPath(environment, runtimeExecutable = process.execPath, platform = process.platform) {
|
|
15518
|
-
const pathKey = Object.keys(environment).find((name) => name.toLowerCase() === "path") ?? "PATH";
|
|
15519
|
-
const delimiter = platform === "win32" ? ";" : ":";
|
|
15520
|
-
const runtimeDirectory = path2.dirname(runtimeExecutable);
|
|
15521
|
-
const directories = (environment[pathKey] ?? "").split(delimiter).filter(Boolean);
|
|
15522
|
-
const equal = platform === "win32" ? (value) => value.toLowerCase() : (value) => value;
|
|
15523
|
-
if (!directories.some((directory) => equal(directory) === equal(runtimeDirectory))) {
|
|
15524
|
-
directories.push(runtimeDirectory);
|
|
15525
|
-
}
|
|
15526
|
-
return { ...environment, [pathKey]: directories.join(delimiter) };
|
|
15527
|
-
}
|
|
15528
|
-
|
|
15529
|
-
// ../../harness-discovery/dist/resolve.js
|
|
15530
|
-
import os from "node:os";
|
|
15531
|
-
|
|
15532
|
-
// ../../harness-discovery/dist/version-managers.js
|
|
15533
|
-
function versionManagerBinaryDirectories(context) {
|
|
15534
|
-
const { platform, environment, home } = context;
|
|
15535
|
-
const list = context.subdirectories ?? subdirectoryNames;
|
|
15536
|
-
const pathFlavor = targetPath(platform);
|
|
15537
|
-
const value = (name) => environmentValue(environment, name);
|
|
15538
|
-
const directories = [];
|
|
15539
|
-
const versioned = (root, ...tail) => {
|
|
15540
|
-
for (const version2 of newestFirst(list(root))) {
|
|
15541
|
-
directories.push(pathFlavor.join(root, version2, ...tail));
|
|
15542
|
-
}
|
|
15543
|
-
};
|
|
15544
|
-
if (platform === "win32") {
|
|
15545
|
-
const appData = value("APPDATA") ?? pathFlavor.join(home, "AppData", "Roaming");
|
|
15546
|
-
const localAppData = value("LOCALAPPDATA") ?? pathFlavor.join(home, "AppData", "Local");
|
|
15547
|
-
versioned(pathFlavor.join(appData, "nvm"));
|
|
15548
|
-
versioned(value("FNM_DIR") ?? pathFlavor.join(appData, "fnm", "node-versions"), "installation");
|
|
15549
|
-
directories.push(pathFlavor.join(localAppData, "Volta", "bin"));
|
|
15550
|
-
directories.push(pathFlavor.join(home, ".bun", "bin"));
|
|
15551
|
-
const pnpmHome2 = value("PNPM_HOME");
|
|
15552
|
-
if (pnpmHome2)
|
|
15553
|
-
directories.push(pnpmHome2);
|
|
15554
|
-
directories.push(pathFlavor.join(localAppData, "pnpm"));
|
|
15555
|
-
return directories;
|
|
15556
|
-
}
|
|
15557
|
-
versioned(pathFlavor.join(value("NVM_DIR") ?? pathFlavor.join(home, ".nvm"), "versions", "node"), "bin");
|
|
15558
|
-
const fnmRoots = [
|
|
15559
|
-
value("FNM_DIR"),
|
|
15560
|
-
pathFlavor.join(home, ".local", "share", "fnm"),
|
|
15561
|
-
pathFlavor.join(home, "Library", "Application Support", "fnm")
|
|
15562
|
-
].filter((root) => root !== void 0);
|
|
15563
|
-
for (const root of fnmRoots) {
|
|
15564
|
-
versioned(pathFlavor.join(root, "node-versions"), "installation", "bin");
|
|
15565
|
-
}
|
|
15566
|
-
const voltaHome = value("VOLTA_HOME") ?? pathFlavor.join(home, ".volta");
|
|
15567
|
-
versioned(pathFlavor.join(voltaHome, "tools", "image", "node"), "bin");
|
|
15568
|
-
directories.push(pathFlavor.join(voltaHome, "bin"));
|
|
15569
|
-
const asdfHome = value("ASDF_DATA_DIR") ?? pathFlavor.join(home, ".asdf");
|
|
15570
|
-
versioned(pathFlavor.join(asdfHome, "installs", "nodejs"), "bin");
|
|
15571
|
-
directories.push(pathFlavor.join(asdfHome, "shims"));
|
|
15572
|
-
const nodenvHome = value("NODENV_ROOT") ?? pathFlavor.join(home, ".nodenv");
|
|
15573
|
-
versioned(pathFlavor.join(nodenvHome, "versions"), "bin");
|
|
15574
|
-
directories.push(pathFlavor.join(nodenvHome, "shims"));
|
|
15575
|
-
versioned(pathFlavor.join(value("N_PREFIX") ?? "/usr/local", "n", "versions", "node"), "bin");
|
|
15576
|
-
directories.push(pathFlavor.join(home, ".bun", "bin"));
|
|
15577
|
-
const pnpmHome = value("PNPM_HOME");
|
|
15578
|
-
if (pnpmHome)
|
|
15579
|
-
directories.push(pnpmHome);
|
|
15580
|
-
directories.push(pathFlavor.join(home, "Library", "pnpm"));
|
|
15581
|
-
directories.push(pathFlavor.join(home, ".local", "share", "pnpm"));
|
|
15582
|
-
for (const prefix of ["/opt/homebrew/opt", "/usr/local/opt"]) {
|
|
15583
|
-
for (const formula of newestFirst(list(prefix).filter((name) => name.startsWith("node@")))) {
|
|
15584
|
-
directories.push(pathFlavor.join(prefix, formula, "bin"));
|
|
15585
|
-
}
|
|
15586
|
-
}
|
|
15587
|
-
return directories;
|
|
15588
|
-
}
|
|
15589
|
-
|
|
15590
|
-
// ../../harness-discovery/dist/resolve.js
|
|
15591
|
-
var VERSION_MANAGER_ROOTS = "<version-managers>";
|
|
15592
|
-
function installRootExtensions(platform) {
|
|
15593
|
-
return platform === "win32" ? [".exe", ".cmd"] : [""];
|
|
15594
|
-
}
|
|
15595
|
-
function resolveHomeDirectory(input) {
|
|
15596
|
-
return input.homeDirectory ?? environmentValue(input.environment, "HOME") ?? environmentValue(input.environment, "USERPROFILE") ?? os.homedir();
|
|
16010
|
+
// dist/account-balance.js
|
|
16011
|
+
var DEEPSEEK_BALANCE_ENDPOINT = "https://api.deepseek.com/user/balance";
|
|
16012
|
+
var SUB2API_USAGE_PATH = "/v1/usage";
|
|
16013
|
+
var REQUEST_TIMEOUT_MS = 1e4;
|
|
16014
|
+
var MAX_PI_ACCOUNTS = 8;
|
|
16015
|
+
function agentDirectory(environment) {
|
|
16016
|
+
const configured = environment.PI_CODING_AGENT_DIR?.trim();
|
|
16017
|
+
if (configured)
|
|
16018
|
+
return configured;
|
|
16019
|
+
return path4.join(environment.HOME ?? environment.USERPROFILE ?? homedir2(), ".pi", "agent");
|
|
16020
|
+
}
|
|
16021
|
+
var record2 = (value) => value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
16022
|
+
async function deepSeekApiKey(environment) {
|
|
16023
|
+
const auth = record2(JSON.parse(await readFile(path4.join(agentDirectory(environment), "auth.json"), "utf8")));
|
|
16024
|
+
const deepseek = record2(auth.deepseek);
|
|
16025
|
+
if (deepseek.type !== "api_key")
|
|
16026
|
+
return void 0;
|
|
16027
|
+
return typeof deepseek.key === "string" && deepseek.key.trim() ? deepseek.key : void 0;
|
|
15597
16028
|
}
|
|
15598
|
-
function
|
|
15599
|
-
const
|
|
15600
|
-
|
|
15601
|
-
|
|
15602
|
-
|
|
15603
|
-
|
|
15604
|
-
|
|
15605
|
-
}
|
|
16029
|
+
function projectSub2ApiUsage(payload, providerId) {
|
|
16030
|
+
const data = record2(payload);
|
|
16031
|
+
if (data.isValid === false)
|
|
16032
|
+
return null;
|
|
16033
|
+
if (data.mode !== "unrestricted" && data.mode !== "quota_limited")
|
|
16034
|
+
return null;
|
|
16035
|
+
const currency = typeof data.unit === "string" ? data.unit.trim() : "";
|
|
16036
|
+
if (!/^[A-Z]{3}$/u.test(currency))
|
|
16037
|
+
return null;
|
|
16038
|
+
const wallet = finiteAmount(data.balance);
|
|
16039
|
+
const remaining = finiteAmount(data.remaining);
|
|
16040
|
+
const quotaRemaining = finiteAmount(record2(data.quota).remaining);
|
|
16041
|
+
const amount = wallet ?? remaining ?? quotaRemaining;
|
|
16042
|
+
if (amount === null)
|
|
16043
|
+
return null;
|
|
16044
|
+
const planName = typeof data.planName === "string" ? data.planName.trim() : "";
|
|
16045
|
+
const label = providerId.trim();
|
|
16046
|
+
if (!label || label.length > 128)
|
|
16047
|
+
return null;
|
|
16048
|
+
const parsed = harnessAccountSnapshotSchema.safeParse({
|
|
16049
|
+
label,
|
|
16050
|
+
...planName ? { plan: planName.slice(0, 128) } : {},
|
|
16051
|
+
balance: { amount, currency, label: planName || label }
|
|
16052
|
+
});
|
|
16053
|
+
return parsed.success ? parsed.data : null;
|
|
15606
16054
|
}
|
|
15607
|
-
function
|
|
15608
|
-
const
|
|
15609
|
-
|
|
15610
|
-
const head = segments[0] ?? "";
|
|
15611
|
-
const tail = segments.slice(1);
|
|
15612
|
-
if (head === "")
|
|
15613
|
-
return pathFlavor.join(pathFlavor.sep, ...tail);
|
|
15614
|
-
return tail.length === 0 ? head : pathFlavor.join(head, ...tail);
|
|
16055
|
+
function finiteAmount(value) {
|
|
16056
|
+
const amount = typeof value === "number" ? value : typeof value === "string" && value.trim() ? Number(value) : Number.NaN;
|
|
16057
|
+
return Number.isFinite(amount) && amount >= 0 ? amount : null;
|
|
15615
16058
|
}
|
|
15616
|
-
function
|
|
15617
|
-
const
|
|
15618
|
-
|
|
15619
|
-
|
|
15620
|
-
|
|
15621
|
-
|
|
15622
|
-
|
|
15623
|
-
|
|
15624
|
-
|
|
15625
|
-
|
|
16059
|
+
function projectDeepSeekBalance(payload) {
|
|
16060
|
+
const data = record2(payload);
|
|
16061
|
+
if (!Array.isArray(data.balance_infos))
|
|
16062
|
+
return null;
|
|
16063
|
+
const first = record2(data.balance_infos[0]);
|
|
16064
|
+
const amount = finiteAmount(first.total_balance);
|
|
16065
|
+
const currency = typeof first.currency === "string" ? first.currency.trim() : "";
|
|
16066
|
+
if (amount === null || !currency)
|
|
16067
|
+
return null;
|
|
16068
|
+
const parsed = harnessAccountSnapshotSchema.safeParse({
|
|
16069
|
+
label: "DeepSeek",
|
|
16070
|
+
balance: { amount, currency, label: "DeepSeek API" }
|
|
15626
16071
|
});
|
|
15627
|
-
return
|
|
15628
|
-
}
|
|
15629
|
-
function installRootDirectories(spec, input, dependencies, platform, home) {
|
|
15630
|
-
const templates = (platform === "win32" ? spec.installRoots?.windows : spec.installRoots?.posix) ?? [];
|
|
15631
|
-
const directories = [];
|
|
15632
|
-
for (const template of templates) {
|
|
15633
|
-
if (template === VERSION_MANAGER_ROOTS) {
|
|
15634
|
-
directories.push(...versionManagerBinaryDirectories({
|
|
15635
|
-
platform,
|
|
15636
|
-
environment: input.environment,
|
|
15637
|
-
home,
|
|
15638
|
-
...dependencies.subdirectories ? { subdirectories: dependencies.subdirectories } : {}
|
|
15639
|
-
}));
|
|
15640
|
-
continue;
|
|
15641
|
-
}
|
|
15642
|
-
const directory = expandInstallRoot(template, input.environment, platform, home);
|
|
15643
|
-
if (directory !== void 0)
|
|
15644
|
-
directories.push(directory);
|
|
15645
|
-
}
|
|
15646
|
-
return directories;
|
|
16072
|
+
return parsed.success ? parsed.data : null;
|
|
15647
16073
|
}
|
|
15648
|
-
function
|
|
15649
|
-
|
|
15650
|
-
|
|
15651
|
-
|
|
15652
|
-
|
|
15653
|
-
|
|
15654
|
-
return [{ candidate: command, source: "configured" }];
|
|
16074
|
+
function usageEndpoint(baseUrl) {
|
|
16075
|
+
let url2;
|
|
16076
|
+
try {
|
|
16077
|
+
url2 = new URL(baseUrl);
|
|
16078
|
+
} catch {
|
|
16079
|
+
return null;
|
|
15655
16080
|
}
|
|
15656
|
-
|
|
15657
|
-
|
|
15658
|
-
|
|
15659
|
-
|
|
15660
|
-
|
|
15661
|
-
|
|
15662
|
-
|
|
15663
|
-
|
|
16081
|
+
if (url2.protocol !== "https:" && url2.protocol !== "http:" || !url2.hostname)
|
|
16082
|
+
return null;
|
|
16083
|
+
url2.username = "";
|
|
16084
|
+
url2.password = "";
|
|
16085
|
+
url2.pathname = SUB2API_USAGE_PATH;
|
|
16086
|
+
url2.search = "";
|
|
16087
|
+
url2.hash = "";
|
|
16088
|
+
return url2.toString();
|
|
16089
|
+
}
|
|
16090
|
+
async function configuredSub2ApiProviders(environment) {
|
|
16091
|
+
try {
|
|
16092
|
+
const models = record2(JSON.parse(await readFile(path4.join(agentDirectory(environment), "models.json"), "utf8")));
|
|
16093
|
+
const providers = record2(models.providers);
|
|
16094
|
+
const found = [];
|
|
16095
|
+
for (const [id, definition] of Object.entries(providers)) {
|
|
16096
|
+
const provider = record2(definition);
|
|
16097
|
+
const apiKey = typeof provider.apiKey === "string" ? provider.apiKey.trim() : "";
|
|
16098
|
+
const baseUrl = typeof provider.baseUrl === "string" ? provider.baseUrl.trim() : "";
|
|
16099
|
+
if (!id.trim() || id.length > 128 || !apiKey || !usageEndpoint(baseUrl))
|
|
16100
|
+
continue;
|
|
16101
|
+
found.push({ id, apiKey, baseUrl });
|
|
15664
16102
|
}
|
|
16103
|
+
return found.sort((left, right) => left.id.localeCompare(right.id));
|
|
16104
|
+
} catch {
|
|
16105
|
+
return [];
|
|
15665
16106
|
}
|
|
15666
|
-
|
|
15667
|
-
|
|
15668
|
-
const
|
|
15669
|
-
|
|
15670
|
-
|
|
15671
|
-
|
|
15672
|
-
|
|
15673
|
-
|
|
15674
|
-
|
|
15675
|
-
|
|
16107
|
+
}
|
|
16108
|
+
async function fetchSub2ApiBalance(provider, fetchImpl, signal) {
|
|
16109
|
+
const endpoint = usageEndpoint(provider.baseUrl);
|
|
16110
|
+
if (!endpoint)
|
|
16111
|
+
return null;
|
|
16112
|
+
const response = await fetchImpl(endpoint, {
|
|
16113
|
+
headers: { Authorization: `Bearer ${provider.apiKey}`, Accept: "application/json" },
|
|
16114
|
+
redirect: "error",
|
|
16115
|
+
signal
|
|
16116
|
+
});
|
|
16117
|
+
if (!response.ok)
|
|
16118
|
+
return null;
|
|
16119
|
+
return projectSub2ApiUsage(await response.json(), provider.id);
|
|
16120
|
+
}
|
|
16121
|
+
async function fetchPiAccounts(input = {}) {
|
|
16122
|
+
try {
|
|
16123
|
+
const environment = input.environment ?? process.env;
|
|
16124
|
+
const fetchImpl = input.fetch ?? fetch;
|
|
16125
|
+
const signal = input.signal ? AbortSignal.any([input.signal, AbortSignal.timeout(REQUEST_TIMEOUT_MS)]) : AbortSignal.timeout(REQUEST_TIMEOUT_MS);
|
|
16126
|
+
const [providers, deepseek] = await Promise.all([
|
|
16127
|
+
input.readProviders ? input.readProviders() : configuredSub2ApiProviders(environment),
|
|
16128
|
+
fetchPiAccountBalance({ ...input, environment, fetch: fetchImpl, signal })
|
|
16129
|
+
]);
|
|
16130
|
+
const wallets = await Promise.all(providers.filter((provider) => provider.apiKey.trim() && usageEndpoint(provider.baseUrl)).map((provider) => fetchSub2ApiBalance(provider, fetchImpl, signal).catch(() => null)));
|
|
16131
|
+
return [...wallets, deepseek].filter((account) => account !== null).slice(0, MAX_PI_ACCOUNTS);
|
|
16132
|
+
} catch {
|
|
16133
|
+
return [];
|
|
15676
16134
|
}
|
|
15677
|
-
return candidates;
|
|
15678
16135
|
}
|
|
15679
|
-
function
|
|
15680
|
-
|
|
15681
|
-
|
|
15682
|
-
|
|
15683
|
-
|
|
15684
|
-
|
|
15685
|
-
|
|
15686
|
-
|
|
15687
|
-
|
|
16136
|
+
async function fetchPiAccountBalance(input) {
|
|
16137
|
+
try {
|
|
16138
|
+
const key = await (input.readApiKey ? input.readApiKey() : deepSeekApiKey(input.environment));
|
|
16139
|
+
if (!key)
|
|
16140
|
+
return null;
|
|
16141
|
+
const response = await input.fetch(DEEPSEEK_BALANCE_ENDPOINT, {
|
|
16142
|
+
headers: { Authorization: `Bearer ${key}`, Accept: "application/json" },
|
|
16143
|
+
signal: input.signal
|
|
16144
|
+
});
|
|
16145
|
+
if (!response.ok)
|
|
16146
|
+
return null;
|
|
16147
|
+
return projectDeepSeekBalance(await response.json());
|
|
16148
|
+
} catch {
|
|
16149
|
+
return null;
|
|
15688
16150
|
}
|
|
15689
|
-
return void 0;
|
|
15690
16151
|
}
|
|
15691
16152
|
|
|
16153
|
+
// dist/pi-credential-imports.js
|
|
16154
|
+
import { randomUUID } from "node:crypto";
|
|
16155
|
+
import { execFile as execFile2 } from "node:child_process";
|
|
16156
|
+
import { promisify } from "node:util";
|
|
16157
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync, rmSync, readdirSync, lstatSync, renameSync, rmdirSync } from "node:fs";
|
|
16158
|
+
import { realpath } from "node:fs/promises";
|
|
16159
|
+
import os2 from "node:os";
|
|
16160
|
+
import path6 from "node:path";
|
|
16161
|
+
import { pathToFileURL } from "node:url";
|
|
16162
|
+
|
|
15692
16163
|
// dist/command.js
|
|
16164
|
+
import fs2 from "node:fs";
|
|
16165
|
+
import { homedir as homedir3, tmpdir as tmpdir2 } from "node:os";
|
|
16166
|
+
import path5 from "node:path";
|
|
15693
16167
|
var piDiscoverySpec = {
|
|
15694
16168
|
id: "pi",
|
|
15695
16169
|
command: "pi",
|
|
@@ -15714,6 +16188,34 @@ function resolvePiExecutable(input, dependencies = {}) {
|
|
|
15714
16188
|
}, { ...dependencies.isExecutable ? { isExecutable: dependencies.isExecutable } : {} });
|
|
15715
16189
|
return resolution?.executable ?? input.command ?? input.environment.PI_COMMAND ?? "pi";
|
|
15716
16190
|
}
|
|
16191
|
+
function isFilesystemRoot(cwd) {
|
|
16192
|
+
const resolved = path5.resolve(cwd);
|
|
16193
|
+
return resolved === path5.parse(resolved).root;
|
|
16194
|
+
}
|
|
16195
|
+
function writableDirectory(candidate) {
|
|
16196
|
+
if (!candidate || !path5.isAbsolute(candidate) || isFilesystemRoot(candidate))
|
|
16197
|
+
return void 0;
|
|
16198
|
+
try {
|
|
16199
|
+
if (!fs2.statSync(candidate).isDirectory())
|
|
16200
|
+
return void 0;
|
|
16201
|
+
fs2.accessSync(candidate, fs2.constants.R_OK | fs2.constants.W_OK);
|
|
16202
|
+
return candidate;
|
|
16203
|
+
} catch {
|
|
16204
|
+
return void 0;
|
|
16205
|
+
}
|
|
16206
|
+
}
|
|
16207
|
+
function resolvePiInspectCwd(inputCwd, environment = process.env) {
|
|
16208
|
+
if (typeof inputCwd === "string" && inputCwd.length > 0 && !isFilesystemRoot(inputCwd)) {
|
|
16209
|
+
return path5.resolve(inputCwd);
|
|
16210
|
+
}
|
|
16211
|
+
const candidates = [environment.USERPROFILE, environment.HOME, homedir3(), tmpdir2()];
|
|
16212
|
+
for (const candidate of candidates) {
|
|
16213
|
+
const usable = writableDirectory(candidate);
|
|
16214
|
+
if (usable)
|
|
16215
|
+
return usable;
|
|
16216
|
+
}
|
|
16217
|
+
return inputCwd && inputCwd.length > 0 ? path5.resolve(inputCwd) : process.cwd();
|
|
16218
|
+
}
|
|
15717
16219
|
|
|
15718
16220
|
// dist/pi-credential-imports.js
|
|
15719
16221
|
var PREFIX = "codexhost-account-";
|
|
@@ -15756,6 +16258,15 @@ function describeOauth(credential) {
|
|
|
15756
16258
|
...match ? { vendor: match.vendor } : {}
|
|
15757
16259
|
};
|
|
15758
16260
|
}
|
|
16261
|
+
function readPiCodexProviderNames(environment) {
|
|
16262
|
+
const agentDir = environment.PI_CODING_AGENT_DIR ?? path6.join(environment.HOME ?? environment.USERPROFILE ?? os2.homedir(), ".pi/agent");
|
|
16263
|
+
try {
|
|
16264
|
+
const auth = parseAuth(readFileSync(path6.join(agentDir, "auth.json"), "utf8"));
|
|
16265
|
+
return Object.entries(auth).filter(([, credential]) => describeOauth(credential).vendor === "openai-codex").map(([provider]) => provider);
|
|
16266
|
+
} catch {
|
|
16267
|
+
return [];
|
|
16268
|
+
}
|
|
16269
|
+
}
|
|
15759
16270
|
function writeAuth(filename, content) {
|
|
15760
16271
|
const temporary = `${filename}.${randomUUID()}.tmp`;
|
|
15761
16272
|
try {
|
|
@@ -15766,8 +16277,8 @@ function writeAuth(filename, content) {
|
|
|
15766
16277
|
}
|
|
15767
16278
|
}
|
|
15768
16279
|
function removeOwnedFiles(dir) {
|
|
15769
|
-
rmSync(
|
|
15770
|
-
rmSync(
|
|
16280
|
+
rmSync(path6.join(dir, "index.ts"), { force: true });
|
|
16281
|
+
rmSync(path6.join(dir, "import.json"), { force: true });
|
|
15771
16282
|
try {
|
|
15772
16283
|
rmdirSync(dir);
|
|
15773
16284
|
} catch {
|
|
@@ -15775,26 +16286,26 @@ function removeOwnedFiles(dir) {
|
|
|
15775
16286
|
}
|
|
15776
16287
|
async function installation(command, environment, authPath) {
|
|
15777
16288
|
const executable = await realpath(resolvePiExecutable({ ...command ? { command } : {}, environment }));
|
|
15778
|
-
let directory =
|
|
16289
|
+
let directory = path6.dirname(executable);
|
|
15779
16290
|
while (true) {
|
|
15780
|
-
const manifest =
|
|
16291
|
+
const manifest = path6.join(directory, "package.json");
|
|
15781
16292
|
if (existsSync(manifest)) {
|
|
15782
16293
|
const pkg = JSON.parse(readFileSync(manifest, "utf8"));
|
|
15783
16294
|
if (pkg.name === "@earendil-works/pi-coding-agent")
|
|
15784
16295
|
break;
|
|
15785
16296
|
}
|
|
15786
|
-
const parent =
|
|
16297
|
+
const parent = path6.dirname(directory);
|
|
15787
16298
|
if (parent === directory)
|
|
15788
16299
|
throw new Error("Pi credential import requires a supported npm Pi installation");
|
|
15789
16300
|
directory = parent;
|
|
15790
16301
|
}
|
|
15791
|
-
const storage = await import(pathToFileURL(
|
|
15792
|
-
const ai =
|
|
15793
|
-
const all = await import(pathToFileURL(
|
|
16302
|
+
const storage = await import(pathToFileURL(path6.join(directory, "dist/core/auth-storage.js")).href);
|
|
16303
|
+
const ai = path6.join(directory, "node_modules/@earendil-works/pi-ai/dist");
|
|
16304
|
+
const all = await import(pathToFileURL(path6.join(ai, "providers/all.js")).href);
|
|
15794
16305
|
const providers = all.getBuiltinProviders();
|
|
15795
16306
|
const providerModules = {
|
|
15796
|
-
"openai-codex": pathToFileURL(
|
|
15797
|
-
xai: pathToFileURL(
|
|
16307
|
+
"openai-codex": pathToFileURL(path6.join(ai, "providers/openai-codex.js")).href,
|
|
16308
|
+
xai: pathToFileURL(path6.join(ai, "providers/xai.js")).href
|
|
15798
16309
|
};
|
|
15799
16310
|
for (const [id, url2] of Object.entries(providerModules)) {
|
|
15800
16311
|
const module = await import(url2);
|
|
@@ -15807,9 +16318,9 @@ async function installation(command, environment, authPath) {
|
|
|
15807
16318
|
providerModules,
|
|
15808
16319
|
reservedNames: providers.map((p) => typeof p === "string" ? p : p.id),
|
|
15809
16320
|
async configuredProviderNames() {
|
|
15810
|
-
const { stdout } = await promisify(
|
|
15811
|
-
cwd: existsSync(
|
|
15812
|
-
env: { ...environment, PI_CODING_AGENT_DIR:
|
|
16321
|
+
const { stdout } = await promisify(execFile2)(process.execPath, [executable, "--offline", "--no-approve", "--list-models"], {
|
|
16322
|
+
cwd: existsSync(path6.dirname(authPath)) ? path6.dirname(authPath) : os2.homedir(),
|
|
16323
|
+
env: { ...environment, PI_CODING_AGENT_DIR: path6.dirname(authPath), PI_OFFLINE: "1" },
|
|
15813
16324
|
timeout: 15e3,
|
|
15814
16325
|
maxBuffer: 4 * 1024 * 1024
|
|
15815
16326
|
});
|
|
@@ -15839,26 +16350,26 @@ export default async function (pi) {
|
|
|
15839
16350
|
}
|
|
15840
16351
|
function createPiCredentialImports(options = {}) {
|
|
15841
16352
|
const env = { ...process.env, ...options.environment };
|
|
15842
|
-
const agentDir = env.PI_CODING_AGENT_DIR ??
|
|
15843
|
-
const authPath =
|
|
15844
|
-
const extensionsDir =
|
|
16353
|
+
const agentDir = env.PI_CODING_AGENT_DIR ?? path6.join(env.HOME ?? os2.homedir(), ".pi/agent");
|
|
16354
|
+
const authPath = path6.join(agentDir, "auth.json");
|
|
16355
|
+
const extensionsDir = path6.join(agentDir, "extensions");
|
|
15845
16356
|
const saveAuth = (auth) => (options.writeAuth ?? writeAuth)(authPath, JSON.stringify(auth, null, 2) + "\n");
|
|
15846
16357
|
const resolve = () => options.resolveInstallation?.(authPath) ?? installation(options.command, env, authPath);
|
|
15847
|
-
const location = (name) =>
|
|
16358
|
+
const location = (name) => path6.join(extensionsDir, `${PREFIX}${credentialImportNameSchema.parse(name)}`);
|
|
15848
16359
|
const readRecord = (name) => {
|
|
15849
16360
|
const dir = location(name);
|
|
15850
16361
|
if (lstatSync(dir).isSymbolicLink())
|
|
15851
16362
|
throw new Error("Imported configuration was changed; manage it in Pi");
|
|
15852
|
-
const value = JSON.parse(readFileSync(
|
|
16363
|
+
const value = JSON.parse(readFileSync(path6.join(dir, "import.json"), "utf8"));
|
|
15853
16364
|
if (value.version !== 1 || typeof value.owner !== "string" || typeof value.extension !== "string")
|
|
15854
16365
|
throw new Error("Invalid import metadata");
|
|
15855
|
-
const
|
|
15856
|
-
if (!object2(
|
|
16366
|
+
const record7 = value.record;
|
|
16367
|
+
if (!object2(record7))
|
|
15857
16368
|
throw new Error("Invalid import metadata");
|
|
15858
16369
|
value.record = credentialImportRecordSchema.parse({
|
|
15859
|
-
name:
|
|
15860
|
-
source:
|
|
15861
|
-
importedAt:
|
|
16370
|
+
name: record7.name,
|
|
16371
|
+
source: record7.source,
|
|
16372
|
+
importedAt: record7.importedAt
|
|
15862
16373
|
});
|
|
15863
16374
|
if (value.record.name !== name)
|
|
15864
16375
|
throw new Error("Import identity mismatch");
|
|
@@ -15866,7 +16377,7 @@ function createPiCredentialImports(options = {}) {
|
|
|
15866
16377
|
};
|
|
15867
16378
|
const owned = (meta3, auth) => {
|
|
15868
16379
|
const credential = auth[meta3.record.name];
|
|
15869
|
-
const file2 =
|
|
16380
|
+
const file2 = path6.join(location(meta3.record.name), "index.ts");
|
|
15870
16381
|
return existsSync(file2) && !lstatSync(file2).isSymbolicLink() && readFileSync(file2, "utf8") === meta3.extension && object2(credential) && credential.type === "oauth" && credential.codexhostImportId === meta3.owner;
|
|
15871
16382
|
};
|
|
15872
16383
|
const readAuth = () => existsSync(authPath) ? parseAuth(readFileSync(authPath, "utf8")) : {};
|
|
@@ -15880,7 +16391,7 @@ function createPiCredentialImports(options = {}) {
|
|
|
15880
16391
|
const name = entry.slice(PREFIX.length);
|
|
15881
16392
|
if (!credentialImportNameSchema.safeParse(name).success)
|
|
15882
16393
|
continue;
|
|
15883
|
-
if (!existsSync(
|
|
16394
|
+
if (!existsSync(path6.join(location(name), "import.json")))
|
|
15884
16395
|
continue;
|
|
15885
16396
|
try {
|
|
15886
16397
|
const meta3 = readRecord(name);
|
|
@@ -15901,7 +16412,7 @@ function createPiCredentialImports(options = {}) {
|
|
|
15901
16412
|
},
|
|
15902
16413
|
async listOthers() {
|
|
15903
16414
|
const auth = readAuth();
|
|
15904
|
-
const ours = new Set(ownedRecords(auth).map((
|
|
16415
|
+
const ours = new Set(ownedRecords(auth).map((record7) => record7.name));
|
|
15905
16416
|
const result = /* @__PURE__ */ new Map();
|
|
15906
16417
|
const usable = (provider) => Boolean(provider) && provider.length <= 128 && !ours.has(provider) && !result.has(provider);
|
|
15907
16418
|
for (const [provider, credential] of Object.entries(auth)) {
|
|
@@ -15914,7 +16425,7 @@ function createPiCredentialImports(options = {}) {
|
|
|
15914
16425
|
...describeOauth(credential)
|
|
15915
16426
|
});
|
|
15916
16427
|
}
|
|
15917
|
-
const modelsPath =
|
|
16428
|
+
const modelsPath = path6.join(agentDir, "models.json");
|
|
15918
16429
|
if (existsSync(modelsPath)) {
|
|
15919
16430
|
const models = JSON.parse(readFileSync(modelsPath, "utf8"));
|
|
15920
16431
|
const providers = object2(models) && object2(models.providers) ? models.providers : {};
|
|
@@ -15936,7 +16447,7 @@ function createPiCredentialImports(options = {}) {
|
|
|
15936
16447
|
if (sdk.reservedNames.includes(name) || (await sdk.configuredProviderNames?.())?.includes(name))
|
|
15937
16448
|
throw new Error("Provider name already exists; choose another name");
|
|
15938
16449
|
const owner = randomUUID();
|
|
15939
|
-
const
|
|
16450
|
+
const record7 = credentialImportRecordSchema.parse({
|
|
15940
16451
|
name,
|
|
15941
16452
|
source: transfer.source,
|
|
15942
16453
|
importedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
@@ -15948,15 +16459,15 @@ function createPiCredentialImports(options = {}) {
|
|
|
15948
16459
|
try {
|
|
15949
16460
|
sdk.backend.withLock((current) => {
|
|
15950
16461
|
const auth = parseAuth(current);
|
|
15951
|
-
const modelsPath =
|
|
16462
|
+
const modelsPath = path6.join(agentDir, "models.json");
|
|
15952
16463
|
const models = existsSync(modelsPath) ? JSON.parse(readFileSync(modelsPath, "utf8")) : {};
|
|
15953
|
-
if (Object.hasOwn(auth, name) || Object.hasOwn(models.providers ?? {}, name) || existsSync(dir) || existsSync(
|
|
16464
|
+
if (Object.hasOwn(auth, name) || Object.hasOwn(models.providers ?? {}, name) || existsSync(dir) || existsSync(path6.join(extensionsDir, `${name}-provider.ts`)))
|
|
15954
16465
|
throw new Error("Provider name already exists; choose another name");
|
|
15955
16466
|
mkdirSync(extensionsDir, { recursive: true, mode: 448 });
|
|
15956
16467
|
mkdirSync(dir, { mode: 448 });
|
|
15957
16468
|
created = true;
|
|
15958
|
-
writeFileSync(
|
|
15959
|
-
writeFileSync(
|
|
16469
|
+
writeFileSync(path6.join(dir, "import.json"), JSON.stringify({ version: 1, owner, record: record7, extension }), { flag: "wx", mode: 384 });
|
|
16470
|
+
writeFileSync(path6.join(dir, "index.ts"), extension, { flag: "wx", mode: 384 });
|
|
15960
16471
|
auth[name] = { type: "oauth", ...transfer.oauth, codexhostImportId: owner };
|
|
15961
16472
|
saveAuth(auth);
|
|
15962
16473
|
committed = true;
|
|
@@ -15975,7 +16486,7 @@ function createPiCredentialImports(options = {}) {
|
|
|
15975
16486
|
const auth = parseAuth(current);
|
|
15976
16487
|
if (!owned(meta3, auth) || meta3.record.source.id !== transfer.source.id || meta3.record.source.provider !== transfer.source.provider)
|
|
15977
16488
|
throw new Error("Import ownership or source account changed; refusing replacement");
|
|
15978
|
-
const metadataPath =
|
|
16489
|
+
const metadataPath = path6.join(location(name), "import.json");
|
|
15979
16490
|
const previous = readFileSync(metadataPath, "utf8");
|
|
15980
16491
|
const updated = {
|
|
15981
16492
|
...meta3,
|
|
@@ -16009,15 +16520,229 @@ function createPiCredentialImports(options = {}) {
|
|
|
16009
16520
|
};
|
|
16010
16521
|
}
|
|
16011
16522
|
|
|
16523
|
+
// dist/pi-fast-mode.js
|
|
16524
|
+
import { createHash, randomUUID as randomUUID2 } from "node:crypto";
|
|
16525
|
+
import { mkdir, readFile as readFile2, rename, rm as rm2, writeFile as writeFile2 } from "node:fs/promises";
|
|
16526
|
+
import { homedir as homedir4 } from "node:os";
|
|
16527
|
+
import path7 from "node:path";
|
|
16528
|
+
|
|
16529
|
+
// dist/pi-model-catalog.js
|
|
16530
|
+
var PI_MODEL_REF_PREFIX = "pi-model-v1.";
|
|
16531
|
+
var PI_DRAFT_THINKING_OPTION_IDS = [
|
|
16532
|
+
"off",
|
|
16533
|
+
"minimal",
|
|
16534
|
+
"low",
|
|
16535
|
+
"medium",
|
|
16536
|
+
"high",
|
|
16537
|
+
"xhigh",
|
|
16538
|
+
"max"
|
|
16539
|
+
].map((id) => harnessThinkingOptionIdSchema.parse(id));
|
|
16540
|
+
var PI_THINKING_LABELS = {
|
|
16541
|
+
off: "Off",
|
|
16542
|
+
minimal: "Minimal",
|
|
16543
|
+
low: "Low",
|
|
16544
|
+
medium: "Medium",
|
|
16545
|
+
high: "High",
|
|
16546
|
+
xhigh: "Extra High",
|
|
16547
|
+
max: "Max"
|
|
16548
|
+
};
|
|
16549
|
+
function compareText(left, right) {
|
|
16550
|
+
return left < right ? -1 : left > right ? 1 : 0;
|
|
16551
|
+
}
|
|
16552
|
+
function assertNativePart(value, name) {
|
|
16553
|
+
if (value.trim().length === 0)
|
|
16554
|
+
throw new Error(`Pi ${name} must not be empty`);
|
|
16555
|
+
}
|
|
16556
|
+
function encodePiModelRef(model) {
|
|
16557
|
+
assertNativePart(model.provider, "Model provider");
|
|
16558
|
+
assertNativePart(model.id, "Model id");
|
|
16559
|
+
const encoded = Buffer.from(JSON.stringify(model.fast ? [model.provider, model.id, true] : [model.provider, model.id]), "utf8").toString("base64url");
|
|
16560
|
+
return harnessModelRefSchema.parse({ id: `${PI_MODEL_REF_PREFIX}${encoded}` });
|
|
16561
|
+
}
|
|
16562
|
+
function decodePiModelRef(ref) {
|
|
16563
|
+
const parsedRef = harnessModelRefSchema.parse(ref);
|
|
16564
|
+
if (!parsedRef.id.startsWith(PI_MODEL_REF_PREFIX)) {
|
|
16565
|
+
throw new Error("Model Ref does not belong to PiAdapter");
|
|
16566
|
+
}
|
|
16567
|
+
const encoded = parsedRef.id.slice(PI_MODEL_REF_PREFIX.length);
|
|
16568
|
+
let decoded;
|
|
16569
|
+
try {
|
|
16570
|
+
decoded = JSON.parse(Buffer.from(encoded, "base64url").toString("utf8"));
|
|
16571
|
+
} catch {
|
|
16572
|
+
throw new Error("Pi Model Ref is malformed");
|
|
16573
|
+
}
|
|
16574
|
+
if (!Array.isArray(decoded) || decoded.length !== 2 && !(decoded.length === 3 && decoded[2] === true) || typeof decoded[0] !== "string" || typeof decoded[1] !== "string") {
|
|
16575
|
+
throw new Error("Pi Model Ref has an invalid native identity");
|
|
16576
|
+
}
|
|
16577
|
+
const native = {
|
|
16578
|
+
provider: decoded[0],
|
|
16579
|
+
id: decoded[1],
|
|
16580
|
+
...decoded[2] === true ? { fast: true } : {}
|
|
16581
|
+
};
|
|
16582
|
+
assertNativePart(native.provider, "Model provider");
|
|
16583
|
+
assertNativePart(native.id, "Model id");
|
|
16584
|
+
if (encodePiModelRef(native).id !== parsedRef.id) {
|
|
16585
|
+
throw new Error("Pi Model Ref is not canonical");
|
|
16586
|
+
}
|
|
16587
|
+
return native;
|
|
16588
|
+
}
|
|
16589
|
+
function samePiModel(left, right) {
|
|
16590
|
+
return left === null ? right === null : right !== null && left.provider === right.provider && left.id === right.id;
|
|
16591
|
+
}
|
|
16592
|
+
function fallbackThinkingLabel(id) {
|
|
16593
|
+
const label = id.split(/[._~-]+/u).filter((part) => part.length > 0).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
|
|
16594
|
+
return label || id;
|
|
16595
|
+
}
|
|
16596
|
+
function normalizePiThinkingOptions(levels) {
|
|
16597
|
+
return levels.map((id) => harnessThinkingOptionSchema.parse({
|
|
16598
|
+
id,
|
|
16599
|
+
label: PI_THINKING_LABELS[id] ?? fallbackThinkingLabel(id)
|
|
16600
|
+
}));
|
|
16601
|
+
}
|
|
16602
|
+
function normalizePiModelCatalog(nativeModels, effectiveModel, thinkingLevels, effectiveThinkingOptionId) {
|
|
16603
|
+
const byRef = /* @__PURE__ */ new Map();
|
|
16604
|
+
for (const native of nativeModels) {
|
|
16605
|
+
const ref = encodePiModelRef(native);
|
|
16606
|
+
const existing = byRef.get(ref.id);
|
|
16607
|
+
if (existing) {
|
|
16608
|
+
if (existing.reasoning !== native.reasoning) {
|
|
16609
|
+
throw new Error("Pi duplicate Model entries disagree on reasoning capability");
|
|
16610
|
+
}
|
|
16611
|
+
continue;
|
|
16612
|
+
}
|
|
16613
|
+
byRef.set(ref.id, {
|
|
16614
|
+
model: {
|
|
16615
|
+
ref,
|
|
16616
|
+
label: `${native.provider} / ${native.id}`
|
|
16617
|
+
},
|
|
16618
|
+
reasoning: native.reasoning
|
|
16619
|
+
});
|
|
16620
|
+
}
|
|
16621
|
+
const defaultModel = effectiveModel ? encodePiModelRef(effectiveModel) : void 0;
|
|
16622
|
+
if (defaultModel && !byRef.has(defaultModel.id)) {
|
|
16623
|
+
throw new Error("Pi effective Model is absent from the available Model catalog");
|
|
16624
|
+
}
|
|
16625
|
+
if (thinkingLevels && effectiveThinkingOptionId && !thinkingLevels.includes(effectiveThinkingOptionId)) {
|
|
16626
|
+
throw new Error("Pi effective Thinking option is absent from the available option catalog");
|
|
16627
|
+
}
|
|
16628
|
+
if (thinkingLevels && !effectiveThinkingOptionId) {
|
|
16629
|
+
throw new Error("Pi did not report an effective Thinking option");
|
|
16630
|
+
}
|
|
16631
|
+
const thinkingOptions = thinkingLevels ? normalizePiThinkingOptions(PI_DRAFT_THINKING_OPTION_IDS) : [];
|
|
16632
|
+
const allThinkingOptionIds = thinkingOptions.map(({ id }) => id);
|
|
16633
|
+
const offThinkingOptionId = thinkingOptions.find(({ id }) => id === "off")?.id;
|
|
16634
|
+
const models = [...byRef.values()].map(({ model, reasoning }) => ({
|
|
16635
|
+
...model,
|
|
16636
|
+
supportedThinkingOptionIds: reasoning ? allThinkingOptionIds : offThinkingOptionId ? [offThinkingOptionId] : []
|
|
16637
|
+
})).sort((left, right) => compareText(left.label, right.label) || compareText(left.ref.id, right.ref.id));
|
|
16638
|
+
const defaultThinkingOptionId = thinkingOptions.find(({ id }) => id === effectiveThinkingOptionId)?.id;
|
|
16639
|
+
return harnessModelCatalogSchema.parse({
|
|
16640
|
+
models,
|
|
16641
|
+
...defaultModel ? { defaultModel } : {},
|
|
16642
|
+
thinkingOptions,
|
|
16643
|
+
...defaultThinkingOptionId ? { defaultThinkingOptionId } : {}
|
|
16644
|
+
});
|
|
16645
|
+
}
|
|
16646
|
+
|
|
16647
|
+
// dist/pi-fast-mode.js
|
|
16648
|
+
var PI_FAST_COMMAND = "codexhost-fast-mode";
|
|
16649
|
+
var PI_FAST_ACK = "codexhost-fast-mode:";
|
|
16650
|
+
var PI_FAST_EXTENSION = `export default function(pi) {
|
|
16651
|
+
let target;
|
|
16652
|
+
const wrapped = new Set();
|
|
16653
|
+
pi.on("model_select", (_event, ctx) => {
|
|
16654
|
+
if (target && (target.provider !== ctx.model?.provider || target.id !== ctx.model?.id || ctx.model?.api !== "openai-codex-responses")) target = undefined;
|
|
16655
|
+
});
|
|
16656
|
+
pi.on("session_start", (_event, ctx) => {
|
|
16657
|
+
if (typeof ctx.modelRegistry.getProvider !== "function") return;
|
|
16658
|
+
pi.registerCommand("${PI_FAST_COMMAND}", {
|
|
16659
|
+
description: "Codex Host Fast mode",
|
|
16660
|
+
handler: async (args, ctx) => {
|
|
16661
|
+
const [mode, nonce] = args.split(" ");
|
|
16662
|
+
if (!nonce || (mode !== "on" && mode !== "off")) throw new Error("Invalid Fast selection");
|
|
16663
|
+
if (mode === "on") {
|
|
16664
|
+
const model = ctx.model;
|
|
16665
|
+
if (!model || model.api !== "openai-codex-responses") throw new Error("Fast requires the Codex API");
|
|
16666
|
+
const original = ctx.modelRegistry.getProvider(model.provider);
|
|
16667
|
+
if (!original) throw new Error("Codex Provider is unavailable");
|
|
16668
|
+
if (!wrapped.has(model.provider)) {
|
|
16669
|
+
const options = (model, value) => target && model.api === "openai-codex-responses" && target.provider === model.provider && target.id === model.id
|
|
16670
|
+
? {
|
|
16671
|
+
...value,
|
|
16672
|
+
serviceTier: "priority",
|
|
16673
|
+
// Pi streamSimple drops serviceTier but preserves onPayload.
|
|
16674
|
+
onPayload: async (payload, requestModel) => {
|
|
16675
|
+
const request = { ...payload, service_tier: "priority" };
|
|
16676
|
+
const replacement = await value?.onPayload?.(request, requestModel);
|
|
16677
|
+
return { ...(replacement === undefined ? request : replacement), service_tier: "priority" };
|
|
16678
|
+
},
|
|
16679
|
+
} : value;
|
|
16680
|
+
pi.registerProvider({
|
|
16681
|
+
...original,
|
|
16682
|
+
stream: (model, context, value) => original.stream(model, context, options(model, value)),
|
|
16683
|
+
streamSimple: (model, context, value) => original.streamSimple(model, context, options(model, value)),
|
|
16684
|
+
});
|
|
16685
|
+
wrapped.add(model.provider);
|
|
16686
|
+
}
|
|
16687
|
+
target = { provider: model.provider, id: model.id };
|
|
16688
|
+
} else target = undefined;
|
|
16689
|
+
ctx.ui.notify("${PI_FAST_ACK}" + nonce + ":" + mode, "info");
|
|
16690
|
+
},
|
|
16691
|
+
});
|
|
16692
|
+
});
|
|
16693
|
+
}
|
|
16694
|
+
`;
|
|
16695
|
+
async function ensurePiFastExtension(environment) {
|
|
16696
|
+
const digest = createHash("sha256").update(PI_FAST_EXTENSION).digest("hex").slice(0, 16);
|
|
16697
|
+
const dataDirectory = environment.CODEXHOST_DATA_DIR ?? path7.join(environment.HOME ?? environment.USERPROFILE ?? homedir4(), ".codexhost");
|
|
16698
|
+
const directory = path7.resolve(dataDirectory, "extensions", "pi-codex-fast");
|
|
16699
|
+
const file2 = path7.join(directory, `${digest}.mjs`);
|
|
16700
|
+
if (await readFile2(file2, "utf8").catch(() => "") === PI_FAST_EXTENSION)
|
|
16701
|
+
return file2;
|
|
16702
|
+
await mkdir(directory, { recursive: true });
|
|
16703
|
+
const temporary = `${file2}.${randomUUID2()}.tmp`;
|
|
16704
|
+
try {
|
|
16705
|
+
await writeFile2(temporary, PI_FAST_EXTENSION, { mode: 384 });
|
|
16706
|
+
try {
|
|
16707
|
+
await rename(temporary, file2);
|
|
16708
|
+
} catch (error51) {
|
|
16709
|
+
if (await readFile2(file2, "utf8").catch(() => "") !== PI_FAST_EXTENSION)
|
|
16710
|
+
throw error51;
|
|
16711
|
+
}
|
|
16712
|
+
} finally {
|
|
16713
|
+
await rm2(temporary, { force: true });
|
|
16714
|
+
}
|
|
16715
|
+
return file2;
|
|
16716
|
+
}
|
|
16717
|
+
async function piFastModelKeys(models, environment) {
|
|
16718
|
+
try {
|
|
16719
|
+
const codexHome = environment.CODEX_HOME ?? path7.join(environment.HOME ?? environment.USERPROFILE ?? homedir4(), ".codex");
|
|
16720
|
+
const cache = JSON.parse(await readFile2(path7.join(codexHome, "models_cache.json"), "utf8"));
|
|
16721
|
+
if (!cache || typeof cache !== "object" || !("models" in cache) || !Array.isArray(cache.models))
|
|
16722
|
+
return /* @__PURE__ */ new Set();
|
|
16723
|
+
const priority = new Set(cache.models.filter((model) => typeof model?.slug === "string" && Array.isArray(model.service_tiers) && model.service_tiers.some((tier) => tier?.id === "priority")).map((model) => model.slug));
|
|
16724
|
+
const codexProviders = new Set(readPiCodexProviderNames(environment));
|
|
16725
|
+
return new Set(models.filter((model) => model.api === "openai-codex-responses" && codexProviders.has(model.provider) && priority.has(model.id)).map((model) => encodePiModelRef(model).id));
|
|
16726
|
+
} catch {
|
|
16727
|
+
return /* @__PURE__ */ new Set();
|
|
16728
|
+
}
|
|
16729
|
+
}
|
|
16730
|
+
function withPiFast(catalog, supported) {
|
|
16731
|
+
return {
|
|
16732
|
+
...catalog,
|
|
16733
|
+
models: catalog.models.map((model) => supported.has(model.ref.id) ? { ...model, fastModel: encodePiModelRef({ ...decodePiModelRef(model.ref), fast: true }) } : model)
|
|
16734
|
+
};
|
|
16735
|
+
}
|
|
16736
|
+
|
|
16012
16737
|
// dist/pi-empty-session.js
|
|
16013
16738
|
import { createReadStream } from "node:fs";
|
|
16014
16739
|
import { createInterface } from "node:readline";
|
|
16015
|
-
import { randomUUID as
|
|
16016
|
-
import { link, open as open2, rm } from "node:fs/promises";
|
|
16017
|
-
import
|
|
16740
|
+
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
16741
|
+
import { link, open as open2, rm as rm3 } from "node:fs/promises";
|
|
16742
|
+
import path8 from "node:path";
|
|
16018
16743
|
|
|
16019
16744
|
// dist/pi-subagents.js
|
|
16020
|
-
import { createHash } from "node:crypto";
|
|
16745
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
16021
16746
|
|
|
16022
16747
|
// dist/pi-subagent-workflow.js
|
|
16023
16748
|
var PREFIX2 = "pi-subagents-workflow-v1:";
|
|
@@ -16031,23 +16756,23 @@ var STATES = {
|
|
|
16031
16756
|
rejected: "failed",
|
|
16032
16757
|
detached: "running"
|
|
16033
16758
|
};
|
|
16034
|
-
function
|
|
16759
|
+
function record3(value) {
|
|
16035
16760
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
16036
16761
|
}
|
|
16037
16762
|
function text(value, limit = 256) {
|
|
16038
16763
|
return typeof value === "string" && value.length > 0 && value.length <= limit;
|
|
16039
16764
|
}
|
|
16040
16765
|
function piWorkflowSummary(result) {
|
|
16041
|
-
if (!
|
|
16766
|
+
if (!record3(result) || !record3(result.details) || result.details.mode !== "workflow" || result.details.asyncId !== void 0)
|
|
16042
16767
|
return null;
|
|
16043
16768
|
const details = result.details;
|
|
16044
16769
|
const summary = details.workflowChildren;
|
|
16045
|
-
if (!
|
|
16770
|
+
if (!record3(summary) || summary.version !== 1 || !text(summary.workflowRunId) || summary.workflowRunId !== details.runId || !text(summary.parentToolCallId) || typeof summary.inventoryComplete !== "boolean" || !Array.isArray(summary.children) || summary.children.length > 256)
|
|
16046
16771
|
return null;
|
|
16047
16772
|
const children = [];
|
|
16048
16773
|
const seen = /* @__PURE__ */ new Set();
|
|
16049
16774
|
for (const child of summary.children) {
|
|
16050
|
-
if (!
|
|
16775
|
+
if (!record3(child) || !text(child.childId) || seen.has(child.childId) || typeof child.state !== "string" || !Object.hasOwn(STATES, child.state))
|
|
16051
16776
|
return null;
|
|
16052
16777
|
for (const key of ["agent", "sessionName", "model", "thinking"]) {
|
|
16053
16778
|
if (child[key] !== void 0 && !text(child[key], 2048))
|
|
@@ -16120,7 +16845,7 @@ var STATUS_PREFIX = "PI_SUBAGENT_ASYNC_JSON:";
|
|
|
16120
16845
|
var INSPECT_PREFIX = "PI_SUBAGENT_INSPECT_JSON:";
|
|
16121
16846
|
var ID_PREFIX = "pi-subagents-v1:";
|
|
16122
16847
|
var MAX_BYTES = 64 * 1024;
|
|
16123
|
-
function
|
|
16848
|
+
function record4(value) {
|
|
16124
16849
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
16125
16850
|
}
|
|
16126
16851
|
function token(value) {
|
|
@@ -16137,7 +16862,7 @@ var statuses = {
|
|
|
16137
16862
|
rejected: "failed"
|
|
16138
16863
|
};
|
|
16139
16864
|
function node(value, depth, budget) {
|
|
16140
|
-
if (!
|
|
16865
|
+
if (!record4(value) || depth > 8 || ++budget.count > 256 || !token(value.id) || !["subagent", "workflow", "step", "host-step"].includes(String(value.kind)) || typeof value.label !== "string" || value.label.length > 2048 || typeof value.state !== "string" || !Object.hasOwn(statuses, value.state))
|
|
16141
16866
|
return null;
|
|
16142
16867
|
const children = [];
|
|
16143
16868
|
if (value.children !== void 0) {
|
|
@@ -16159,14 +16884,14 @@ function node(value, depth, budget) {
|
|
|
16159
16884
|
};
|
|
16160
16885
|
}
|
|
16161
16886
|
function widget(value, key, prefix) {
|
|
16162
|
-
if (!
|
|
16887
|
+
if (!record4(value) || value.type !== "extension_ui_request" || value.method !== "setWidget" || value.widgetKey !== key || !Array.isArray(value.widgetLines))
|
|
16163
16888
|
return null;
|
|
16164
16889
|
const line = value.widgetLines.find((part) => typeof part === "string" && part.startsWith(prefix));
|
|
16165
16890
|
if (!line || Buffer.byteLength(line) > MAX_BYTES + prefix.length)
|
|
16166
16891
|
return null;
|
|
16167
16892
|
try {
|
|
16168
16893
|
const parsed = JSON.parse(line.slice(prefix.length));
|
|
16169
|
-
return
|
|
16894
|
+
return record4(parsed) && parsed.version === 1 ? parsed : null;
|
|
16170
16895
|
} catch {
|
|
16171
16896
|
return null;
|
|
16172
16897
|
}
|
|
@@ -16230,7 +16955,7 @@ function states(run) {
|
|
|
16230
16955
|
return result;
|
|
16231
16956
|
}
|
|
16232
16957
|
function asyncRunId(toolName, result) {
|
|
16233
|
-
if (toolName !== "subagent" || !
|
|
16958
|
+
if (toolName !== "subagent" || !record4(result) || !record4(result.details))
|
|
16234
16959
|
return null;
|
|
16235
16960
|
const details = result.details;
|
|
16236
16961
|
return ["single", "parallel", "chain", "workflow"].includes(String(details.mode)) && token(details.asyncId) && typeof details.asyncDir === "string" ? details.asyncId : null;
|
|
@@ -16370,15 +17095,15 @@ function parsePiSubagentInspection(value) {
|
|
|
16370
17095
|
const parsed = widget(value, "subagent-inspect", INSPECT_PREFIX);
|
|
16371
17096
|
if (!parsed || parsed.kind !== "pi-subagents.inspect-reply" || !token(parsed.requestId))
|
|
16372
17097
|
return null;
|
|
16373
|
-
if (parsed.error !== void 0 && (!
|
|
17098
|
+
if (parsed.error !== void 0 && (!record4(parsed.error) || typeof parsed.error.code !== "string" || typeof parsed.error.message !== "string"))
|
|
16374
17099
|
return null;
|
|
16375
17100
|
for (const field of ["asyncId", "childId", "status", "task", "finalOutput"]) {
|
|
16376
17101
|
if (parsed[field] !== void 0 && typeof parsed[field] !== "string")
|
|
16377
17102
|
return null;
|
|
16378
17103
|
}
|
|
16379
|
-
if (parsed.messages !== void 0 && (!Array.isArray(parsed.messages) || parsed.messages.length > 200 || parsed.messages.some((entry) => !
|
|
17104
|
+
if (parsed.messages !== void 0 && (!Array.isArray(parsed.messages) || parsed.messages.length > 200 || parsed.messages.some((entry) => !record4(entry) || typeof entry.role !== "string" || typeof entry.text !== "string" || !["text", "toolCall", "toolResult"].includes(String(entry.kind)) || entry.name !== void 0 && typeof entry.name !== "string")))
|
|
16380
17105
|
return null;
|
|
16381
|
-
if (parsed.truncated !== void 0 && (!
|
|
17106
|
+
if (parsed.truncated !== void 0 && (!record4(parsed.truncated) || typeof parsed.truncated.task !== "boolean" || typeof parsed.truncated.finalOutput !== "boolean" || !Number.isSafeInteger(parsed.truncated.messages) || Number(parsed.truncated.messages) < 0))
|
|
16382
17107
|
return null;
|
|
16383
17108
|
return parsed;
|
|
16384
17109
|
}
|
|
@@ -16397,7 +17122,7 @@ ${entry.text}`);
|
|
|
16397
17122
|
nativeTurnRef: nativeTurnRefSchema.parse({
|
|
16398
17123
|
harnessId: "pi",
|
|
16399
17124
|
nativeSessionId: parentSessionId,
|
|
16400
|
-
nativeTurnKey: `pi-subagent-${
|
|
17125
|
+
nativeTurnKey: `pi-subagent-${createHash2("sha256").update(id).digest("hex")}`,
|
|
16401
17126
|
formatVersion: 1
|
|
16402
17127
|
}),
|
|
16403
17128
|
input: reply.task ? [{ type: "text", text: reply.task }] : [],
|
|
@@ -16405,7 +17130,7 @@ ${entry.text}`);
|
|
|
16405
17130
|
item: {
|
|
16406
17131
|
type: "agentMessage",
|
|
16407
17132
|
text: text2,
|
|
16408
|
-
itemId: hostItemIdSchema.parse(`pi-subagent-${
|
|
17133
|
+
itemId: hostItemIdSchema.parse(`pi-subagent-${createHash2("sha256").update(`${id}:${index}:${text2}`).digest("hex")}`)
|
|
16409
17134
|
},
|
|
16410
17135
|
outcome: { status: "succeeded" }
|
|
16411
17136
|
})),
|
|
@@ -16425,120 +17150,6 @@ ${entry.text}`);
|
|
|
16425
17150
|
};
|
|
16426
17151
|
}
|
|
16427
17152
|
|
|
16428
|
-
// dist/pi-model-catalog.js
|
|
16429
|
-
var PI_MODEL_REF_PREFIX = "pi-model-v1.";
|
|
16430
|
-
var PI_DRAFT_THINKING_OPTION_IDS = [
|
|
16431
|
-
"off",
|
|
16432
|
-
"minimal",
|
|
16433
|
-
"low",
|
|
16434
|
-
"medium",
|
|
16435
|
-
"high",
|
|
16436
|
-
"xhigh",
|
|
16437
|
-
"max"
|
|
16438
|
-
].map((id) => harnessThinkingOptionIdSchema.parse(id));
|
|
16439
|
-
var PI_THINKING_LABELS = {
|
|
16440
|
-
off: "Off",
|
|
16441
|
-
minimal: "Minimal",
|
|
16442
|
-
low: "Low",
|
|
16443
|
-
medium: "Medium",
|
|
16444
|
-
high: "High",
|
|
16445
|
-
xhigh: "Extra High",
|
|
16446
|
-
max: "Max"
|
|
16447
|
-
};
|
|
16448
|
-
function compareText(left, right) {
|
|
16449
|
-
return left < right ? -1 : left > right ? 1 : 0;
|
|
16450
|
-
}
|
|
16451
|
-
function assertNativePart(value, name) {
|
|
16452
|
-
if (value.trim().length === 0)
|
|
16453
|
-
throw new Error(`Pi ${name} must not be empty`);
|
|
16454
|
-
}
|
|
16455
|
-
function encodePiModelRef(model) {
|
|
16456
|
-
assertNativePart(model.provider, "Model provider");
|
|
16457
|
-
assertNativePart(model.id, "Model id");
|
|
16458
|
-
const encoded = Buffer.from(JSON.stringify([model.provider, model.id]), "utf8").toString("base64url");
|
|
16459
|
-
return harnessModelRefSchema.parse({ id: `${PI_MODEL_REF_PREFIX}${encoded}` });
|
|
16460
|
-
}
|
|
16461
|
-
function decodePiModelRef(ref) {
|
|
16462
|
-
const parsedRef = harnessModelRefSchema.parse(ref);
|
|
16463
|
-
if (!parsedRef.id.startsWith(PI_MODEL_REF_PREFIX)) {
|
|
16464
|
-
throw new Error("Model Ref does not belong to PiAdapter");
|
|
16465
|
-
}
|
|
16466
|
-
const encoded = parsedRef.id.slice(PI_MODEL_REF_PREFIX.length);
|
|
16467
|
-
let decoded;
|
|
16468
|
-
try {
|
|
16469
|
-
decoded = JSON.parse(Buffer.from(encoded, "base64url").toString("utf8"));
|
|
16470
|
-
} catch {
|
|
16471
|
-
throw new Error("Pi Model Ref is malformed");
|
|
16472
|
-
}
|
|
16473
|
-
if (!Array.isArray(decoded) || decoded.length !== 2 || typeof decoded[0] !== "string" || typeof decoded[1] !== "string") {
|
|
16474
|
-
throw new Error("Pi Model Ref has an invalid native identity");
|
|
16475
|
-
}
|
|
16476
|
-
const native = { provider: decoded[0], id: decoded[1] };
|
|
16477
|
-
assertNativePart(native.provider, "Model provider");
|
|
16478
|
-
assertNativePart(native.id, "Model id");
|
|
16479
|
-
if (encodePiModelRef(native).id !== parsedRef.id) {
|
|
16480
|
-
throw new Error("Pi Model Ref is not canonical");
|
|
16481
|
-
}
|
|
16482
|
-
return native;
|
|
16483
|
-
}
|
|
16484
|
-
function samePiModel(left, right) {
|
|
16485
|
-
return left === null ? right === null : right !== null && left.provider === right.provider && left.id === right.id;
|
|
16486
|
-
}
|
|
16487
|
-
function fallbackThinkingLabel(id) {
|
|
16488
|
-
const label = id.split(/[._~-]+/u).filter((part) => part.length > 0).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
|
|
16489
|
-
return label || id;
|
|
16490
|
-
}
|
|
16491
|
-
function normalizePiThinkingOptions(levels) {
|
|
16492
|
-
return levels.map((id) => harnessThinkingOptionSchema.parse({
|
|
16493
|
-
id,
|
|
16494
|
-
label: PI_THINKING_LABELS[id] ?? fallbackThinkingLabel(id)
|
|
16495
|
-
}));
|
|
16496
|
-
}
|
|
16497
|
-
function normalizePiModelCatalog(nativeModels, effectiveModel, thinkingLevels, effectiveThinkingOptionId) {
|
|
16498
|
-
const byRef = /* @__PURE__ */ new Map();
|
|
16499
|
-
for (const native of nativeModels) {
|
|
16500
|
-
const ref = encodePiModelRef(native);
|
|
16501
|
-
const existing = byRef.get(ref.id);
|
|
16502
|
-
if (existing) {
|
|
16503
|
-
if (existing.reasoning !== native.reasoning) {
|
|
16504
|
-
throw new Error("Pi duplicate Model entries disagree on reasoning capability");
|
|
16505
|
-
}
|
|
16506
|
-
continue;
|
|
16507
|
-
}
|
|
16508
|
-
byRef.set(ref.id, {
|
|
16509
|
-
model: {
|
|
16510
|
-
ref,
|
|
16511
|
-
label: `${native.provider} / ${native.id}`
|
|
16512
|
-
},
|
|
16513
|
-
reasoning: native.reasoning
|
|
16514
|
-
});
|
|
16515
|
-
}
|
|
16516
|
-
const defaultModel = effectiveModel ? encodePiModelRef(effectiveModel) : void 0;
|
|
16517
|
-
if (defaultModel && !byRef.has(defaultModel.id)) {
|
|
16518
|
-
throw new Error("Pi effective Model is absent from the available Model catalog");
|
|
16519
|
-
}
|
|
16520
|
-
if (thinkingLevels && effectiveThinkingOptionId && !thinkingLevels.includes(effectiveThinkingOptionId)) {
|
|
16521
|
-
throw new Error("Pi effective Thinking option is absent from the available option catalog");
|
|
16522
|
-
}
|
|
16523
|
-
if (thinkingLevels && !effectiveThinkingOptionId) {
|
|
16524
|
-
throw new Error("Pi did not report an effective Thinking option");
|
|
16525
|
-
}
|
|
16526
|
-
const thinkingOptions = thinkingLevels ? normalizePiThinkingOptions(PI_DRAFT_THINKING_OPTION_IDS) : [];
|
|
16527
|
-
const allThinkingOptionIds = thinkingOptions.map(({ id }) => id);
|
|
16528
|
-
const offThinkingOptionId = thinkingOptions.find(({ id }) => id === "off")?.id;
|
|
16529
|
-
const models = [...byRef.values()].map(({ model, reasoning }) => ({
|
|
16530
|
-
...model,
|
|
16531
|
-
supportedThinkingOptionIds: reasoning ? allThinkingOptionIds : offThinkingOptionId ? [offThinkingOptionId] : []
|
|
16532
|
-
})).sort((left, right) => compareText(left.label, right.label) || compareText(left.ref.id, right.ref.id));
|
|
16533
|
-
const defaultThinkingOptionId = thinkingOptions.find(({ id }) => id === effectiveThinkingOptionId)?.id;
|
|
16534
|
-
return harnessModelCatalogSchema.parse({
|
|
16535
|
-
models,
|
|
16536
|
-
...defaultModel ? { defaultModel } : {},
|
|
16537
|
-
thinkingOptions,
|
|
16538
|
-
...defaultThinkingOptionId ? { defaultThinkingOptionId } : {}
|
|
16539
|
-
});
|
|
16540
|
-
}
|
|
16541
|
-
|
|
16542
17153
|
// dist/pi-history.js
|
|
16543
17154
|
var piHarnessId = harnessIdSchema.parse("pi");
|
|
16544
17155
|
function isRecord(value) {
|
|
@@ -16844,7 +17455,7 @@ async function verifyPiSessionCwd(input) {
|
|
|
16844
17455
|
async function persistEmptyPiSession(input) {
|
|
16845
17456
|
const { state: state2, history, sourceSessionFile, sourceSessionId, cwd } = input;
|
|
16846
17457
|
const destination = state2.sessionFile;
|
|
16847
|
-
if (!destination || !
|
|
17458
|
+
if (!destination || !path8.isAbsolute(destination) || path8.resolve(destination) === path8.resolve(sourceSessionFile) || state2.sessionId === sourceSessionId || mapPiSnapshot(history, { sessionId: state2.sessionId, model: null }).turns.length !== 0)
|
|
16848
17459
|
throw new Error("Pi empty Session is not an independent empty native fork");
|
|
16849
17460
|
await verifyPiSessionCwd({
|
|
16850
17461
|
sessionFile: sourceSessionFile,
|
|
@@ -16868,7 +17479,7 @@ async function persistEmptyPiSession(input) {
|
|
|
16868
17479
|
cwd,
|
|
16869
17480
|
parentSession: sourceSessionFile
|
|
16870
17481
|
};
|
|
16871
|
-
const temporary =
|
|
17482
|
+
const temporary = path8.join(path8.dirname(destination), `.codexhost-${randomUUID3()}.tmp`);
|
|
16872
17483
|
try {
|
|
16873
17484
|
const file2 = await open2(temporary, "wx", 384);
|
|
16874
17485
|
try {
|
|
@@ -16879,7 +17490,7 @@ async function persistEmptyPiSession(input) {
|
|
|
16879
17490
|
}
|
|
16880
17491
|
await link(temporary, destination);
|
|
16881
17492
|
if (process.platform !== "win32") {
|
|
16882
|
-
const directory = await open2(
|
|
17493
|
+
const directory = await open2(path8.dirname(destination), "r");
|
|
16883
17494
|
try {
|
|
16884
17495
|
await directory.sync();
|
|
16885
17496
|
} finally {
|
|
@@ -16887,7 +17498,7 @@ async function persistEmptyPiSession(input) {
|
|
|
16887
17498
|
}
|
|
16888
17499
|
}
|
|
16889
17500
|
} finally {
|
|
16890
|
-
await
|
|
17501
|
+
await rm3(temporary, { force: true });
|
|
16891
17502
|
}
|
|
16892
17503
|
}
|
|
16893
17504
|
async function readPiEmptySessionConfiguration(sessionFile) {
|
|
@@ -17042,16 +17653,16 @@ var Diff = class {
|
|
|
17042
17653
|
}
|
|
17043
17654
|
}
|
|
17044
17655
|
}
|
|
17045
|
-
addToPath(
|
|
17046
|
-
const last =
|
|
17656
|
+
addToPath(path14, added, removed, oldPosInc, options) {
|
|
17657
|
+
const last = path14.lastComponent;
|
|
17047
17658
|
if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
|
|
17048
17659
|
return {
|
|
17049
|
-
oldPos:
|
|
17660
|
+
oldPos: path14.oldPos + oldPosInc,
|
|
17050
17661
|
lastComponent: { count: last.count + 1, added, removed, previousComponent: last.previousComponent }
|
|
17051
17662
|
};
|
|
17052
17663
|
} else {
|
|
17053
17664
|
return {
|
|
17054
|
-
oldPos:
|
|
17665
|
+
oldPos: path14.oldPos + oldPosInc,
|
|
17055
17666
|
lastComponent: { count: 1, added, removed, previousComponent: last }
|
|
17056
17667
|
};
|
|
17057
17668
|
}
|
|
@@ -17463,8 +18074,8 @@ function splitLines(text2) {
|
|
|
17463
18074
|
}
|
|
17464
18075
|
|
|
17465
18076
|
// dist/pi-adapter.js
|
|
17466
|
-
import { randomUUID as
|
|
17467
|
-
import
|
|
18077
|
+
import { randomUUID as randomUUID6 } from "node:crypto";
|
|
18078
|
+
import path13 from "node:path";
|
|
17468
18079
|
|
|
17469
18080
|
// ../../harness-adapter/dist/question.js
|
|
17470
18081
|
function invalidRequest(message3) {
|
|
@@ -17769,16 +18380,16 @@ function mergeLiveHarnessCommands(builtIns, idPrefix, live, exclusions = {}) {
|
|
|
17769
18380
|
}
|
|
17770
18381
|
|
|
17771
18382
|
// dist/pi-workflow-child-history.js
|
|
17772
|
-
import { createHash as
|
|
18383
|
+
import { createHash as createHash3 } from "node:crypto";
|
|
17773
18384
|
import { constants } from "node:fs";
|
|
17774
18385
|
import { open as open3 } from "node:fs/promises";
|
|
17775
|
-
import
|
|
17776
|
-
function
|
|
18386
|
+
import path9 from "node:path";
|
|
18387
|
+
function record5(value) {
|
|
17777
18388
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
17778
18389
|
}
|
|
17779
18390
|
var MAX_SESSION_BYTES = 8 * 1024 * 1024;
|
|
17780
18391
|
async function childHistory(file2, parentSessionId, identity) {
|
|
17781
|
-
if (!
|
|
18392
|
+
if (!path9.isAbsolute(file2))
|
|
17782
18393
|
throw new Error("Pi child Session path is not absolute");
|
|
17783
18394
|
const handle = await open3(file2, constants.O_RDONLY | (constants.O_NOFOLLOW ?? 0) | (constants.O_NONBLOCK ?? 0));
|
|
17784
18395
|
try {
|
|
@@ -17791,18 +18402,18 @@ async function childHistory(file2, parentSessionId, identity) {
|
|
|
17791
18402
|
throw new Error("Pi child Session exceeds read bounds");
|
|
17792
18403
|
const values = buffer.subarray(0, bytesRead).toString("utf8").split("\n").filter((line) => line.trim()).map((line) => JSON.parse(line));
|
|
17793
18404
|
const header = values[0];
|
|
17794
|
-
if (!
|
|
18405
|
+
if (!record5(header) || header.type !== "session" || typeof header.id !== "string" || header.version !== 3)
|
|
17795
18406
|
throw new Error("Unsupported Pi child Session header");
|
|
17796
18407
|
const entries = [];
|
|
17797
18408
|
for (const entry of values.slice(1)) {
|
|
17798
18409
|
const parsed = jsonValueSchema.safeParse(entry);
|
|
17799
|
-
if (!parsed.success || !
|
|
18410
|
+
if (!parsed.success || !record5(parsed.data) || typeof parsed.data.id !== "string")
|
|
17800
18411
|
throw new Error("Malformed Pi child Session entry");
|
|
17801
18412
|
entries.push(parsed.data);
|
|
17802
18413
|
}
|
|
17803
18414
|
const history = { entries, leafId: String(entries.at(-1)?.id ?? "") || null };
|
|
17804
18415
|
const snapshot = mapPiSnapshot(history, { sessionId: parentSessionId, model: null });
|
|
17805
|
-
const prefix =
|
|
18416
|
+
const prefix = createHash3("sha256").update(identity).digest("hex");
|
|
17806
18417
|
return {
|
|
17807
18418
|
turns: snapshot.turns.map((turn) => {
|
|
17808
18419
|
const readonlyTurn = {
|
|
@@ -17823,7 +18434,7 @@ async function childHistory(file2, parentSessionId, identity) {
|
|
|
17823
18434
|
async function readPiWorkflowChild(history, parentSessionId, address) {
|
|
17824
18435
|
for (const entry of activePiEntries(history).reverse()) {
|
|
17825
18436
|
const message3 = entry.message;
|
|
17826
|
-
if (!
|
|
18437
|
+
if (!record5(message3) || message3.role !== "toolResult" || message3.toolName !== "subagent")
|
|
17827
18438
|
continue;
|
|
17828
18439
|
const summary = piWorkflowSummary(message3);
|
|
17829
18440
|
if (!summary || summary.workflowRunId !== address.workflowRunId || summary.parentToolCallId !== message3.toolCallId)
|
|
@@ -17832,10 +18443,10 @@ async function readPiWorkflowChild(history, parentSessionId, address) {
|
|
|
17832
18443
|
if (!child)
|
|
17833
18444
|
break;
|
|
17834
18445
|
const details = message3.details;
|
|
17835
|
-
if (!
|
|
18446
|
+
if (!record5(details) || !Array.isArray(details.results))
|
|
17836
18447
|
break;
|
|
17837
|
-
const result = details.results.findLast((candidate) =>
|
|
17838
|
-
if (!
|
|
18448
|
+
const result = details.results.findLast((candidate) => record5(candidate) && candidate.workflowKey === address.childId);
|
|
18449
|
+
if (!record5(result))
|
|
17839
18450
|
break;
|
|
17840
18451
|
const id = piWorkflowSubagentId(address);
|
|
17841
18452
|
if (typeof result.sessionFile === "string") {
|
|
@@ -17881,22 +18492,22 @@ ${output}`,
|
|
|
17881
18492
|
// dist/pi-subagent-history.js
|
|
17882
18493
|
import { constants as constants2 } from "node:fs";
|
|
17883
18494
|
import { open as open4 } from "node:fs/promises";
|
|
17884
|
-
import
|
|
17885
|
-
function
|
|
18495
|
+
import path10 from "node:path";
|
|
18496
|
+
function record6(value) {
|
|
17886
18497
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
17887
18498
|
}
|
|
17888
18499
|
function state(value) {
|
|
17889
18500
|
return value === "pending" ? "queued" : value === "completed" ? "complete" : value;
|
|
17890
18501
|
}
|
|
17891
18502
|
function piSubagentArtifact(value, runId, parentSessionId) {
|
|
17892
|
-
if (!
|
|
18503
|
+
if (!record6(value) || value.lifecycleArtifactVersion !== 3 || value.runId !== runId || value.sessionId !== parentSessionId || !["single", "parallel", "chain", "workflow"].includes(String(value.mode)))
|
|
17893
18504
|
return null;
|
|
17894
18505
|
if (value.steps !== void 0 && (!Array.isArray(value.steps) || value.steps.length > 128))
|
|
17895
18506
|
return null;
|
|
17896
18507
|
const steps = Array.isArray(value.steps) ? value.steps : [];
|
|
17897
18508
|
const children = [];
|
|
17898
18509
|
for (const [index, step] of steps.entries()) {
|
|
17899
|
-
if (!
|
|
18510
|
+
if (!record6(step) || typeof step.agent !== "string")
|
|
17900
18511
|
return null;
|
|
17901
18512
|
children.push({
|
|
17902
18513
|
id: step.workflowKey ?? step.runId ?? `step:${index}`,
|
|
@@ -17929,17 +18540,17 @@ function piSubagentArtifact(value, runId, parentSessionId) {
|
|
|
17929
18540
|
async function restorePiSubagents(history, parentSessionId, observer) {
|
|
17930
18541
|
const receipts = /* @__PURE__ */ new Map();
|
|
17931
18542
|
for (const entry of activePiEntries(history)) {
|
|
17932
|
-
if (!
|
|
18543
|
+
if (!record6(entry.message) || entry.message.role !== "toolResult" || entry.message.toolName !== "subagent" || entry.message.isError !== false || !record6(entry.message.details))
|
|
17933
18544
|
continue;
|
|
17934
18545
|
const details = entry.message.details;
|
|
17935
|
-
if (!["single", "parallel", "chain", "workflow"].includes(String(details.mode)) || typeof details.asyncId !== "string" || typeof details.asyncDir !== "string" || !
|
|
18546
|
+
if (!["single", "parallel", "chain", "workflow"].includes(String(details.mode)) || typeof details.asyncId !== "string" || typeof details.asyncDir !== "string" || !path10.isAbsolute(details.asyncDir) || path10.basename(details.asyncDir) !== details.asyncId)
|
|
17936
18547
|
continue;
|
|
17937
18548
|
receipts.set(details.asyncId, details.asyncDir);
|
|
17938
18549
|
}
|
|
17939
18550
|
for (const [id, directory] of [...receipts].slice(-128)) {
|
|
17940
18551
|
let file2;
|
|
17941
18552
|
try {
|
|
17942
|
-
file2 = await open4(
|
|
18553
|
+
file2 = await open4(path10.join(directory, "status.json"), constants2.O_RDONLY | (constants2.O_NOFOLLOW ?? 0));
|
|
17943
18554
|
const stat2 = await file2.stat();
|
|
17944
18555
|
if (!stat2.isFile() || stat2.size > 1024 * 1024)
|
|
17945
18556
|
continue;
|
|
@@ -18021,24 +18632,109 @@ async function rollbackPiLastTurn(transport, sourceSessionId, cwd) {
|
|
|
18021
18632
|
import { createReadStream as createReadStream2 } from "node:fs";
|
|
18022
18633
|
import { opendir, realpath as realpath3, stat } from "node:fs/promises";
|
|
18023
18634
|
import os3 from "node:os";
|
|
18024
|
-
import
|
|
18635
|
+
import path11 from "node:path";
|
|
18025
18636
|
import { createInterface as createInterface2 } from "node:readline";
|
|
18026
|
-
|
|
18027
|
-
|
|
18028
|
-
|
|
18637
|
+
|
|
18638
|
+
// ../../harness-adapter/dist/session-import.js
|
|
18639
|
+
var SessionImportChangedError = class extends Error {
|
|
18640
|
+
constructor(message3 = "Native Session changed during discovery; refresh and retry") {
|
|
18641
|
+
super(message3);
|
|
18642
|
+
this.name = "SessionImportChangedError";
|
|
18029
18643
|
}
|
|
18030
18644
|
};
|
|
18031
|
-
function
|
|
18032
|
-
return
|
|
18645
|
+
function isMissingFileError(error51) {
|
|
18646
|
+
return typeof error51 === "object" && error51 !== null && "code" in error51 && error51.code === "ENOENT";
|
|
18647
|
+
}
|
|
18648
|
+
function sameFileFingerprint(left, right) {
|
|
18649
|
+
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;
|
|
18650
|
+
}
|
|
18651
|
+
function sessionImportTitle(value, maxLength = HARNESS_SESSION_IMPORT_TITLE_MAX_LENGTH) {
|
|
18652
|
+
if (typeof value !== "string")
|
|
18653
|
+
return null;
|
|
18654
|
+
const normalized = value.replaceAll("\0", "").replaceAll(/\s+/gu, " ").trim();
|
|
18655
|
+
if (!normalized)
|
|
18656
|
+
return null;
|
|
18657
|
+
if (normalized.length <= maxLength)
|
|
18658
|
+
return normalized;
|
|
18659
|
+
const characters = [...normalized];
|
|
18660
|
+
if (characters.length <= maxLength)
|
|
18661
|
+
return normalized;
|
|
18662
|
+
return `${characters.slice(0, maxLength - 1).join("").trimEnd()}…`;
|
|
18663
|
+
}
|
|
18664
|
+
function sessionImportCandidate(input) {
|
|
18665
|
+
const time3 = typeof input.updatedAt === "number" ? input.updatedAt : typeof input.updatedAt === "string" ? Date.parse(input.updatedAt) : Number.NaN;
|
|
18666
|
+
const parsed = harnessSessionImportCandidateSchema.safeParse({
|
|
18667
|
+
nativeSessionId: input.nativeSessionId,
|
|
18668
|
+
cwd: input.cwd,
|
|
18669
|
+
title: typeof input.title === "string" && input.title.trim().length > 0 ? input.title : null,
|
|
18670
|
+
updatedAt: Math.floor(time3),
|
|
18671
|
+
// Unknown must stay unknown; only an explicit boolean is a native statement.
|
|
18672
|
+
running: typeof input.running === "boolean" ? input.running : null
|
|
18673
|
+
});
|
|
18674
|
+
return parsed.success ? parsed.data : null;
|
|
18033
18675
|
}
|
|
18676
|
+
var SessionImportScope = class {
|
|
18677
|
+
#abort = new AbortController();
|
|
18678
|
+
#options;
|
|
18679
|
+
#pending = /* @__PURE__ */ new Set();
|
|
18680
|
+
constructor(options) {
|
|
18681
|
+
this.#options = options;
|
|
18682
|
+
}
|
|
18683
|
+
#closed() {
|
|
18684
|
+
return {
|
|
18685
|
+
ok: false,
|
|
18686
|
+
error: { code: "invalidState", message: this.#options.closedMessage, retryable: false }
|
|
18687
|
+
};
|
|
18688
|
+
}
|
|
18689
|
+
read(operation) {
|
|
18690
|
+
const signal = this.#abort.signal;
|
|
18691
|
+
if (signal.aborted)
|
|
18692
|
+
return Promise.resolve(this.#closed());
|
|
18693
|
+
let started;
|
|
18694
|
+
try {
|
|
18695
|
+
started = operation(signal);
|
|
18696
|
+
} catch (error51) {
|
|
18697
|
+
started = Promise.reject(error51 instanceof Error ? error51 : new Error("Session read failed"));
|
|
18698
|
+
}
|
|
18699
|
+
const request = started.then((value) => signal.aborted ? this.#closed() : { ok: true, value }).catch(() => signal.aborted ? this.#closed() : {
|
|
18700
|
+
ok: false,
|
|
18701
|
+
error: {
|
|
18702
|
+
code: "unavailable",
|
|
18703
|
+
message: this.#options.unavailableMessage,
|
|
18704
|
+
retryable: true
|
|
18705
|
+
}
|
|
18706
|
+
}).finally(() => this.#pending.delete(request));
|
|
18707
|
+
this.#pending.add(request);
|
|
18708
|
+
return request;
|
|
18709
|
+
}
|
|
18710
|
+
/** `read` for `resolveCandidate`: a null source is the selected Session having disappeared. */
|
|
18711
|
+
async resolve(operation) {
|
|
18712
|
+
const result = await this.read(operation);
|
|
18713
|
+
if (!result.ok)
|
|
18714
|
+
return result;
|
|
18715
|
+
return result.value ? { ok: true, value: result.value } : {
|
|
18716
|
+
ok: false,
|
|
18717
|
+
error: {
|
|
18718
|
+
code: "sessionNotFound",
|
|
18719
|
+
message: this.#options.notFoundMessage,
|
|
18720
|
+
retryable: false
|
|
18721
|
+
}
|
|
18722
|
+
};
|
|
18723
|
+
}
|
|
18724
|
+
/** Idempotent. Resolves after every started read has settled. */
|
|
18725
|
+
async close() {
|
|
18726
|
+
this.#abort.abort();
|
|
18727
|
+
await Promise.allSettled(this.#pending);
|
|
18728
|
+
}
|
|
18729
|
+
};
|
|
18730
|
+
|
|
18731
|
+
// dist/pi-session-import.js
|
|
18732
|
+
var PI_SESSION_CHANGED = "Pi Session changed during discovery; refresh and retry";
|
|
18034
18733
|
function isRecord4(value) {
|
|
18035
18734
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
18036
18735
|
}
|
|
18037
|
-
function missing(error51) {
|
|
18038
|
-
return isRecord4(error51) && error51.code === "ENOENT";
|
|
18039
|
-
}
|
|
18040
18736
|
function expandDirectory(value, home) {
|
|
18041
|
-
return
|
|
18737
|
+
return path11.resolve(value === "~" ? home : value.startsWith(`~${path11.sep}`) || value.startsWith("~/") ? path11.join(home, value.slice(2)) : value);
|
|
18042
18738
|
}
|
|
18043
18739
|
function piSessionImportDirectory(environment) {
|
|
18044
18740
|
const home = (process.platform === "win32" ? environment.USERPROFILE : environment.HOME) || os3.homedir();
|
|
@@ -18047,7 +18743,7 @@ function piSessionImportDirectory(environment) {
|
|
|
18047
18743
|
return { directory: expandDirectory(custom2, home), flat: true };
|
|
18048
18744
|
const agent = environment.PI_CODING_AGENT_DIR;
|
|
18049
18745
|
return {
|
|
18050
|
-
directory:
|
|
18746
|
+
directory: path11.join(agent ? expandDirectory(agent, home) : path11.join(home, ".pi", "agent"), "sessions"),
|
|
18051
18747
|
flat: false
|
|
18052
18748
|
};
|
|
18053
18749
|
}
|
|
@@ -18056,7 +18752,7 @@ async function sessionFiles(directory, flat, signal) {
|
|
|
18056
18752
|
const visit = async (dir, projectLevel) => {
|
|
18057
18753
|
signal.throwIfAborted();
|
|
18058
18754
|
const entries = await opendir(dir).catch((error51) => {
|
|
18059
|
-
if (
|
|
18755
|
+
if (isMissingFileError(error51))
|
|
18060
18756
|
return null;
|
|
18061
18757
|
throw error51;
|
|
18062
18758
|
});
|
|
@@ -18065,9 +18761,9 @@ async function sessionFiles(directory, flat, signal) {
|
|
|
18065
18761
|
for await (const entry of entries) {
|
|
18066
18762
|
signal.throwIfAborted();
|
|
18067
18763
|
if (projectLevel && entry.isDirectory())
|
|
18068
|
-
await visit(
|
|
18764
|
+
await visit(path11.join(dir, entry.name), false);
|
|
18069
18765
|
else if (!projectLevel && entry.isFile() && entry.name.endsWith(".jsonl")) {
|
|
18070
|
-
files.push(
|
|
18766
|
+
files.push(path11.join(dir, entry.name));
|
|
18071
18767
|
}
|
|
18072
18768
|
}
|
|
18073
18769
|
};
|
|
@@ -18100,7 +18796,7 @@ async function readCandidate(file2, signal) {
|
|
|
18100
18796
|
if (!isRecord4(entry))
|
|
18101
18797
|
return null;
|
|
18102
18798
|
if (!header) {
|
|
18103
|
-
if (entry.type !== "session" || entry.version !== 3 || typeof entry.id !== "string" || typeof entry.cwd !== "string" || !
|
|
18799
|
+
if (entry.type !== "session" || entry.version !== 3 || typeof entry.id !== "string" || typeof entry.cwd !== "string" || !path11.isAbsolute(entry.cwd))
|
|
18104
18800
|
return null;
|
|
18105
18801
|
header = entry;
|
|
18106
18802
|
continue;
|
|
@@ -18111,12 +18807,12 @@ async function readCandidate(file2, signal) {
|
|
|
18111
18807
|
if (!firstMessage && entry.type === "message" && message3?.role === "user") {
|
|
18112
18808
|
const content = message3.content;
|
|
18113
18809
|
const text2 = typeof content === "string" ? content : Array.isArray(content) ? content.filter((block) => isRecord4(block) && block.type === "text" && typeof block.text === "string").map((block) => block.text).join(" ") : "";
|
|
18114
|
-
firstMessage = text2
|
|
18810
|
+
firstMessage = sessionImportTitle(text2);
|
|
18115
18811
|
}
|
|
18116
18812
|
hasUser = entry.type === "message" && message3?.role === "user" || typeof entry.parentId === "string" && entries.get(entry.parentId) === true;
|
|
18117
18813
|
entries.set(entry.id, hasUser);
|
|
18118
18814
|
if (entry.type === "session_info")
|
|
18119
|
-
name =
|
|
18815
|
+
name = sessionImportTitle(entry.name);
|
|
18120
18816
|
if (entry.type === "message" && (message3?.role === "user" || message3?.role === "assistant")) {
|
|
18121
18817
|
const time3 = typeof message3.timestamp === "number" ? message3.timestamp : typeof entry.timestamp === "string" ? Date.parse(entry.timestamp) : NaN;
|
|
18122
18818
|
if (Number.isFinite(time3))
|
|
@@ -18132,8 +18828,8 @@ async function readCandidate(file2, signal) {
|
|
|
18132
18828
|
if (!hasUser)
|
|
18133
18829
|
return null;
|
|
18134
18830
|
const after = await stat(file2);
|
|
18135
|
-
if (!
|
|
18136
|
-
throw new
|
|
18831
|
+
if (!sameFileFingerprint(before, after))
|
|
18832
|
+
throw new SessionImportChangedError(PI_SESSION_CHANGED);
|
|
18137
18833
|
const cwd = await realpath3(String(header.cwd));
|
|
18138
18834
|
if (!(await stat(cwd)).isDirectory())
|
|
18139
18835
|
return null;
|
|
@@ -18143,14 +18839,13 @@ async function readCandidate(file2, signal) {
|
|
|
18143
18839
|
locator: { sessionFile: await realpath3(file2) },
|
|
18144
18840
|
formatVersion: 1
|
|
18145
18841
|
});
|
|
18146
|
-
const candidate =
|
|
18842
|
+
const candidate = sessionImportCandidate({
|
|
18147
18843
|
nativeSessionId: header.id,
|
|
18148
18844
|
cwd,
|
|
18149
18845
|
title: name ?? firstMessage,
|
|
18150
|
-
updatedAt
|
|
18151
|
-
running: null
|
|
18846
|
+
updatedAt
|
|
18152
18847
|
});
|
|
18153
|
-
return candidate
|
|
18848
|
+
return candidate && nativeRef.success ? { candidate, nativeRef: nativeRef.data } : null;
|
|
18154
18849
|
}
|
|
18155
18850
|
async function readIdentity(file2, signal) {
|
|
18156
18851
|
const stream = createReadStream2(file2, { encoding: "utf8", signal });
|
|
@@ -18198,7 +18893,7 @@ var PiSessionImportIndex = class {
|
|
|
18198
18893
|
try {
|
|
18199
18894
|
const fingerprint = await stat(file2);
|
|
18200
18895
|
const cached2 = this.#cache.get(file2);
|
|
18201
|
-
const source = cached2 &&
|
|
18896
|
+
const source = cached2 && sameFileFingerprint(cached2.fingerprint, fingerprint) ? cached2.source : await readCandidate(file2, signal);
|
|
18202
18897
|
if (!source)
|
|
18203
18898
|
continue;
|
|
18204
18899
|
if (!(await stat(source.candidate.cwd)).isDirectory())
|
|
@@ -18209,7 +18904,7 @@ var PiSessionImportIndex = class {
|
|
|
18209
18904
|
next.set(file2, { fingerprint, source });
|
|
18210
18905
|
sources.push(source);
|
|
18211
18906
|
} catch (error51) {
|
|
18212
|
-
if (!
|
|
18907
|
+
if (!isMissingFileError(error51) && !(error51 instanceof SessionImportChangedError))
|
|
18213
18908
|
throw error51;
|
|
18214
18909
|
}
|
|
18215
18910
|
}
|
|
@@ -18224,14 +18919,14 @@ var PiSessionImportIndex = class {
|
|
|
18224
18919
|
try {
|
|
18225
18920
|
const fingerprint = await stat(file2);
|
|
18226
18921
|
const cached2 = this.#cache.get(file2);
|
|
18227
|
-
const id = cached2 &&
|
|
18922
|
+
const id = cached2 && sameFileFingerprint(cached2.fingerprint, fingerprint) ? cached2.source.nativeRef.nativeSessionId : await readIdentity(file2, signal);
|
|
18228
18923
|
if (id !== nativeSessionId)
|
|
18229
18924
|
continue;
|
|
18230
18925
|
if (selected)
|
|
18231
18926
|
throw new Error("Pi Session identity is ambiguous across files");
|
|
18232
18927
|
selected = file2;
|
|
18233
18928
|
} catch (error51) {
|
|
18234
|
-
if (!
|
|
18929
|
+
if (!isMissingFileError(error51))
|
|
18235
18930
|
throw error51;
|
|
18236
18931
|
}
|
|
18237
18932
|
}
|
|
@@ -18241,7 +18936,7 @@ var PiSessionImportIndex = class {
|
|
|
18241
18936
|
const source = await readCandidate(selected, signal);
|
|
18242
18937
|
return source?.nativeRef.nativeSessionId === nativeSessionId ? source : null;
|
|
18243
18938
|
} catch (error51) {
|
|
18244
|
-
if (
|
|
18939
|
+
if (isMissingFileError(error51))
|
|
18245
18940
|
return null;
|
|
18246
18941
|
throw error51;
|
|
18247
18942
|
}
|
|
@@ -18250,8 +18945,8 @@ var PiSessionImportIndex = class {
|
|
|
18250
18945
|
|
|
18251
18946
|
// dist/pi-rpc-session.js
|
|
18252
18947
|
import { spawn, spawnSync } from "node:child_process";
|
|
18253
|
-
import { randomUUID as
|
|
18254
|
-
import
|
|
18948
|
+
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
18949
|
+
import path12 from "node:path";
|
|
18255
18950
|
|
|
18256
18951
|
// dist/pi-slash-commands.js
|
|
18257
18952
|
var DYNAMIC_ID_PREFIX = "pi.slash.";
|
|
@@ -18273,15 +18968,15 @@ function parsePiNativeCommands(response) {
|
|
|
18273
18968
|
return data.commands.flatMap((entry) => {
|
|
18274
18969
|
if (typeof entry !== "object" || entry === null)
|
|
18275
18970
|
return [];
|
|
18276
|
-
const
|
|
18277
|
-
const name = typeof
|
|
18971
|
+
const record7 = entry;
|
|
18972
|
+
const name = typeof record7.name === "string" ? record7.name.trim().replace(/^\//u, "") : "";
|
|
18278
18973
|
if (!name)
|
|
18279
18974
|
return [];
|
|
18280
18975
|
return [
|
|
18281
18976
|
{
|
|
18282
18977
|
name,
|
|
18283
|
-
...typeof
|
|
18284
|
-
...typeof
|
|
18978
|
+
...typeof record7.description === "string" ? { description: record7.description } : {},
|
|
18979
|
+
...typeof record7.source === "string" ? { source: record7.source } : {}
|
|
18285
18980
|
}
|
|
18286
18981
|
];
|
|
18287
18982
|
});
|
|
@@ -18369,7 +19064,7 @@ function optionalPiStateContextUsage(value) {
|
|
|
18369
19064
|
}
|
|
18370
19065
|
|
|
18371
19066
|
// dist/pi-subagent-rpc.js
|
|
18372
|
-
import { randomUUID as
|
|
19067
|
+
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
18373
19068
|
var PiSubagentRpc = class {
|
|
18374
19069
|
send;
|
|
18375
19070
|
timeoutMs;
|
|
@@ -18411,7 +19106,7 @@ var PiSubagentRpc = class {
|
|
|
18411
19106
|
if (!Array.isArray(data?.commands) || !data.commands.some((command) => command?.name === "subagents-inspect-rpc" && command.source === "extension")) {
|
|
18412
19107
|
throw new Error("Installed Pi has no pi-subagents Host inspection command");
|
|
18413
19108
|
}
|
|
18414
|
-
const requestId =
|
|
19109
|
+
const requestId = randomUUID4();
|
|
18415
19110
|
const reply = new Promise((resolve, reject) => {
|
|
18416
19111
|
const timer = setTimeout(() => {
|
|
18417
19112
|
this.#pending.delete(requestId);
|
|
@@ -18557,7 +19252,11 @@ function parseAvailableModels(response) {
|
|
|
18557
19252
|
if (!parsed || !isRecord6(model) || typeof model.reasoning !== "boolean") {
|
|
18558
19253
|
throw new PiRpcFaultError("protocolError", "Pi RPC catalog contains a Model without reasoning capability");
|
|
18559
19254
|
}
|
|
18560
|
-
return {
|
|
19255
|
+
return {
|
|
19256
|
+
...parsed,
|
|
19257
|
+
reasoning: model.reasoning,
|
|
19258
|
+
...typeof model.api === "string" ? { api: model.api } : {}
|
|
19259
|
+
};
|
|
18561
19260
|
});
|
|
18562
19261
|
}
|
|
18563
19262
|
function assistantText(value) {
|
|
@@ -18642,13 +19341,14 @@ function piRpcProcessCommand(options, dependencies = {}) {
|
|
|
18642
19341
|
const modelArguments = startupModel ? ["--provider", startupModel.provider, "--model", startupModel.id] : [];
|
|
18643
19342
|
const thinkingArguments = options.emptySessionConfiguration ? ["--thinking", options.emptySessionConfiguration.thinkingLevel] : [];
|
|
18644
19343
|
const arguments_ = [
|
|
19344
|
+
...options.fastExtension ? ["--extension", options.fastExtension] : [],
|
|
18645
19345
|
"--mode",
|
|
18646
19346
|
"rpc",
|
|
18647
19347
|
...modelArguments,
|
|
18648
19348
|
...thinkingArguments,
|
|
18649
19349
|
...sessionArguments
|
|
18650
19350
|
];
|
|
18651
|
-
const extension =
|
|
19351
|
+
const extension = path12.win32.extname(command).toLowerCase();
|
|
18652
19352
|
if (platform !== "win32" || ![".cmd", ".bat"].includes(extension)) {
|
|
18653
19353
|
return { command, arguments: arguments_, windowsVerbatimArguments: false };
|
|
18654
19354
|
}
|
|
@@ -18687,6 +19387,8 @@ var PiRpcSession = class {
|
|
|
18687
19387
|
#failed = false;
|
|
18688
19388
|
#pending = /* @__PURE__ */ new Map();
|
|
18689
19389
|
#state = null;
|
|
19390
|
+
#fast = null;
|
|
19391
|
+
#fastAcknowledgement = null;
|
|
18690
19392
|
#latestCacheHitRatePercent;
|
|
18691
19393
|
#manualCompaction = null;
|
|
18692
19394
|
#stderrTail = "";
|
|
@@ -18713,7 +19415,9 @@ var PiRpcSession = class {
|
|
|
18713
19415
|
get state() {
|
|
18714
19416
|
if (!this.#state)
|
|
18715
19417
|
throw new Error("Pi RPC Session has not started");
|
|
18716
|
-
|
|
19418
|
+
if (this.#fast && (this.#fast.provider !== this.#state.provider || this.#fast.id !== this.#state.modelId))
|
|
19419
|
+
this.#fast = null;
|
|
19420
|
+
return this.#fast ? { ...this.#state, fast: true } : this.#state;
|
|
18717
19421
|
}
|
|
18718
19422
|
get stderrTail() {
|
|
18719
19423
|
return this.#stderrTail;
|
|
@@ -18730,8 +19434,10 @@ var PiRpcSession = class {
|
|
|
18730
19434
|
async start() {
|
|
18731
19435
|
if (this.#child || this.#closed)
|
|
18732
19436
|
throw new Error("Pi RPC Session cannot be started twice");
|
|
19437
|
+
const fastExtension = this.#processAdapter === nodeProcessAdapter ? await ensurePiFastExtension({ ...process.env, ...this.#options.environment }) : void 0;
|
|
18733
19438
|
const child = this.#processAdapter.spawn({
|
|
18734
19439
|
cwd: this.#options.cwd,
|
|
19440
|
+
...fastExtension ? { fastExtension } : {},
|
|
18735
19441
|
...this.#options.command ? { command: this.#options.command } : {},
|
|
18736
19442
|
environment: withNodeRuntimeOnPath({
|
|
18737
19443
|
...process.env,
|
|
@@ -18878,7 +19584,36 @@ var PiRpcSession = class {
|
|
|
18878
19584
|
throw error51;
|
|
18879
19585
|
}
|
|
18880
19586
|
}
|
|
19587
|
+
async supportsFastMode() {
|
|
19588
|
+
return (await this.getCommands()).some((command) => command.name === PI_FAST_COMMAND && command.source === "extension");
|
|
19589
|
+
}
|
|
19590
|
+
async selectFastMode(enabled) {
|
|
19591
|
+
if (!enabled && !this.#fast)
|
|
19592
|
+
return this.state;
|
|
19593
|
+
if (!await this.supportsFastMode())
|
|
19594
|
+
throw new Error("Installed Pi does not support the Host Fast extension");
|
|
19595
|
+
const nonce = randomUUID5();
|
|
19596
|
+
const mode = enabled ? "on" : "off";
|
|
19597
|
+
const acknowledgement = { message: `${PI_FAST_ACK}${nonce}:${mode}`, received: false };
|
|
19598
|
+
this.#fastAcknowledgement = acknowledgement;
|
|
19599
|
+
try {
|
|
19600
|
+
await this.#send("prompt", { message: `/${PI_FAST_COMMAND} ${mode} ${nonce}` });
|
|
19601
|
+
if (!acknowledgement.received)
|
|
19602
|
+
throw new Error("Pi did not confirm the Fast selection");
|
|
19603
|
+
this.#fast = enabled ? { provider: this.state.provider ?? "", id: this.state.modelId ?? "" } : null;
|
|
19604
|
+
return this.state;
|
|
19605
|
+
} catch (error51) {
|
|
19606
|
+
const fault = error51 instanceof PiRpcFaultError ? error51 : new PiRpcFaultError("protocolError", `Pi Fast selection could not be confirmed: ${message2(error51)}`);
|
|
19607
|
+
this.#fail(fault);
|
|
19608
|
+
await this.close().catch(() => void 0);
|
|
19609
|
+
throw fault;
|
|
19610
|
+
} finally {
|
|
19611
|
+
this.#fastAcknowledgement = null;
|
|
19612
|
+
}
|
|
19613
|
+
}
|
|
18881
19614
|
async selectModel(model) {
|
|
19615
|
+
if (this.#fast)
|
|
19616
|
+
await this.selectFastMode(false);
|
|
18882
19617
|
await this.#send("set_model", { provider: model.provider, modelId: model.id });
|
|
18883
19618
|
return this.#refreshState("Model");
|
|
18884
19619
|
}
|
|
@@ -18890,7 +19625,7 @@ var PiRpcSession = class {
|
|
|
18890
19625
|
async #refreshState(operation) {
|
|
18891
19626
|
try {
|
|
18892
19627
|
this.#state = parseSessionState(await this.#send("get_state", {}));
|
|
18893
|
-
return this
|
|
19628
|
+
return this.state;
|
|
18894
19629
|
} catch (error51) {
|
|
18895
19630
|
const fault = error51 instanceof PiRpcFaultError ? error51 : new PiRpcFaultError("protocolError", `Pi RPC ${operation} state could not be confirmed: ${message2(error51)}`);
|
|
18896
19631
|
this.#fail(fault);
|
|
@@ -19046,6 +19781,11 @@ var PiRpcSession = class {
|
|
|
19046
19781
|
}
|
|
19047
19782
|
}
|
|
19048
19783
|
#handle(value) {
|
|
19784
|
+
if (value.type === "extension_ui_request" && value.method === "notify" && typeof value.message === "string" && value.message.startsWith(PI_FAST_ACK)) {
|
|
19785
|
+
if (this.#fastAcknowledgement?.message === value.message)
|
|
19786
|
+
this.#fastAcknowledgement.received = true;
|
|
19787
|
+
return;
|
|
19788
|
+
}
|
|
19049
19789
|
if (this.#closed || this.#failed)
|
|
19050
19790
|
return;
|
|
19051
19791
|
if (value.type === "response") {
|
|
@@ -19168,7 +19908,7 @@ var PiRpcSession = class {
|
|
|
19168
19908
|
const active = {
|
|
19169
19909
|
origin: "autonomous",
|
|
19170
19910
|
autonomousEvents: events,
|
|
19171
|
-
nativeTurnKey: assistantMessageId(value) ??
|
|
19911
|
+
nativeTurnKey: assistantMessageId(value) ?? randomUUID5(),
|
|
19172
19912
|
nativeCancellationObserved: false,
|
|
19173
19913
|
text: "",
|
|
19174
19914
|
assistantMessageId: null,
|
|
@@ -19411,7 +20151,7 @@ var PiRpcSession = class {
|
|
|
19411
20151
|
if (active.assistantMessageId !== null && active.reasoningMessageOpen) {
|
|
19412
20152
|
active.onEvent({ type: "reasoning.completed", messageId: active.assistantMessageId });
|
|
19413
20153
|
}
|
|
19414
|
-
const messageId = assistantMessageId(value) ??
|
|
20154
|
+
const messageId = assistantMessageId(value) ?? randomUUID5();
|
|
19415
20155
|
active.assistantMessageId = messageId;
|
|
19416
20156
|
active.sawStreamedMessageText = false;
|
|
19417
20157
|
active.sawStreamedMessageReasoning = false;
|
|
@@ -19472,7 +20212,7 @@ var PiRpcSession = class {
|
|
|
19472
20212
|
if (!child?.stdin.writable || this.#closed || this.#failed) {
|
|
19473
20213
|
return Promise.reject(new Error("Pi RPC stdin is unavailable"));
|
|
19474
20214
|
}
|
|
19475
|
-
const id = `codexhost-${
|
|
20215
|
+
const id = `codexhost-${randomUUID5()}`;
|
|
19476
20216
|
return new Promise((resolve, reject) => {
|
|
19477
20217
|
const pending = {
|
|
19478
20218
|
command: type,
|
|
@@ -19647,7 +20387,7 @@ function nativeModelFromState(state2) {
|
|
|
19647
20387
|
}
|
|
19648
20388
|
function effectiveModelFromState(state2) {
|
|
19649
20389
|
const model = nativeModelFromState(state2);
|
|
19650
|
-
return model ? encodePiModelRef(model) : void 0;
|
|
20390
|
+
return model ? encodePiModelRef({ ...model, ...state2.fast ? { fast: true } : {} }) : void 0;
|
|
19651
20391
|
}
|
|
19652
20392
|
function harnessStateFromPi(state2, thinkingLevels) {
|
|
19653
20393
|
const effectiveModel = effectiveModelFromState(state2);
|
|
@@ -19733,10 +20473,10 @@ function stripDiffPrefix(pathString) {
|
|
|
19733
20473
|
return pathString.startsWith("a/") || pathString.startsWith("b/") ? pathString.slice(2) : pathString;
|
|
19734
20474
|
}
|
|
19735
20475
|
function displayPath(nativePath, cwd) {
|
|
19736
|
-
const resolvedCwd =
|
|
19737
|
-
const resolvedPath =
|
|
19738
|
-
const relative =
|
|
19739
|
-
const inside = relative.length > 0 && relative !== ".." && !relative.startsWith(`..${
|
|
20476
|
+
const resolvedCwd = path13.resolve(cwd);
|
|
20477
|
+
const resolvedPath = path13.isAbsolute(nativePath) ? path13.resolve(nativePath) : path13.resolve(cwd, nativePath);
|
|
20478
|
+
const relative = path13.relative(resolvedCwd, resolvedPath);
|
|
20479
|
+
const inside = relative.length > 0 && relative !== ".." && !relative.startsWith(`..${path13.sep}`);
|
|
19740
20480
|
const selected = inside ? relative : resolvedPath;
|
|
19741
20481
|
const normalized = selected.replaceAll("\\", "/");
|
|
19742
20482
|
if (normalized.length === 0 || normalized === ".")
|
|
@@ -19935,6 +20675,7 @@ var PiHarnessSession = class {
|
|
|
19935
20675
|
#requestedModel;
|
|
19936
20676
|
#requestedThinkingOptionId;
|
|
19937
20677
|
#toolOutputLimit;
|
|
20678
|
+
#isFastSupported;
|
|
19938
20679
|
#acceptingTurn = false;
|
|
19939
20680
|
#active = null;
|
|
19940
20681
|
#closePromise = null;
|
|
@@ -19956,6 +20697,7 @@ var PiHarnessSession = class {
|
|
|
19956
20697
|
this.#requestedModel = options.model;
|
|
19957
20698
|
this.#requestedThinkingOptionId = options.thinkingOptionId;
|
|
19958
20699
|
this.#toolOutputLimit = options.toolOutputLimit;
|
|
20700
|
+
this.#isFastSupported = options.isFastSupported;
|
|
19959
20701
|
this.capabilities = {
|
|
19960
20702
|
configuration: {
|
|
19961
20703
|
selectModel: true,
|
|
@@ -19984,13 +20726,13 @@ var PiHarnessSession = class {
|
|
|
19984
20726
|
return this.#transport?.state.sessionId === id;
|
|
19985
20727
|
}
|
|
19986
20728
|
async readSubagentHistory(cwd) {
|
|
19987
|
-
if (this.#phase !== "open" ||
|
|
20729
|
+
if (this.#phase !== "open" || path13.resolve(cwd) !== path13.resolve(this.#cwd)) {
|
|
19988
20730
|
throw new Error("Pi Subagent parent workspace or Session is unavailable");
|
|
19989
20731
|
}
|
|
19990
20732
|
return (await this.#ensureTransport()).getEntries();
|
|
19991
20733
|
}
|
|
19992
20734
|
async inspectSubagent(id, cwd) {
|
|
19993
|
-
if (this.#phase !== "open" ||
|
|
20735
|
+
if (this.#phase !== "open" || path13.resolve(cwd) !== path13.resolve(this.#cwd)) {
|
|
19994
20736
|
throw new Error("Pi Subagent parent workspace or Session is unavailable");
|
|
19995
20737
|
}
|
|
19996
20738
|
const transport = await this.#ensureTransport();
|
|
@@ -20233,20 +20975,27 @@ var PiHarnessSession = class {
|
|
|
20233
20975
|
error: invalidState("Pi Model selection requires a started Native Session")
|
|
20234
20976
|
};
|
|
20235
20977
|
}
|
|
20236
|
-
let requested;
|
|
20237
|
-
try {
|
|
20238
|
-
requested = decodePiModelRef(command.model);
|
|
20239
|
-
} catch (error51) {
|
|
20240
|
-
return { ok: false, error: normalizedError(error51, "invalidRequest") };
|
|
20241
|
-
}
|
|
20242
20978
|
const previousModel = this.#state.effectiveModel;
|
|
20243
20979
|
this.#configuring = true;
|
|
20244
20980
|
try {
|
|
20981
|
+
let requested;
|
|
20982
|
+
try {
|
|
20983
|
+
requested = decodePiModelRef(command.model);
|
|
20984
|
+
if (requested.fast && !await this.#isFastSupported(command.model, transport))
|
|
20985
|
+
throw new Error("Fast is unavailable for this Pi Model");
|
|
20986
|
+
} catch (error51) {
|
|
20987
|
+
return { ok: false, error: normalizedError(error51, "invalidRequest") };
|
|
20988
|
+
}
|
|
20245
20989
|
let state2;
|
|
20246
20990
|
let thinkingLevels;
|
|
20247
20991
|
try {
|
|
20248
|
-
state2 = await transport.selectModel(requested);
|
|
20992
|
+
state2 = samePiModel(nativeModelFromState(transport.state), requested) ? transport.state : await transport.selectModel(requested);
|
|
20249
20993
|
thinkingLevels = await transport.getAvailableThinkingLevels();
|
|
20994
|
+
if (requested.fast || state2.fast) {
|
|
20995
|
+
if (!transport.selectFastMode)
|
|
20996
|
+
throw new Error("Pi Fast extension is unavailable");
|
|
20997
|
+
state2 = await transport.selectFastMode(requested.fast === true);
|
|
20998
|
+
}
|
|
20250
20999
|
this.#publishTransportState(state2, thinkingLevels);
|
|
20251
21000
|
} catch (error51) {
|
|
20252
21001
|
if (error51 instanceof PiRpcFaultError)
|
|
@@ -20383,7 +21132,7 @@ var PiHarnessSession = class {
|
|
|
20383
21132
|
const transport = this.#transport;
|
|
20384
21133
|
if (this.#phase === "open" && transport?.getCommands) {
|
|
20385
21134
|
try {
|
|
20386
|
-
this.#liveCommands = piLiveCommandCatalog(piCommandCatalog, await transport.getCommands());
|
|
21135
|
+
this.#liveCommands = piLiveCommandCatalog(piCommandCatalog, (await transport.getCommands()).filter((command) => command.name !== PI_FAST_COMMAND));
|
|
20387
21136
|
} catch {
|
|
20388
21137
|
}
|
|
20389
21138
|
}
|
|
@@ -20530,6 +21279,11 @@ var PiHarnessSession = class {
|
|
|
20530
21279
|
this.#publishTransportState(state2, thinkingLevels);
|
|
20531
21280
|
throw new Error("Pi did not activate the requested create Model");
|
|
20532
21281
|
}
|
|
21282
|
+
if (requested.fast) {
|
|
21283
|
+
if (!await this.#isFastSupported(this.#requestedModel, transport) || !transport.selectFastMode)
|
|
21284
|
+
throw new Error("Fast is unavailable for this Pi Model");
|
|
21285
|
+
state2 = await transport.selectFastMode(true);
|
|
21286
|
+
}
|
|
20533
21287
|
}
|
|
20534
21288
|
if (this.#requestedThinkingOptionId) {
|
|
20535
21289
|
if (!thinkingLevels) {
|
|
@@ -20610,7 +21364,7 @@ var PiHarnessSession = class {
|
|
|
20610
21364
|
}));
|
|
20611
21365
|
return;
|
|
20612
21366
|
}
|
|
20613
|
-
const turnId = hostTurnIdSchema.parse(
|
|
21367
|
+
const turnId = hostTurnIdSchema.parse(randomUUID6());
|
|
20614
21368
|
let resolveCompletion = () => void 0;
|
|
20615
21369
|
const completion = new Promise((resolve) => {
|
|
20616
21370
|
resolveCompletion = resolve;
|
|
@@ -20772,7 +21526,7 @@ var PiHarnessSession = class {
|
|
|
20772
21526
|
if (active.interactionByNativeId.has(request.requestId)) {
|
|
20773
21527
|
throw new Error("Pi Interaction started more than once");
|
|
20774
21528
|
}
|
|
20775
|
-
const interactionId = hostInteractionIdSchema.parse(
|
|
21529
|
+
const interactionId = hostInteractionIdSchema.parse(randomUUID6());
|
|
20776
21530
|
const question = request.method === "select" ? {
|
|
20777
21531
|
id: "answer",
|
|
20778
21532
|
type: "choice",
|
|
@@ -21119,7 +21873,7 @@ var PiHarnessSession = class {
|
|
|
21119
21873
|
this.#channel.emit({ kind: "event", event });
|
|
21120
21874
|
}
|
|
21121
21875
|
#newItemId() {
|
|
21122
|
-
return hostItemIdSchema.parse(
|
|
21876
|
+
return hostItemIdSchema.parse(randomUUID6());
|
|
21123
21877
|
}
|
|
21124
21878
|
};
|
|
21125
21879
|
var PiAdapter = class {
|
|
@@ -21182,27 +21936,17 @@ var PiAdapter = class {
|
|
|
21182
21936
|
};
|
|
21183
21937
|
sessionImport = Object.freeze({
|
|
21184
21938
|
listCandidates: async () => {
|
|
21185
|
-
const result = await this.#
|
|
21939
|
+
const result = await this.#importScope.read((signal) => this.#importIndex.list(signal));
|
|
21186
21940
|
return result.ok ? { ok: true, value: result.value.map(({ candidate }) => candidate) } : result;
|
|
21187
21941
|
},
|
|
21188
|
-
resolveCandidate:
|
|
21189
|
-
const result = await this.#readImport((signal) => this.#importIndex.resolve(nativeSessionId, signal));
|
|
21190
|
-
if (!result.ok)
|
|
21191
|
-
return result;
|
|
21192
|
-
const source = result.value;
|
|
21193
|
-
return source ? { ok: true, value: source } : {
|
|
21194
|
-
ok: false,
|
|
21195
|
-
error: {
|
|
21196
|
-
code: "sessionNotFound",
|
|
21197
|
-
message: "Pi Session is no longer importable",
|
|
21198
|
-
retryable: false
|
|
21199
|
-
}
|
|
21200
|
-
};
|
|
21201
|
-
}
|
|
21942
|
+
resolveCandidate: (nativeSessionId) => this.#importScope.resolve((signal) => this.#importIndex.resolve(nativeSessionId, signal))
|
|
21202
21943
|
});
|
|
21203
21944
|
#importIndex;
|
|
21204
|
-
#
|
|
21205
|
-
|
|
21945
|
+
#importScope = new SessionImportScope({
|
|
21946
|
+
closedMessage: "Pi Adapter is closed",
|
|
21947
|
+
unavailableMessage: "Pi Session discovery failed; check storage access and duplicate Session identities, then retry after closing native clients",
|
|
21948
|
+
notFoundMessage: "Pi Session is no longer importable"
|
|
21949
|
+
});
|
|
21206
21950
|
#closeTimeoutMs;
|
|
21207
21951
|
#createTransport;
|
|
21208
21952
|
#inspectionCache = /* @__PURE__ */ new Map();
|
|
@@ -21210,6 +21954,7 @@ var PiAdapter = class {
|
|
|
21210
21954
|
#inspections = /* @__PURE__ */ new Set();
|
|
21211
21955
|
#sessions = /* @__PURE__ */ new Set();
|
|
21212
21956
|
#toolOutputLimit;
|
|
21957
|
+
#environment;
|
|
21213
21958
|
#closePromise = null;
|
|
21214
21959
|
#thinkingSelectionSupported = null;
|
|
21215
21960
|
constructor(options = {}, dependencies = {
|
|
@@ -21229,23 +21974,20 @@ var PiAdapter = class {
|
|
|
21229
21974
|
remove: (name) => updateCatalog(imports.remove(name))
|
|
21230
21975
|
};
|
|
21231
21976
|
this.#createTransport = dependencies.createTransport;
|
|
21977
|
+
this.#environment = options.environment ?? process.env;
|
|
21232
21978
|
this.#importIndex = new PiSessionImportIndex({ ...process.env, ...options.environment });
|
|
21233
21979
|
this.#closeTimeoutMs = options.closeTimeoutMs ?? 2e3;
|
|
21234
21980
|
this.#toolOutputLimit = options.toolOutputLimit ?? DEFAULT_TOOL_OUTPUT_LIMIT;
|
|
21235
21981
|
}
|
|
21236
|
-
|
|
21237
|
-
|
|
21238
|
-
|
|
21239
|
-
|
|
21240
|
-
|
|
21241
|
-
|
|
21242
|
-
|
|
21243
|
-
|
|
21244
|
-
|
|
21245
|
-
}
|
|
21246
|
-
})).finally(() => this.#importRequests.delete(request));
|
|
21247
|
-
this.#importRequests.add(request);
|
|
21248
|
-
return request;
|
|
21982
|
+
/** Pi itself holds no Account; this reports configured Provider balances. */
|
|
21983
|
+
async inspectAccounts() {
|
|
21984
|
+
if (this.#closePromise)
|
|
21985
|
+
return [];
|
|
21986
|
+
return fetchPiAccounts({ environment: this.#environment });
|
|
21987
|
+
}
|
|
21988
|
+
async inspectAccount() {
|
|
21989
|
+
const accounts = await this.inspectAccounts();
|
|
21990
|
+
return accounts[0] ?? null;
|
|
21249
21991
|
}
|
|
21250
21992
|
async inspect(input = {}) {
|
|
21251
21993
|
if (this.#closePromise) {
|
|
@@ -21258,7 +22000,7 @@ var PiAdapter = class {
|
|
|
21258
22000
|
}
|
|
21259
22001
|
};
|
|
21260
22002
|
}
|
|
21261
|
-
const cwd = input.cwd
|
|
22003
|
+
const cwd = resolvePiInspectCwd(input.cwd);
|
|
21262
22004
|
const inFlight = this.#inspectionInFlight.get(cwd);
|
|
21263
22005
|
if (inFlight)
|
|
21264
22006
|
return inFlight;
|
|
@@ -21292,7 +22034,9 @@ var PiAdapter = class {
|
|
|
21292
22034
|
stage = "capabilities";
|
|
21293
22035
|
const thinkingLevels = await transport.getAvailableThinkingLevels();
|
|
21294
22036
|
this.#thinkingSelectionSupported = thinkingLevels !== null;
|
|
21295
|
-
const
|
|
22037
|
+
const normalized = normalizePiModelCatalog(models, nativeModelFromState(transport.state), thinkingLevels, transport.state.thinkingLevel);
|
|
22038
|
+
const fastModels = await transport.supportsFastMode?.() ? await piFastModelKeys(models, this.#environment) : /* @__PURE__ */ new Set();
|
|
22039
|
+
const catalog = withPiFast(normalized, fastModels);
|
|
21296
22040
|
await transport.close();
|
|
21297
22041
|
return {
|
|
21298
22042
|
status: "ready",
|
|
@@ -21329,6 +22073,27 @@ var PiAdapter = class {
|
|
|
21329
22073
|
if (this.#closePromise) {
|
|
21330
22074
|
return { ok: false, error: invalidState("Pi Adapter is closed") };
|
|
21331
22075
|
}
|
|
22076
|
+
if ("model" in input && input.model) {
|
|
22077
|
+
let model;
|
|
22078
|
+
try {
|
|
22079
|
+
model = decodePiModelRef(input.model);
|
|
22080
|
+
} catch (error51) {
|
|
22081
|
+
return { ok: false, error: normalizedError(error51, "invalidRequest") };
|
|
22082
|
+
}
|
|
22083
|
+
if (model.fast) {
|
|
22084
|
+
if (!this.#isFastSupported(input.model, input.cwd))
|
|
22085
|
+
await this.inspect({ cwd: input.cwd });
|
|
22086
|
+
if (!this.#isFastSupported(input.model, input.cwd) && input.kind !== "resume")
|
|
22087
|
+
return {
|
|
22088
|
+
ok: false,
|
|
22089
|
+
error: {
|
|
22090
|
+
code: "unsupported",
|
|
22091
|
+
message: "Fast is unavailable for this Pi Model",
|
|
22092
|
+
retryable: false
|
|
22093
|
+
}
|
|
22094
|
+
};
|
|
22095
|
+
}
|
|
22096
|
+
}
|
|
21332
22097
|
if (input.cwd.length === 0) {
|
|
21333
22098
|
return {
|
|
21334
22099
|
ok: false,
|
|
@@ -21499,6 +22264,11 @@ var PiAdapter = class {
|
|
|
21499
22264
|
await transport.verifySessionCwd(input.cwd);
|
|
21500
22265
|
}
|
|
21501
22266
|
}
|
|
22267
|
+
if (input.kind === "resume" && input.model && this.#isFastSupported(input.model, input.cwd) && decodePiModelRef(input.model).fast && samePiModel(nativeModelFromState(transport.state), decodePiModelRef(input.model))) {
|
|
22268
|
+
if (!transport.selectFastMode)
|
|
22269
|
+
throw new Error("Pi Fast extension is unavailable");
|
|
22270
|
+
await transport.selectFastMode(true);
|
|
22271
|
+
}
|
|
21502
22272
|
const startedThinkingLevels = await transport.getAvailableThinkingLevels();
|
|
21503
22273
|
this.#thinkingSelectionSupported = startedThinkingLevels !== null;
|
|
21504
22274
|
const initialUsage = await transport.getSessionUsage().catch(() => null);
|
|
@@ -21515,6 +22285,9 @@ var PiAdapter = class {
|
|
|
21515
22285
|
return { ok: false, error: normalizedError(error51, "nativeFailure") };
|
|
21516
22286
|
}
|
|
21517
22287
|
}
|
|
22288
|
+
#isFastSupported(ref, cwd) {
|
|
22289
|
+
return this.#inspectionCache.get(cwd)?.catalog.models.some((model) => model.fastModel?.id === ref.id) ?? false;
|
|
22290
|
+
}
|
|
21518
22291
|
#trackSession(cwd, options) {
|
|
21519
22292
|
const environment = options.environment;
|
|
21520
22293
|
const createTransport = environment ? (input) => this.#createTransport({ ...input, environment }) : this.#createTransport;
|
|
@@ -21526,6 +22299,14 @@ var PiAdapter = class {
|
|
|
21526
22299
|
...options.thinkingOptionId ? { thinkingOptionId: options.thinkingOptionId } : {},
|
|
21527
22300
|
toolOutputLimit: this.#toolOutputLimit,
|
|
21528
22301
|
supportsThinkingSelection: options.supportsThinkingSelection,
|
|
22302
|
+
isFastSupported: async (ref, transport) => {
|
|
22303
|
+
if (this.#inspectionCache.has(cwd))
|
|
22304
|
+
return this.#isFastSupported(ref, cwd);
|
|
22305
|
+
if (!await transport.supportsFastMode?.())
|
|
22306
|
+
return false;
|
|
22307
|
+
const fastModels = await piFastModelKeys(await transport.getAvailableModels(), environment ?? this.#environment);
|
|
22308
|
+
return fastModels.has(encodePiModelRef({ ...decodePiModelRef(ref), fast: false }).id);
|
|
22309
|
+
},
|
|
21529
22310
|
...options.startedTransport ? { startedTransport: options.startedTransport } : {},
|
|
21530
22311
|
...options.startedThinkingLevels !== void 0 ? { startedThinkingLevels: options.startedThinkingLevels } : {},
|
|
21531
22312
|
...options.initialUsage !== void 0 ? { initialUsage: options.initialUsage } : {}
|
|
@@ -21535,9 +22316,8 @@ var PiAdapter = class {
|
|
|
21535
22316
|
}
|
|
21536
22317
|
close() {
|
|
21537
22318
|
if (!this.#closePromise) {
|
|
21538
|
-
this.#importAbort.abort();
|
|
21539
22319
|
this.#closePromise = Promise.all([
|
|
21540
|
-
|
|
22320
|
+
this.#importScope.close(),
|
|
21541
22321
|
...[...this.#inspections].map((transport) => transport.close()),
|
|
21542
22322
|
...[...this.#sessions].map((session) => session.close())
|
|
21543
22323
|
]).then(() => void 0);
|
|
@@ -21546,13 +22326,42 @@ var PiAdapter = class {
|
|
|
21546
22326
|
}
|
|
21547
22327
|
};
|
|
21548
22328
|
|
|
22329
|
+
// dist/installation.js
|
|
22330
|
+
var PI_LATEST_VERSION_URL = "https://pi.dev/api/latest-version";
|
|
22331
|
+
function createPiInstallation(environment, command) {
|
|
22332
|
+
const run = (args, timeout) => runInstallationCommand(resolvePiExecutable({ environment, ...command ? { command } : {} }), args, environment, timeout);
|
|
22333
|
+
return createInstallationManager({
|
|
22334
|
+
async check() {
|
|
22335
|
+
const currentVersion = versionFromOutput(await run(["--version"]));
|
|
22336
|
+
const payload = JSON.parse(await fetchInstallationText(PI_LATEST_VERSION_URL));
|
|
22337
|
+
const latestVersion = installationVersion(payload.version);
|
|
22338
|
+
return {
|
|
22339
|
+
currentVersion,
|
|
22340
|
+
latestVersion,
|
|
22341
|
+
updateAvailable: newerInstallationVersion(currentVersion, latestVersion),
|
|
22342
|
+
canUpdate: true
|
|
22343
|
+
};
|
|
22344
|
+
},
|
|
22345
|
+
async update() {
|
|
22346
|
+
await run(["update"], 3e5);
|
|
22347
|
+
}
|
|
22348
|
+
});
|
|
22349
|
+
}
|
|
22350
|
+
|
|
21549
22351
|
// dist/plugin.js
|
|
21550
22352
|
var PI_COMMAND_ENV = "CODEXHOST_PI_COMMAND";
|
|
21551
22353
|
function createHarnessAdapter(context) {
|
|
21552
22354
|
const environment = { ...context.environment };
|
|
21553
|
-
return new PiAdapter({
|
|
22355
|
+
return Object.assign(new PiAdapter({
|
|
21554
22356
|
...environment[PI_COMMAND_ENV] ? { command: environment[PI_COMMAND_ENV] } : {},
|
|
21555
22357
|
environment
|
|
22358
|
+
}), {
|
|
22359
|
+
installation: createPiInstallation(environment, environment[PI_COMMAND_ENV]),
|
|
22360
|
+
install: createHarnessInstaller(environment, {
|
|
22361
|
+
posix: "https://pi.dev/install.sh",
|
|
22362
|
+
windows: "https://pi.dev/install.ps1",
|
|
22363
|
+
shell: "sh"
|
|
22364
|
+
})
|
|
21556
22365
|
});
|
|
21557
22366
|
}
|
|
21558
22367
|
export {
|