@super-one/cli 0.49.4-alpha → 0.50.0-alpha
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/MANIFEST.json +2 -2
- package/lib/cli.mjs +1377 -972
- package/package.json +11 -11
package/lib/cli.mjs
CHANGED
|
@@ -3212,6 +3212,13 @@ var init_descriptor = __esm({
|
|
|
3212
3212
|
}
|
|
3213
3213
|
});
|
|
3214
3214
|
|
|
3215
|
+
// ../../packages/shared/src/environment/cli-version.ts
|
|
3216
|
+
var init_cli_version = __esm({
|
|
3217
|
+
"../../packages/shared/src/environment/cli-version.ts"() {
|
|
3218
|
+
"use strict";
|
|
3219
|
+
}
|
|
3220
|
+
});
|
|
3221
|
+
|
|
3215
3222
|
// ../../packages/shared/src/environment/known-environment.ts
|
|
3216
3223
|
var init_known_environment = __esm({
|
|
3217
3224
|
"../../packages/shared/src/environment/known-environment.ts"() {
|
|
@@ -3512,6 +3519,7 @@ var init_environment = __esm({
|
|
|
3512
3519
|
init_host_action_browser_catalog();
|
|
3513
3520
|
init_harness_installation();
|
|
3514
3521
|
init_descriptor();
|
|
3522
|
+
init_cli_version();
|
|
3515
3523
|
init_known_environment();
|
|
3516
3524
|
init_auth();
|
|
3517
3525
|
init_rpc();
|
|
@@ -3584,9 +3592,9 @@ var require_node_gyp_build = __commonJS({
|
|
|
3584
3592
|
var debug = getFirst(path.join(dir, "build/Debug"), matchBuild);
|
|
3585
3593
|
if (debug) return debug;
|
|
3586
3594
|
}
|
|
3587
|
-
var prebuild =
|
|
3595
|
+
var prebuild = resolve12(dir);
|
|
3588
3596
|
if (prebuild) return prebuild;
|
|
3589
|
-
var nearby =
|
|
3597
|
+
var nearby = resolve12(path.dirname(process.execPath));
|
|
3590
3598
|
if (nearby) return nearby;
|
|
3591
3599
|
var target = [
|
|
3592
3600
|
"platform=" + platform2,
|
|
@@ -3602,18 +3610,18 @@ var require_node_gyp_build = __commonJS({
|
|
|
3602
3610
|
// eslint-disable-line
|
|
3603
3611
|
].filter(Boolean).join(" ");
|
|
3604
3612
|
throw new Error("No native build was found for " + target + "\n loaded from: " + dir + "\n");
|
|
3605
|
-
function
|
|
3606
|
-
var tuples =
|
|
3613
|
+
function resolve12(dir2) {
|
|
3614
|
+
var tuples = readdirSync8(path.join(dir2, "prebuilds")).map(parseTuple);
|
|
3607
3615
|
var tuple2 = tuples.filter(matchTuple(platform2, arch2)).sort(compareTuples)[0];
|
|
3608
3616
|
if (!tuple2) return;
|
|
3609
3617
|
var prebuilds = path.join(dir2, "prebuilds", tuple2.name);
|
|
3610
|
-
var parsed =
|
|
3618
|
+
var parsed = readdirSync8(prebuilds).map(parseTags);
|
|
3611
3619
|
var candidates = parsed.filter(matchTags(runtime, abi));
|
|
3612
3620
|
var winner = candidates.sort(compareTags(runtime))[0];
|
|
3613
3621
|
if (winner) return path.join(prebuilds, winner.file);
|
|
3614
3622
|
}
|
|
3615
3623
|
};
|
|
3616
|
-
function
|
|
3624
|
+
function readdirSync8(dir) {
|
|
3617
3625
|
try {
|
|
3618
3626
|
return fs.readdirSync(dir);
|
|
3619
3627
|
} catch (err) {
|
|
@@ -3621,7 +3629,7 @@ var require_node_gyp_build = __commonJS({
|
|
|
3621
3629
|
}
|
|
3622
3630
|
}
|
|
3623
3631
|
function getFirst(dir, filter) {
|
|
3624
|
-
var files =
|
|
3632
|
+
var files = readdirSync8(dir).filter(filter);
|
|
3625
3633
|
return files[0] && path.join(dir, files[0]);
|
|
3626
3634
|
}
|
|
3627
3635
|
function matchBuild(name) {
|
|
@@ -8008,12 +8016,12 @@ var init_agent_event_mapper = __esm({
|
|
|
8008
8016
|
// ../../packages/codex/src/app-server-client.ts
|
|
8009
8017
|
import { spawn } from "node:child_process";
|
|
8010
8018
|
import { createInterface } from "node:readline";
|
|
8011
|
-
import { existsSync as
|
|
8019
|
+
import { existsSync as existsSync3 } from "node:fs";
|
|
8012
8020
|
async function openCodexAppServer(opts) {
|
|
8013
8021
|
if (opts.signal?.aborted) {
|
|
8014
8022
|
throw new Error("Codex app-server launch interrupted");
|
|
8015
8023
|
}
|
|
8016
|
-
if (!opts.binaryPath || !
|
|
8024
|
+
if (!opts.binaryPath || !existsSync3(opts.binaryPath)) {
|
|
8017
8025
|
throw new Error(`Codex binary not found: ${opts.binaryPath || "(empty)"}`);
|
|
8018
8026
|
}
|
|
8019
8027
|
const spawnFn = opts.spawnFn ?? defaultSpawn;
|
|
@@ -8077,21 +8085,21 @@ async function openCodexAppServer(opts) {
|
|
|
8077
8085
|
const terminateChild = async () => {
|
|
8078
8086
|
if (processExited) return;
|
|
8079
8087
|
const killTimeoutMs = opts.killTimeoutMs ?? 2e3;
|
|
8080
|
-
await new Promise((
|
|
8088
|
+
await new Promise((resolve12) => {
|
|
8081
8089
|
if (processExited) {
|
|
8082
|
-
|
|
8090
|
+
resolve12();
|
|
8083
8091
|
return;
|
|
8084
8092
|
}
|
|
8085
8093
|
const onExit = () => {
|
|
8086
8094
|
clearTimeout(t);
|
|
8087
|
-
|
|
8095
|
+
resolve12();
|
|
8088
8096
|
};
|
|
8089
8097
|
child.once("exit", onExit);
|
|
8090
8098
|
try {
|
|
8091
8099
|
child.kill("SIGTERM");
|
|
8092
8100
|
} catch {
|
|
8093
8101
|
child.removeListener("exit", onExit);
|
|
8094
|
-
|
|
8102
|
+
resolve12();
|
|
8095
8103
|
return;
|
|
8096
8104
|
}
|
|
8097
8105
|
const t = setTimeout(() => {
|
|
@@ -8103,7 +8111,7 @@ async function openCodexAppServer(opts) {
|
|
|
8103
8111
|
}
|
|
8104
8112
|
setTimeout(() => {
|
|
8105
8113
|
child.removeListener("exit", onExit);
|
|
8106
|
-
|
|
8114
|
+
resolve12();
|
|
8107
8115
|
}, 500);
|
|
8108
8116
|
}, killTimeoutMs);
|
|
8109
8117
|
});
|
|
@@ -8183,7 +8191,7 @@ async function openCodexAppServer(opts) {
|
|
|
8183
8191
|
failAll(safePublicError("Codex app-server read failed", readLoopError));
|
|
8184
8192
|
}
|
|
8185
8193
|
})();
|
|
8186
|
-
const request = (method, params, timeoutMs = DEFAULT_REQUEST_TIMEOUT_MS) => new Promise((
|
|
8194
|
+
const request = (method, params, timeoutMs = DEFAULT_REQUEST_TIMEOUT_MS) => new Promise((resolve12, reject) => {
|
|
8187
8195
|
if (closed) {
|
|
8188
8196
|
reject(new Error("Codex app-server connection closed"));
|
|
8189
8197
|
return;
|
|
@@ -8201,7 +8209,7 @@ async function openCodexAppServer(opts) {
|
|
|
8201
8209
|
pending.delete(id);
|
|
8202
8210
|
reject(new Error(`Codex app-server ${method} timed out after ${timeoutMs}ms`));
|
|
8203
8211
|
}, timeoutMs);
|
|
8204
|
-
pending.set(id, { resolve:
|
|
8212
|
+
pending.set(id, { resolve: resolve12, reject, timer });
|
|
8205
8213
|
try {
|
|
8206
8214
|
writeLine({ jsonrpc: "2.0", id, method, params: params ?? {} });
|
|
8207
8215
|
} catch (err) {
|
|
@@ -8213,9 +8221,9 @@ async function openCodexAppServer(opts) {
|
|
|
8213
8221
|
const notify = async (method, params) => {
|
|
8214
8222
|
writeLine({ jsonrpc: "2.0", method, params: params ?? {} });
|
|
8215
8223
|
};
|
|
8216
|
-
const nextNotification = (timeoutMs = 3e4) => new Promise((
|
|
8224
|
+
const nextNotification = (timeoutMs = 3e4) => new Promise((resolve12, reject) => {
|
|
8217
8225
|
if (notificationQueue.length) {
|
|
8218
|
-
|
|
8226
|
+
resolve12(notificationQueue.shift());
|
|
8219
8227
|
return;
|
|
8220
8228
|
}
|
|
8221
8229
|
if (readLoopError) {
|
|
@@ -8223,16 +8231,16 @@ async function openCodexAppServer(opts) {
|
|
|
8223
8231
|
return;
|
|
8224
8232
|
}
|
|
8225
8233
|
if (closed) {
|
|
8226
|
-
|
|
8234
|
+
resolve12(null);
|
|
8227
8235
|
return;
|
|
8228
8236
|
}
|
|
8229
8237
|
const timer = setTimeout(() => {
|
|
8230
8238
|
const idx = notificationWaiters.findIndex((w) => w.timer === timer);
|
|
8231
8239
|
if (idx >= 0) notificationWaiters.splice(idx, 1);
|
|
8232
8240
|
if (readLoopError) reject(readLoopError);
|
|
8233
|
-
else
|
|
8241
|
+
else resolve12(null);
|
|
8234
8242
|
}, timeoutMs);
|
|
8235
|
-
notificationWaiters.push({ resolve:
|
|
8243
|
+
notificationWaiters.push({ resolve: resolve12, reject, timer });
|
|
8236
8244
|
});
|
|
8237
8245
|
child.stdin.on("error", (err) => {
|
|
8238
8246
|
const publicErr = safePublicError("Codex app-server stdin error", err);
|
|
@@ -9436,7 +9444,7 @@ var init_agent_event_mapper2 = __esm({
|
|
|
9436
9444
|
|
|
9437
9445
|
// ../../packages/claude/src/resolve-sdk-binary.ts
|
|
9438
9446
|
import { createRequire } from "node:module";
|
|
9439
|
-
import { existsSync as
|
|
9447
|
+
import { existsSync as existsSync4 } from "node:fs";
|
|
9440
9448
|
function resolveSdkClaudeBinary() {
|
|
9441
9449
|
if (cached !== void 0) return cached;
|
|
9442
9450
|
try {
|
|
@@ -9451,7 +9459,7 @@ function resolveSdkClaudeBinary() {
|
|
|
9451
9459
|
let p = req.resolve(c);
|
|
9452
9460
|
if (p.includes("/app.asar/")) p = p.replace("/app.asar/", "/app.asar.unpacked/");
|
|
9453
9461
|
if (p.includes("\\app.asar\\")) p = p.replace("\\app.asar\\", "\\app.asar.unpacked\\");
|
|
9454
|
-
if (
|
|
9462
|
+
if (existsSync4(p)) {
|
|
9455
9463
|
cached = p;
|
|
9456
9464
|
return p;
|
|
9457
9465
|
}
|
|
@@ -9539,8 +9547,8 @@ var init_message_bridge = __esm({
|
|
|
9539
9547
|
if (this.closed) {
|
|
9540
9548
|
return Promise.resolve({ value: void 0, done: true });
|
|
9541
9549
|
}
|
|
9542
|
-
return new Promise((
|
|
9543
|
-
this.waiter = { resolve:
|
|
9550
|
+
return new Promise((resolve12) => {
|
|
9551
|
+
this.waiter = { resolve: resolve12 };
|
|
9544
9552
|
});
|
|
9545
9553
|
}
|
|
9546
9554
|
};
|
|
@@ -9550,7 +9558,7 @@ var init_message_bridge = __esm({
|
|
|
9550
9558
|
});
|
|
9551
9559
|
|
|
9552
9560
|
// ../../packages/claude/src/claude-live-session.ts
|
|
9553
|
-
import { existsSync as
|
|
9561
|
+
import { existsSync as existsSync5 } from "node:fs";
|
|
9554
9562
|
import { randomUUID } from "node:crypto";
|
|
9555
9563
|
import { query as sdkQuery2 } from "@anthropic-ai/claude-agent-sdk";
|
|
9556
9564
|
function buildLiveOptions(opts, onPermission, onQuestion, onPlan, signal, timing) {
|
|
@@ -9620,7 +9628,7 @@ function buildLiveOptions(opts, onPermission, onQuestion, onPlan, signal, timing
|
|
|
9620
9628
|
if (decision === "allow") return { behavior: "allow" };
|
|
9621
9629
|
return { behavior: "deny", message: "Permission denied by SuperOne node" };
|
|
9622
9630
|
};
|
|
9623
|
-
const binaryPath = (opts.binaryPath &&
|
|
9631
|
+
const binaryPath = (opts.binaryPath && existsSync5(opts.binaryPath) ? opts.binaryPath : null) ?? resolveSdkClaudeBinary() ?? void 0;
|
|
9624
9632
|
const effort = opts.effort === "low" || opts.effort === "medium" || opts.effort === "high" || opts.effort === "xhigh" || opts.effort === "max" ? opts.effort : void 0;
|
|
9625
9633
|
const env = opts.env ? { ...process.env, ...opts.env } : void 0;
|
|
9626
9634
|
const base = {
|
|
@@ -9716,8 +9724,8 @@ var init_claude_live_session = __esm({
|
|
|
9716
9724
|
planHandler;
|
|
9717
9725
|
timing = { pausedMs: 0 };
|
|
9718
9726
|
static open(opts) {
|
|
9719
|
-
const binary = (opts.binaryPath &&
|
|
9720
|
-
if (opts.binaryPath && !
|
|
9727
|
+
const binary = (opts.binaryPath && existsSync5(opts.binaryPath) ? opts.binaryPath : null) ?? resolveSdkClaudeBinary();
|
|
9728
|
+
if (opts.binaryPath && !existsSync5(opts.binaryPath)) {
|
|
9721
9729
|
throw new Error(`Claude binary not found: ${opts.binaryPath}`);
|
|
9722
9730
|
}
|
|
9723
9731
|
if (!binary && !opts.queryFn) {
|
|
@@ -9747,7 +9755,7 @@ var init_claude_live_session = __esm({
|
|
|
9747
9755
|
const sessionId = this.sdkSessionId || "";
|
|
9748
9756
|
const priorityNext = input.priorityNext !== false && this.active != null;
|
|
9749
9757
|
const msg = toUserMessage(input.content, sessionId, priorityNext);
|
|
9750
|
-
return new Promise((
|
|
9758
|
+
return new Promise((resolve12, reject) => {
|
|
9751
9759
|
if (input.signal?.aborted) {
|
|
9752
9760
|
reject(new Error("Claude turn interrupted"));
|
|
9753
9761
|
return;
|
|
@@ -9768,10 +9776,10 @@ var init_claude_live_session = __esm({
|
|
|
9768
9776
|
};
|
|
9769
9777
|
input.signal?.addEventListener("abort", onAbort, { once: true });
|
|
9770
9778
|
if (this.active) {
|
|
9771
|
-
this.pending.push({ tag, msg, input, resolve:
|
|
9779
|
+
this.pending.push({ tag, msg, input, resolve: resolve12, reject });
|
|
9772
9780
|
return;
|
|
9773
9781
|
}
|
|
9774
|
-
this.startTurn({ tag, msg, input, resolve:
|
|
9782
|
+
this.startTurn({ tag, msg, input, resolve: resolve12, reject });
|
|
9775
9783
|
});
|
|
9776
9784
|
}
|
|
9777
9785
|
async dispose() {
|
|
@@ -9913,16 +9921,16 @@ var init_claude_live_session = __esm({
|
|
|
9913
9921
|
});
|
|
9914
9922
|
|
|
9915
9923
|
// ../../packages/claude/src/fork-session.ts
|
|
9916
|
-
import { existsSync as
|
|
9924
|
+
import { existsSync as existsSync6, mkdirSync as mkdirSync3, readdirSync, realpathSync, renameSync } from "node:fs";
|
|
9917
9925
|
import { homedir as homedir2 } from "node:os";
|
|
9918
|
-
import { join as
|
|
9926
|
+
import { join as join4 } from "node:path";
|
|
9919
9927
|
import { forkSession as defaultSdkForkSession } from "@anthropic-ai/claude-agent-sdk";
|
|
9920
9928
|
function claudeProjectSlug(p) {
|
|
9921
9929
|
return p.replace(/[^a-zA-Z0-9]/g, "-");
|
|
9922
9930
|
}
|
|
9923
9931
|
function claudeProjectsDir(configDir) {
|
|
9924
|
-
const root = configDir || process.env.CLAUDE_CONFIG_DIR ||
|
|
9925
|
-
return
|
|
9932
|
+
const root = configDir || process.env.CLAUDE_CONFIG_DIR || join4(homedir2(), ".claude");
|
|
9933
|
+
return join4(root, "projects");
|
|
9926
9934
|
}
|
|
9927
9935
|
async function forkClaudeTranscript(input) {
|
|
9928
9936
|
const providerSessionId = input.providerSessionId?.trim();
|
|
@@ -9942,13 +9950,13 @@ async function forkClaudeTranscript(input) {
|
|
|
9942
9950
|
throw new Error("Claude forkSession did not return a session id");
|
|
9943
9951
|
}
|
|
9944
9952
|
const projectsDir = input.projectsDir ?? claudeProjectsDir();
|
|
9945
|
-
if (!
|
|
9953
|
+
if (!existsSync6(projectsDir)) {
|
|
9946
9954
|
throw new Error(`Claude projects dir not found: ${projectsDir}`);
|
|
9947
9955
|
}
|
|
9948
9956
|
let forkedFile = null;
|
|
9949
9957
|
for (const dir of readdirSync(projectsDir)) {
|
|
9950
|
-
const candidate =
|
|
9951
|
-
if (
|
|
9958
|
+
const candidate = join4(projectsDir, dir, `${newSdkId}.jsonl`);
|
|
9959
|
+
if (existsSync6(candidate)) {
|
|
9952
9960
|
forkedFile = candidate;
|
|
9953
9961
|
break;
|
|
9954
9962
|
}
|
|
@@ -9956,9 +9964,9 @@ async function forkClaudeTranscript(input) {
|
|
|
9956
9964
|
if (!forkedFile) {
|
|
9957
9965
|
throw new Error(`forked transcript ${newSdkId}.jsonl not found under ${projectsDir}`);
|
|
9958
9966
|
}
|
|
9959
|
-
const destDir =
|
|
9967
|
+
const destDir = join4(projectsDir, claudeProjectSlug(realpathSync(targetCwd)));
|
|
9960
9968
|
mkdirSync3(destDir, { recursive: true });
|
|
9961
|
-
const dest =
|
|
9969
|
+
const dest = join4(destDir, `${newSdkId}.jsonl`);
|
|
9962
9970
|
if (dest !== forkedFile) {
|
|
9963
9971
|
renameSync(forkedFile, dest);
|
|
9964
9972
|
}
|
|
@@ -11406,7 +11414,7 @@ var init_session_runtime = __esm({
|
|
|
11406
11414
|
eventType: SESSION_DURABLE_EVENT.hostActionRequested,
|
|
11407
11415
|
payload: { actionId: row.actionId }
|
|
11408
11416
|
});
|
|
11409
|
-
return new Promise((
|
|
11417
|
+
return new Promise((resolve12) => {
|
|
11410
11418
|
const remaining = Math.max(0, row.deadline - Date.now());
|
|
11411
11419
|
const timer = setTimeout(() => {
|
|
11412
11420
|
this.cancelHostActionInternal(row.actionId, "deadline_exceeded");
|
|
@@ -11433,7 +11441,7 @@ var init_session_runtime = __esm({
|
|
|
11433
11441
|
clearTimeout(timer);
|
|
11434
11442
|
for (const c of abortCleanups) c();
|
|
11435
11443
|
this.hostActionWaiters.delete(row.actionId);
|
|
11436
|
-
|
|
11444
|
+
resolve12(result);
|
|
11437
11445
|
},
|
|
11438
11446
|
timer
|
|
11439
11447
|
});
|
|
@@ -11474,14 +11482,14 @@ var init_session_runtime = __esm({
|
|
|
11474
11482
|
cursor: existing.length ? existing[existing.length - 1].sequence : this.hostActions.headSequence()
|
|
11475
11483
|
};
|
|
11476
11484
|
}
|
|
11477
|
-
await new Promise((
|
|
11485
|
+
await new Promise((resolve12) => {
|
|
11478
11486
|
let settled = false;
|
|
11479
11487
|
const done = () => {
|
|
11480
11488
|
if (settled) return;
|
|
11481
11489
|
settled = true;
|
|
11482
11490
|
this.hostActionPollWaiters.delete(done);
|
|
11483
11491
|
clearTimeout(timer);
|
|
11484
|
-
|
|
11492
|
+
resolve12();
|
|
11485
11493
|
};
|
|
11486
11494
|
const timer = setTimeout(done, waitMs);
|
|
11487
11495
|
this.hostActionPollWaiters.add(done);
|
|
@@ -11727,7 +11735,7 @@ var init_session_runtime = __esm({
|
|
|
11727
11735
|
if (session.pendingInteraction) {
|
|
11728
11736
|
this.rejectPendingPermission(session, "aborted");
|
|
11729
11737
|
}
|
|
11730
|
-
return new Promise((
|
|
11738
|
+
return new Promise((resolve12) => {
|
|
11731
11739
|
let settled = false;
|
|
11732
11740
|
session.pendingInteraction = interaction;
|
|
11733
11741
|
session.updatedAt = Date.now();
|
|
@@ -11773,7 +11781,7 @@ var init_session_runtime = __esm({
|
|
|
11773
11781
|
payload: { interactionId: interaction.interactionId, decision: "deny" }
|
|
11774
11782
|
});
|
|
11775
11783
|
}
|
|
11776
|
-
|
|
11784
|
+
resolve12(result.decision);
|
|
11777
11785
|
};
|
|
11778
11786
|
const timer = setTimeout(() => {
|
|
11779
11787
|
settle({ decision: "deny", reason: "timeout" });
|
|
@@ -11824,7 +11832,7 @@ var init_session_runtime = __esm({
|
|
|
11824
11832
|
this.rejectPendingPermission(session, "aborted");
|
|
11825
11833
|
}
|
|
11826
11834
|
const pending = { ...interaction, kind: "question" };
|
|
11827
|
-
return new Promise((
|
|
11835
|
+
return new Promise((resolve12) => {
|
|
11828
11836
|
let settled = false;
|
|
11829
11837
|
session.pendingInteraction = pending;
|
|
11830
11838
|
session.updatedAt = Date.now();
|
|
@@ -11867,7 +11875,7 @@ var init_session_runtime = __esm({
|
|
|
11867
11875
|
payload: { interactionId: pending.interactionId }
|
|
11868
11876
|
});
|
|
11869
11877
|
}
|
|
11870
|
-
|
|
11878
|
+
resolve12(result.answers);
|
|
11871
11879
|
};
|
|
11872
11880
|
const timer = setTimeout(() => {
|
|
11873
11881
|
settle({ answers: {}, reason: "timeout" });
|
|
@@ -11895,7 +11903,7 @@ var init_session_runtime = __esm({
|
|
|
11895
11903
|
this.rejectPendingPermission(session, "aborted");
|
|
11896
11904
|
}
|
|
11897
11905
|
const pending = { ...interaction, kind: "plan" };
|
|
11898
|
-
return new Promise((
|
|
11906
|
+
return new Promise((resolve12) => {
|
|
11899
11907
|
let settled = false;
|
|
11900
11908
|
session.pendingInteraction = pending;
|
|
11901
11909
|
session.updatedAt = Date.now();
|
|
@@ -11942,7 +11950,7 @@ var init_session_runtime = __esm({
|
|
|
11942
11950
|
payload: { interactionId: pending.interactionId, decision: "reject" }
|
|
11943
11951
|
});
|
|
11944
11952
|
}
|
|
11945
|
-
|
|
11953
|
+
resolve12({ decision: result.decision, options: result.options });
|
|
11946
11954
|
};
|
|
11947
11955
|
const timer = setTimeout(() => {
|
|
11948
11956
|
settle({ decision: "reject", reason: "timeout" });
|
|
@@ -12024,7 +12032,7 @@ var init_session_runtime = __esm({
|
|
|
12024
12032
|
Promise.allSettled(batch).then(() => {
|
|
12025
12033
|
settled = true;
|
|
12026
12034
|
}),
|
|
12027
|
-
new Promise((
|
|
12035
|
+
new Promise((resolve12) => setTimeout(resolve12, remaining))
|
|
12028
12036
|
]);
|
|
12029
12037
|
if (!settled && Date.now() >= deadline) break;
|
|
12030
12038
|
}
|
|
@@ -13636,12 +13644,12 @@ var init_resolve_service = __esm({
|
|
|
13636
13644
|
// ../../packages/shared/src/attachment-store.ts
|
|
13637
13645
|
import { mkdirSync as mkdirSync4, writeFileSync as writeFileSync2 } from "node:fs";
|
|
13638
13646
|
import { tmpdir } from "node:os";
|
|
13639
|
-
import { join as
|
|
13647
|
+
import { join as join5 } from "node:path";
|
|
13640
13648
|
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
13641
13649
|
function resolveAttachmentsDir() {
|
|
13642
13650
|
const override = process.env.SUPERONE_ATTACHMENTS_DIR?.trim();
|
|
13643
13651
|
if (override) return override;
|
|
13644
|
-
return
|
|
13652
|
+
return join5(tmpdir(), SUPERONE_ATTACHMENTS_DIR_NAME);
|
|
13645
13653
|
}
|
|
13646
13654
|
function extForAttachmentMime(mimeType) {
|
|
13647
13655
|
const m = mimeType.toLowerCase();
|
|
@@ -13678,7 +13686,7 @@ function persistAttachment(base643, mimeType, opts) {
|
|
|
13678
13686
|
const dir = resolveAttachmentsDir();
|
|
13679
13687
|
mkdirSync4(dir, { recursive: true });
|
|
13680
13688
|
const fileName = `${randomUUID5()}-${safeFileBase(opts?.name, mimeType)}`;
|
|
13681
|
-
const filePath =
|
|
13689
|
+
const filePath = join5(dir, fileName);
|
|
13682
13690
|
writeFileSync2(filePath, buf);
|
|
13683
13691
|
return filePath;
|
|
13684
13692
|
} catch {
|
|
@@ -13761,26 +13769,26 @@ var init_turn_attachments = __esm({
|
|
|
13761
13769
|
});
|
|
13762
13770
|
|
|
13763
13771
|
// ../../packages/runtime/src/fs/path-security.ts
|
|
13764
|
-
import { realpathSync as realpathSync2, existsSync as
|
|
13765
|
-
import { isAbsolute, join as
|
|
13772
|
+
import { realpathSync as realpathSync2, existsSync as existsSync7, lstatSync, statSync } from "node:fs";
|
|
13773
|
+
import { isAbsolute, join as join6, normalize, resolve, sep } from "node:path";
|
|
13766
13774
|
function resolveProjectPath(projectRoot2, relativePath) {
|
|
13767
13775
|
if (relativePath.includes("\0")) {
|
|
13768
13776
|
return { ok: false, reason: "null byte in path" };
|
|
13769
13777
|
}
|
|
13770
13778
|
let root = resolve(projectRoot2);
|
|
13771
13779
|
try {
|
|
13772
|
-
if (
|
|
13780
|
+
if (existsSync7(root)) root = realpathSync2(root);
|
|
13773
13781
|
} catch {
|
|
13774
13782
|
}
|
|
13775
13783
|
if (isAbsolute(relativePath)) {
|
|
13776
13784
|
return { ok: false, reason: "absolute paths are not allowed" };
|
|
13777
13785
|
}
|
|
13778
|
-
const candidate = normalize(
|
|
13786
|
+
const candidate = normalize(join6(root, relativePath));
|
|
13779
13787
|
if (candidate !== root && !candidate.startsWith(root + sep)) {
|
|
13780
13788
|
return { ok: false, reason: "path escapes project root" };
|
|
13781
13789
|
}
|
|
13782
13790
|
try {
|
|
13783
|
-
if (
|
|
13791
|
+
if (existsSync7(candidate)) {
|
|
13784
13792
|
const real = realpathSync2(candidate);
|
|
13785
13793
|
if (real !== root && !real.startsWith(root + sep)) {
|
|
13786
13794
|
return { ok: false, reason: "symlink escapes project root" };
|
|
@@ -13789,13 +13797,13 @@ function resolveProjectPath(projectRoot2, relativePath) {
|
|
|
13789
13797
|
}
|
|
13790
13798
|
let parent = resolve(candidate, "..");
|
|
13791
13799
|
while (parent === root || parent.startsWith(root + sep)) {
|
|
13792
|
-
if (
|
|
13800
|
+
if (existsSync7(parent)) {
|
|
13793
13801
|
const realParent = realpathSync2(parent);
|
|
13794
13802
|
if (realParent !== root && !realParent.startsWith(root + sep)) {
|
|
13795
13803
|
return { ok: false, reason: "parent symlink escapes project root" };
|
|
13796
13804
|
}
|
|
13797
13805
|
const remainder = candidate === parent ? "" : candidate.slice(parent.length + (candidate.startsWith(parent + sep) ? sep.length : 0));
|
|
13798
|
-
const absolutePath = remainder ?
|
|
13806
|
+
const absolutePath = remainder ? join6(realParent, remainder) : realParent;
|
|
13799
13807
|
if (absolutePath !== realParent && !absolutePath.startsWith(realParent + sep) && absolutePath !== root && !absolutePath.startsWith(root + sep)) {
|
|
13800
13808
|
return { ok: false, reason: "path escapes project root" };
|
|
13801
13809
|
}
|
|
@@ -13858,15 +13866,15 @@ var init_path_security = __esm({
|
|
|
13858
13866
|
});
|
|
13859
13867
|
|
|
13860
13868
|
// ../../packages/runtime/src/fs/list-files.ts
|
|
13861
|
-
import { existsSync as
|
|
13862
|
-
import { join as
|
|
13869
|
+
import { existsSync as existsSync8, readdirSync as readdirSync2, statSync as statSync2 } from "node:fs";
|
|
13870
|
+
import { join as join7 } from "node:path";
|
|
13863
13871
|
function listFilesUnderRoot(projectRoot2, opts) {
|
|
13864
13872
|
const startRel = opts?.relativePath?.trim() || ".";
|
|
13865
13873
|
const resolved = resolveProjectPath(projectRoot2, startRel);
|
|
13866
13874
|
if (!resolved.ok) {
|
|
13867
13875
|
throw Object.assign(new Error(resolved.reason), { code: "invalid_argument" });
|
|
13868
13876
|
}
|
|
13869
|
-
if (!
|
|
13877
|
+
if (!existsSync8(resolved.absolutePath)) {
|
|
13870
13878
|
throw Object.assign(new Error("path not found"), { code: "not_found" });
|
|
13871
13879
|
}
|
|
13872
13880
|
const st = statSync2(resolved.absolutePath);
|
|
@@ -13888,7 +13896,7 @@ function listFilesUnderRoot(projectRoot2, opts) {
|
|
|
13888
13896
|
for (const ent of ents) {
|
|
13889
13897
|
if (out.length >= maxFiles) return;
|
|
13890
13898
|
if (LIST_FILES_EXCLUDED.has(ent.name) || ent.name === ".DS_Store") continue;
|
|
13891
|
-
const abs =
|
|
13899
|
+
const abs = join7(absDir, ent.name);
|
|
13892
13900
|
const rel = relPrefix ? `${relPrefix}/${ent.name}` : ent.name;
|
|
13893
13901
|
const check2 = resolveProjectPath(projectRoot2, rel);
|
|
13894
13902
|
if (!check2.ok) continue;
|
|
@@ -13934,11 +13942,11 @@ var init_list_files = __esm({
|
|
|
13934
13942
|
});
|
|
13935
13943
|
|
|
13936
13944
|
// ../../packages/runtime/src/fs/skills-discover.ts
|
|
13937
|
-
import { existsSync as
|
|
13938
|
-
import { join as
|
|
13945
|
+
import { existsSync as existsSync9, readdirSync as readdirSync3, readFileSync as readFileSync3 } from "node:fs";
|
|
13946
|
+
import { join as join8 } from "node:path";
|
|
13939
13947
|
function safeReadText(path) {
|
|
13940
13948
|
try {
|
|
13941
|
-
return
|
|
13949
|
+
return readFileSync3(path, "utf8");
|
|
13942
13950
|
} catch {
|
|
13943
13951
|
return "";
|
|
13944
13952
|
}
|
|
@@ -13972,7 +13980,7 @@ function discoverClaudeSkillsAndCommands(projectRoot2, opts) {
|
|
|
13972
13980
|
const seenSkills = /* @__PURE__ */ new Set();
|
|
13973
13981
|
const seenCommands = /* @__PURE__ */ new Set();
|
|
13974
13982
|
const scanSkills = (dir, scope) => {
|
|
13975
|
-
if (!
|
|
13983
|
+
if (!existsSync9(dir)) return;
|
|
13976
13984
|
let ents;
|
|
13977
13985
|
try {
|
|
13978
13986
|
ents = readdirSync3(dir, { withFileTypes: true });
|
|
@@ -13981,8 +13989,8 @@ function discoverClaudeSkillsAndCommands(projectRoot2, opts) {
|
|
|
13981
13989
|
}
|
|
13982
13990
|
for (const ent of ents) {
|
|
13983
13991
|
if (!ent.isDirectory()) continue;
|
|
13984
|
-
const skillMd =
|
|
13985
|
-
if (!
|
|
13992
|
+
const skillMd = join8(dir, ent.name, "SKILL.md");
|
|
13993
|
+
if (!existsSync9(skillMd)) continue;
|
|
13986
13994
|
if (seenSkills.has(ent.name)) continue;
|
|
13987
13995
|
seenSkills.add(ent.name);
|
|
13988
13996
|
const fm = parseSimpleFrontmatter(safeReadText(skillMd));
|
|
@@ -13996,7 +14004,7 @@ function discoverClaudeSkillsAndCommands(projectRoot2, opts) {
|
|
|
13996
14004
|
}
|
|
13997
14005
|
};
|
|
13998
14006
|
const scanCommands = (dir, scope) => {
|
|
13999
|
-
if (!
|
|
14007
|
+
if (!existsSync9(dir)) return;
|
|
14000
14008
|
let ents;
|
|
14001
14009
|
try {
|
|
14002
14010
|
ents = readdirSync3(dir, { withFileTypes: true });
|
|
@@ -14008,7 +14016,7 @@ function discoverClaudeSkillsAndCommands(projectRoot2, opts) {
|
|
|
14008
14016
|
const name = ent.name.replace(/\.md$/, "");
|
|
14009
14017
|
if (seenCommands.has(name)) continue;
|
|
14010
14018
|
seenCommands.add(name);
|
|
14011
|
-
const content = safeReadText(
|
|
14019
|
+
const content = safeReadText(join8(dir, ent.name));
|
|
14012
14020
|
const fm = parseSimpleFrontmatter(content);
|
|
14013
14021
|
commands.push({
|
|
14014
14022
|
name,
|
|
@@ -14021,12 +14029,12 @@ function discoverClaudeSkillsAndCommands(projectRoot2, opts) {
|
|
|
14021
14029
|
};
|
|
14022
14030
|
const home = opts?.homeDir === void 0 ? process.env.HOME || process.env.USERPROFILE || "" : opts.homeDir || "";
|
|
14023
14031
|
if (home) {
|
|
14024
|
-
scanSkills(
|
|
14025
|
-
scanCommands(
|
|
14032
|
+
scanSkills(join8(home, ".claude", "skills"), "user");
|
|
14033
|
+
scanCommands(join8(home, ".claude", "commands"), "user");
|
|
14026
14034
|
}
|
|
14027
|
-
scanSkills(
|
|
14028
|
-
scanSkills(
|
|
14029
|
-
scanCommands(
|
|
14035
|
+
scanSkills(join8(projectRoot2, ".claude", "skills"), "project");
|
|
14036
|
+
scanSkills(join8(projectRoot2, ".agents", "skills"), "project");
|
|
14037
|
+
scanCommands(join8(projectRoot2, ".claude", "commands"), "project");
|
|
14030
14038
|
return { skills, commands };
|
|
14031
14039
|
}
|
|
14032
14040
|
var init_skills_discover = __esm({
|
|
@@ -14037,15 +14045,15 @@ var init_skills_discover = __esm({
|
|
|
14037
14045
|
|
|
14038
14046
|
// ../../packages/runtime/src/fs/skills-manage.ts
|
|
14039
14047
|
import {
|
|
14040
|
-
existsSync as
|
|
14048
|
+
existsSync as existsSync10,
|
|
14041
14049
|
mkdirSync as mkdirSync5,
|
|
14042
14050
|
readdirSync as readdirSync4,
|
|
14043
|
-
readFileSync as
|
|
14051
|
+
readFileSync as readFileSync4,
|
|
14044
14052
|
rmSync,
|
|
14045
14053
|
statSync as statSync3,
|
|
14046
14054
|
writeFileSync as writeFileSync3
|
|
14047
14055
|
} from "node:fs";
|
|
14048
|
-
import { basename, dirname as
|
|
14056
|
+
import { basename, dirname as dirname4, join as join9, resolve as resolve2, sep as sep2 } from "node:path";
|
|
14049
14057
|
import { homedir as osHomedir } from "node:os";
|
|
14050
14058
|
function homeOf(opts) {
|
|
14051
14059
|
return opts?.homeDir ?? osHomedir();
|
|
@@ -14053,11 +14061,11 @@ function homeOf(opts) {
|
|
|
14053
14061
|
function codexHomeOf(opts) {
|
|
14054
14062
|
if (opts?.codexHome) return opts.codexHome;
|
|
14055
14063
|
const env = process.env.CODEX_HOME?.trim();
|
|
14056
|
-
return env ||
|
|
14064
|
+
return env || join9(homeOf(opts), ".codex");
|
|
14057
14065
|
}
|
|
14058
14066
|
function parseFrontmatterFile(filePath) {
|
|
14059
14067
|
try {
|
|
14060
|
-
const content =
|
|
14068
|
+
const content = readFileSync4(filePath, "utf8");
|
|
14061
14069
|
const fm = parseSimpleFrontmatter(content);
|
|
14062
14070
|
let description = fm.description ?? "";
|
|
14063
14071
|
if (!description && content.startsWith("---")) {
|
|
@@ -14092,7 +14100,7 @@ function isDirLike(dirPath, entry) {
|
|
|
14092
14100
|
if (entry.isDirectory()) return true;
|
|
14093
14101
|
if (entry.isSymbolicLink()) {
|
|
14094
14102
|
try {
|
|
14095
|
-
return statSync3(
|
|
14103
|
+
return statSync3(join9(dirPath, entry.name)).isDirectory();
|
|
14096
14104
|
} catch {
|
|
14097
14105
|
return false;
|
|
14098
14106
|
}
|
|
@@ -14102,13 +14110,13 @@ function isDirLike(dirPath, entry) {
|
|
|
14102
14110
|
function getClaudeSkillDirs(cwd, opts) {
|
|
14103
14111
|
const home = homeOf(opts);
|
|
14104
14112
|
const dirs = [
|
|
14105
|
-
{ dir:
|
|
14106
|
-
{ dir:
|
|
14113
|
+
{ dir: join9(home, ".claude", "skills"), scope: "user" },
|
|
14114
|
+
{ dir: join9(cwd, ".claude", "skills"), scope: "project" }
|
|
14107
14115
|
];
|
|
14108
|
-
const pluginsFile =
|
|
14109
|
-
if (
|
|
14116
|
+
const pluginsFile = join9(home, ".claude", "plugins", "installed_plugins.json");
|
|
14117
|
+
if (existsSync10(pluginsFile)) {
|
|
14110
14118
|
try {
|
|
14111
|
-
const data = JSON.parse(
|
|
14119
|
+
const data = JSON.parse(readFileSync4(pluginsFile, "utf8"));
|
|
14112
14120
|
const plugins = data.plugins ?? {};
|
|
14113
14121
|
for (const [pluginKey, entries] of Object.entries(plugins)) {
|
|
14114
14122
|
const pluginName = pluginKey.split("@")[0] ?? pluginKey;
|
|
@@ -14118,7 +14126,7 @@ function getClaudeSkillDirs(cwd, opts) {
|
|
|
14118
14126
|
const isUser = entry.scope === "user";
|
|
14119
14127
|
if (!isUser && !isProject) continue;
|
|
14120
14128
|
dirs.push({
|
|
14121
|
-
dir:
|
|
14129
|
+
dir: join9(entry.installPath, "skills"),
|
|
14122
14130
|
scope: isUser ? "user" : "project",
|
|
14123
14131
|
namePrefix: `${pluginName}:`,
|
|
14124
14132
|
readOnly: true
|
|
@@ -14134,16 +14142,16 @@ function getCodexSkillDirs(cwd, opts) {
|
|
|
14134
14142
|
const home = homeOf(opts);
|
|
14135
14143
|
const cHome = codexHomeOf(opts);
|
|
14136
14144
|
const dirs = [
|
|
14137
|
-
{ dir:
|
|
14138
|
-
{ dir:
|
|
14139
|
-
{ dir:
|
|
14145
|
+
{ dir: join9(home, ".agents", "skills"), scope: "user" },
|
|
14146
|
+
{ dir: join9(cHome, "skills"), scope: "user" },
|
|
14147
|
+
{ dir: join9(cHome, "skills", ".system"), scope: "user", readOnly: true }
|
|
14140
14148
|
];
|
|
14141
14149
|
if (process.platform !== "win32") {
|
|
14142
|
-
dirs.push({ dir:
|
|
14150
|
+
dirs.push({ dir: join9("/etc", "codex", "skills"), scope: "user", readOnly: true });
|
|
14143
14151
|
}
|
|
14144
14152
|
dirs.push(
|
|
14145
|
-
{ dir:
|
|
14146
|
-
{ dir:
|
|
14153
|
+
{ dir: join9(cwd, ".agents", "skills"), scope: "project" },
|
|
14154
|
+
{ dir: join9(cwd, ".codex", "skills"), scope: "project" }
|
|
14147
14155
|
);
|
|
14148
14156
|
return dirs;
|
|
14149
14157
|
}
|
|
@@ -14151,7 +14159,7 @@ function getSkillDirs(provider, cwd, opts) {
|
|
|
14151
14159
|
return provider === "codex" ? getCodexSkillDirs(cwd, opts) : getClaudeSkillDirs(cwd, opts);
|
|
14152
14160
|
}
|
|
14153
14161
|
function walkSkills(root, relPrefix, depth, scope, seen, skills, namePrefix, readOnly) {
|
|
14154
|
-
const absDir = relPrefix ?
|
|
14162
|
+
const absDir = relPrefix ? join9(root, relPrefix) : root;
|
|
14155
14163
|
let entries;
|
|
14156
14164
|
try {
|
|
14157
14165
|
entries = readdirSync4(absDir, { withFileTypes: true });
|
|
@@ -14162,20 +14170,20 @@ function walkSkills(root, relPrefix, depth, scope, seen, skills, namePrefix, rea
|
|
|
14162
14170
|
if (entry.name.startsWith(".")) continue;
|
|
14163
14171
|
if (!isDirLike(absDir, entry)) continue;
|
|
14164
14172
|
const relPath = relPrefix ? `${relPrefix}/${entry.name}` : entry.name;
|
|
14165
|
-
const skillDir =
|
|
14166
|
-
if (
|
|
14173
|
+
const skillDir = join9(absDir, entry.name);
|
|
14174
|
+
if (existsSync10(join9(skillDir, "SKILL.md"))) {
|
|
14167
14175
|
const name = (namePrefix ?? "") + relPath;
|
|
14168
14176
|
const key = resolve2(skillDir);
|
|
14169
14177
|
if (!seen.has(key)) {
|
|
14170
14178
|
seen.add(key);
|
|
14171
|
-
const fm = parseFrontmatterFile(
|
|
14179
|
+
const fm = parseFrontmatterFile(join9(skillDir, "SKILL.md"));
|
|
14172
14180
|
skills.push({
|
|
14173
14181
|
name,
|
|
14174
14182
|
displayName: fm.name || entry.name,
|
|
14175
14183
|
scope,
|
|
14176
14184
|
description: fm.description,
|
|
14177
14185
|
argumentHint: fm.argumentHint || void 0,
|
|
14178
|
-
hasConfig:
|
|
14186
|
+
hasConfig: existsSync10(join9(skillDir, "config.json")),
|
|
14179
14187
|
sourcePath: skillDir,
|
|
14180
14188
|
...readOnly ? { builtin: true } : {}
|
|
14181
14189
|
});
|
|
@@ -14191,7 +14199,7 @@ function listManagedSkills(provider, cwd, opts) {
|
|
|
14191
14199
|
const skills = [];
|
|
14192
14200
|
const seen = /* @__PURE__ */ new Set();
|
|
14193
14201
|
for (const { dir, scope, namePrefix, readOnly } of dirs) {
|
|
14194
|
-
if (!
|
|
14202
|
+
if (!existsSync10(dir)) continue;
|
|
14195
14203
|
walkSkills(dir, "", 0, scope, seen, skills, namePrefix, readOnly);
|
|
14196
14204
|
}
|
|
14197
14205
|
return skills;
|
|
@@ -14208,16 +14216,16 @@ function scanDir(dirPath, depth = 0, seen = /* @__PURE__ */ new Set()) {
|
|
|
14208
14216
|
}
|
|
14209
14217
|
try {
|
|
14210
14218
|
return readdirSync4(dirPath, { withFileTypes: true }).filter((e) => !e.name.startsWith(".")).sort((a, b) => {
|
|
14211
|
-
const aDir = a.isDirectory() || a.isSymbolicLink() && statSync3(
|
|
14212
|
-
const bDir = b.isDirectory() || b.isSymbolicLink() && statSync3(
|
|
14219
|
+
const aDir = a.isDirectory() || a.isSymbolicLink() && statSync3(join9(dirPath, a.name)).isDirectory();
|
|
14220
|
+
const bDir = b.isDirectory() || b.isSymbolicLink() && statSync3(join9(dirPath, b.name)).isDirectory();
|
|
14213
14221
|
if (aDir !== bDir) return aDir ? -1 : 1;
|
|
14214
14222
|
return a.name.localeCompare(b.name);
|
|
14215
14223
|
}).map((e) => {
|
|
14216
|
-
const isDir = e.isDirectory() || e.isSymbolicLink() && statSync3(
|
|
14224
|
+
const isDir = e.isDirectory() || e.isSymbolicLink() && statSync3(join9(dirPath, e.name)).isDirectory();
|
|
14217
14225
|
return {
|
|
14218
14226
|
name: e.name,
|
|
14219
14227
|
isDirectory: isDir,
|
|
14220
|
-
...isDir ? { children: scanDir(
|
|
14228
|
+
...isDir ? { children: scanDir(join9(dirPath, e.name), depth + 1, seen) } : {}
|
|
14221
14229
|
};
|
|
14222
14230
|
});
|
|
14223
14231
|
} catch {
|
|
@@ -14236,8 +14244,8 @@ function getManagedSkill(provider, cwd, name, sourcePath, opts) {
|
|
|
14236
14244
|
const skillDir = resolveSkillDir(dir, dirName);
|
|
14237
14245
|
if (!skillDir) continue;
|
|
14238
14246
|
if (!isPathAtOrWithinAllowed(skillDir, [dir])) continue;
|
|
14239
|
-
const skillMd =
|
|
14240
|
-
if (!
|
|
14247
|
+
const skillMd = join9(skillDir, "SKILL.md");
|
|
14248
|
+
if (!existsSync10(skillMd)) continue;
|
|
14241
14249
|
const expectedName = (namePrefix ?? "") + dirName;
|
|
14242
14250
|
if (expectedName !== name) continue;
|
|
14243
14251
|
if (sourcePath && resolve2(skillDir) !== resolve2(sourcePath)) continue;
|
|
@@ -14248,7 +14256,7 @@ function getManagedSkill(provider, cwd, name, sourcePath, opts) {
|
|
|
14248
14256
|
scope,
|
|
14249
14257
|
description: fm.description,
|
|
14250
14258
|
argumentHint: fm.argumentHint || void 0,
|
|
14251
|
-
hasConfig:
|
|
14259
|
+
hasConfig: existsSync10(join9(skillDir, "config.json")),
|
|
14252
14260
|
sourcePath: sourcePath ?? skillDir,
|
|
14253
14261
|
files: scanDir(skillDir)
|
|
14254
14262
|
};
|
|
@@ -14264,16 +14272,16 @@ function readManagedSkillFile(provider, cwd, skillName, relativePath, sourcePath
|
|
|
14264
14272
|
const skillDir = resolveSkillDir(dir, dirName);
|
|
14265
14273
|
if (!skillDir) continue;
|
|
14266
14274
|
if (!isPathAtOrWithinAllowed(skillDir, [dir])) continue;
|
|
14267
|
-
if (!
|
|
14275
|
+
if (!existsSync10(join9(skillDir, "SKILL.md"))) continue;
|
|
14268
14276
|
const expectedName = (namePrefix ?? "") + dirName;
|
|
14269
14277
|
if (expectedName !== skillName) continue;
|
|
14270
14278
|
if (sourcePath && resolve2(skillDir) !== resolve2(sourcePath)) continue;
|
|
14271
14279
|
const resolved = resolve2(skillDir, relativePath);
|
|
14272
14280
|
if (resolved !== skillDir && !resolved.startsWith(skillDir + sep2)) return null;
|
|
14273
|
-
if (!
|
|
14281
|
+
if (!existsSync10(resolved) || statSync3(resolved).isDirectory()) return null;
|
|
14274
14282
|
if (!isPathAtOrWithinAllowed(resolved, [skillDir])) return null;
|
|
14275
14283
|
try {
|
|
14276
|
-
return
|
|
14284
|
+
return readFileSync4(resolved, "utf8");
|
|
14277
14285
|
} catch {
|
|
14278
14286
|
return null;
|
|
14279
14287
|
}
|
|
@@ -14318,7 +14326,7 @@ function deleteManagedSkill(provider, cwd, sourcePath, opts) {
|
|
|
14318
14326
|
code: "forbidden"
|
|
14319
14327
|
});
|
|
14320
14328
|
}
|
|
14321
|
-
if (!
|
|
14329
|
+
if (!existsSync10(join9(target, "SKILL.md"))) {
|
|
14322
14330
|
throw Object.assign(new Error("not a skill directory (missing SKILL.md)"), {
|
|
14323
14331
|
code: "not_found"
|
|
14324
14332
|
});
|
|
@@ -14352,8 +14360,8 @@ function installManagedSkill(provider, cwd, input, opts) {
|
|
|
14352
14360
|
code: "failed_precondition"
|
|
14353
14361
|
});
|
|
14354
14362
|
}
|
|
14355
|
-
const dest =
|
|
14356
|
-
if (
|
|
14363
|
+
const dest = join9(root.dir, input.name);
|
|
14364
|
+
if (existsSync10(dest)) {
|
|
14357
14365
|
throw Object.assign(new Error(`skill already exists: ${input.name}`), {
|
|
14358
14366
|
code: "conflict"
|
|
14359
14367
|
});
|
|
@@ -14379,21 +14387,21 @@ function installManagedSkill(provider, cwd, input, opts) {
|
|
|
14379
14387
|
code: "invalid_argument"
|
|
14380
14388
|
});
|
|
14381
14389
|
}
|
|
14382
|
-
mkdirSync5(
|
|
14390
|
+
mkdirSync5(dirname4(abs), { recursive: true });
|
|
14383
14391
|
writeFileSync3(abs, content, "utf8");
|
|
14384
14392
|
}
|
|
14385
14393
|
} catch (err) {
|
|
14386
14394
|
rmSync(dest, { recursive: true, force: true });
|
|
14387
14395
|
throw err;
|
|
14388
14396
|
}
|
|
14389
|
-
const fm = parseFrontmatterFile(
|
|
14397
|
+
const fm = parseFrontmatterFile(join9(dest, "SKILL.md"));
|
|
14390
14398
|
return {
|
|
14391
14399
|
name: input.name,
|
|
14392
14400
|
displayName: fm.name || input.name,
|
|
14393
14401
|
scope: input.scope,
|
|
14394
14402
|
description: fm.description,
|
|
14395
14403
|
argumentHint: fm.argumentHint || void 0,
|
|
14396
|
-
hasConfig:
|
|
14404
|
+
hasConfig: existsSync10(join9(dest, "config.json")),
|
|
14397
14405
|
sourcePath: dest
|
|
14398
14406
|
};
|
|
14399
14407
|
}
|
|
@@ -14410,31 +14418,31 @@ var init_skills_manage = __esm({
|
|
|
14410
14418
|
});
|
|
14411
14419
|
|
|
14412
14420
|
// ../../packages/runtime/src/fs/mcp-config-claude.ts
|
|
14413
|
-
import { existsSync as
|
|
14414
|
-
import { dirname as
|
|
14421
|
+
import { existsSync as existsSync11, mkdirSync as mkdirSync6, readFileSync as readFileSync5, writeFileSync as writeFileSync4 } from "node:fs";
|
|
14422
|
+
import { dirname as dirname5, join as join10 } from "node:path";
|
|
14415
14423
|
import { homedir as osHomedir2 } from "node:os";
|
|
14416
14424
|
function homeOf2(opts) {
|
|
14417
14425
|
return opts?.homeDir ?? osHomedir2();
|
|
14418
14426
|
}
|
|
14419
14427
|
function getUserConfigPath(opts) {
|
|
14420
|
-
return
|
|
14428
|
+
return join10(homeOf2(opts), ".claude.json");
|
|
14421
14429
|
}
|
|
14422
14430
|
function getProjectSettingsPath(cwd) {
|
|
14423
|
-
return
|
|
14431
|
+
return join10(cwd, ".claude", "settings.json");
|
|
14424
14432
|
}
|
|
14425
14433
|
function getProjectMcpJsonPath(cwd) {
|
|
14426
|
-
return
|
|
14434
|
+
return join10(cwd, ".mcp.json");
|
|
14427
14435
|
}
|
|
14428
14436
|
function readJsonFile(filePath) {
|
|
14429
|
-
if (!
|
|
14437
|
+
if (!existsSync11(filePath)) return {};
|
|
14430
14438
|
try {
|
|
14431
|
-
return JSON.parse(
|
|
14439
|
+
return JSON.parse(readFileSync5(filePath, "utf8"));
|
|
14432
14440
|
} catch {
|
|
14433
14441
|
return {};
|
|
14434
14442
|
}
|
|
14435
14443
|
}
|
|
14436
14444
|
function writeJsonFile(filePath, data) {
|
|
14437
|
-
mkdirSync6(
|
|
14445
|
+
mkdirSync6(dirname5(filePath), { recursive: true });
|
|
14438
14446
|
writeFileSync4(filePath, JSON.stringify(data, null, 2) + "\n", "utf8");
|
|
14439
14447
|
}
|
|
14440
14448
|
function extractServers(config2, scope) {
|
|
@@ -15464,8 +15472,8 @@ var init_dist = __esm({
|
|
|
15464
15472
|
});
|
|
15465
15473
|
|
|
15466
15474
|
// ../../packages/runtime/src/fs/mcp-config-codex.ts
|
|
15467
|
-
import { existsSync as
|
|
15468
|
-
import { dirname as
|
|
15475
|
+
import { existsSync as existsSync12, mkdirSync as mkdirSync7, readFileSync as readFileSync6, writeFileSync as writeFileSync5 } from "node:fs";
|
|
15476
|
+
import { dirname as dirname6, join as join11 } from "node:path";
|
|
15469
15477
|
import { homedir as osHomedir3 } from "node:os";
|
|
15470
15478
|
function homeOf3(opts) {
|
|
15471
15479
|
return opts?.homeDir ?? osHomedir3();
|
|
@@ -15473,21 +15481,21 @@ function homeOf3(opts) {
|
|
|
15473
15481
|
function codexHomeOf2(opts) {
|
|
15474
15482
|
if (opts?.codexHome) return opts.codexHome;
|
|
15475
15483
|
const env = process.env.CODEX_HOME?.trim();
|
|
15476
|
-
return env ||
|
|
15484
|
+
return env || join11(homeOf3(opts), ".codex");
|
|
15477
15485
|
}
|
|
15478
15486
|
function getCodexConfigPath(scope, cwd, opts) {
|
|
15479
|
-
return scope === "project" ?
|
|
15487
|
+
return scope === "project" ? join11(cwd, ".codex", "config.toml") : join11(codexHomeOf2(opts), "config.toml");
|
|
15480
15488
|
}
|
|
15481
15489
|
function readConfigFile(filePath) {
|
|
15482
|
-
if (!
|
|
15490
|
+
if (!existsSync12(filePath)) return {};
|
|
15483
15491
|
try {
|
|
15484
|
-
return parse(
|
|
15492
|
+
return parse(readFileSync6(filePath, "utf8"));
|
|
15485
15493
|
} catch {
|
|
15486
15494
|
return {};
|
|
15487
15495
|
}
|
|
15488
15496
|
}
|
|
15489
15497
|
function writeConfigFile(filePath, data) {
|
|
15490
|
-
mkdirSync7(
|
|
15498
|
+
mkdirSync7(dirname6(filePath), { recursive: true });
|
|
15491
15499
|
writeFileSync5(filePath, stringify(data), "utf8");
|
|
15492
15500
|
}
|
|
15493
15501
|
function parseConfigFile(filePath, scope) {
|
|
@@ -15516,8 +15524,8 @@ function parseConfigFile(filePath, scope) {
|
|
|
15516
15524
|
return configs;
|
|
15517
15525
|
}
|
|
15518
15526
|
function listCodexMcpConfigs(cwd, opts) {
|
|
15519
|
-
const userConfigs = parseConfigFile(
|
|
15520
|
-
const projectConfigs = parseConfigFile(
|
|
15527
|
+
const userConfigs = parseConfigFile(join11(codexHomeOf2(opts), "config.toml"), "user");
|
|
15528
|
+
const projectConfigs = parseConfigFile(join11(cwd, ".codex", "config.toml"), "project");
|
|
15521
15529
|
const merged = /* @__PURE__ */ new Map();
|
|
15522
15530
|
for (const config2 of userConfigs) merged.set(config2.name, config2);
|
|
15523
15531
|
for (const config2 of projectConfigs) merged.set(config2.name, config2);
|
|
@@ -15643,11 +15651,11 @@ var init_fs = __esm({
|
|
|
15643
15651
|
});
|
|
15644
15652
|
|
|
15645
15653
|
// src/session/claude-turn-runner.ts
|
|
15646
|
-
import { existsSync as
|
|
15654
|
+
import { existsSync as existsSync13 } from "node:fs";
|
|
15647
15655
|
function resolveClaudeBinaryPath(opts) {
|
|
15648
|
-
if (opts.binaryPath &&
|
|
15656
|
+
if (opts.binaryPath && existsSync13(opts.binaryPath)) return opts.binaryPath;
|
|
15649
15657
|
const status = opts.harnesses?.get("claude");
|
|
15650
|
-
if (status?.enabled && (status.state === "ready" || status.state === "needs_auth") && status.command &&
|
|
15658
|
+
if (status?.enabled && (status.state === "ready" || status.state === "needs_auth") && status.command && existsSync13(status.command)) {
|
|
15651
15659
|
return status.command;
|
|
15652
15660
|
}
|
|
15653
15661
|
if (!opts.skipSdkBinary) {
|
|
@@ -15655,7 +15663,7 @@ function resolveClaudeBinaryPath(opts) {
|
|
|
15655
15663
|
if (sdk) return sdk;
|
|
15656
15664
|
}
|
|
15657
15665
|
const fromEnv = process.env.SUPERONE_CLAUDE_BINARY?.trim();
|
|
15658
|
-
if (fromEnv &&
|
|
15666
|
+
if (fromEnv && existsSync13(fromEnv)) return fromEnv;
|
|
15659
15667
|
return null;
|
|
15660
15668
|
}
|
|
15661
15669
|
function isClaudeRuntimeRunnable() {
|
|
@@ -32987,12 +32995,12 @@ var init_jsonrpc = __esm({
|
|
|
32987
32995
|
const id = this.nextRequestId++;
|
|
32988
32996
|
let cancel = () => {
|
|
32989
32997
|
};
|
|
32990
|
-
const responsePromise = new Promise((
|
|
32998
|
+
const responsePromise = new Promise((resolve12, reject) => {
|
|
32991
32999
|
const pendingResponse = {
|
|
32992
33000
|
resolve: (response) => {
|
|
32993
33001
|
try {
|
|
32994
33002
|
const value = mapResponse ? mapResponse(response) : response;
|
|
32995
|
-
|
|
33003
|
+
resolve12(value);
|
|
32996
33004
|
} catch (error51) {
|
|
32997
33005
|
reject(error51);
|
|
32998
33006
|
}
|
|
@@ -33070,8 +33078,8 @@ var init_jsonrpc = __esm({
|
|
|
33070
33078
|
initialize(stream, handlers) {
|
|
33071
33079
|
this.stream = stream;
|
|
33072
33080
|
this.staticHandlers = handlers;
|
|
33073
|
-
this.closedPromise = new Promise((
|
|
33074
|
-
this.abortController.signal.addEventListener("abort", () =>
|
|
33081
|
+
this.closedPromise = new Promise((resolve12) => {
|
|
33082
|
+
this.abortController.signal.addEventListener("abort", () => resolve12());
|
|
33075
33083
|
});
|
|
33076
33084
|
void this.receive();
|
|
33077
33085
|
}
|
|
@@ -33975,8 +33983,8 @@ var init_acp = __esm({
|
|
|
33975
33983
|
if (this.failed) {
|
|
33976
33984
|
return Promise.reject(this.failure);
|
|
33977
33985
|
}
|
|
33978
|
-
return new Promise((
|
|
33979
|
-
this.waiters.push({ resolve:
|
|
33986
|
+
return new Promise((resolve12, reject) => {
|
|
33987
|
+
this.waiters.push({ resolve: resolve12, reject });
|
|
33980
33988
|
});
|
|
33981
33989
|
}
|
|
33982
33990
|
};
|
|
@@ -36775,7 +36783,7 @@ async function stopProcess(child, closed) {
|
|
|
36775
36783
|
signalProcess(child, "SIGTERM");
|
|
36776
36784
|
const stopped = await Promise.race([
|
|
36777
36785
|
closed.then(() => true),
|
|
36778
|
-
new Promise((
|
|
36786
|
+
new Promise((resolve12) => setTimeout(() => resolve12(false), KILL_ESCALATE_MS))
|
|
36779
36787
|
]);
|
|
36780
36788
|
if (stopped) return;
|
|
36781
36789
|
signalProcess(child, "SIGKILL");
|
|
@@ -36803,9 +36811,9 @@ function spawnAcpProcess(launch2) {
|
|
|
36803
36811
|
const output = Writable.toWeb(stdin);
|
|
36804
36812
|
const input = Readable.toWeb(stdout);
|
|
36805
36813
|
const stream = ndJsonStream(output, input);
|
|
36806
|
-
const closed = new Promise((
|
|
36814
|
+
const closed = new Promise((resolve12) => {
|
|
36807
36815
|
child.once("exit", (code, signal) => {
|
|
36808
|
-
|
|
36816
|
+
resolve12({ code, signal, stderr: stderrChunks.join("") });
|
|
36809
36817
|
});
|
|
36810
36818
|
});
|
|
36811
36819
|
let killPromise = null;
|
|
@@ -36986,7 +36994,7 @@ var init_run_turn = __esm({
|
|
|
36986
36994
|
});
|
|
36987
36995
|
|
|
36988
36996
|
// ../../packages/acp/src/simulated-runner.ts
|
|
36989
|
-
import { existsSync as
|
|
36997
|
+
import { existsSync as existsSync14 } from "node:fs";
|
|
36990
36998
|
function createSimulatedAcpTurnRunner(opts) {
|
|
36991
36999
|
return createSimulatedTurnRunner({
|
|
36992
37000
|
delayMs: opts?.delayMs ?? 15,
|
|
@@ -37000,7 +37008,7 @@ function resolveLaunch(opts) {
|
|
|
37000
37008
|
const fromEnv = process.env.SUPERONE_ACP_BINARY?.trim() || process.env.SUPERONE_ACP_COMMAND?.trim() || opts.binaryPath?.trim();
|
|
37001
37009
|
if (!fromEnv) return null;
|
|
37002
37010
|
if (fromEnv.includes("/") || fromEnv.includes("\\")) {
|
|
37003
|
-
if (!
|
|
37011
|
+
if (!existsSync14(fromEnv)) return null;
|
|
37004
37012
|
}
|
|
37005
37013
|
return {
|
|
37006
37014
|
command: fromEnv,
|
|
@@ -37064,7 +37072,7 @@ var init_serverSentEvents_gen = __esm({
|
|
|
37064
37072
|
"../../node_modules/@opencode-ai/sdk/dist/v2/gen/core/serverSentEvents.gen.js"() {
|
|
37065
37073
|
createSseClient = ({ onRequest, onSseError, onSseEvent, responseTransformer, responseValidator, sseDefaultRetryDelay, sseMaxRetryAttempts, sseMaxRetryDelay, sseSleepFn, url: url2, ...options }) => {
|
|
37066
37074
|
let lastEventId;
|
|
37067
|
-
const sleep = sseSleepFn ?? ((ms) => new Promise((
|
|
37075
|
+
const sleep = sseSleepFn ?? ((ms) => new Promise((resolve12) => setTimeout(resolve12, ms)));
|
|
37068
37076
|
const createStream = async function* () {
|
|
37069
37077
|
let retryDelay = sseDefaultRetryDelay ?? 3e3;
|
|
37070
37078
|
let attempt = 0;
|
|
@@ -42548,9 +42556,9 @@ var init_client2 = __esm({
|
|
|
42548
42556
|
}
|
|
42549
42557
|
});
|
|
42550
42558
|
|
|
42551
|
-
// ../../node_modules/
|
|
42559
|
+
// ../../node_modules/isexe/windows.js
|
|
42552
42560
|
var require_windows = __commonJS({
|
|
42553
|
-
"../../node_modules/
|
|
42561
|
+
"../../node_modules/isexe/windows.js"(exports, module) {
|
|
42554
42562
|
module.exports = isexe;
|
|
42555
42563
|
isexe.sync = sync;
|
|
42556
42564
|
var fs = __require("fs");
|
|
@@ -42588,9 +42596,9 @@ var require_windows = __commonJS({
|
|
|
42588
42596
|
}
|
|
42589
42597
|
});
|
|
42590
42598
|
|
|
42591
|
-
// ../../node_modules/
|
|
42599
|
+
// ../../node_modules/isexe/mode.js
|
|
42592
42600
|
var require_mode = __commonJS({
|
|
42593
|
-
"../../node_modules/
|
|
42601
|
+
"../../node_modules/isexe/mode.js"(exports, module) {
|
|
42594
42602
|
module.exports = isexe;
|
|
42595
42603
|
isexe.sync = sync;
|
|
42596
42604
|
var fs = __require("fs");
|
|
@@ -42621,9 +42629,9 @@ var require_mode = __commonJS({
|
|
|
42621
42629
|
}
|
|
42622
42630
|
});
|
|
42623
42631
|
|
|
42624
|
-
// ../../node_modules/
|
|
42632
|
+
// ../../node_modules/isexe/index.js
|
|
42625
42633
|
var require_isexe = __commonJS({
|
|
42626
|
-
"../../node_modules/
|
|
42634
|
+
"../../node_modules/isexe/index.js"(exports, module) {
|
|
42627
42635
|
var fs = __require("fs");
|
|
42628
42636
|
var core;
|
|
42629
42637
|
if (process.platform === "win32" || global.TESTING_WINDOWS) {
|
|
@@ -42642,12 +42650,12 @@ var require_isexe = __commonJS({
|
|
|
42642
42650
|
if (typeof Promise !== "function") {
|
|
42643
42651
|
throw new TypeError("callback not provided");
|
|
42644
42652
|
}
|
|
42645
|
-
return new Promise(function(
|
|
42653
|
+
return new Promise(function(resolve12, reject) {
|
|
42646
42654
|
isexe(path, options || {}, function(er, is) {
|
|
42647
42655
|
if (er) {
|
|
42648
42656
|
reject(er);
|
|
42649
42657
|
} else {
|
|
42650
|
-
|
|
42658
|
+
resolve12(is);
|
|
42651
42659
|
}
|
|
42652
42660
|
});
|
|
42653
42661
|
});
|
|
@@ -42676,9 +42684,9 @@ var require_isexe = __commonJS({
|
|
|
42676
42684
|
}
|
|
42677
42685
|
});
|
|
42678
42686
|
|
|
42679
|
-
// ../../node_modules/
|
|
42687
|
+
// ../../node_modules/which/which.js
|
|
42680
42688
|
var require_which = __commonJS({
|
|
42681
|
-
"../../node_modules/
|
|
42689
|
+
"../../node_modules/which/which.js"(exports, module) {
|
|
42682
42690
|
var isWindows = process.platform === "win32" || process.env.OSTYPE === "cygwin" || process.env.OSTYPE === "msys";
|
|
42683
42691
|
var path = __require("path");
|
|
42684
42692
|
var COLON = isWindows ? ";" : ":";
|
|
@@ -42713,27 +42721,27 @@ var require_which = __commonJS({
|
|
|
42713
42721
|
opt = {};
|
|
42714
42722
|
const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt);
|
|
42715
42723
|
const found = [];
|
|
42716
|
-
const step = (i) => new Promise((
|
|
42724
|
+
const step = (i) => new Promise((resolve12, reject) => {
|
|
42717
42725
|
if (i === pathEnv.length)
|
|
42718
|
-
return opt.all && found.length ?
|
|
42726
|
+
return opt.all && found.length ? resolve12(found) : reject(getNotFoundError(cmd));
|
|
42719
42727
|
const ppRaw = pathEnv[i];
|
|
42720
42728
|
const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
|
|
42721
42729
|
const pCmd = path.join(pathPart, cmd);
|
|
42722
42730
|
const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
|
|
42723
|
-
|
|
42731
|
+
resolve12(subStep(p, i, 0));
|
|
42724
42732
|
});
|
|
42725
|
-
const subStep = (p, i, ii) => new Promise((
|
|
42733
|
+
const subStep = (p, i, ii) => new Promise((resolve12, reject) => {
|
|
42726
42734
|
if (ii === pathExt.length)
|
|
42727
|
-
return
|
|
42735
|
+
return resolve12(step(i + 1));
|
|
42728
42736
|
const ext = pathExt[ii];
|
|
42729
42737
|
isexe(p + ext, { pathExt: pathExtExe }, (er, is) => {
|
|
42730
42738
|
if (!er && is) {
|
|
42731
42739
|
if (opt.all)
|
|
42732
42740
|
found.push(p + ext);
|
|
42733
42741
|
else
|
|
42734
|
-
return
|
|
42742
|
+
return resolve12(p + ext);
|
|
42735
42743
|
}
|
|
42736
|
-
return
|
|
42744
|
+
return resolve12(subStep(p, i, ii + 1));
|
|
42737
42745
|
});
|
|
42738
42746
|
});
|
|
42739
42747
|
return cb ? step(0).then((res) => cb(null, res), cb) : step(0);
|
|
@@ -43025,7 +43033,7 @@ var require_cross_spawn = __commonJS({
|
|
|
43025
43033
|
var cp = __require("child_process");
|
|
43026
43034
|
var parse4 = require_parse();
|
|
43027
43035
|
var enoent = require_enoent();
|
|
43028
|
-
function
|
|
43036
|
+
function spawn6(command, args, options) {
|
|
43029
43037
|
const parsed = parse4(command, args, options);
|
|
43030
43038
|
const spawned = cp.spawn(parsed.command, parsed.args, parsed.options);
|
|
43031
43039
|
enoent.hookChildProcess(spawned, parsed);
|
|
@@ -43037,8 +43045,8 @@ var require_cross_spawn = __commonJS({
|
|
|
43037
43045
|
result.error = result.error || enoent.verifyENOENTSync(result.status, parsed);
|
|
43038
43046
|
return result;
|
|
43039
43047
|
}
|
|
43040
|
-
module.exports =
|
|
43041
|
-
module.exports.spawn =
|
|
43048
|
+
module.exports = spawn6;
|
|
43049
|
+
module.exports.spawn = spawn6;
|
|
43042
43050
|
module.exports.sync = spawnSync2;
|
|
43043
43051
|
module.exports._parse = parse4;
|
|
43044
43052
|
module.exports._enoent = enoent;
|
|
@@ -43430,24 +43438,24 @@ var init_parse4 = __esm({
|
|
|
43430
43438
|
|
|
43431
43439
|
// ../../packages/opencode/src/server.ts
|
|
43432
43440
|
import { spawn as spawn3 } from "node:child_process";
|
|
43433
|
-
import { existsSync as
|
|
43441
|
+
import { existsSync as existsSync15 } from "node:fs";
|
|
43434
43442
|
import { homedir as homedir3 } from "node:os";
|
|
43435
|
-
import { delimiter, join as
|
|
43443
|
+
import { delimiter, join as join12 } from "node:path";
|
|
43436
43444
|
function appendOutput(current, chunk) {
|
|
43437
43445
|
const next = current + chunk.toString();
|
|
43438
43446
|
return next.length <= maxServerOutput ? next : next.slice(-maxServerOutput);
|
|
43439
43447
|
}
|
|
43440
43448
|
function defaultOpenCodeBinaryPath() {
|
|
43441
43449
|
const filename = process.platform === "win32" ? "opencode.exe" : "opencode";
|
|
43442
|
-
const installed =
|
|
43443
|
-
return
|
|
43450
|
+
const installed = join12(homedir3(), ".opencode", "bin", filename);
|
|
43451
|
+
return existsSync15(installed) ? installed : filename;
|
|
43444
43452
|
}
|
|
43445
43453
|
function openCodePath(pathEnv) {
|
|
43446
43454
|
const home = homedir3();
|
|
43447
43455
|
const paths = [
|
|
43448
|
-
|
|
43449
|
-
|
|
43450
|
-
|
|
43456
|
+
join12(home, ".opencode", "bin"),
|
|
43457
|
+
join12(home, ".local", "bin"),
|
|
43458
|
+
join12(home, ".bun", "bin"),
|
|
43451
43459
|
"/opt/homebrew/bin",
|
|
43452
43460
|
"/usr/local/bin",
|
|
43453
43461
|
...(pathEnv ?? "").split(delimiter)
|
|
@@ -43465,7 +43473,7 @@ async function stopChild(child, exited) {
|
|
|
43465
43473
|
signalChild(child, "SIGTERM");
|
|
43466
43474
|
const stopped = await Promise.race([
|
|
43467
43475
|
exited.then(() => true),
|
|
43468
|
-
new Promise((
|
|
43476
|
+
new Promise((resolve12) => setTimeout(() => resolve12(false), 1500))
|
|
43469
43477
|
]);
|
|
43470
43478
|
if (stopped) return;
|
|
43471
43479
|
signalChild(child, "SIGKILL");
|
|
@@ -43473,7 +43481,7 @@ async function stopChild(child, exited) {
|
|
|
43473
43481
|
}
|
|
43474
43482
|
async function waitForServer(child, exited, timeoutMs, signal) {
|
|
43475
43483
|
let output = "";
|
|
43476
|
-
return new Promise((
|
|
43484
|
+
return new Promise((resolve12, reject) => {
|
|
43477
43485
|
let settled = false;
|
|
43478
43486
|
const finish = (error51, url2) => {
|
|
43479
43487
|
if (settled) return;
|
|
@@ -43483,7 +43491,7 @@ async function waitForServer(child, exited, timeoutMs, signal) {
|
|
|
43483
43491
|
child.stderr.off("data", onData);
|
|
43484
43492
|
signal?.removeEventListener("abort", onAbort);
|
|
43485
43493
|
if (error51) reject(error51);
|
|
43486
|
-
else
|
|
43494
|
+
else resolve12(url2);
|
|
43487
43495
|
};
|
|
43488
43496
|
const onData = (chunk) => {
|
|
43489
43497
|
output = appendOutput(output, chunk);
|
|
@@ -43524,12 +43532,12 @@ async function startOpenCodeServer(opts) {
|
|
|
43524
43532
|
},
|
|
43525
43533
|
stdio: "pipe"
|
|
43526
43534
|
});
|
|
43527
|
-
const exited = new Promise((
|
|
43535
|
+
const exited = new Promise((resolve12) => {
|
|
43528
43536
|
let settled = false;
|
|
43529
43537
|
const finish = (code, signal) => {
|
|
43530
43538
|
if (settled) return;
|
|
43531
43539
|
settled = true;
|
|
43532
|
-
|
|
43540
|
+
resolve12({ code, signal });
|
|
43533
43541
|
};
|
|
43534
43542
|
child.once("exit", finish);
|
|
43535
43543
|
child.once("close", finish);
|
|
@@ -43554,7 +43562,7 @@ function isOpenCodeBinaryRunnable(binaryPath) {
|
|
|
43554
43562
|
const fromEnv = process.env.SUPERONE_OPENCODE_BINARY?.trim();
|
|
43555
43563
|
const candidate = binaryPath?.trim() || fromEnv;
|
|
43556
43564
|
if (!candidate) return false;
|
|
43557
|
-
return
|
|
43565
|
+
return existsSync15(candidate);
|
|
43558
43566
|
}
|
|
43559
43567
|
var OPENCODE_SERVE_ARGS, maxServerOutput;
|
|
43560
43568
|
var init_server2 = __esm({
|
|
@@ -43826,7 +43834,7 @@ var init_harness_runners = __esm({
|
|
|
43826
43834
|
});
|
|
43827
43835
|
|
|
43828
43836
|
// src/session/codex-turn-runner.ts
|
|
43829
|
-
import { existsSync as
|
|
43837
|
+
import { existsSync as existsSync16 } from "node:fs";
|
|
43830
43838
|
function mapCodexReasoningEffort(effort) {
|
|
43831
43839
|
if (!effort) return void 0;
|
|
43832
43840
|
const e = effort.trim().toLowerCase();
|
|
@@ -43837,18 +43845,18 @@ function mapCodexReasoningEffort(effort) {
|
|
|
43837
43845
|
return void 0;
|
|
43838
43846
|
}
|
|
43839
43847
|
function resolveCodexBinaryPath(opts) {
|
|
43840
|
-
if (opts.binaryPath &&
|
|
43848
|
+
if (opts.binaryPath && existsSync16(opts.binaryPath)) return opts.binaryPath;
|
|
43841
43849
|
const fromEnv = process.env.SUPERONE_CODEX_BINARY?.trim();
|
|
43842
|
-
if (fromEnv &&
|
|
43850
|
+
if (fromEnv && existsSync16(fromEnv)) return fromEnv;
|
|
43843
43851
|
const status = opts.harnesses?.get("codex");
|
|
43844
|
-
if (status?.enabled && (status.state === "ready" || status.state === "needs_auth") && status.command &&
|
|
43852
|
+
if (status?.enabled && (status.state === "ready" || status.state === "needs_auth") && status.command && existsSync16(status.command)) {
|
|
43845
43853
|
return status.command;
|
|
43846
43854
|
}
|
|
43847
43855
|
return null;
|
|
43848
43856
|
}
|
|
43849
43857
|
function isCodexBinaryOverrideRunnable() {
|
|
43850
43858
|
const fromEnv = process.env.SUPERONE_CODEX_BINARY?.trim();
|
|
43851
|
-
return Boolean(fromEnv &&
|
|
43859
|
+
return Boolean(fromEnv && existsSync16(fromEnv));
|
|
43852
43860
|
}
|
|
43853
43861
|
function createNodeCodexTurnRunner(opts) {
|
|
43854
43862
|
const simulatedCodex = createSimulatedCodexRunner();
|
|
@@ -43967,6 +43975,199 @@ var init_codex_turn_runner = __esm({
|
|
|
43967
43975
|
}
|
|
43968
43976
|
});
|
|
43969
43977
|
|
|
43978
|
+
// src/session/managed-harness-official.ts
|
|
43979
|
+
var managed_harness_official_exports = {};
|
|
43980
|
+
__export(managed_harness_official_exports, {
|
|
43981
|
+
OFFICIAL_CLAUDE_SDK_PACKAGE: () => OFFICIAL_CLAUDE_SDK_PACKAGE,
|
|
43982
|
+
OFFICIAL_CLAUDE_SDK_VERSION: () => OFFICIAL_CLAUDE_SDK_VERSION,
|
|
43983
|
+
OFFICIAL_CODEX_NPM_VERSION: () => OFFICIAL_CODEX_NPM_VERSION,
|
|
43984
|
+
OFFICIAL_CODEX_PACKAGE: () => OFFICIAL_CODEX_PACKAGE,
|
|
43985
|
+
claudePlatformPackageName: () => claudePlatformPackageName,
|
|
43986
|
+
installManagedFromOfficialNpm: () => installManagedFromOfficialNpm,
|
|
43987
|
+
managedNpmPrefix: () => managedNpmPrefix,
|
|
43988
|
+
officialPackageSpecs: () => officialPackageSpecs,
|
|
43989
|
+
resolveOfficialInstallBinary: () => resolveOfficialInstallBinary
|
|
43990
|
+
});
|
|
43991
|
+
import { existsSync as existsSync19, mkdirSync as mkdirSync9, readFileSync as readFileSync8, readdirSync as readdirSync5, statSync as statSync5 } from "node:fs";
|
|
43992
|
+
import { arch as osArch2, platform as osPlatform2 } from "node:os";
|
|
43993
|
+
import { join as join14, resolve as resolve4 } from "node:path";
|
|
43994
|
+
import { spawn as spawn4 } from "node:child_process";
|
|
43995
|
+
function managedNpmPrefix(nodeHome, harnessId) {
|
|
43996
|
+
return resolve4(nodeHome, "managed-npm", harnessId);
|
|
43997
|
+
}
|
|
43998
|
+
function claudePlatformPackageName() {
|
|
43999
|
+
const p = osPlatform2();
|
|
44000
|
+
const a = osArch2();
|
|
44001
|
+
if (a !== "arm64" && a !== "x64") {
|
|
44002
|
+
throw new Error(`unsupported arch for Claude Agent SDK: ${a}`);
|
|
44003
|
+
}
|
|
44004
|
+
if (p === "darwin") return `@anthropic-ai/claude-agent-sdk-darwin-${a}`;
|
|
44005
|
+
if (p === "win32") return `@anthropic-ai/claude-agent-sdk-win32-${a}`;
|
|
44006
|
+
if (p === "linux") {
|
|
44007
|
+
if (isMuslLinux()) return `@anthropic-ai/claude-agent-sdk-linux-${a}-musl`;
|
|
44008
|
+
return `@anthropic-ai/claude-agent-sdk-linux-${a}`;
|
|
44009
|
+
}
|
|
44010
|
+
throw new Error(`unsupported platform for Claude Agent SDK: ${p}`);
|
|
44011
|
+
}
|
|
44012
|
+
function isMuslLinux() {
|
|
44013
|
+
try {
|
|
44014
|
+
if (existsSync19("/etc/alpine-release")) return true;
|
|
44015
|
+
const lib = readdirSync5("/lib").some((n) => n.startsWith("ld-musl"));
|
|
44016
|
+
if (lib) return true;
|
|
44017
|
+
} catch {
|
|
44018
|
+
}
|
|
44019
|
+
return false;
|
|
44020
|
+
}
|
|
44021
|
+
function officialPackageSpecs(harnessId) {
|
|
44022
|
+
if (harnessId === "claude") {
|
|
44023
|
+
const ver2 = process.env.SUPERONE_CLAUDE_SDK_VERSION?.trim() || OFFICIAL_CLAUDE_SDK_VERSION;
|
|
44024
|
+
const platform2 = claudePlatformPackageName();
|
|
44025
|
+
return {
|
|
44026
|
+
runtimeVersion: ver2,
|
|
44027
|
+
specs: [`${OFFICIAL_CLAUDE_SDK_PACKAGE}@${ver2}`, `${platform2}@${ver2}`]
|
|
44028
|
+
};
|
|
44029
|
+
}
|
|
44030
|
+
const ver = process.env.SUPERONE_CODEX_NPM_VERSION?.trim() || OFFICIAL_CODEX_NPM_VERSION;
|
|
44031
|
+
return {
|
|
44032
|
+
runtimeVersion: ver,
|
|
44033
|
+
specs: [`${OFFICIAL_CODEX_PACKAGE}@${ver}`]
|
|
44034
|
+
};
|
|
44035
|
+
}
|
|
44036
|
+
function resolveOfficialInstallBinary(harnessId, prefix) {
|
|
44037
|
+
if (harnessId === "codex") {
|
|
44038
|
+
const candidates = [
|
|
44039
|
+
join14(prefix, "bin", "codex"),
|
|
44040
|
+
join14(prefix, "bin", "codex.cmd"),
|
|
44041
|
+
join14(prefix, "lib", "node_modules", "@openai", "codex", "bin", "codex.js")
|
|
44042
|
+
];
|
|
44043
|
+
for (const c of candidates) {
|
|
44044
|
+
if (existsSync19(c) && (c.endsWith(".js") || isExecutableFile(c))) return c;
|
|
44045
|
+
}
|
|
44046
|
+
return null;
|
|
44047
|
+
}
|
|
44048
|
+
const nm = join14(prefix, "lib", "node_modules");
|
|
44049
|
+
const scoped = join14(nm, "@anthropic-ai");
|
|
44050
|
+
try {
|
|
44051
|
+
if (existsSync19(scoped)) {
|
|
44052
|
+
const names = readdirSync5(scoped).filter((n) => n.startsWith("claude-agent-sdk-"));
|
|
44053
|
+
for (const n of names) {
|
|
44054
|
+
const ext = process.platform === "win32" ? ".exe" : "";
|
|
44055
|
+
const bin = join14(scoped, n, `claude${ext}`);
|
|
44056
|
+
if (existsSync19(bin)) return bin;
|
|
44057
|
+
}
|
|
44058
|
+
}
|
|
44059
|
+
} catch {
|
|
44060
|
+
}
|
|
44061
|
+
const direct = join14(
|
|
44062
|
+
nm,
|
|
44063
|
+
...claudePlatformPackageName().split("/"),
|
|
44064
|
+
process.platform === "win32" ? "claude.exe" : "claude"
|
|
44065
|
+
);
|
|
44066
|
+
if (existsSync19(direct)) return direct;
|
|
44067
|
+
return null;
|
|
44068
|
+
}
|
|
44069
|
+
function isExecutableFile(path) {
|
|
44070
|
+
try {
|
|
44071
|
+
const st = statSync5(path);
|
|
44072
|
+
if (!st.isFile()) return false;
|
|
44073
|
+
if (process.platform === "win32") return true;
|
|
44074
|
+
return (st.mode & 73) !== 0;
|
|
44075
|
+
} catch {
|
|
44076
|
+
return false;
|
|
44077
|
+
}
|
|
44078
|
+
}
|
|
44079
|
+
async function installManagedFromOfficialNpm(opts) {
|
|
44080
|
+
const { specs, runtimeVersion } = officialPackageSpecs(opts.harnessId);
|
|
44081
|
+
const prefix = managedNpmPrefix(opts.nodeHome, opts.harnessId);
|
|
44082
|
+
mkdirSync9(prefix, { recursive: true });
|
|
44083
|
+
const existing = resolveOfficialInstallBinary(opts.harnessId, prefix);
|
|
44084
|
+
if (existing) {
|
|
44085
|
+
return {
|
|
44086
|
+
harnessId: opts.harnessId,
|
|
44087
|
+
command: existing,
|
|
44088
|
+
runtimeVersion: readInstalledVersion(prefix, opts.harnessId) ?? runtimeVersion,
|
|
44089
|
+
source: "official-npm",
|
|
44090
|
+
packageSpec: specs.join(" "),
|
|
44091
|
+
installPrefix: prefix
|
|
44092
|
+
};
|
|
44093
|
+
}
|
|
44094
|
+
const runNpm = opts.runNpm ?? defaultRunNpm;
|
|
44095
|
+
await runNpm(
|
|
44096
|
+
["install", "--prefix", prefix, "--omit=dev", "--no-fund", "--no-audit", ...specs],
|
|
44097
|
+
prefix
|
|
44098
|
+
);
|
|
44099
|
+
const command = resolveOfficialInstallBinary(opts.harnessId, prefix);
|
|
44100
|
+
if (!command) {
|
|
44101
|
+
throw new Error(
|
|
44102
|
+
`official npm install of ${specs.join(" ")} succeeded but binary was not found under ${prefix}`
|
|
44103
|
+
);
|
|
44104
|
+
}
|
|
44105
|
+
return {
|
|
44106
|
+
harnessId: opts.harnessId,
|
|
44107
|
+
command,
|
|
44108
|
+
runtimeVersion: readInstalledVersion(prefix, opts.harnessId) ?? runtimeVersion,
|
|
44109
|
+
source: "official-npm",
|
|
44110
|
+
packageSpec: specs.join(" "),
|
|
44111
|
+
installPrefix: prefix
|
|
44112
|
+
};
|
|
44113
|
+
}
|
|
44114
|
+
function readInstalledVersion(prefix, harnessId) {
|
|
44115
|
+
try {
|
|
44116
|
+
const pkgPath = harnessId === "claude" ? join14(prefix, "lib", "node_modules", "@anthropic-ai", "claude-agent-sdk", "package.json") : join14(prefix, "lib", "node_modules", "@openai", "codex", "package.json");
|
|
44117
|
+
if (!existsSync19(pkgPath)) return null;
|
|
44118
|
+
const raw = JSON.parse(readFileSync8(pkgPath, "utf8"));
|
|
44119
|
+
return raw.version?.trim() || null;
|
|
44120
|
+
} catch {
|
|
44121
|
+
return null;
|
|
44122
|
+
}
|
|
44123
|
+
}
|
|
44124
|
+
function defaultRunNpm(args, cwd) {
|
|
44125
|
+
return new Promise((resolvePromise, reject) => {
|
|
44126
|
+
const child = spawn4("npm", args, {
|
|
44127
|
+
cwd,
|
|
44128
|
+
env: { ...process.env, npm_config_update_notifier: "false" },
|
|
44129
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
44130
|
+
});
|
|
44131
|
+
let stderr = "";
|
|
44132
|
+
child.stderr?.on("data", (c) => {
|
|
44133
|
+
stderr += c.toString();
|
|
44134
|
+
});
|
|
44135
|
+
child.on("error", (err) => {
|
|
44136
|
+
reject(
|
|
44137
|
+
new Error(
|
|
44138
|
+
`failed to spawn npm (${err.message}). Node.js/npm is required on the host for official harness install.`
|
|
44139
|
+
)
|
|
44140
|
+
);
|
|
44141
|
+
});
|
|
44142
|
+
const timer = setTimeout(() => {
|
|
44143
|
+
child.kill("SIGTERM");
|
|
44144
|
+
reject(new Error(`npm install timed out after 10m: npm ${args.join(" ")}`));
|
|
44145
|
+
}, 10 * 6e4);
|
|
44146
|
+
child.on("close", (code) => {
|
|
44147
|
+
clearTimeout(timer);
|
|
44148
|
+
if (code === 0) resolvePromise();
|
|
44149
|
+
else {
|
|
44150
|
+
reject(
|
|
44151
|
+
new Error(
|
|
44152
|
+
`npm install failed (exit ${code}): npm ${args.join(" ")}
|
|
44153
|
+
${stderr.slice(-1200)}`
|
|
44154
|
+
)
|
|
44155
|
+
);
|
|
44156
|
+
}
|
|
44157
|
+
});
|
|
44158
|
+
});
|
|
44159
|
+
}
|
|
44160
|
+
var OFFICIAL_CLAUDE_SDK_VERSION, OFFICIAL_CODEX_NPM_VERSION, OFFICIAL_CLAUDE_SDK_PACKAGE, OFFICIAL_CODEX_PACKAGE;
|
|
44161
|
+
var init_managed_harness_official = __esm({
|
|
44162
|
+
"src/session/managed-harness-official.ts"() {
|
|
44163
|
+
"use strict";
|
|
44164
|
+
OFFICIAL_CLAUDE_SDK_VERSION = "0.3.223";
|
|
44165
|
+
OFFICIAL_CODEX_NPM_VERSION = "0.146.1";
|
|
44166
|
+
OFFICIAL_CLAUDE_SDK_PACKAGE = "@anthropic-ai/claude-agent-sdk";
|
|
44167
|
+
OFFICIAL_CODEX_PACKAGE = "@openai/codex";
|
|
44168
|
+
}
|
|
44169
|
+
});
|
|
44170
|
+
|
|
43970
44171
|
// src/session/harness-fork.ts
|
|
43971
44172
|
var harness_fork_exports = {};
|
|
43972
44173
|
__export(harness_fork_exports, {
|
|
@@ -44414,11 +44615,11 @@ var require_codegen = __commonJS({
|
|
|
44414
44615
|
const rhs = this.rhs === void 0 ? "" : ` = ${this.rhs}`;
|
|
44415
44616
|
return `${varKind} ${this.name}${rhs};` + _n;
|
|
44416
44617
|
}
|
|
44417
|
-
optimizeNames(names,
|
|
44618
|
+
optimizeNames(names, constants3) {
|
|
44418
44619
|
if (!names[this.name.str])
|
|
44419
44620
|
return;
|
|
44420
44621
|
if (this.rhs)
|
|
44421
|
-
this.rhs = optimizeExpr(this.rhs, names,
|
|
44622
|
+
this.rhs = optimizeExpr(this.rhs, names, constants3);
|
|
44422
44623
|
return this;
|
|
44423
44624
|
}
|
|
44424
44625
|
get names() {
|
|
@@ -44435,10 +44636,10 @@ var require_codegen = __commonJS({
|
|
|
44435
44636
|
render({ _n }) {
|
|
44436
44637
|
return `${this.lhs} = ${this.rhs};` + _n;
|
|
44437
44638
|
}
|
|
44438
|
-
optimizeNames(names,
|
|
44639
|
+
optimizeNames(names, constants3) {
|
|
44439
44640
|
if (this.lhs instanceof code_1.Name && !names[this.lhs.str] && !this.sideEffects)
|
|
44440
44641
|
return;
|
|
44441
|
-
this.rhs = optimizeExpr(this.rhs, names,
|
|
44642
|
+
this.rhs = optimizeExpr(this.rhs, names, constants3);
|
|
44442
44643
|
return this;
|
|
44443
44644
|
}
|
|
44444
44645
|
get names() {
|
|
@@ -44499,8 +44700,8 @@ var require_codegen = __commonJS({
|
|
|
44499
44700
|
optimizeNodes() {
|
|
44500
44701
|
return `${this.code}` ? this : void 0;
|
|
44501
44702
|
}
|
|
44502
|
-
optimizeNames(names,
|
|
44503
|
-
this.code = optimizeExpr(this.code, names,
|
|
44703
|
+
optimizeNames(names, constants3) {
|
|
44704
|
+
this.code = optimizeExpr(this.code, names, constants3);
|
|
44504
44705
|
return this;
|
|
44505
44706
|
}
|
|
44506
44707
|
get names() {
|
|
@@ -44529,12 +44730,12 @@ var require_codegen = __commonJS({
|
|
|
44529
44730
|
}
|
|
44530
44731
|
return nodes.length > 0 ? this : void 0;
|
|
44531
44732
|
}
|
|
44532
|
-
optimizeNames(names,
|
|
44733
|
+
optimizeNames(names, constants3) {
|
|
44533
44734
|
const { nodes } = this;
|
|
44534
44735
|
let i = nodes.length;
|
|
44535
44736
|
while (i--) {
|
|
44536
44737
|
const n = nodes[i];
|
|
44537
|
-
if (n.optimizeNames(names,
|
|
44738
|
+
if (n.optimizeNames(names, constants3))
|
|
44538
44739
|
continue;
|
|
44539
44740
|
subtractNames(names, n.names);
|
|
44540
44741
|
nodes.splice(i, 1);
|
|
@@ -44587,12 +44788,12 @@ var require_codegen = __commonJS({
|
|
|
44587
44788
|
return void 0;
|
|
44588
44789
|
return this;
|
|
44589
44790
|
}
|
|
44590
|
-
optimizeNames(names,
|
|
44791
|
+
optimizeNames(names, constants3) {
|
|
44591
44792
|
var _a3;
|
|
44592
|
-
this.else = (_a3 = this.else) === null || _a3 === void 0 ? void 0 : _a3.optimizeNames(names,
|
|
44593
|
-
if (!(super.optimizeNames(names,
|
|
44793
|
+
this.else = (_a3 = this.else) === null || _a3 === void 0 ? void 0 : _a3.optimizeNames(names, constants3);
|
|
44794
|
+
if (!(super.optimizeNames(names, constants3) || this.else))
|
|
44594
44795
|
return;
|
|
44595
|
-
this.condition = optimizeExpr(this.condition, names,
|
|
44796
|
+
this.condition = optimizeExpr(this.condition, names, constants3);
|
|
44596
44797
|
return this;
|
|
44597
44798
|
}
|
|
44598
44799
|
get names() {
|
|
@@ -44615,10 +44816,10 @@ var require_codegen = __commonJS({
|
|
|
44615
44816
|
render(opts) {
|
|
44616
44817
|
return `for(${this.iteration})` + super.render(opts);
|
|
44617
44818
|
}
|
|
44618
|
-
optimizeNames(names,
|
|
44619
|
-
if (!super.optimizeNames(names,
|
|
44819
|
+
optimizeNames(names, constants3) {
|
|
44820
|
+
if (!super.optimizeNames(names, constants3))
|
|
44620
44821
|
return;
|
|
44621
|
-
this.iteration = optimizeExpr(this.iteration, names,
|
|
44822
|
+
this.iteration = optimizeExpr(this.iteration, names, constants3);
|
|
44622
44823
|
return this;
|
|
44623
44824
|
}
|
|
44624
44825
|
get names() {
|
|
@@ -44654,10 +44855,10 @@ var require_codegen = __commonJS({
|
|
|
44654
44855
|
render(opts) {
|
|
44655
44856
|
return `for(${this.varKind} ${this.name} ${this.loop} ${this.iterable})` + super.render(opts);
|
|
44656
44857
|
}
|
|
44657
|
-
optimizeNames(names,
|
|
44658
|
-
if (!super.optimizeNames(names,
|
|
44858
|
+
optimizeNames(names, constants3) {
|
|
44859
|
+
if (!super.optimizeNames(names, constants3))
|
|
44659
44860
|
return;
|
|
44660
|
-
this.iterable = optimizeExpr(this.iterable, names,
|
|
44861
|
+
this.iterable = optimizeExpr(this.iterable, names, constants3);
|
|
44661
44862
|
return this;
|
|
44662
44863
|
}
|
|
44663
44864
|
get names() {
|
|
@@ -44699,11 +44900,11 @@ var require_codegen = __commonJS({
|
|
|
44699
44900
|
(_b = this.finally) === null || _b === void 0 ? void 0 : _b.optimizeNodes();
|
|
44700
44901
|
return this;
|
|
44701
44902
|
}
|
|
44702
|
-
optimizeNames(names,
|
|
44903
|
+
optimizeNames(names, constants3) {
|
|
44703
44904
|
var _a3, _b;
|
|
44704
|
-
super.optimizeNames(names,
|
|
44705
|
-
(_a3 = this.catch) === null || _a3 === void 0 ? void 0 : _a3.optimizeNames(names,
|
|
44706
|
-
(_b = this.finally) === null || _b === void 0 ? void 0 : _b.optimizeNames(names,
|
|
44905
|
+
super.optimizeNames(names, constants3);
|
|
44906
|
+
(_a3 = this.catch) === null || _a3 === void 0 ? void 0 : _a3.optimizeNames(names, constants3);
|
|
44907
|
+
(_b = this.finally) === null || _b === void 0 ? void 0 : _b.optimizeNames(names, constants3);
|
|
44707
44908
|
return this;
|
|
44708
44909
|
}
|
|
44709
44910
|
get names() {
|
|
@@ -45004,7 +45205,7 @@ var require_codegen = __commonJS({
|
|
|
45004
45205
|
function addExprNames(names, from) {
|
|
45005
45206
|
return from instanceof code_1._CodeOrName ? addNames(names, from.names) : names;
|
|
45006
45207
|
}
|
|
45007
|
-
function optimizeExpr(expr, names,
|
|
45208
|
+
function optimizeExpr(expr, names, constants3) {
|
|
45008
45209
|
if (expr instanceof code_1.Name)
|
|
45009
45210
|
return replaceName(expr);
|
|
45010
45211
|
if (!canOptimize(expr))
|
|
@@ -45019,14 +45220,14 @@ var require_codegen = __commonJS({
|
|
|
45019
45220
|
return items;
|
|
45020
45221
|
}, []));
|
|
45021
45222
|
function replaceName(n) {
|
|
45022
|
-
const c =
|
|
45223
|
+
const c = constants3[n.str];
|
|
45023
45224
|
if (c === void 0 || names[n.str] !== 1)
|
|
45024
45225
|
return n;
|
|
45025
45226
|
delete names[n.str];
|
|
45026
45227
|
return c;
|
|
45027
45228
|
}
|
|
45028
45229
|
function canOptimize(e) {
|
|
45029
|
-
return e instanceof code_1._Code && e._items.some((c) => c instanceof code_1.Name && names[c.str] === 1 &&
|
|
45230
|
+
return e instanceof code_1._Code && e._items.some((c) => c instanceof code_1.Name && names[c.str] === 1 && constants3[c.str] !== void 0);
|
|
45030
45231
|
}
|
|
45031
45232
|
}
|
|
45032
45233
|
function subtractNames(names, from) {
|
|
@@ -46988,7 +47189,7 @@ var require_compile = __commonJS({
|
|
|
46988
47189
|
const schOrFunc = root.refs[ref];
|
|
46989
47190
|
if (schOrFunc)
|
|
46990
47191
|
return schOrFunc;
|
|
46991
|
-
let _sch =
|
|
47192
|
+
let _sch = resolve12.call(this, root, ref);
|
|
46992
47193
|
if (_sch === void 0) {
|
|
46993
47194
|
const schema = (_a3 = root.localRefs) === null || _a3 === void 0 ? void 0 : _a3[ref];
|
|
46994
47195
|
const { schemaId } = this.opts;
|
|
@@ -47015,7 +47216,7 @@ var require_compile = __commonJS({
|
|
|
47015
47216
|
function sameSchemaEnv(s1, s2) {
|
|
47016
47217
|
return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId;
|
|
47017
47218
|
}
|
|
47018
|
-
function
|
|
47219
|
+
function resolve12(root, ref) {
|
|
47019
47220
|
let sch;
|
|
47020
47221
|
while (typeof (sch = this.refs[ref]) == "string")
|
|
47021
47222
|
ref = sch;
|
|
@@ -47646,7 +47847,7 @@ var require_fast_uri = __commonJS({
|
|
|
47646
47847
|
}
|
|
47647
47848
|
return uri;
|
|
47648
47849
|
}
|
|
47649
|
-
function
|
|
47850
|
+
function resolve12(baseURI, relativeURI, options) {
|
|
47650
47851
|
const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
|
|
47651
47852
|
const resolved = resolveComponent(parse4(baseURI, schemelessOptions), parse4(relativeURI, schemelessOptions), schemelessOptions, true);
|
|
47652
47853
|
schemelessOptions.skipEscape = true;
|
|
@@ -47904,7 +48105,7 @@ var require_fast_uri = __commonJS({
|
|
|
47904
48105
|
var fastUri = {
|
|
47905
48106
|
SCHEMES,
|
|
47906
48107
|
normalize: normalize2,
|
|
47907
|
-
resolve:
|
|
48108
|
+
resolve: resolve12,
|
|
47908
48109
|
resolveComponent,
|
|
47909
48110
|
equal,
|
|
47910
48111
|
serialize,
|
|
@@ -50895,7 +51096,7 @@ var require_dist = __commonJS({
|
|
|
50895
51096
|
|
|
50896
51097
|
// src/cli.ts
|
|
50897
51098
|
import { homedir as homedir7 } from "node:os";
|
|
50898
|
-
import { resolve as
|
|
51099
|
+
import { resolve as resolve11 } from "node:path";
|
|
50899
51100
|
|
|
50900
51101
|
// src/config.ts
|
|
50901
51102
|
import { homedir } from "node:os";
|
|
@@ -50929,10 +51130,59 @@ function nodePaths(nodeHome) {
|
|
|
50929
51130
|
};
|
|
50930
51131
|
}
|
|
50931
51132
|
|
|
51133
|
+
// src/cli-release-version.ts
|
|
51134
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
51135
|
+
import { dirname, join as join2 } from "node:path";
|
|
51136
|
+
import { fileURLToPath } from "node:url";
|
|
51137
|
+
function resolveCliReleaseVersion() {
|
|
51138
|
+
const fromEnv = process.env.SUPERONE_CLI_VERSION?.trim();
|
|
51139
|
+
if (fromEnv) return fromEnv;
|
|
51140
|
+
if ("0.50.0-alpha".trim()) {
|
|
51141
|
+
return "0.50.0-alpha".trim();
|
|
51142
|
+
}
|
|
51143
|
+
const fromDist = readDistManifestVersion();
|
|
51144
|
+
if (fromDist) return fromDist;
|
|
51145
|
+
const fromRepo = readMonorepoPackageVersion();
|
|
51146
|
+
if (fromRepo) return fromRepo;
|
|
51147
|
+
throw new Error(
|
|
51148
|
+
"unable to determine CLI version for harness release coupling (set SUPERONE_CLI_VERSION or use a built dist with MANIFEST.json)"
|
|
51149
|
+
);
|
|
51150
|
+
}
|
|
51151
|
+
function readDistManifestVersion() {
|
|
51152
|
+
try {
|
|
51153
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
51154
|
+
const candidates = [
|
|
51155
|
+
join2(here, "..", "MANIFEST.json"),
|
|
51156
|
+
join2(here, "MANIFEST.json"),
|
|
51157
|
+
join2(here, "..", "..", "MANIFEST.json")
|
|
51158
|
+
];
|
|
51159
|
+
for (const p of candidates) {
|
|
51160
|
+
if (!existsSync(p)) continue;
|
|
51161
|
+
const raw = JSON.parse(readFileSync(p, "utf8"));
|
|
51162
|
+
if (typeof raw.version === "string" && raw.version.trim()) return raw.version.trim();
|
|
51163
|
+
}
|
|
51164
|
+
} catch {
|
|
51165
|
+
return null;
|
|
51166
|
+
}
|
|
51167
|
+
return null;
|
|
51168
|
+
}
|
|
51169
|
+
function readMonorepoPackageVersion() {
|
|
51170
|
+
try {
|
|
51171
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
51172
|
+
const rootPkg = join2(here, "..", "..", "..", "package.json");
|
|
51173
|
+
if (!existsSync(rootPkg)) return null;
|
|
51174
|
+
const raw = JSON.parse(readFileSync(rootPkg, "utf8"));
|
|
51175
|
+
if (typeof raw.version === "string" && raw.version.trim()) return raw.version.trim();
|
|
51176
|
+
} catch {
|
|
51177
|
+
return null;
|
|
51178
|
+
}
|
|
51179
|
+
return null;
|
|
51180
|
+
}
|
|
51181
|
+
|
|
50932
51182
|
// src/identity.ts
|
|
50933
|
-
import { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
51183
|
+
import { chmodSync, existsSync as existsSync2, mkdirSync, readFileSync as readFileSync2, writeFileSync } from "node:fs";
|
|
50934
51184
|
import { hostname, userInfo } from "node:os";
|
|
50935
|
-
import { dirname, join as
|
|
51185
|
+
import { dirname as dirname2, join as join3 } from "node:path";
|
|
50936
51186
|
import { createPublicKey as createPublicKey2 } from "node:crypto";
|
|
50937
51187
|
|
|
50938
51188
|
// ../../packages/runtime/src/crypto/crypto-util.ts
|
|
@@ -51035,7 +51285,7 @@ function ensureDir(path, mode = 448) {
|
|
|
51035
51285
|
}
|
|
51036
51286
|
}
|
|
51037
51287
|
function writeSecretFile(path, content) {
|
|
51038
|
-
ensureDir(
|
|
51288
|
+
ensureDir(dirname2(path));
|
|
51039
51289
|
writeFileSync(path, content, { encoding: "utf8", mode: 384 });
|
|
51040
51290
|
try {
|
|
51041
51291
|
chmodSync(path, 384);
|
|
@@ -51057,8 +51307,8 @@ function loadOrCreateIdentity(nodeHome, label) {
|
|
|
51057
51307
|
ensureDir(paths.secretsDir);
|
|
51058
51308
|
ensureDir(paths.logsDir);
|
|
51059
51309
|
let environmentId;
|
|
51060
|
-
if (
|
|
51061
|
-
environmentId =
|
|
51310
|
+
if (existsSync2(paths.environmentId)) {
|
|
51311
|
+
environmentId = readFileSync2(paths.environmentId, "utf8").trim();
|
|
51062
51312
|
if (!environmentId) {
|
|
51063
51313
|
environmentId = crypto.randomUUID();
|
|
51064
51314
|
writeSecretFile(paths.environmentId, `${environmentId}
|
|
@@ -51070,8 +51320,8 @@ function loadOrCreateIdentity(nodeHome, label) {
|
|
|
51070
51320
|
`);
|
|
51071
51321
|
}
|
|
51072
51322
|
let keyPair;
|
|
51073
|
-
if (
|
|
51074
|
-
const privateKeyPem =
|
|
51323
|
+
if (existsSync2(paths.instanceKey)) {
|
|
51324
|
+
const privateKeyPem = readFileSync2(paths.instanceKey, "utf8");
|
|
51075
51325
|
const privateKey = loadPrivateKey(privateKeyPem);
|
|
51076
51326
|
const publicKey = createPublicKey2(privateKey);
|
|
51077
51327
|
const publicKeyPem = publicKey.export({ type: "spki", format: "pem" }).toString();
|
|
@@ -51087,11 +51337,11 @@ function loadOrCreateIdentity(nodeHome, label) {
|
|
|
51087
51337
|
writeSecretFile(paths.instanceKey, keyPair.privateKeyPem);
|
|
51088
51338
|
}
|
|
51089
51339
|
const bindingHash = computeBindingHash(nodeHome);
|
|
51090
|
-
const bindingPath =
|
|
51340
|
+
const bindingPath = join3(paths.secretsDir, "binding-hash");
|
|
51091
51341
|
let persistedBindingHash = null;
|
|
51092
51342
|
let identityConflict = false;
|
|
51093
|
-
if (
|
|
51094
|
-
persistedBindingHash =
|
|
51343
|
+
if (existsSync2(bindingPath)) {
|
|
51344
|
+
persistedBindingHash = readFileSync2(bindingPath, "utf8").trim() || null;
|
|
51095
51345
|
if (persistedBindingHash && persistedBindingHash !== bindingHash) {
|
|
51096
51346
|
identityConflict = true;
|
|
51097
51347
|
}
|
|
@@ -51122,7 +51372,7 @@ function regenerateIdentity(nodeHome, label) {
|
|
|
51122
51372
|
const keyPair = generateEd25519KeyPair();
|
|
51123
51373
|
writeSecretFile(paths.instanceKey, keyPair.privateKeyPem);
|
|
51124
51374
|
const bindingHash = computeBindingHash(nodeHome);
|
|
51125
|
-
writeSecretFile(
|
|
51375
|
+
writeSecretFile(join3(paths.secretsDir, "binding-hash"), `${bindingHash}
|
|
51126
51376
|
`);
|
|
51127
51377
|
return {
|
|
51128
51378
|
environmentId,
|
|
@@ -51138,7 +51388,7 @@ function regenerateIdentity(nodeHome, label) {
|
|
|
51138
51388
|
}
|
|
51139
51389
|
|
|
51140
51390
|
// src/runtime.ts
|
|
51141
|
-
import { existsSync as
|
|
51391
|
+
import { existsSync as existsSync28, readFileSync as readFileSync11, writeFileSync as writeFileSync10 } from "node:fs";
|
|
51142
51392
|
|
|
51143
51393
|
// src/auth/auth-service.ts
|
|
51144
51394
|
init_environment();
|
|
@@ -51455,7 +51705,7 @@ var AuthService = class {
|
|
|
51455
51705
|
// src/db/database.ts
|
|
51456
51706
|
import Database from "better-sqlite3";
|
|
51457
51707
|
import { mkdirSync as mkdirSync2 } from "node:fs";
|
|
51458
|
-
import { dirname as
|
|
51708
|
+
import { dirname as dirname3 } from "node:path";
|
|
51459
51709
|
|
|
51460
51710
|
// src/db/schema.ts
|
|
51461
51711
|
var SCHEMA_SQL = `
|
|
@@ -51651,7 +51901,7 @@ var SCHEMA_GENERATION = 1;
|
|
|
51651
51901
|
|
|
51652
51902
|
// src/db/database.ts
|
|
51653
51903
|
function openNodeDatabase(dbPath) {
|
|
51654
|
-
mkdirSync2(
|
|
51904
|
+
mkdirSync2(dirname3(dbPath), { recursive: true });
|
|
51655
51905
|
const db = new Database(dbPath);
|
|
51656
51906
|
db.pragma("journal_mode = WAL");
|
|
51657
51907
|
db.pragma("foreign_keys = ON");
|
|
@@ -51824,13 +52074,13 @@ init_claude_turn_runner();
|
|
|
51824
52074
|
init_claude_turn_runner();
|
|
51825
52075
|
init_codex_turn_runner();
|
|
51826
52076
|
init_resolve_service();
|
|
51827
|
-
import { existsSync as
|
|
52077
|
+
import { existsSync as existsSync17 } from "node:fs";
|
|
51828
52078
|
function commandExists(command) {
|
|
51829
|
-
return Boolean(command &&
|
|
52079
|
+
return Boolean(command && existsSync17(command));
|
|
51830
52080
|
}
|
|
51831
52081
|
function envBinaryExists(envName) {
|
|
51832
52082
|
const v = process.env[envName]?.trim();
|
|
51833
|
-
return Boolean(v &&
|
|
52083
|
+
return Boolean(v && existsSync17(v));
|
|
51834
52084
|
}
|
|
51835
52085
|
function assertSessionHarnessRuntimeReady(sessionHarnessId, harnesses) {
|
|
51836
52086
|
const id = sessionHarnessId === "acp" ? "acp" : sessionHarnessId;
|
|
@@ -52000,10 +52250,675 @@ function isAuthSatisfied(id, providers) {
|
|
|
52000
52250
|
};
|
|
52001
52251
|
}
|
|
52002
52252
|
|
|
52253
|
+
// src/session/harness-enable.ts
|
|
52254
|
+
init_environment();
|
|
52255
|
+
init_src2();
|
|
52256
|
+
import { accessSync, constants, existsSync as existsSync20, realpathSync as realpathSync3, statSync as statSync6 } from "node:fs";
|
|
52257
|
+
import { isAbsolute as isAbsolute2, resolve as resolve5 } from "node:path";
|
|
52258
|
+
|
|
52259
|
+
// src/session/managed-harness-release.ts
|
|
52260
|
+
import {
|
|
52261
|
+
copyFileSync,
|
|
52262
|
+
createReadStream,
|
|
52263
|
+
existsSync as existsSync18,
|
|
52264
|
+
mkdirSync as mkdirSync8,
|
|
52265
|
+
mkdtempSync,
|
|
52266
|
+
readFileSync as readFileSync7,
|
|
52267
|
+
renameSync as renameSync2,
|
|
52268
|
+
rmSync as rmSync2,
|
|
52269
|
+
statSync as statSync4,
|
|
52270
|
+
writeFileSync as writeFileSync6
|
|
52271
|
+
} from "node:fs";
|
|
52272
|
+
import { createHash as createHash3, randomBytes as randomBytes3 } from "node:crypto";
|
|
52273
|
+
import { dirname as dirname7, join as join13, relative, resolve as resolve3, sep as sep3 } from "node:path";
|
|
52274
|
+
import { arch as osArch, platform as osPlatform } from "node:os";
|
|
52275
|
+
var MANAGED_PAYLOAD_BASENAME = "payload.bin";
|
|
52276
|
+
var MANAGED_META_BASENAME = "artifact.json";
|
|
52277
|
+
var MANAGED_CURRENT_BASENAME = "current";
|
|
52278
|
+
var MAX_SEGMENT_LEN = 64;
|
|
52279
|
+
var SAFE_SEGMENT = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/;
|
|
52280
|
+
function currentCliVersion() {
|
|
52281
|
+
const v = resolveCliReleaseVersion();
|
|
52282
|
+
return assertSafePathSegment(v, "cli version");
|
|
52283
|
+
}
|
|
52284
|
+
function currentHostPlatform() {
|
|
52285
|
+
const p = osPlatform();
|
|
52286
|
+
if (p === "darwin") return "darwin";
|
|
52287
|
+
if (p === "linux") return "linux";
|
|
52288
|
+
if (p === "win32") return "windows";
|
|
52289
|
+
throw new Error(`unsupported host platform for managed harnesses: ${p}`);
|
|
52290
|
+
}
|
|
52291
|
+
function currentHostArch() {
|
|
52292
|
+
const a = osArch();
|
|
52293
|
+
if (a === "arm64") return "arm64";
|
|
52294
|
+
if (a === "x64") return "x64";
|
|
52295
|
+
throw new Error(`unsupported host arch for managed harnesses: ${a}`);
|
|
52296
|
+
}
|
|
52297
|
+
function assertSafePathSegment(value, label) {
|
|
52298
|
+
const v = value.trim();
|
|
52299
|
+
if (!v) throw new Error(`${label} must be non-empty`);
|
|
52300
|
+
if (v.length > MAX_SEGMENT_LEN) throw new Error(`${label} exceeds ${MAX_SEGMENT_LEN} chars`);
|
|
52301
|
+
if (v === "." || v === "..") throw new Error(`${label} must not be '.' or '..'`);
|
|
52302
|
+
if (v.includes("/") || v.includes("\\") || v.includes("\0")) {
|
|
52303
|
+
throw new Error(`${label} must be a single path segment`);
|
|
52304
|
+
}
|
|
52305
|
+
if (!SAFE_SEGMENT.test(v)) {
|
|
52306
|
+
throw new Error(`${label} contains invalid characters`);
|
|
52307
|
+
}
|
|
52308
|
+
if (/^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\.|$)/i.test(v)) {
|
|
52309
|
+
throw new Error(`${label} is a reserved name`);
|
|
52310
|
+
}
|
|
52311
|
+
return v;
|
|
52312
|
+
}
|
|
52313
|
+
function parseHarnessReleaseManifest(raw) {
|
|
52314
|
+
if (!raw || typeof raw !== "object") {
|
|
52315
|
+
throw new Error("release manifest must be an object");
|
|
52316
|
+
}
|
|
52317
|
+
const obj = raw;
|
|
52318
|
+
if (typeof obj.cliVersion !== "string") {
|
|
52319
|
+
throw new Error("release manifest missing cliVersion");
|
|
52320
|
+
}
|
|
52321
|
+
const cliVersion = assertSafePathSegment(obj.cliVersion, "cliVersion");
|
|
52322
|
+
const mh = obj.managedHarnesses;
|
|
52323
|
+
if (!mh || typeof mh !== "object") {
|
|
52324
|
+
throw new Error("release manifest missing managedHarnesses");
|
|
52325
|
+
}
|
|
52326
|
+
const managedHarnesses = {};
|
|
52327
|
+
for (const id of ["claude", "codex"]) {
|
|
52328
|
+
const entry = mh[id];
|
|
52329
|
+
if (entry == null) continue;
|
|
52330
|
+
managedHarnesses[id] = parseManagedHarnessPin(id, entry);
|
|
52331
|
+
}
|
|
52332
|
+
return { cliVersion, managedHarnesses };
|
|
52333
|
+
}
|
|
52334
|
+
function parseManagedHarnessPin(id, raw) {
|
|
52335
|
+
if (!raw || typeof raw !== "object") {
|
|
52336
|
+
throw new Error(`manifest harness ${id} must be an object`);
|
|
52337
|
+
}
|
|
52338
|
+
const o = raw;
|
|
52339
|
+
if (typeof o.runtimeVersion !== "string" || typeof o.artifactVersion !== "string") {
|
|
52340
|
+
throw new Error(`manifest harness ${id} missing runtimeVersion/artifactVersion`);
|
|
52341
|
+
}
|
|
52342
|
+
const runtimeVersion = assertSafePathSegment(o.runtimeVersion, `${id}.runtimeVersion`);
|
|
52343
|
+
const artifactVersion = assertSafePathSegment(o.artifactVersion, `${id}.artifactVersion`);
|
|
52344
|
+
if (!Array.isArray(o.artifacts) || o.artifacts.length === 0) {
|
|
52345
|
+
throw new Error(`manifest harness ${id} must list artifacts`);
|
|
52346
|
+
}
|
|
52347
|
+
const seen = /* @__PURE__ */ new Set();
|
|
52348
|
+
const artifacts = o.artifacts.map((a, i) => {
|
|
52349
|
+
if (!a || typeof a !== "object") throw new Error(`manifest ${id} artifacts[${i}] invalid`);
|
|
52350
|
+
const art = a;
|
|
52351
|
+
const platform2 = art.platform;
|
|
52352
|
+
const arch2 = art.arch;
|
|
52353
|
+
const digest = art.digestSha256;
|
|
52354
|
+
if (platform2 !== "darwin" && platform2 !== "linux" && platform2 !== "windows") {
|
|
52355
|
+
throw new Error(`manifest ${id} artifacts[${i}] invalid platform`);
|
|
52356
|
+
}
|
|
52357
|
+
if (arch2 !== "arm64" && arch2 !== "x64") {
|
|
52358
|
+
throw new Error(`manifest ${id} artifacts[${i}] invalid arch`);
|
|
52359
|
+
}
|
|
52360
|
+
if (typeof digest !== "string" || !/^[a-f0-9]{64}$/i.test(digest)) {
|
|
52361
|
+
throw new Error(`manifest ${id} artifacts[${i}] digestSha256 must be 64 hex chars`);
|
|
52362
|
+
}
|
|
52363
|
+
const key = `${platform2}/${arch2}`;
|
|
52364
|
+
if (seen.has(key)) {
|
|
52365
|
+
throw new Error(`manifest ${id} has duplicate artifact pin for ${key}`);
|
|
52366
|
+
}
|
|
52367
|
+
seen.add(key);
|
|
52368
|
+
let fileName;
|
|
52369
|
+
if (typeof art.fileName === "string") {
|
|
52370
|
+
if (art.fileName.includes("/") || art.fileName.includes("\\") || art.fileName.includes("\0")) {
|
|
52371
|
+
throw new Error(`manifest ${id} artifacts[${i}] fileName must not contain path separators`);
|
|
52372
|
+
}
|
|
52373
|
+
fileName = art.fileName.slice(0, 128);
|
|
52374
|
+
}
|
|
52375
|
+
return {
|
|
52376
|
+
platform: platform2,
|
|
52377
|
+
arch: arch2,
|
|
52378
|
+
digestSha256: digest.toLowerCase(),
|
|
52379
|
+
fileName
|
|
52380
|
+
};
|
|
52381
|
+
});
|
|
52382
|
+
return { runtimeVersion, artifactVersion, artifacts };
|
|
52383
|
+
}
|
|
52384
|
+
function loadHarnessReleaseManifest(nodeHome) {
|
|
52385
|
+
const fromEnv = process.env.SUPERONE_HARNESS_MANIFEST;
|
|
52386
|
+
if (fromEnv) {
|
|
52387
|
+
if (!existsSync18(fromEnv)) {
|
|
52388
|
+
throw new Error(`SUPERONE_HARNESS_MANIFEST not found: ${fromEnv}`);
|
|
52389
|
+
}
|
|
52390
|
+
return parseHarnessReleaseManifest(JSON.parse(readFileSync7(fromEnv, "utf8")));
|
|
52391
|
+
}
|
|
52392
|
+
const local = join13(nodeHome, "release-manifest.json");
|
|
52393
|
+
if (existsSync18(local)) {
|
|
52394
|
+
return parseHarnessReleaseManifest(JSON.parse(readFileSync7(local, "utf8")));
|
|
52395
|
+
}
|
|
52396
|
+
return null;
|
|
52397
|
+
}
|
|
52398
|
+
function selectArtifactPin(pin, platform2 = currentHostPlatform(), arch2 = currentHostArch()) {
|
|
52399
|
+
const match = pin.artifacts.find((a) => a.platform === platform2 && a.arch === arch2);
|
|
52400
|
+
if (!match) {
|
|
52401
|
+
throw new Error(
|
|
52402
|
+
`no managed artifact pin for ${platform2}/${arch2} (available: ${pin.artifacts.map((a) => `${a.platform}/${a.arch}`).join(", ")})`
|
|
52403
|
+
);
|
|
52404
|
+
}
|
|
52405
|
+
return match;
|
|
52406
|
+
}
|
|
52407
|
+
async function sha256File(path) {
|
|
52408
|
+
return new Promise((resolveHash, reject) => {
|
|
52409
|
+
const hash2 = createHash3("sha256");
|
|
52410
|
+
const stream = createReadStream(path);
|
|
52411
|
+
stream.on("data", (chunk) => hash2.update(chunk));
|
|
52412
|
+
stream.on("error", reject);
|
|
52413
|
+
stream.on("end", () => resolveHash(hash2.digest("hex")));
|
|
52414
|
+
});
|
|
52415
|
+
}
|
|
52416
|
+
function releasesRoot(nodeHome) {
|
|
52417
|
+
return resolve3(nodeHome, "releases");
|
|
52418
|
+
}
|
|
52419
|
+
function harnessVersionDir(nodeHome, cliVersion, harnessId, artifactVersion) {
|
|
52420
|
+
const cli = assertSafePathSegment(cliVersion, "cliVersion");
|
|
52421
|
+
const ver = assertSafePathSegment(artifactVersion, "artifactVersion");
|
|
52422
|
+
const root = releasesRoot(nodeHome);
|
|
52423
|
+
const dest = resolve3(root, cli, "harnesses", harnessId, ver);
|
|
52424
|
+
assertPathInside(dest, resolve3(root, cli, "harnesses", harnessId), "version install dir");
|
|
52425
|
+
return dest;
|
|
52426
|
+
}
|
|
52427
|
+
function assertPathInside(path, root, label) {
|
|
52428
|
+
const resolvedPath = resolve3(path);
|
|
52429
|
+
const resolvedRoot = resolve3(root);
|
|
52430
|
+
const rel = relative(resolvedRoot, resolvedPath);
|
|
52431
|
+
if (rel.startsWith("..") || rel === "..") {
|
|
52432
|
+
throw new Error(`${label} escapes install root: ${resolvedPath}`);
|
|
52433
|
+
}
|
|
52434
|
+
if (rel.startsWith("/") || /^[A-Za-z]:/.test(rel)) {
|
|
52435
|
+
throw new Error(`${label} escapes install root: ${resolvedPath}`);
|
|
52436
|
+
}
|
|
52437
|
+
if (resolvedPath !== resolvedRoot && !resolvedPath.startsWith(resolvedRoot + sep3)) {
|
|
52438
|
+
throw new Error(`${label} escapes install root: ${resolvedPath}`);
|
|
52439
|
+
}
|
|
52440
|
+
}
|
|
52441
|
+
function assertStrictChild(path, parent, label) {
|
|
52442
|
+
const resolvedPath = resolve3(path);
|
|
52443
|
+
const resolvedParent = resolve3(parent);
|
|
52444
|
+
if (resolvedPath === resolvedParent) {
|
|
52445
|
+
throw new Error(`${label} must be a child of ${resolvedParent}`);
|
|
52446
|
+
}
|
|
52447
|
+
assertPathInside(resolvedPath, resolvedParent, label);
|
|
52448
|
+
}
|
|
52449
|
+
async function installManagedArtifactFromFile(opts) {
|
|
52450
|
+
const mode = opts.mode ?? "enable";
|
|
52451
|
+
const expected = opts.expectedCliVersion ?? currentCliVersion();
|
|
52452
|
+
if (opts.manifest.cliVersion !== expected) {
|
|
52453
|
+
throw new Error(
|
|
52454
|
+
`release manifest cliVersion ${opts.manifest.cliVersion} does not match CLI ${expected}`
|
|
52455
|
+
);
|
|
52456
|
+
}
|
|
52457
|
+
const pin = opts.manifest.managedHarnesses[opts.harnessId];
|
|
52458
|
+
if (!pin) {
|
|
52459
|
+
throw new Error(`release manifest does not pin managed harness ${opts.harnessId}`);
|
|
52460
|
+
}
|
|
52461
|
+
const art = selectArtifactPin(pin);
|
|
52462
|
+
if (!existsSync18(opts.artifactPath)) {
|
|
52463
|
+
throw new Error(`artifact not found: ${opts.artifactPath}`);
|
|
52464
|
+
}
|
|
52465
|
+
if (!statSync4(opts.artifactPath).isFile()) {
|
|
52466
|
+
throw new Error(`artifact is not a regular file: ${opts.artifactPath}`);
|
|
52467
|
+
}
|
|
52468
|
+
const digest = await sha256File(opts.artifactPath);
|
|
52469
|
+
if (digest !== art.digestSha256) {
|
|
52470
|
+
throw new Error(
|
|
52471
|
+
`artifact digest mismatch for ${opts.harnessId}: expected ${art.digestSha256}, got ${digest}`
|
|
52472
|
+
);
|
|
52473
|
+
}
|
|
52474
|
+
const destDir = harnessVersionDir(
|
|
52475
|
+
opts.nodeHome,
|
|
52476
|
+
opts.manifest.cliVersion,
|
|
52477
|
+
opts.harnessId,
|
|
52478
|
+
pin.artifactVersion
|
|
52479
|
+
);
|
|
52480
|
+
const finalFile = join13(destDir, MANAGED_PAYLOAD_BASENAME);
|
|
52481
|
+
const metaPath = join13(destDir, MANAGED_META_BASENAME);
|
|
52482
|
+
assertStrictChild(finalFile, destDir, "payload path");
|
|
52483
|
+
assertStrictChild(metaPath, destDir, "meta path");
|
|
52484
|
+
const metaBody = JSON.stringify(
|
|
52485
|
+
{
|
|
52486
|
+
harnessId: opts.harnessId,
|
|
52487
|
+
cliVersion: opts.manifest.cliVersion,
|
|
52488
|
+
runtimeVersion: pin.runtimeVersion,
|
|
52489
|
+
artifactVersion: pin.artifactVersion,
|
|
52490
|
+
platform: art.platform,
|
|
52491
|
+
arch: art.arch,
|
|
52492
|
+
digestSha256: art.digestSha256,
|
|
52493
|
+
displayFileName: art.fileName ?? null,
|
|
52494
|
+
installedAt: Date.now()
|
|
52495
|
+
},
|
|
52496
|
+
null,
|
|
52497
|
+
2
|
|
52498
|
+
);
|
|
52499
|
+
let reusedExisting = false;
|
|
52500
|
+
if (existsSync18(destDir)) {
|
|
52501
|
+
const payloadOk = existsSync18(finalFile) && statSync4(finalFile).isFile() && await sha256File(finalFile) === art.digestSha256;
|
|
52502
|
+
if (payloadOk) {
|
|
52503
|
+
reusedExisting = true;
|
|
52504
|
+
} else if (mode === "repair") {
|
|
52505
|
+
await replacePayloadAtomically({
|
|
52506
|
+
destDir,
|
|
52507
|
+
finalFile,
|
|
52508
|
+
metaPath,
|
|
52509
|
+
sourceArtifact: opts.artifactPath,
|
|
52510
|
+
expectedDigest: art.digestSha256,
|
|
52511
|
+
metaBody
|
|
52512
|
+
});
|
|
52513
|
+
reusedExisting = false;
|
|
52514
|
+
} else {
|
|
52515
|
+
throw new Error(
|
|
52516
|
+
`existing install digest mismatch for ${opts.harnessId}@${pin.artifactVersion}: refusing to overwrite (use harness repair)`
|
|
52517
|
+
);
|
|
52518
|
+
}
|
|
52519
|
+
} else {
|
|
52520
|
+
const harnessRoot2 = dirname7(destDir);
|
|
52521
|
+
mkdirSync8(harnessRoot2, { recursive: true });
|
|
52522
|
+
assertPathInside(destDir, harnessRoot2, "version dir");
|
|
52523
|
+
const stagingDir = mkdtempSync(
|
|
52524
|
+
join13(harnessRoot2, `.staging-${opts.harnessId}-${randomBytes3(8).toString("hex")}-`)
|
|
52525
|
+
);
|
|
52526
|
+
assertPathInside(stagingDir, harnessRoot2, "staging dir");
|
|
52527
|
+
const stagingFile = join13(stagingDir, MANAGED_PAYLOAD_BASENAME);
|
|
52528
|
+
const stagingMeta = join13(stagingDir, MANAGED_META_BASENAME);
|
|
52529
|
+
try {
|
|
52530
|
+
copyFileSync(opts.artifactPath, stagingFile);
|
|
52531
|
+
const stagedDigest = await sha256File(stagingFile);
|
|
52532
|
+
if (stagedDigest !== art.digestSha256) {
|
|
52533
|
+
throw new Error(`staged artifact digest mismatch for ${opts.harnessId}`);
|
|
52534
|
+
}
|
|
52535
|
+
writeFileSync6(stagingMeta, metaBody, "utf8");
|
|
52536
|
+
renameSync2(stagingDir, destDir);
|
|
52537
|
+
} catch (err) {
|
|
52538
|
+
rmSync2(stagingDir, { recursive: true, force: true });
|
|
52539
|
+
if (existsSync18(destDir) && existsSync18(finalFile)) {
|
|
52540
|
+
const existingDigest = await sha256File(finalFile);
|
|
52541
|
+
if (existingDigest === art.digestSha256) {
|
|
52542
|
+
reusedExisting = true;
|
|
52543
|
+
} else if (mode === "repair") {
|
|
52544
|
+
await replacePayloadAtomically({
|
|
52545
|
+
destDir,
|
|
52546
|
+
finalFile,
|
|
52547
|
+
metaPath,
|
|
52548
|
+
sourceArtifact: opts.artifactPath,
|
|
52549
|
+
expectedDigest: art.digestSha256,
|
|
52550
|
+
metaBody
|
|
52551
|
+
});
|
|
52552
|
+
} else {
|
|
52553
|
+
throw err;
|
|
52554
|
+
}
|
|
52555
|
+
} else {
|
|
52556
|
+
throw err;
|
|
52557
|
+
}
|
|
52558
|
+
}
|
|
52559
|
+
}
|
|
52560
|
+
const finalDigest = await sha256File(finalFile);
|
|
52561
|
+
if (finalDigest !== art.digestSha256) {
|
|
52562
|
+
throw new Error(`final payload digest mismatch for ${opts.harnessId}`);
|
|
52563
|
+
}
|
|
52564
|
+
const harnessRoot = join13(
|
|
52565
|
+
releasesRoot(opts.nodeHome),
|
|
52566
|
+
opts.manifest.cliVersion,
|
|
52567
|
+
"harnesses",
|
|
52568
|
+
opts.harnessId
|
|
52569
|
+
);
|
|
52570
|
+
assertPathInside(harnessRoot, releasesRoot(opts.nodeHome), "harness root");
|
|
52571
|
+
mkdirSync8(harnessRoot, { recursive: true });
|
|
52572
|
+
const currentPath = join13(harnessRoot, MANAGED_CURRENT_BASENAME);
|
|
52573
|
+
const currentTmp = join13(
|
|
52574
|
+
harnessRoot,
|
|
52575
|
+
`.${MANAGED_CURRENT_BASENAME}.${process.pid}.${randomBytes3(6).toString("hex")}.tmp`
|
|
52576
|
+
);
|
|
52577
|
+
assertStrictChild(currentTmp, harnessRoot, "current pointer temp");
|
|
52578
|
+
try {
|
|
52579
|
+
writeFileSync6(
|
|
52580
|
+
currentTmp,
|
|
52581
|
+
JSON.stringify(
|
|
52582
|
+
{
|
|
52583
|
+
artifactVersion: pin.artifactVersion,
|
|
52584
|
+
installPath: finalFile,
|
|
52585
|
+
digestSha256: art.digestSha256,
|
|
52586
|
+
runtimeVersion: pin.runtimeVersion
|
|
52587
|
+
},
|
|
52588
|
+
null,
|
|
52589
|
+
2
|
|
52590
|
+
),
|
|
52591
|
+
"utf8"
|
|
52592
|
+
);
|
|
52593
|
+
renameSync2(currentTmp, currentPath);
|
|
52594
|
+
} catch (err) {
|
|
52595
|
+
rmSync2(currentTmp, { force: true });
|
|
52596
|
+
throw err;
|
|
52597
|
+
}
|
|
52598
|
+
return {
|
|
52599
|
+
harnessId: opts.harnessId,
|
|
52600
|
+
cliVersion: opts.manifest.cliVersion,
|
|
52601
|
+
runtimeVersion: pin.runtimeVersion,
|
|
52602
|
+
artifactVersion: pin.artifactVersion,
|
|
52603
|
+
digestSha256: art.digestSha256,
|
|
52604
|
+
installPath: finalFile,
|
|
52605
|
+
source: "offline-artifact",
|
|
52606
|
+
reusedExisting
|
|
52607
|
+
};
|
|
52608
|
+
}
|
|
52609
|
+
async function replacePayloadAtomically(opts) {
|
|
52610
|
+
mkdirSync8(opts.destDir, { recursive: true });
|
|
52611
|
+
const nonce = randomBytes3(8).toString("hex");
|
|
52612
|
+
const payloadTmp = join13(opts.destDir, `.${MANAGED_PAYLOAD_BASENAME}.${nonce}.tmp`);
|
|
52613
|
+
const metaTmp = join13(opts.destDir, `.${MANAGED_META_BASENAME}.${nonce}.tmp`);
|
|
52614
|
+
assertStrictChild(payloadTmp, opts.destDir, "payload temp");
|
|
52615
|
+
assertStrictChild(metaTmp, opts.destDir, "meta temp");
|
|
52616
|
+
try {
|
|
52617
|
+
copyFileSync(opts.sourceArtifact, payloadTmp);
|
|
52618
|
+
const d = await sha256File(payloadTmp);
|
|
52619
|
+
if (d !== opts.expectedDigest) {
|
|
52620
|
+
throw new Error(`repair staged digest mismatch: expected ${opts.expectedDigest}, got ${d}`);
|
|
52621
|
+
}
|
|
52622
|
+
writeFileSync6(metaTmp, opts.metaBody, "utf8");
|
|
52623
|
+
renameSync2(payloadTmp, opts.finalFile);
|
|
52624
|
+
renameSync2(metaTmp, opts.metaPath);
|
|
52625
|
+
} catch (err) {
|
|
52626
|
+
rmSync2(payloadTmp, { force: true });
|
|
52627
|
+
rmSync2(metaTmp, { force: true });
|
|
52628
|
+
throw err;
|
|
52629
|
+
}
|
|
52630
|
+
}
|
|
52631
|
+
function describeExpectedArtifact(harnessId, manifest) {
|
|
52632
|
+
const pin = manifest.managedHarnesses[harnessId];
|
|
52633
|
+
if (!pin) return `harness ${harnessId} is not pinned in the release manifest`;
|
|
52634
|
+
try {
|
|
52635
|
+
const art = selectArtifactPin(pin);
|
|
52636
|
+
return `${harnessId} requires offline --artifact matching ${art.platform}/${art.arch} digest ${art.digestSha256} (runtime ${pin.runtimeVersion}, artifact ${pin.artifactVersion}); network download is not enabled in Stage 3`;
|
|
52637
|
+
} catch (err) {
|
|
52638
|
+
return err instanceof Error ? err.message : String(err);
|
|
52639
|
+
}
|
|
52640
|
+
}
|
|
52641
|
+
function requiredRuntimeVersion(harnessId, manifest) {
|
|
52642
|
+
if (harnessId !== "claude" && harnessId !== "codex") return null;
|
|
52643
|
+
return manifest?.managedHarnesses[harnessId]?.runtimeVersion ?? null;
|
|
52644
|
+
}
|
|
52645
|
+
|
|
52646
|
+
// src/session/harness-enable.ts
|
|
52647
|
+
init_codex_turn_runner();
|
|
52648
|
+
async function enableHarness(manager, input, providers) {
|
|
52649
|
+
const id = input.harnessId;
|
|
52650
|
+
if (!isNodeHarnessId(id)) throw new Error(`unknown harnessId: ${id}`);
|
|
52651
|
+
let status;
|
|
52652
|
+
if (id === "claude" || id === "codex") {
|
|
52653
|
+
status = await enableManaged(manager, id, input.artifactPath);
|
|
52654
|
+
} else if (id === "opencode") {
|
|
52655
|
+
status = enableOpencode(manager, {
|
|
52656
|
+
command: input.command,
|
|
52657
|
+
serverUrl: input.serverUrl
|
|
52658
|
+
});
|
|
52659
|
+
} else {
|
|
52660
|
+
status = enableAcpGrok(manager, {
|
|
52661
|
+
command: input.command,
|
|
52662
|
+
args: input.args ?? []
|
|
52663
|
+
});
|
|
52664
|
+
}
|
|
52665
|
+
try {
|
|
52666
|
+
probeHarnessReadiness(manager, id, providers ?? null);
|
|
52667
|
+
} catch {
|
|
52668
|
+
}
|
|
52669
|
+
return manager.get(id);
|
|
52670
|
+
}
|
|
52671
|
+
function disableHarness(manager, harnessId) {
|
|
52672
|
+
if (!isNodeHarnessId(harnessId)) throw new Error(`unknown harnessId: ${harnessId}`);
|
|
52673
|
+
return manager.disable(harnessId);
|
|
52674
|
+
}
|
|
52675
|
+
async function enableManaged(manager, id, artifact, mode = "enable") {
|
|
52676
|
+
const nodeHome = resolveNodeHome(void 0);
|
|
52677
|
+
const def = getNodeHarnessDefinition(id);
|
|
52678
|
+
if (artifact) {
|
|
52679
|
+
const manifest = loadHarnessReleaseManifest(nodeHome);
|
|
52680
|
+
if (!manifest) {
|
|
52681
|
+
throw new Error(
|
|
52682
|
+
`no release manifest found (set SUPERONE_HARNESS_MANIFEST or write ${nodeHome}/release-manifest.json)`
|
|
52683
|
+
);
|
|
52684
|
+
}
|
|
52685
|
+
if (!manifest.managedHarnesses[id]) {
|
|
52686
|
+
throw new Error(`release manifest does not pin ${id}`);
|
|
52687
|
+
}
|
|
52688
|
+
const abs = requireRegularReadableFile(artifact);
|
|
52689
|
+
const installed = await installManagedArtifactFromFile({
|
|
52690
|
+
nodeHome,
|
|
52691
|
+
harnessId: id,
|
|
52692
|
+
artifactPath: abs,
|
|
52693
|
+
manifest,
|
|
52694
|
+
expectedCliVersion: currentCliVersion(),
|
|
52695
|
+
mode
|
|
52696
|
+
});
|
|
52697
|
+
return manager.update(id, {
|
|
52698
|
+
enabled: true,
|
|
52699
|
+
state: def.requiresAuth ? "needs_auth" : "ready",
|
|
52700
|
+
command: installed.installPath,
|
|
52701
|
+
runtimeVersion: installed.runtimeVersion,
|
|
52702
|
+
diagnosticCode: def.requiresAuth ? "needs_auth" : null,
|
|
52703
|
+
diagnosticFields: def.requiresAuth ? { command: installed.installPath, runtimeVersion: installed.runtimeVersion } : null,
|
|
52704
|
+
lastProbedAt: Date.now(),
|
|
52705
|
+
configJson: JSON.stringify({
|
|
52706
|
+
artifactPath: installed.installPath,
|
|
52707
|
+
source: installed.source,
|
|
52708
|
+
cliVersion: installed.cliVersion,
|
|
52709
|
+
artifactVersion: installed.artifactVersion,
|
|
52710
|
+
digestSha256: installed.digestSha256
|
|
52711
|
+
})
|
|
52712
|
+
});
|
|
52713
|
+
}
|
|
52714
|
+
const auto = resolveManagedAutoRuntime(id);
|
|
52715
|
+
if (auto) {
|
|
52716
|
+
return manager.update(id, {
|
|
52717
|
+
enabled: true,
|
|
52718
|
+
state: def.requiresAuth ? "needs_auth" : "ready",
|
|
52719
|
+
command: auto.command,
|
|
52720
|
+
runtimeVersion: auto.runtimeVersion ?? null,
|
|
52721
|
+
diagnosticCode: def.requiresAuth ? "needs_auth" : null,
|
|
52722
|
+
diagnosticFields: def.requiresAuth ? { command: auto.command, runtimeVersion: auto.runtimeVersion } : null,
|
|
52723
|
+
lastProbedAt: Date.now(),
|
|
52724
|
+
configJson: JSON.stringify({
|
|
52725
|
+
command: auto.command,
|
|
52726
|
+
source: auto.source
|
|
52727
|
+
})
|
|
52728
|
+
});
|
|
52729
|
+
}
|
|
52730
|
+
try {
|
|
52731
|
+
const { installManagedFromOfficialNpm: installManagedFromOfficialNpm2 } = await Promise.resolve().then(() => (init_managed_harness_official(), managed_harness_official_exports));
|
|
52732
|
+
const official = await installManagedFromOfficialNpm2({ nodeHome, harnessId: id });
|
|
52733
|
+
return manager.update(id, {
|
|
52734
|
+
enabled: true,
|
|
52735
|
+
state: def.requiresAuth ? "needs_auth" : "ready",
|
|
52736
|
+
command: official.command,
|
|
52737
|
+
runtimeVersion: official.runtimeVersion,
|
|
52738
|
+
diagnosticCode: def.requiresAuth ? "needs_auth" : null,
|
|
52739
|
+
diagnosticFields: def.requiresAuth ? { command: official.command, runtimeVersion: official.runtimeVersion } : null,
|
|
52740
|
+
lastProbedAt: Date.now(),
|
|
52741
|
+
configJson: JSON.stringify({
|
|
52742
|
+
command: official.command,
|
|
52743
|
+
source: official.source,
|
|
52744
|
+
packageSpec: official.packageSpec,
|
|
52745
|
+
installPrefix: official.installPrefix,
|
|
52746
|
+
runtimeVersion: official.runtimeVersion
|
|
52747
|
+
})
|
|
52748
|
+
});
|
|
52749
|
+
} catch (officialErr) {
|
|
52750
|
+
const detail = officialErr instanceof Error ? officialErr.message : String(officialErr);
|
|
52751
|
+
const manifest = loadHarnessReleaseManifest(nodeHome);
|
|
52752
|
+
if (manifest?.managedHarnesses[id]) {
|
|
52753
|
+
throw new Error(
|
|
52754
|
+
`official install failed (${detail}); ${describeExpectedArtifact(id, manifest)} as offline fallback`
|
|
52755
|
+
);
|
|
52756
|
+
}
|
|
52757
|
+
throw new Error(
|
|
52758
|
+
`official install of ${id} failed: ${detail}. Ensure npm is on PATH and the host can reach registry.npmjs.org.`
|
|
52759
|
+
);
|
|
52760
|
+
}
|
|
52761
|
+
}
|
|
52762
|
+
function resolveManagedAutoRuntime(id) {
|
|
52763
|
+
if (id === "claude") {
|
|
52764
|
+
const sdk = resolveSdkClaudeBinary();
|
|
52765
|
+
if (sdk && existsSync20(sdk)) {
|
|
52766
|
+
return { command: sdk, source: "agent-sdk-optional" };
|
|
52767
|
+
}
|
|
52768
|
+
return null;
|
|
52769
|
+
}
|
|
52770
|
+
const fromEnv = resolveCodexBinaryPath({});
|
|
52771
|
+
if (fromEnv) return { command: fromEnv, source: "env-or-catalog" };
|
|
52772
|
+
const fromPath = resolveExternalCommand(void 0, ["codex"]);
|
|
52773
|
+
if (fromPath) return { command: fromPath, source: "path" };
|
|
52774
|
+
return null;
|
|
52775
|
+
}
|
|
52776
|
+
function enableOpencode(manager, opts) {
|
|
52777
|
+
if (opts.serverUrl) {
|
|
52778
|
+
const safeUrl = validateServerUrl(opts.serverUrl);
|
|
52779
|
+
return manager.update("opencode", {
|
|
52780
|
+
enabled: true,
|
|
52781
|
+
state: "ready",
|
|
52782
|
+
command: null,
|
|
52783
|
+
diagnosticCode: null,
|
|
52784
|
+
lastProbedAt: Date.now(),
|
|
52785
|
+
configJson: JSON.stringify({ serverUrl: safeUrl })
|
|
52786
|
+
});
|
|
52787
|
+
}
|
|
52788
|
+
const resolved = resolveExternalCommand(opts.command, ["opencode"]);
|
|
52789
|
+
if (!resolved) {
|
|
52790
|
+
return manager.update("opencode", {
|
|
52791
|
+
enabled: true,
|
|
52792
|
+
state: "missing",
|
|
52793
|
+
command: null,
|
|
52794
|
+
diagnosticCode: "not_found",
|
|
52795
|
+
lastProbedAt: Date.now(),
|
|
52796
|
+
configJson: JSON.stringify({})
|
|
52797
|
+
});
|
|
52798
|
+
}
|
|
52799
|
+
return manager.update("opencode", {
|
|
52800
|
+
enabled: true,
|
|
52801
|
+
state: "ready",
|
|
52802
|
+
command: resolved,
|
|
52803
|
+
diagnosticCode: null,
|
|
52804
|
+
lastProbedAt: Date.now(),
|
|
52805
|
+
configJson: JSON.stringify({ command: resolved })
|
|
52806
|
+
});
|
|
52807
|
+
}
|
|
52808
|
+
function enableAcpGrok(manager, opts) {
|
|
52809
|
+
const defaultArgs = ["agent", "stdio"];
|
|
52810
|
+
const args = sanitizeHarnessArgs(opts.args.length > 0 ? opts.args : defaultArgs);
|
|
52811
|
+
const resolved = resolveExternalCommand(opts.command, ["grok"]);
|
|
52812
|
+
if (!resolved) {
|
|
52813
|
+
return manager.update("acp-grok", {
|
|
52814
|
+
enabled: true,
|
|
52815
|
+
state: "missing",
|
|
52816
|
+
command: null,
|
|
52817
|
+
diagnosticCode: "not_found",
|
|
52818
|
+
lastProbedAt: Date.now(),
|
|
52819
|
+
configJson: JSON.stringify({ args, usesDefaultArgs: opts.args.length === 0 })
|
|
52820
|
+
});
|
|
52821
|
+
}
|
|
52822
|
+
return manager.update("acp-grok", {
|
|
52823
|
+
enabled: true,
|
|
52824
|
+
state: "ready",
|
|
52825
|
+
command: resolved,
|
|
52826
|
+
diagnosticCode: null,
|
|
52827
|
+
lastProbedAt: Date.now(),
|
|
52828
|
+
configJson: JSON.stringify({
|
|
52829
|
+
command: resolved,
|
|
52830
|
+
args,
|
|
52831
|
+
usesDefaultArgs: opts.args.length === 0
|
|
52832
|
+
})
|
|
52833
|
+
});
|
|
52834
|
+
}
|
|
52835
|
+
function requireRegularReadableFile(path) {
|
|
52836
|
+
if (!isAbsolute2(path)) {
|
|
52837
|
+
throw new Error(`path must be absolute: ${path}`);
|
|
52838
|
+
}
|
|
52839
|
+
const abs = resolve5(path);
|
|
52840
|
+
if (!existsSync20(abs) || !statSync6(abs).isFile()) {
|
|
52841
|
+
throw new Error(`not a regular file: ${abs}`);
|
|
52842
|
+
}
|
|
52843
|
+
accessSync(abs, constants.R_OK);
|
|
52844
|
+
return realpathSync3(abs);
|
|
52845
|
+
}
|
|
52846
|
+
function resolveExternalCommand(explicit, searchNames) {
|
|
52847
|
+
if (explicit) {
|
|
52848
|
+
const abs = isAbsolute2(explicit) ? explicit : resolve5(explicit);
|
|
52849
|
+
if (!existsSync20(abs)) return null;
|
|
52850
|
+
try {
|
|
52851
|
+
if (!statSync6(abs).isFile()) return null;
|
|
52852
|
+
accessSync(abs, constants.X_OK);
|
|
52853
|
+
} catch {
|
|
52854
|
+
return null;
|
|
52855
|
+
}
|
|
52856
|
+
return realpathSync3(abs);
|
|
52857
|
+
}
|
|
52858
|
+
const pathEnv = process.env.PATH || "";
|
|
52859
|
+
const dirs = pathEnv.split(process.platform === "win32" ? ";" : ":");
|
|
52860
|
+
for (const name of searchNames) {
|
|
52861
|
+
for (const dir of dirs) {
|
|
52862
|
+
if (!dir) continue;
|
|
52863
|
+
const candidate = resolve5(dir, name);
|
|
52864
|
+
if (!existsSync20(candidate)) continue;
|
|
52865
|
+
try {
|
|
52866
|
+
if (!statSync6(candidate).isFile()) continue;
|
|
52867
|
+
accessSync(candidate, constants.X_OK);
|
|
52868
|
+
return realpathSync3(candidate);
|
|
52869
|
+
} catch {
|
|
52870
|
+
}
|
|
52871
|
+
}
|
|
52872
|
+
}
|
|
52873
|
+
return null;
|
|
52874
|
+
}
|
|
52875
|
+
function validateServerUrl(raw) {
|
|
52876
|
+
let url2;
|
|
52877
|
+
try {
|
|
52878
|
+
url2 = new URL(raw);
|
|
52879
|
+
} catch {
|
|
52880
|
+
throw new Error("--server-url is not a valid URL");
|
|
52881
|
+
}
|
|
52882
|
+
if (url2.username || url2.password) {
|
|
52883
|
+
throw new Error("--server-url must not include credentials");
|
|
52884
|
+
}
|
|
52885
|
+
if (url2.search && url2.search !== "?") {
|
|
52886
|
+
throw new Error("--server-url must not include query parameters");
|
|
52887
|
+
}
|
|
52888
|
+
if (url2.hash) {
|
|
52889
|
+
throw new Error("--server-url must not include a fragment");
|
|
52890
|
+
}
|
|
52891
|
+
const host = url2.hostname.toLowerCase();
|
|
52892
|
+
const loopback = host === "localhost" || host === "127.0.0.1" || host === "::1";
|
|
52893
|
+
if (url2.protocol === "http:") {
|
|
52894
|
+
if (!loopback) {
|
|
52895
|
+
throw new Error("--server-url http is only allowed for loopback hosts");
|
|
52896
|
+
}
|
|
52897
|
+
} else if (url2.protocol !== "https:") {
|
|
52898
|
+
throw new Error("--server-url must be http(s)");
|
|
52899
|
+
}
|
|
52900
|
+
return `${url2.origin}${url2.pathname === "/" ? "" : url2.pathname}`;
|
|
52901
|
+
}
|
|
52902
|
+
function sanitizeHarnessArgs(args) {
|
|
52903
|
+
for (const a of args) {
|
|
52904
|
+
if (looksLikeSecretArg(a)) {
|
|
52905
|
+
throw new Error("refusing to store credential-like --arg values");
|
|
52906
|
+
}
|
|
52907
|
+
}
|
|
52908
|
+
return args.map((a) => a.slice(0, 512)).filter((a) => a.length > 0);
|
|
52909
|
+
}
|
|
52910
|
+
function looksLikeSecretArg(value) {
|
|
52911
|
+
if (/Bearer\s+\S+/i.test(value)) return true;
|
|
52912
|
+
if (/\b(password|passwd|token|secret|api[_-]?key)\b\s*=/i.test(value)) return true;
|
|
52913
|
+
if (/^[A-Z][A-Z0-9_]*(KEY|TOKEN|SECRET|PASSWORD)\s*=/.test(value)) return true;
|
|
52914
|
+
if (/\bsk-[A-Za-z0-9_-]{8,}\b/.test(value)) return true;
|
|
52915
|
+
return false;
|
|
52916
|
+
}
|
|
52917
|
+
|
|
52003
52918
|
// ../../packages/shared/src/git-clone.ts
|
|
52004
52919
|
import { execFile } from "node:child_process";
|
|
52005
|
-
import { existsSync as
|
|
52006
|
-
import { isAbsolute as
|
|
52920
|
+
import { existsSync as existsSync21, mkdirSync as mkdirSync10 } from "node:fs";
|
|
52921
|
+
import { isAbsolute as isAbsolute3, join as join15, resolve as resolve6 } from "node:path";
|
|
52007
52922
|
|
|
52008
52923
|
// ../../packages/shared/src/git-remote.ts
|
|
52009
52924
|
function repoNameFromGitUrl(url2) {
|
|
@@ -52061,24 +52976,24 @@ function resolveCloneDestination(input) {
|
|
|
52061
52976
|
if (urlError) throw invalid(urlError);
|
|
52062
52977
|
const parent = input.parentPath.trim();
|
|
52063
52978
|
if (!parent) throw invalid("destination directory is required");
|
|
52064
|
-
if (!
|
|
52979
|
+
if (!isAbsolute3(parent)) throw invalid("destination directory must be an absolute path");
|
|
52065
52980
|
const requested = input.directoryName?.trim();
|
|
52066
52981
|
const name = requested || repoNameFromGitUrl(input.remoteUrl);
|
|
52067
52982
|
if (!name) throw invalid("cannot determine a folder name for this repository");
|
|
52068
52983
|
if (name.includes("/") || name.includes("\\") || name === "." || name === "..") {
|
|
52069
52984
|
throw invalid(`invalid folder name: ${name}`);
|
|
52070
52985
|
}
|
|
52071
|
-
return { path:
|
|
52986
|
+
return { path: join15(resolve6(parent), name), name };
|
|
52072
52987
|
}
|
|
52073
52988
|
async function cloneRepository(input) {
|
|
52074
52989
|
const destination = resolveCloneDestination(input);
|
|
52075
|
-
if (
|
|
52990
|
+
if (existsSync21(destination.path)) {
|
|
52076
52991
|
throw Object.assign(new Error(`destination already exists: ${destination.path}`), {
|
|
52077
52992
|
code: "conflict"
|
|
52078
52993
|
});
|
|
52079
52994
|
}
|
|
52080
|
-
const parent =
|
|
52081
|
-
|
|
52995
|
+
const parent = resolve6(input.parentPath.trim());
|
|
52996
|
+
mkdirSync10(parent, { recursive: true });
|
|
52082
52997
|
await new Promise((resolvePromise, reject) => {
|
|
52083
52998
|
execFile(
|
|
52084
52999
|
"git",
|
|
@@ -52116,7 +53031,7 @@ async function cloneRepository(input) {
|
|
|
52116
53031
|
|
|
52117
53032
|
// src/rpc/handlers.ts
|
|
52118
53033
|
init_resolve_service();
|
|
52119
|
-
import { existsSync as
|
|
53034
|
+
import { existsSync as existsSync22, mkdirSync as mkdirSync11, readdirSync as readdirSync6, statSync as statSync7 } from "node:fs";
|
|
52120
53035
|
import { join as pathJoin, resolve as pathResolve } from "node:path";
|
|
52121
53036
|
import { arch, cpus, freemem, homedir as homedir4, hostname as hostname4, platform, totalmem, uptime } from "node:os";
|
|
52122
53037
|
|
|
@@ -52640,6 +53555,10 @@ async function dispatchRpcInner(method, payload, ctx) {
|
|
|
52640
53555
|
return handleHarnessShow(payload, ctx);
|
|
52641
53556
|
case "harness.probe":
|
|
52642
53557
|
return handleHarnessProbe(payload, ctx);
|
|
53558
|
+
case "harness.enable":
|
|
53559
|
+
return handleHarnessEnable(payload, ctx);
|
|
53560
|
+
case "harness.disable":
|
|
53561
|
+
return handleHarnessDisable(payload, ctx);
|
|
52643
53562
|
case "terminal.create":
|
|
52644
53563
|
return handleTerminalCreate(payload, ctx);
|
|
52645
53564
|
case "terminal.attach":
|
|
@@ -52936,11 +53855,18 @@ function handleDescriptor(ctx) {
|
|
|
52936
53855
|
if (isClaudeBinaryOverrideRunnable() && !harnessIds.includes("claude")) {
|
|
52937
53856
|
harnessIds.push("claude");
|
|
52938
53857
|
}
|
|
53858
|
+
let cliVersion;
|
|
53859
|
+
try {
|
|
53860
|
+
cliVersion = resolveCliReleaseVersion();
|
|
53861
|
+
} catch {
|
|
53862
|
+
cliVersion = process.env.SUPERONE_CLI_VERSION?.trim() || void 0;
|
|
53863
|
+
}
|
|
52939
53864
|
const descriptor = {
|
|
52940
53865
|
environmentId: ctx.identity.environmentId,
|
|
52941
53866
|
label: ctx.identity.label,
|
|
52942
53867
|
platform: { os: mapOs(), arch: arch() },
|
|
52943
53868
|
nodeVersion: process.version,
|
|
53869
|
+
cliVersion,
|
|
52944
53870
|
protocolVersion: PROTOCOL_GENERATION.current,
|
|
52945
53871
|
capabilities: {
|
|
52946
53872
|
...PHASE1_NODE_CAPABILITIES,
|
|
@@ -52992,6 +53918,46 @@ function handleHarnessProbe(payload, ctx) {
|
|
|
52992
53918
|
return mapThrown2(err);
|
|
52993
53919
|
}
|
|
52994
53920
|
}
|
|
53921
|
+
async function handleHarnessEnable(payload, ctx) {
|
|
53922
|
+
const denied = requireScopes2(ctx.client, OPERATION_SCOPES.adminNode);
|
|
53923
|
+
if (denied) return denied;
|
|
53924
|
+
const p = asRecord7(payload);
|
|
53925
|
+
const id = typeof p.harnessId === "string" ? p.harnessId : typeof p.id === "string" ? p.id : "";
|
|
53926
|
+
if (!isNodeHarnessId(id)) {
|
|
53927
|
+
return { error: { code: "invalid_argument", message: `unknown harnessId: ${id}` } };
|
|
53928
|
+
}
|
|
53929
|
+
try {
|
|
53930
|
+
const args = Array.isArray(p.args) ? p.args.filter((a) => typeof a === "string") : void 0;
|
|
53931
|
+
const status = await enableHarness(
|
|
53932
|
+
ctx.harnesses,
|
|
53933
|
+
{
|
|
53934
|
+
harnessId: id,
|
|
53935
|
+
artifactPath: typeof p.artifactPath === "string" ? p.artifactPath : void 0,
|
|
53936
|
+
command: typeof p.command === "string" ? p.command : void 0,
|
|
53937
|
+
serverUrl: typeof p.serverUrl === "string" ? p.serverUrl : void 0,
|
|
53938
|
+
args
|
|
53939
|
+
},
|
|
53940
|
+
ctx.providers ?? null
|
|
53941
|
+
);
|
|
53942
|
+
return { result: status };
|
|
53943
|
+
} catch (err) {
|
|
53944
|
+
return mapThrown2(err);
|
|
53945
|
+
}
|
|
53946
|
+
}
|
|
53947
|
+
function handleHarnessDisable(payload, ctx) {
|
|
53948
|
+
const denied = requireScopes2(ctx.client, OPERATION_SCOPES.adminNode);
|
|
53949
|
+
if (denied) return denied;
|
|
53950
|
+
const p = asRecord7(payload);
|
|
53951
|
+
const id = typeof p.harnessId === "string" ? p.harnessId : typeof p.id === "string" ? p.id : "";
|
|
53952
|
+
if (!isNodeHarnessId(id)) {
|
|
53953
|
+
return { error: { code: "invalid_argument", message: `unknown harnessId: ${id}` } };
|
|
53954
|
+
}
|
|
53955
|
+
try {
|
|
53956
|
+
return { result: disableHarness(ctx.harnesses, id) };
|
|
53957
|
+
} catch (err) {
|
|
53958
|
+
return mapThrown2(err);
|
|
53959
|
+
}
|
|
53960
|
+
}
|
|
52995
53961
|
function handleHealth(ctx) {
|
|
52996
53962
|
const denied = requireScopes2(ctx.client, OPERATION_SCOPES.readEnvironment);
|
|
52997
53963
|
if (denied) return denied;
|
|
@@ -53222,8 +54188,8 @@ function handleProjectOpen(payload, ctx) {
|
|
|
53222
54188
|
}
|
|
53223
54189
|
const name = typeof p.name === "string" ? p.name : void 0;
|
|
53224
54190
|
try {
|
|
53225
|
-
if (p.createIfMissing === true && !
|
|
53226
|
-
|
|
54191
|
+
if (p.createIfMissing === true && !existsSync22(path)) {
|
|
54192
|
+
mkdirSync11(path, { recursive: true });
|
|
53227
54193
|
}
|
|
53228
54194
|
return { result: ctx.projects.open(path, name) };
|
|
53229
54195
|
} catch (err) {
|
|
@@ -53259,13 +54225,13 @@ function handleFsListDir(payload, ctx) {
|
|
|
53259
54225
|
}
|
|
53260
54226
|
try {
|
|
53261
54227
|
const resolved = expandHostPath(raw);
|
|
53262
|
-
if (!
|
|
54228
|
+
if (!existsSync22(resolved)) {
|
|
53263
54229
|
return { error: { code: "not_found", message: "path not found" } };
|
|
53264
54230
|
}
|
|
53265
|
-
if (!
|
|
54231
|
+
if (!statSync7(resolved).isDirectory()) {
|
|
53266
54232
|
return { error: { code: "invalid_argument", message: "not a directory" } };
|
|
53267
54233
|
}
|
|
53268
|
-
const entries =
|
|
54234
|
+
const entries = readdirSync6(resolved, { withFileTypes: true }).filter((ent) => ent.isDirectory() && !ent.name.startsWith(".")).map((ent) => ({
|
|
53269
54235
|
name: ent.name,
|
|
53270
54236
|
path: pathJoin(resolved, ent.name),
|
|
53271
54237
|
type: "directory"
|
|
@@ -54516,9 +55482,9 @@ async function startNodeServer(opts) {
|
|
|
54516
55482
|
}
|
|
54517
55483
|
});
|
|
54518
55484
|
});
|
|
54519
|
-
await new Promise((
|
|
55485
|
+
await new Promise((resolve12, reject) => {
|
|
54520
55486
|
httpServer.once("error", reject);
|
|
54521
|
-
httpServer.listen(opts.bindPort, opts.bindHost, () =>
|
|
55487
|
+
httpServer.listen(opts.bindPort, opts.bindHost, () => resolve12());
|
|
54522
55488
|
});
|
|
54523
55489
|
const address = httpServer.address();
|
|
54524
55490
|
const port = typeof address === "object" && address ? address.port : opts.bindPort;
|
|
@@ -54531,9 +55497,9 @@ async function startNodeServer(opts) {
|
|
|
54531
55497
|
async close() {
|
|
54532
55498
|
for (const ws of activeSockets.keys()) ws.close();
|
|
54533
55499
|
activeSockets.clear();
|
|
54534
|
-
await new Promise((
|
|
54535
|
-
await new Promise((
|
|
54536
|
-
httpServer.close((err) => err ? reject(err) :
|
|
55500
|
+
await new Promise((resolve12) => wss.close(() => resolve12()));
|
|
55501
|
+
await new Promise((resolve12, reject) => {
|
|
55502
|
+
httpServer.close((err) => err ? reject(err) : resolve12());
|
|
54537
55503
|
});
|
|
54538
55504
|
}
|
|
54539
55505
|
};
|
|
@@ -54644,9 +55610,9 @@ async function handleHttp(req, res, opts) {
|
|
|
54644
55610
|
|
|
54645
55611
|
// src/terminal/manager.ts
|
|
54646
55612
|
import { createRequire as createRequire2 } from "node:module";
|
|
54647
|
-
import { existsSync as
|
|
55613
|
+
import { existsSync as existsSync23 } from "node:fs";
|
|
54648
55614
|
var nodeRequire = createRequire2(import.meta.url);
|
|
54649
|
-
var { spawn:
|
|
55615
|
+
var { spawn: spawn5 } = nodeRequire("node-pty");
|
|
54650
55616
|
var SNAPSHOT_SOFT_LIMIT = 64 * 1024;
|
|
54651
55617
|
var OUTPUT_BUFFER_SOFT_LIMIT = 256 * 1024;
|
|
54652
55618
|
function defaultShell() {
|
|
@@ -54659,7 +55625,7 @@ var NodeTerminalManager = class {
|
|
|
54659
55625
|
}
|
|
54660
55626
|
byId = /* @__PURE__ */ new Map();
|
|
54661
55627
|
create(opts) {
|
|
54662
|
-
if (!
|
|
55628
|
+
if (!existsSync23(opts.cwd)) {
|
|
54663
55629
|
throw Object.assign(new Error(`cwd does not exist: ${opts.cwd}`), { code: "invalid_argument" });
|
|
54664
55630
|
}
|
|
54665
55631
|
const terminalId = crypto.randomUUID();
|
|
@@ -54678,7 +55644,7 @@ var NodeTerminalManager = class {
|
|
|
54678
55644
|
sequence: 0
|
|
54679
55645
|
};
|
|
54680
55646
|
const shell = opts.shell || defaultShell();
|
|
54681
|
-
const proc =
|
|
55647
|
+
const proc = spawn5(shell, [], {
|
|
54682
55648
|
cwd: opts.cwd,
|
|
54683
55649
|
env: { ...process.env, TERM: "xterm-256color" },
|
|
54684
55650
|
name: "xterm-256color",
|
|
@@ -54799,9 +55765,9 @@ var NodeTerminalManager = class {
|
|
|
54799
55765
|
};
|
|
54800
55766
|
|
|
54801
55767
|
// src/workspace/project-registry.ts
|
|
54802
|
-
import { basename as basename2, resolve as
|
|
54803
|
-
import { existsSync as
|
|
54804
|
-
import { createHash as
|
|
55768
|
+
import { basename as basename2, resolve as resolve7 } from "node:path";
|
|
55769
|
+
import { existsSync as existsSync24, realpathSync as realpathSync4, statSync as statSync8 } from "node:fs";
|
|
55770
|
+
import { createHash as createHash4 } from "node:crypto";
|
|
54805
55771
|
import { execFileSync } from "node:child_process";
|
|
54806
55772
|
var ProjectRegistry = class {
|
|
54807
55773
|
constructor(db) {
|
|
@@ -54821,7 +55787,7 @@ var ProjectRegistry = class {
|
|
|
54821
55787
|
return this.toSnapshot(r);
|
|
54822
55788
|
}
|
|
54823
55789
|
getByPath(path) {
|
|
54824
|
-
const abs =
|
|
55790
|
+
const abs = resolve7(path);
|
|
54825
55791
|
const r = this.db.prepare(
|
|
54826
55792
|
`SELECT project_id, path, name, repo_identity, opened_at, last_active_at FROM projects WHERE path = ?`
|
|
54827
55793
|
).get(abs);
|
|
@@ -54829,14 +55795,14 @@ var ProjectRegistry = class {
|
|
|
54829
55795
|
return this.toSnapshot(r);
|
|
54830
55796
|
}
|
|
54831
55797
|
open(path, name) {
|
|
54832
|
-
let abs =
|
|
54833
|
-
if (!
|
|
55798
|
+
let abs = resolve7(path);
|
|
55799
|
+
if (!existsSync24(abs) || !statSync8(abs).isDirectory()) {
|
|
54834
55800
|
throw Object.assign(new Error(`project path is not a directory: ${abs}`), {
|
|
54835
55801
|
code: "invalid_argument"
|
|
54836
55802
|
});
|
|
54837
55803
|
}
|
|
54838
55804
|
try {
|
|
54839
|
-
abs =
|
|
55805
|
+
abs = realpathSync4(abs);
|
|
54840
55806
|
} catch {
|
|
54841
55807
|
}
|
|
54842
55808
|
const existing = this.getByPath(abs);
|
|
@@ -54845,7 +55811,7 @@ var ProjectRegistry = class {
|
|
|
54845
55811
|
this.db.prepare(`UPDATE projects SET last_active_at = ?, name = COALESCE(?, name) WHERE project_id = ?`).run(now, name ?? null, existing.projectId);
|
|
54846
55812
|
return this.get(existing.projectId);
|
|
54847
55813
|
}
|
|
54848
|
-
const projectId =
|
|
55814
|
+
const projectId = createHash4("sha256").update(abs).digest("hex").slice(0, 32);
|
|
54849
55815
|
const repoIdentity = detectRepoIdentity(abs);
|
|
54850
55816
|
this.db.prepare(
|
|
54851
55817
|
`INSERT INTO projects (project_id, path, name, repo_identity, opened_at, last_active_at)
|
|
@@ -54874,7 +55840,7 @@ var ProjectRegistry = class {
|
|
|
54874
55840
|
toSnapshot(r) {
|
|
54875
55841
|
let missing = false;
|
|
54876
55842
|
try {
|
|
54877
|
-
missing = !
|
|
55843
|
+
missing = !statSync8(r.path).isDirectory();
|
|
54878
55844
|
} catch {
|
|
54879
55845
|
missing = true;
|
|
54880
55846
|
}
|
|
@@ -54904,7 +55870,7 @@ function detectRepoIdentity(abs) {
|
|
|
54904
55870
|
if (remote) return `git:${remote}`;
|
|
54905
55871
|
} catch {
|
|
54906
55872
|
}
|
|
54907
|
-
return `gitdir:${
|
|
55873
|
+
return `gitdir:${resolve7(abs, out)}`;
|
|
54908
55874
|
} catch {
|
|
54909
55875
|
return null;
|
|
54910
55876
|
}
|
|
@@ -54914,21 +55880,21 @@ function detectRepoIdentity(abs) {
|
|
|
54914
55880
|
init_fs();
|
|
54915
55881
|
import {
|
|
54916
55882
|
closeSync,
|
|
54917
|
-
existsSync as
|
|
55883
|
+
existsSync as existsSync25,
|
|
54918
55884
|
fstatSync,
|
|
54919
|
-
mkdirSync as
|
|
55885
|
+
mkdirSync as mkdirSync12,
|
|
54920
55886
|
openSync,
|
|
54921
55887
|
readSync,
|
|
54922
|
-
readdirSync as
|
|
54923
|
-
readFileSync as
|
|
54924
|
-
renameSync as
|
|
54925
|
-
rmSync as
|
|
54926
|
-
statSync as
|
|
55888
|
+
readdirSync as readdirSync7,
|
|
55889
|
+
readFileSync as readFileSync9,
|
|
55890
|
+
renameSync as renameSync3,
|
|
55891
|
+
rmSync as rmSync3,
|
|
55892
|
+
statSync as statSync9,
|
|
54927
55893
|
unlinkSync,
|
|
54928
|
-
writeFileSync as
|
|
55894
|
+
writeFileSync as writeFileSync7
|
|
54929
55895
|
} from "node:fs";
|
|
54930
|
-
import { dirname as
|
|
54931
|
-
import { createHash as
|
|
55896
|
+
import { dirname as dirname8, join as join16, relative as relative2 } from "node:path";
|
|
55897
|
+
import { createHash as createHash5 } from "node:crypto";
|
|
54932
55898
|
function normalizeRel(path) {
|
|
54933
55899
|
return path.replace(/\\/g, "/").replace(/\/+$/, "") || ".";
|
|
54934
55900
|
}
|
|
@@ -54973,21 +55939,21 @@ var WorkspaceFsService = class {
|
|
|
54973
55939
|
if (!resolved.ok) {
|
|
54974
55940
|
throw Object.assign(new Error(resolved.reason), { code: "invalid_argument" });
|
|
54975
55941
|
}
|
|
54976
|
-
if (!
|
|
55942
|
+
if (!existsSync25(resolved.absolutePath)) {
|
|
54977
55943
|
throw Object.assign(new Error("path not found"), { code: "not_found" });
|
|
54978
55944
|
}
|
|
54979
|
-
const st =
|
|
55945
|
+
const st = statSync9(resolved.absolutePath);
|
|
54980
55946
|
if (!st.isDirectory()) {
|
|
54981
55947
|
throw Object.assign(new Error("not a directory"), { code: "invalid_argument" });
|
|
54982
55948
|
}
|
|
54983
55949
|
this.projects.touch(projectId);
|
|
54984
|
-
const ents =
|
|
55950
|
+
const ents = readdirSync7(resolved.absolutePath, { withFileTypes: true });
|
|
54985
55951
|
return ents.map((ent) => {
|
|
54986
|
-
const abs =
|
|
55952
|
+
const abs = join16(resolved.absolutePath, ent.name);
|
|
54987
55953
|
let size;
|
|
54988
55954
|
let mtimeMs;
|
|
54989
55955
|
try {
|
|
54990
|
-
const s =
|
|
55956
|
+
const s = statSync9(abs);
|
|
54991
55957
|
size = s.size;
|
|
54992
55958
|
mtimeMs = s.mtimeMs;
|
|
54993
55959
|
} catch {
|
|
@@ -54995,7 +55961,7 @@ var WorkspaceFsService = class {
|
|
|
54995
55961
|
const kind = pathKind(abs);
|
|
54996
55962
|
return {
|
|
54997
55963
|
name: ent.name,
|
|
54998
|
-
path:
|
|
55964
|
+
path: relative2(root, abs).split("\\").join("/") || ".",
|
|
54999
55965
|
type: kind === "symlink" ? "symlink" : kind === "directory" ? "directory" : kind === "file" ? "file" : "other",
|
|
55000
55966
|
size,
|
|
55001
55967
|
mtimeMs
|
|
@@ -55008,10 +55974,10 @@ var WorkspaceFsService = class {
|
|
|
55008
55974
|
if (!resolved.ok) {
|
|
55009
55975
|
throw Object.assign(new Error(resolved.reason), { code: "invalid_argument" });
|
|
55010
55976
|
}
|
|
55011
|
-
if (!
|
|
55977
|
+
if (!existsSync25(resolved.absolutePath)) {
|
|
55012
55978
|
throw Object.assign(new Error("file not found"), { code: "not_found" });
|
|
55013
55979
|
}
|
|
55014
|
-
const st =
|
|
55980
|
+
const st = statSync9(resolved.absolutePath);
|
|
55015
55981
|
if (!st.isFile()) {
|
|
55016
55982
|
throw Object.assign(new Error("not a file"), { code: "invalid_argument" });
|
|
55017
55983
|
}
|
|
@@ -55034,7 +56000,7 @@ var WorkspaceFsService = class {
|
|
|
55034
56000
|
const slice = Buffer.alloc(toRead);
|
|
55035
56001
|
if (toRead > 0) readSync(fd, slice, 0, toRead, offset);
|
|
55036
56002
|
const content = slice.toString("base64");
|
|
55037
|
-
const hash2 =
|
|
56003
|
+
const hash2 = createHash5("sha256").update(slice).digest("hex");
|
|
55038
56004
|
this.projects.touch(projectId);
|
|
55039
56005
|
return { content, hash: hash2, encoding: "base64" };
|
|
55040
56006
|
} finally {
|
|
@@ -55047,8 +56013,8 @@ var WorkspaceFsService = class {
|
|
|
55047
56013
|
if (!resolved.ok) {
|
|
55048
56014
|
throw Object.assign(new Error(resolved.reason), { code: "invalid_argument" });
|
|
55049
56015
|
}
|
|
55050
|
-
if (
|
|
55051
|
-
const st =
|
|
56016
|
+
if (existsSync25(resolved.absolutePath) && expectedHash) {
|
|
56017
|
+
const st = statSync9(resolved.absolutePath);
|
|
55052
56018
|
if (st.size > MAX_READ_BYTES) {
|
|
55053
56019
|
throw Object.assign(
|
|
55054
56020
|
new Error(`optimistic-write target too large (${st.size} bytes; max ${MAX_READ_BYTES})`),
|
|
@@ -55060,27 +56026,27 @@ var WorkspaceFsService = class {
|
|
|
55060
56026
|
throw Object.assign(new Error("content hash mismatch"), { code: "conflict" });
|
|
55061
56027
|
}
|
|
55062
56028
|
}
|
|
55063
|
-
|
|
56029
|
+
mkdirSync12(dirname8(resolved.absolutePath), { recursive: true });
|
|
55064
56030
|
const data = typeof content === "string" ? Buffer.from(content, "utf8") : Buffer.from(content);
|
|
55065
56031
|
if (data.length > MAX_READ_BYTES) {
|
|
55066
56032
|
throw Object.assign(new Error("write payload too large"), { code: "invalid_argument" });
|
|
55067
56033
|
}
|
|
55068
56034
|
let mode = 384;
|
|
55069
|
-
if (
|
|
56035
|
+
if (existsSync25(resolved.absolutePath)) {
|
|
55070
56036
|
try {
|
|
55071
|
-
mode =
|
|
56037
|
+
mode = statSync9(resolved.absolutePath).mode & 511;
|
|
55072
56038
|
} catch {
|
|
55073
56039
|
}
|
|
55074
56040
|
}
|
|
55075
56041
|
const tmp = `${resolved.absolutePath}.tmp-${crypto.randomUUID()}`;
|
|
55076
56042
|
let renamed = false;
|
|
55077
56043
|
try {
|
|
55078
|
-
|
|
56044
|
+
writeFileSync7(tmp, data, { mode });
|
|
55079
56045
|
const again = resolveProjectPath(root, relativePath);
|
|
55080
56046
|
if (!again.ok || again.absolutePath !== resolved.absolutePath) {
|
|
55081
56047
|
throw Object.assign(new Error("path changed during write"), { code: "failed_precondition" });
|
|
55082
56048
|
}
|
|
55083
|
-
|
|
56049
|
+
renameSync3(tmp, resolved.absolutePath);
|
|
55084
56050
|
renamed = true;
|
|
55085
56051
|
} finally {
|
|
55086
56052
|
if (!renamed) {
|
|
@@ -55090,7 +56056,7 @@ var WorkspaceFsService = class {
|
|
|
55090
56056
|
}
|
|
55091
56057
|
}
|
|
55092
56058
|
}
|
|
55093
|
-
const hash2 =
|
|
56059
|
+
const hash2 = createHash5("sha256").update(data).digest("hex");
|
|
55094
56060
|
this.projects.touch(projectId);
|
|
55095
56061
|
return { hash: hash2 };
|
|
55096
56062
|
}
|
|
@@ -55129,15 +56095,15 @@ var WorkspaceFsService = class {
|
|
|
55129
56095
|
if (hits.length >= MAX_SEARCH_HITS) return;
|
|
55130
56096
|
let ents;
|
|
55131
56097
|
try {
|
|
55132
|
-
ents =
|
|
56098
|
+
ents = readdirSync7(dir, { withFileTypes: true });
|
|
55133
56099
|
} catch {
|
|
55134
56100
|
return;
|
|
55135
56101
|
}
|
|
55136
56102
|
for (const ent of ents) {
|
|
55137
56103
|
if (hits.length >= MAX_SEARCH_HITS) return;
|
|
55138
56104
|
if (ent.name === ".git" || ent.name === "node_modules") continue;
|
|
55139
|
-
const abs =
|
|
55140
|
-
const rel =
|
|
56105
|
+
const abs = join16(dir, ent.name);
|
|
56106
|
+
const rel = relative2(root, abs).split("\\").join("/");
|
|
55141
56107
|
const check2 = resolveProjectPath(root, rel);
|
|
55142
56108
|
if (!check2.ok) continue;
|
|
55143
56109
|
if (ent.isDirectory()) {
|
|
@@ -55146,9 +56112,9 @@ var WorkspaceFsService = class {
|
|
|
55146
56112
|
}
|
|
55147
56113
|
if (!ent.isFile()) continue;
|
|
55148
56114
|
try {
|
|
55149
|
-
const st =
|
|
56115
|
+
const st = statSync9(abs);
|
|
55150
56116
|
if (st.size > MAX_SEARCH_FILE_BYTES) continue;
|
|
55151
|
-
const text =
|
|
56117
|
+
const text = readFileSync9(abs, "utf8");
|
|
55152
56118
|
const lines = text.split(/\r?\n/);
|
|
55153
56119
|
for (let i = 0; i < lines.length; i++) {
|
|
55154
56120
|
if (lines[i].includes(query)) {
|
|
@@ -55210,15 +56176,15 @@ var WorkspaceFsService = class {
|
|
|
55210
56176
|
if (!resolved.ok) {
|
|
55211
56177
|
throw Object.assign(new Error(resolved.reason), { code: "invalid_argument" });
|
|
55212
56178
|
}
|
|
55213
|
-
if (
|
|
55214
|
-
const st =
|
|
56179
|
+
if (existsSync25(resolved.absolutePath)) {
|
|
56180
|
+
const st = statSync9(resolved.absolutePath);
|
|
55215
56181
|
if (!st.isDirectory()) {
|
|
55216
56182
|
throw Object.assign(new Error("path exists and is not a directory"), { code: "conflict" });
|
|
55217
56183
|
}
|
|
55218
56184
|
this.projects.touch(projectId);
|
|
55219
56185
|
return { path: rel };
|
|
55220
56186
|
}
|
|
55221
|
-
|
|
56187
|
+
mkdirSync12(resolved.absolutePath, { recursive: true });
|
|
55222
56188
|
this.projects.touch(projectId);
|
|
55223
56189
|
return { path: rel };
|
|
55224
56190
|
}
|
|
@@ -55233,13 +56199,13 @@ var WorkspaceFsService = class {
|
|
|
55233
56199
|
if (!resolved.ok) {
|
|
55234
56200
|
throw Object.assign(new Error(resolved.reason), { code: "invalid_argument" });
|
|
55235
56201
|
}
|
|
55236
|
-
if (!
|
|
56202
|
+
if (!existsSync25(resolved.absolutePath)) {
|
|
55237
56203
|
throw Object.assign(new Error("path not found"), { code: "not_found" });
|
|
55238
56204
|
}
|
|
55239
56205
|
if (resolved.absolutePath === root) {
|
|
55240
56206
|
throw Object.assign(new Error("cannot delete project root"), { code: "invalid_argument" });
|
|
55241
56207
|
}
|
|
55242
|
-
|
|
56208
|
+
rmSync3(resolved.absolutePath, { recursive: true, force: false });
|
|
55243
56209
|
this.projects.touch(projectId);
|
|
55244
56210
|
return { path: rel };
|
|
55245
56211
|
}
|
|
@@ -55257,20 +56223,20 @@ var WorkspaceFsService = class {
|
|
|
55257
56223
|
if (!from.ok) {
|
|
55258
56224
|
throw Object.assign(new Error(from.reason), { code: "invalid_argument" });
|
|
55259
56225
|
}
|
|
55260
|
-
if (!
|
|
56226
|
+
if (!existsSync25(from.absolutePath)) {
|
|
55261
56227
|
throw Object.assign(new Error("source not found"), { code: "not_found" });
|
|
55262
56228
|
}
|
|
55263
56229
|
const to = resolveProjectPath(root, toN);
|
|
55264
56230
|
if (!to.ok) {
|
|
55265
56231
|
throw Object.assign(new Error(to.reason), { code: "invalid_argument" });
|
|
55266
56232
|
}
|
|
55267
|
-
if (
|
|
56233
|
+
if (existsSync25(to.absolutePath)) {
|
|
55268
56234
|
throw Object.assign(new Error(`target already exists: ${baseNameRel(toN)}`), {
|
|
55269
56235
|
code: "conflict"
|
|
55270
56236
|
});
|
|
55271
56237
|
}
|
|
55272
|
-
|
|
55273
|
-
|
|
56238
|
+
mkdirSync12(dirname8(to.absolutePath), { recursive: true });
|
|
56239
|
+
renameSync3(from.absolutePath, to.absolutePath);
|
|
55274
56240
|
this.projects.touch(projectId);
|
|
55275
56241
|
return { from: fromN, to: toN };
|
|
55276
56242
|
}
|
|
@@ -55278,7 +56244,7 @@ var WorkspaceFsService = class {
|
|
|
55278
56244
|
function hashFileBounded(absolutePath, size) {
|
|
55279
56245
|
const fd = openSync(absolutePath, "r");
|
|
55280
56246
|
try {
|
|
55281
|
-
const hash2 =
|
|
56247
|
+
const hash2 = createHash5("sha256");
|
|
55282
56248
|
const buf = Buffer.alloc(Math.min(64 * 1024, Math.max(1, size)));
|
|
55283
56249
|
let offset = 0;
|
|
55284
56250
|
while (offset < size) {
|
|
@@ -55294,8 +56260,8 @@ function hashFileBounded(absolutePath, size) {
|
|
|
55294
56260
|
}
|
|
55295
56261
|
|
|
55296
56262
|
// src/workspace/git-service.ts
|
|
55297
|
-
import { existsSync as
|
|
55298
|
-
import { join as
|
|
56263
|
+
import { existsSync as existsSync26, mkdirSync as mkdirSync13, realpathSync as realpathSync5, rmSync as rmSync4, writeFileSync as writeFileSync8 } from "node:fs";
|
|
56264
|
+
import { join as join18, resolve as resolve9 } from "node:path";
|
|
55299
56265
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
55300
56266
|
import { randomUUID as randomUUID6 } from "node:crypto";
|
|
55301
56267
|
|
|
@@ -55490,19 +56456,19 @@ function gitRunSync(folderPath, args, env) {
|
|
|
55490
56456
|
}
|
|
55491
56457
|
|
|
55492
56458
|
// ../../packages/runtime/src/git/worktree-plan.ts
|
|
55493
|
-
import { basename as basename3, dirname as
|
|
56459
|
+
import { basename as basename3, dirname as dirname9, join as join17, resolve as resolve8, sep as sep4 } from "node:path";
|
|
55494
56460
|
import { homedir as homedir5 } from "node:os";
|
|
55495
56461
|
function resolveMainDirFromCommonDir(folderPath, gitCommonDir) {
|
|
55496
|
-
const repoRoot =
|
|
55497
|
-
return repoRoot.endsWith(`${
|
|
56462
|
+
const repoRoot = resolve8(folderPath, gitCommonDir.trim());
|
|
56463
|
+
return repoRoot.endsWith(`${sep4}.git`) || repoRoot.endsWith("/.git") ? dirname9(repoRoot) : repoRoot;
|
|
55498
56464
|
}
|
|
55499
56465
|
function planNewWorktreePaths(input) {
|
|
55500
56466
|
const home = input.homeDir ?? homedir5();
|
|
55501
56467
|
const repoName = basename3(input.mainDir);
|
|
55502
56468
|
const epoch = Math.floor((input.nowMs ?? Date.now()) / 1e3).toString(36);
|
|
55503
56469
|
const short = input.shortHash.slice(0, 7);
|
|
55504
|
-
const wtDir =
|
|
55505
|
-
const wtPath =
|
|
56470
|
+
const wtDir = join17(home, ".worktrees", repoName);
|
|
56471
|
+
const wtPath = join17(wtDir, `${epoch}-${short}`);
|
|
55506
56472
|
return { wtDir, wtPath };
|
|
55507
56473
|
}
|
|
55508
56474
|
function worktreeAddArgs(mode, wtPath, baseRef, branchName) {
|
|
@@ -55561,11 +56527,11 @@ function resolveMainWorktreeDir(folderPath) {
|
|
|
55561
56527
|
}
|
|
55562
56528
|
function samePath(a, b) {
|
|
55563
56529
|
try {
|
|
55564
|
-
const ra =
|
|
55565
|
-
const rb =
|
|
56530
|
+
const ra = existsSync26(a) ? realpathSync5(a) : resolve9(a);
|
|
56531
|
+
const rb = existsSync26(b) ? realpathSync5(b) : resolve9(b);
|
|
55566
56532
|
return ra === rb;
|
|
55567
56533
|
} catch {
|
|
55568
|
-
return
|
|
56534
|
+
return resolve9(a) === resolve9(b);
|
|
55569
56535
|
}
|
|
55570
56536
|
}
|
|
55571
56537
|
var WorkspaceGitService = class {
|
|
@@ -55594,7 +56560,7 @@ var WorkspaceGitService = class {
|
|
|
55594
56560
|
* --ignored walks the whole tree of ignored paths and dominates remote latency.
|
|
55595
56561
|
*/
|
|
55596
56562
|
statusForCwd(cwd) {
|
|
55597
|
-
if (!
|
|
56563
|
+
if (!existsSync26(join18(cwd, ".git")) && !isGitWorktree(cwd)) {
|
|
55598
56564
|
return { isRepo: false, branch: null, dirty: false, ahead: 0, behind: 0, porcelain: "" };
|
|
55599
56565
|
}
|
|
55600
56566
|
try {
|
|
@@ -55701,21 +56667,21 @@ var WorkspaceGitService = class {
|
|
|
55701
56667
|
if (worktreePath.includes("\0") || worktreePath.includes("..")) {
|
|
55702
56668
|
throw Object.assign(new Error("invalid worktree path"), { code: "invalid_argument" });
|
|
55703
56669
|
}
|
|
55704
|
-
const abs =
|
|
55705
|
-
const main2 =
|
|
55706
|
-
if (samePath(abs, main2)) return
|
|
56670
|
+
const abs = resolve9(worktreePath);
|
|
56671
|
+
const main2 = resolve9(this.root(projectId));
|
|
56672
|
+
if (samePath(abs, main2)) return existsSync26(abs) ? realpathSync5(abs) : abs;
|
|
55707
56673
|
const listed = this.worktrees(projectId);
|
|
55708
56674
|
for (const wt of listed) {
|
|
55709
56675
|
if (samePath(abs, wt.path)) {
|
|
55710
|
-
return
|
|
56676
|
+
return existsSync26(abs) ? realpathSync5(abs) : resolve9(wt.path);
|
|
55711
56677
|
}
|
|
55712
56678
|
}
|
|
55713
56679
|
try {
|
|
55714
|
-
if (
|
|
55715
|
-
const commonA =
|
|
55716
|
-
const commonB =
|
|
56680
|
+
if (existsSync26(abs) && isGitWorktree(abs)) {
|
|
56681
|
+
const commonA = resolve9(abs, git(abs, ["rev-parse", "--git-common-dir"]).trim());
|
|
56682
|
+
const commonB = resolve9(main2, git(main2, ["rev-parse", "--git-common-dir"]).trim());
|
|
55717
56683
|
if (samePath(commonA, commonB)) {
|
|
55718
|
-
return
|
|
56684
|
+
return realpathSync5(abs);
|
|
55719
56685
|
}
|
|
55720
56686
|
}
|
|
55721
56687
|
} catch {
|
|
@@ -55753,7 +56719,7 @@ var WorkspaceGitService = class {
|
|
|
55753
56719
|
mainDir,
|
|
55754
56720
|
shortHash: commitHash.slice(0, 7)
|
|
55755
56721
|
});
|
|
55756
|
-
if (!
|
|
56722
|
+
if (!existsSync26(wtDir)) mkdirSync13(wtDir, { recursive: true });
|
|
55757
56723
|
try {
|
|
55758
56724
|
const addArgs = worktreeAddArgs(mode, wtPath, baseBranch, safeBranchName);
|
|
55759
56725
|
git(folderPath, ["worktree", ...addArgs]);
|
|
@@ -55849,11 +56815,11 @@ var WorkspaceGitService = class {
|
|
|
55849
56815
|
const mainStatus = git(diff.mainDir, ["status", "--porcelain"]).trim();
|
|
55850
56816
|
if (mainStatus) return { ok: false, reason: "main-dirty" };
|
|
55851
56817
|
const patch = git(diff.worktreePath, ["diff", "--binary", diff.base, diff.tree]);
|
|
55852
|
-
const patchFile =
|
|
55853
|
-
|
|
56818
|
+
const patchFile = join18(tmpdir2(), `s1-handoff-${randomUUID6()}.patch`);
|
|
56819
|
+
writeFileSync8(patchFile, `${patch}
|
|
55854
56820
|
`);
|
|
55855
56821
|
if (git(diff.mainDir, ["status", "--porcelain"]).trim()) {
|
|
55856
|
-
|
|
56822
|
+
rmSync4(patchFile, { force: true });
|
|
55857
56823
|
return { ok: false, reason: "main-dirty" };
|
|
55858
56824
|
}
|
|
55859
56825
|
try {
|
|
@@ -55866,7 +56832,7 @@ var WorkspaceGitService = class {
|
|
|
55866
56832
|
}
|
|
55867
56833
|
return { ok: false, reason: "conflict", error: gitErrorMessage(err) };
|
|
55868
56834
|
} finally {
|
|
55869
|
-
|
|
56835
|
+
rmSync4(patchFile, { force: true });
|
|
55870
56836
|
}
|
|
55871
56837
|
try {
|
|
55872
56838
|
git(diff.mainDir, ["reset", "--quiet"]);
|
|
@@ -55911,14 +56877,14 @@ var WorkspaceGitService = class {
|
|
|
55911
56877
|
};
|
|
55912
56878
|
}
|
|
55913
56879
|
writeWorkingTree(worktreePath) {
|
|
55914
|
-
const tmpIndex =
|
|
56880
|
+
const tmpIndex = join18(tmpdir2(), `s1-handoff-${randomUUID6()}.index`);
|
|
55915
56881
|
const env = { GIT_INDEX_FILE: tmpIndex };
|
|
55916
56882
|
try {
|
|
55917
56883
|
git(worktreePath, ["read-tree", "HEAD"], env);
|
|
55918
56884
|
git(worktreePath, ["add", "-A"], env);
|
|
55919
56885
|
return git(worktreePath, ["write-tree"], env).trim();
|
|
55920
56886
|
} finally {
|
|
55921
|
-
|
|
56887
|
+
rmSync4(tmpIndex, { force: true });
|
|
55922
56888
|
}
|
|
55923
56889
|
}
|
|
55924
56890
|
repoIdentity(projectId) {
|
|
@@ -56445,9 +57411,9 @@ var WorkspaceWatchService = class {
|
|
|
56445
57411
|
try {
|
|
56446
57412
|
while (!closed) {
|
|
56447
57413
|
if (queue.length === 0) {
|
|
56448
|
-
await new Promise((
|
|
56449
|
-
wake =
|
|
56450
|
-
setTimeout(() =>
|
|
57414
|
+
await new Promise((resolve12) => {
|
|
57415
|
+
wake = resolve12;
|
|
57416
|
+
setTimeout(() => resolve12(), 100);
|
|
56451
57417
|
});
|
|
56452
57418
|
wake = null;
|
|
56453
57419
|
continue;
|
|
@@ -56504,14 +57470,14 @@ var WorkspaceWatchService = class {
|
|
|
56504
57470
|
};
|
|
56505
57471
|
|
|
56506
57472
|
// src/auth/idempotency.ts
|
|
56507
|
-
import { createHash as
|
|
57473
|
+
import { createHash as createHash6 } from "node:crypto";
|
|
56508
57474
|
var IdempotencyService = class {
|
|
56509
57475
|
constructor(db) {
|
|
56510
57476
|
this.db = db;
|
|
56511
57477
|
}
|
|
56512
57478
|
inflight = /* @__PURE__ */ new Map();
|
|
56513
57479
|
payloadHash(payload) {
|
|
56514
|
-
return
|
|
57480
|
+
return createHash6("sha256").update(JSON.stringify(payload ?? null)).digest("hex");
|
|
56515
57481
|
}
|
|
56516
57482
|
key(clientIdentity, operation, idempotencyKey) {
|
|
56517
57483
|
return `${clientIdentity}\0${operation}\0${idempotencyKey}`;
|
|
@@ -56613,22 +57579,22 @@ var IdempotencyService = class {
|
|
|
56613
57579
|
import { randomUUID as randomUUID9 } from "node:crypto";
|
|
56614
57580
|
|
|
56615
57581
|
// src/provider/secret-crypto.ts
|
|
56616
|
-
import { existsSync as
|
|
56617
|
-
import { dirname as
|
|
56618
|
-
import { createCipheriv, createDecipheriv, randomBytes as
|
|
57582
|
+
import { existsSync as existsSync27, mkdirSync as mkdirSync14, readFileSync as readFileSync10, writeFileSync as writeFileSync9, chmodSync as chmodSync2 } from "node:fs";
|
|
57583
|
+
import { dirname as dirname10 } from "node:path";
|
|
57584
|
+
import { createCipheriv, createDecipheriv, randomBytes as randomBytes4 } from "node:crypto";
|
|
56619
57585
|
var ENC_PREFIX = "enc:v1:";
|
|
56620
57586
|
var KEY_BYTES = 32;
|
|
56621
57587
|
function isEncryptedSecret(value) {
|
|
56622
57588
|
return typeof value === "string" && value.startsWith(ENC_PREFIX);
|
|
56623
57589
|
}
|
|
56624
57590
|
function ensureKeyFile(keyPath) {
|
|
56625
|
-
if (
|
|
56626
|
-
const raw =
|
|
57591
|
+
if (existsSync27(keyPath)) {
|
|
57592
|
+
const raw = readFileSync10(keyPath);
|
|
56627
57593
|
if (raw.length === KEY_BYTES) return raw;
|
|
56628
57594
|
}
|
|
56629
|
-
|
|
56630
|
-
const key =
|
|
56631
|
-
|
|
57595
|
+
mkdirSync14(dirname10(keyPath), { recursive: true, mode: 448 });
|
|
57596
|
+
const key = randomBytes4(KEY_BYTES);
|
|
57597
|
+
writeFileSync9(keyPath, key, { mode: 384 });
|
|
56632
57598
|
try {
|
|
56633
57599
|
chmodSync2(keyPath, 384);
|
|
56634
57600
|
} catch {
|
|
@@ -56641,7 +57607,7 @@ function createNodeSecretCrypto(keyPath) {
|
|
|
56641
57607
|
encrypt(plain) {
|
|
56642
57608
|
if (!plain) return "";
|
|
56643
57609
|
if (isEncryptedSecret(plain)) return plain;
|
|
56644
|
-
const iv =
|
|
57610
|
+
const iv = randomBytes4(12);
|
|
56645
57611
|
const cipher = createCipheriv("aes-256-gcm", key, iv);
|
|
56646
57612
|
const ciphertext = Buffer.concat([cipher.update(plain, "utf8"), cipher.final()]);
|
|
56647
57613
|
const tag = cipher.getAuthTag();
|
|
@@ -57385,7 +58351,7 @@ var responseViaResponseObject = async (res, outgoing, options = {}) => {
|
|
|
57385
58351
|
});
|
|
57386
58352
|
if (!chunk) {
|
|
57387
58353
|
if (i === 1) {
|
|
57388
|
-
await new Promise((
|
|
58354
|
+
await new Promise((resolve12) => setTimeout(resolve12));
|
|
57389
58355
|
maxReadCount = 3;
|
|
57390
58356
|
continue;
|
|
57391
58357
|
}
|
|
@@ -59419,9 +60385,9 @@ data:
|
|
|
59419
60385
|
const initRequest = messages.find((m) => isInitializeRequest(m));
|
|
59420
60386
|
const clientProtocolVersion = initRequest ? initRequest.params.protocolVersion : req.headers.get("mcp-protocol-version") ?? DEFAULT_NEGOTIATED_PROTOCOL_VERSION;
|
|
59421
60387
|
if (this._enableJsonResponse) {
|
|
59422
|
-
return new Promise((
|
|
60388
|
+
return new Promise((resolve12) => {
|
|
59423
60389
|
this._streamMapping.set(streamId, {
|
|
59424
|
-
resolveJson:
|
|
60390
|
+
resolveJson: resolve12,
|
|
59425
60391
|
cleanup: () => {
|
|
59426
60392
|
this._streamMapping.delete(streamId);
|
|
59427
60393
|
}
|
|
@@ -65664,7 +66630,7 @@ var Protocol = class {
|
|
|
65664
66630
|
return;
|
|
65665
66631
|
}
|
|
65666
66632
|
const pollInterval = task2.pollInterval ?? this._options?.defaultTaskPollInterval ?? 1e3;
|
|
65667
|
-
await new Promise((
|
|
66633
|
+
await new Promise((resolve12) => setTimeout(resolve12, pollInterval));
|
|
65668
66634
|
options?.signal?.throwIfAborted();
|
|
65669
66635
|
}
|
|
65670
66636
|
} catch (error51) {
|
|
@@ -65681,7 +66647,7 @@ var Protocol = class {
|
|
|
65681
66647
|
*/
|
|
65682
66648
|
request(request, resultSchema, options) {
|
|
65683
66649
|
const { relatedRequestId, resumptionToken, onresumptiontoken, task, relatedTask } = options ?? {};
|
|
65684
|
-
return new Promise((
|
|
66650
|
+
return new Promise((resolve12, reject) => {
|
|
65685
66651
|
const earlyReject = (error51) => {
|
|
65686
66652
|
reject(error51);
|
|
65687
66653
|
};
|
|
@@ -65759,7 +66725,7 @@ var Protocol = class {
|
|
|
65759
66725
|
if (!parseResult.success) {
|
|
65760
66726
|
reject(parseResult.error);
|
|
65761
66727
|
} else {
|
|
65762
|
-
|
|
66728
|
+
resolve12(parseResult.data);
|
|
65763
66729
|
}
|
|
65764
66730
|
} catch (error51) {
|
|
65765
66731
|
reject(error51);
|
|
@@ -66020,12 +66986,12 @@ var Protocol = class {
|
|
|
66020
66986
|
}
|
|
66021
66987
|
} catch {
|
|
66022
66988
|
}
|
|
66023
|
-
return new Promise((
|
|
66989
|
+
return new Promise((resolve12, reject) => {
|
|
66024
66990
|
if (signal.aborted) {
|
|
66025
66991
|
reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
|
|
66026
66992
|
return;
|
|
66027
66993
|
}
|
|
66028
|
-
const timeoutId = setTimeout(
|
|
66994
|
+
const timeoutId = setTimeout(resolve12, interval);
|
|
66029
66995
|
signal.addEventListener("abort", () => {
|
|
66030
66996
|
clearTimeout(timeoutId);
|
|
66031
66997
|
reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
|
|
@@ -67129,7 +68095,7 @@ var McpServer = class {
|
|
|
67129
68095
|
let task = createTaskResult.task;
|
|
67130
68096
|
const pollInterval = task.pollInterval ?? 5e3;
|
|
67131
68097
|
while (task.status !== "completed" && task.status !== "failed" && task.status !== "cancelled") {
|
|
67132
|
-
await new Promise((
|
|
68098
|
+
await new Promise((resolve12) => setTimeout(resolve12, pollInterval));
|
|
67133
68099
|
const updatedTask = await extra.taskStore.getTask(taskId);
|
|
67134
68100
|
if (!updatedTask) {
|
|
67135
68101
|
throw new McpError(ErrorCode.InternalError, `Task ${taskId} not found during polling`);
|
|
@@ -68036,11 +69002,11 @@ async function startHostActionMcpServer(opts) {
|
|
|
68036
69002
|
writeHttpError(res, 500, err instanceof Error ? err.message : "Internal MCP server error");
|
|
68037
69003
|
}
|
|
68038
69004
|
}
|
|
68039
|
-
await new Promise((
|
|
69005
|
+
await new Promise((resolve12, reject) => {
|
|
68040
69006
|
httpServer.once("error", reject);
|
|
68041
69007
|
httpServer.listen(0, "127.0.0.1", () => {
|
|
68042
69008
|
httpServer.off("error", reject);
|
|
68043
|
-
|
|
69009
|
+
resolve12();
|
|
68044
69010
|
});
|
|
68045
69011
|
});
|
|
68046
69012
|
const address = httpServer.address();
|
|
@@ -68091,8 +69057,8 @@ async function startHostActionMcpServer(opts) {
|
|
|
68091
69057
|
}
|
|
68092
69058
|
httpSessions.clear();
|
|
68093
69059
|
httpSessionsBySuperone.clear();
|
|
68094
|
-
await new Promise((
|
|
68095
|
-
httpServer.close(() =>
|
|
69060
|
+
await new Promise((resolve12) => {
|
|
69061
|
+
httpServer.close(() => resolve12());
|
|
68096
69062
|
});
|
|
68097
69063
|
}
|
|
68098
69064
|
};
|
|
@@ -68178,7 +69144,7 @@ async function startNodeRuntime(partial2 = {}) {
|
|
|
68178
69144
|
startedAt,
|
|
68179
69145
|
simulatedHarness
|
|
68180
69146
|
});
|
|
68181
|
-
|
|
69147
|
+
writeFileSync10(
|
|
68182
69148
|
paths.runtimeJson,
|
|
68183
69149
|
JSON.stringify(
|
|
68184
69150
|
{
|
|
@@ -68246,9 +69212,9 @@ function createLocalPairingToken(nodeHome) {
|
|
|
68246
69212
|
}
|
|
68247
69213
|
function readRuntimeStatus(nodeHome) {
|
|
68248
69214
|
const paths = nodePaths(resolveRuntimeConfig({ nodeHome }).nodeHome);
|
|
68249
|
-
if (!
|
|
69215
|
+
if (!existsSync28(paths.runtimeJson)) return null;
|
|
68250
69216
|
try {
|
|
68251
|
-
return JSON.parse(
|
|
69217
|
+
return JSON.parse(readFileSync11(paths.runtimeJson, "utf8"));
|
|
68252
69218
|
} catch {
|
|
68253
69219
|
return null;
|
|
68254
69220
|
}
|
|
@@ -68256,8 +69222,8 @@ function readRuntimeStatus(nodeHome) {
|
|
|
68256
69222
|
|
|
68257
69223
|
// src/systemd/install.ts
|
|
68258
69224
|
import { spawnSync } from "node:child_process";
|
|
68259
|
-
import { chmodSync as chmodSync3, existsSync as
|
|
68260
|
-
import { dirname as
|
|
69225
|
+
import { chmodSync as chmodSync3, existsSync as existsSync29, mkdirSync as mkdirSync15, unlinkSync as unlinkSync2, writeFileSync as writeFileSync11 } from "node:fs";
|
|
69226
|
+
import { dirname as dirname11 } from "node:path";
|
|
68261
69227
|
|
|
68262
69228
|
// src/systemd/unit.ts
|
|
68263
69229
|
function renderSystemdUserUnit(opts) {
|
|
@@ -68314,8 +69280,8 @@ function checkLinger(user) {
|
|
|
68314
69280
|
return { enabled: null, raw };
|
|
68315
69281
|
}
|
|
68316
69282
|
function writeSystemdUserUnit(opts, unitPath = systemdUserUnitPath()) {
|
|
68317
|
-
|
|
68318
|
-
|
|
69283
|
+
mkdirSync15(dirname11(unitPath), { recursive: true });
|
|
69284
|
+
writeFileSync11(unitPath, renderSystemdUserUnit(opts), { encoding: "utf8", mode: 420 });
|
|
68319
69285
|
try {
|
|
68320
69286
|
chmodSync3(unitPath, 420);
|
|
68321
69287
|
} catch {
|
|
@@ -68368,7 +69334,7 @@ function uninstallSystemdUserService(removeUnitFile = true) {
|
|
|
68368
69334
|
}
|
|
68369
69335
|
if (removeUnitFile) {
|
|
68370
69336
|
const path = systemdUserUnitPath();
|
|
68371
|
-
if (
|
|
69337
|
+
if (existsSync29(path)) {
|
|
68372
69338
|
try {
|
|
68373
69339
|
unlinkSync2(path);
|
|
68374
69340
|
} catch (err) {
|
|
@@ -68391,452 +69357,9 @@ function systemdUserStatus() {
|
|
|
68391
69357
|
|
|
68392
69358
|
// src/session/harness-cli.ts
|
|
68393
69359
|
init_environment();
|
|
68394
|
-
import { accessSync, constants, existsSync as
|
|
68395
|
-
import { isAbsolute as
|
|
69360
|
+
import { accessSync as accessSync2, constants as constants2, existsSync as existsSync30, realpathSync as realpathSync6, statSync as statSync10 } from "node:fs";
|
|
69361
|
+
import { isAbsolute as isAbsolute4, resolve as resolve10 } from "node:path";
|
|
68396
69362
|
import { homedir as homedir6 } from "node:os";
|
|
68397
|
-
|
|
68398
|
-
// src/session/managed-harness-release.ts
|
|
68399
|
-
import {
|
|
68400
|
-
copyFileSync,
|
|
68401
|
-
createReadStream,
|
|
68402
|
-
existsSync as existsSync27,
|
|
68403
|
-
mkdirSync as mkdirSync14,
|
|
68404
|
-
mkdtempSync,
|
|
68405
|
-
readFileSync as readFileSync10,
|
|
68406
|
-
renameSync as renameSync3,
|
|
68407
|
-
rmSync as rmSync4,
|
|
68408
|
-
statSync as statSync7,
|
|
68409
|
-
writeFileSync as writeFileSync11
|
|
68410
|
-
} from "node:fs";
|
|
68411
|
-
import { createHash as createHash6, randomBytes as randomBytes4 } from "node:crypto";
|
|
68412
|
-
import { dirname as dirname11, join as join17, relative as relative2, resolve as resolve7, sep as sep4 } from "node:path";
|
|
68413
|
-
import { arch as osArch, platform as osPlatform } from "node:os";
|
|
68414
|
-
|
|
68415
|
-
// src/cli-release-version.ts
|
|
68416
|
-
import { existsSync as existsSync26, readFileSync as readFileSync9 } from "node:fs";
|
|
68417
|
-
import { dirname as dirname10, join as join16 } from "node:path";
|
|
68418
|
-
import { fileURLToPath } from "node:url";
|
|
68419
|
-
function resolveCliReleaseVersion() {
|
|
68420
|
-
const fromEnv = process.env.SUPERONE_CLI_VERSION?.trim();
|
|
68421
|
-
if (fromEnv) return fromEnv;
|
|
68422
|
-
if ("0.49.4-alpha".trim()) {
|
|
68423
|
-
return "0.49.4-alpha".trim();
|
|
68424
|
-
}
|
|
68425
|
-
const fromDist = readDistManifestVersion();
|
|
68426
|
-
if (fromDist) return fromDist;
|
|
68427
|
-
const fromRepo = readMonorepoPackageVersion();
|
|
68428
|
-
if (fromRepo) return fromRepo;
|
|
68429
|
-
throw new Error(
|
|
68430
|
-
"unable to determine CLI version for harness release coupling (set SUPERONE_CLI_VERSION or use a built dist with MANIFEST.json)"
|
|
68431
|
-
);
|
|
68432
|
-
}
|
|
68433
|
-
function readDistManifestVersion() {
|
|
68434
|
-
try {
|
|
68435
|
-
const here = dirname10(fileURLToPath(import.meta.url));
|
|
68436
|
-
const candidates = [
|
|
68437
|
-
join16(here, "..", "MANIFEST.json"),
|
|
68438
|
-
join16(here, "MANIFEST.json"),
|
|
68439
|
-
join16(here, "..", "..", "MANIFEST.json")
|
|
68440
|
-
];
|
|
68441
|
-
for (const p of candidates) {
|
|
68442
|
-
if (!existsSync26(p)) continue;
|
|
68443
|
-
const raw = JSON.parse(readFileSync9(p, "utf8"));
|
|
68444
|
-
if (typeof raw.version === "string" && raw.version.trim()) return raw.version.trim();
|
|
68445
|
-
}
|
|
68446
|
-
} catch {
|
|
68447
|
-
return null;
|
|
68448
|
-
}
|
|
68449
|
-
return null;
|
|
68450
|
-
}
|
|
68451
|
-
function readMonorepoPackageVersion() {
|
|
68452
|
-
try {
|
|
68453
|
-
const here = dirname10(fileURLToPath(import.meta.url));
|
|
68454
|
-
const rootPkg = join16(here, "..", "..", "..", "package.json");
|
|
68455
|
-
if (!existsSync26(rootPkg)) return null;
|
|
68456
|
-
const raw = JSON.parse(readFileSync9(rootPkg, "utf8"));
|
|
68457
|
-
if (typeof raw.version === "string" && raw.version.trim()) return raw.version.trim();
|
|
68458
|
-
} catch {
|
|
68459
|
-
return null;
|
|
68460
|
-
}
|
|
68461
|
-
return null;
|
|
68462
|
-
}
|
|
68463
|
-
|
|
68464
|
-
// src/session/managed-harness-release.ts
|
|
68465
|
-
var MANAGED_PAYLOAD_BASENAME = "payload.bin";
|
|
68466
|
-
var MANAGED_META_BASENAME = "artifact.json";
|
|
68467
|
-
var MANAGED_CURRENT_BASENAME = "current";
|
|
68468
|
-
var MAX_SEGMENT_LEN = 64;
|
|
68469
|
-
var SAFE_SEGMENT = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/;
|
|
68470
|
-
function currentCliVersion() {
|
|
68471
|
-
const v = resolveCliReleaseVersion();
|
|
68472
|
-
return assertSafePathSegment(v, "cli version");
|
|
68473
|
-
}
|
|
68474
|
-
function currentHostPlatform() {
|
|
68475
|
-
const p = osPlatform();
|
|
68476
|
-
if (p === "darwin") return "darwin";
|
|
68477
|
-
if (p === "linux") return "linux";
|
|
68478
|
-
if (p === "win32") return "windows";
|
|
68479
|
-
throw new Error(`unsupported host platform for managed harnesses: ${p}`);
|
|
68480
|
-
}
|
|
68481
|
-
function currentHostArch() {
|
|
68482
|
-
const a = osArch();
|
|
68483
|
-
if (a === "arm64") return "arm64";
|
|
68484
|
-
if (a === "x64") return "x64";
|
|
68485
|
-
throw new Error(`unsupported host arch for managed harnesses: ${a}`);
|
|
68486
|
-
}
|
|
68487
|
-
function isManagedHarnessId(id) {
|
|
68488
|
-
return id === "claude" || id === "codex";
|
|
68489
|
-
}
|
|
68490
|
-
function assertSafePathSegment(value, label) {
|
|
68491
|
-
const v = value.trim();
|
|
68492
|
-
if (!v) throw new Error(`${label} must be non-empty`);
|
|
68493
|
-
if (v.length > MAX_SEGMENT_LEN) throw new Error(`${label} exceeds ${MAX_SEGMENT_LEN} chars`);
|
|
68494
|
-
if (v === "." || v === "..") throw new Error(`${label} must not be '.' or '..'`);
|
|
68495
|
-
if (v.includes("/") || v.includes("\\") || v.includes("\0")) {
|
|
68496
|
-
throw new Error(`${label} must be a single path segment`);
|
|
68497
|
-
}
|
|
68498
|
-
if (!SAFE_SEGMENT.test(v)) {
|
|
68499
|
-
throw new Error(`${label} contains invalid characters`);
|
|
68500
|
-
}
|
|
68501
|
-
if (/^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\.|$)/i.test(v)) {
|
|
68502
|
-
throw new Error(`${label} is a reserved name`);
|
|
68503
|
-
}
|
|
68504
|
-
return v;
|
|
68505
|
-
}
|
|
68506
|
-
function parseHarnessReleaseManifest(raw) {
|
|
68507
|
-
if (!raw || typeof raw !== "object") {
|
|
68508
|
-
throw new Error("release manifest must be an object");
|
|
68509
|
-
}
|
|
68510
|
-
const obj = raw;
|
|
68511
|
-
if (typeof obj.cliVersion !== "string") {
|
|
68512
|
-
throw new Error("release manifest missing cliVersion");
|
|
68513
|
-
}
|
|
68514
|
-
const cliVersion = assertSafePathSegment(obj.cliVersion, "cliVersion");
|
|
68515
|
-
const mh = obj.managedHarnesses;
|
|
68516
|
-
if (!mh || typeof mh !== "object") {
|
|
68517
|
-
throw new Error("release manifest missing managedHarnesses");
|
|
68518
|
-
}
|
|
68519
|
-
const managedHarnesses = {};
|
|
68520
|
-
for (const id of ["claude", "codex"]) {
|
|
68521
|
-
const entry = mh[id];
|
|
68522
|
-
if (entry == null) continue;
|
|
68523
|
-
managedHarnesses[id] = parseManagedHarnessPin(id, entry);
|
|
68524
|
-
}
|
|
68525
|
-
return { cliVersion, managedHarnesses };
|
|
68526
|
-
}
|
|
68527
|
-
function parseManagedHarnessPin(id, raw) {
|
|
68528
|
-
if (!raw || typeof raw !== "object") {
|
|
68529
|
-
throw new Error(`manifest harness ${id} must be an object`);
|
|
68530
|
-
}
|
|
68531
|
-
const o = raw;
|
|
68532
|
-
if (typeof o.runtimeVersion !== "string" || typeof o.artifactVersion !== "string") {
|
|
68533
|
-
throw new Error(`manifest harness ${id} missing runtimeVersion/artifactVersion`);
|
|
68534
|
-
}
|
|
68535
|
-
const runtimeVersion = assertSafePathSegment(o.runtimeVersion, `${id}.runtimeVersion`);
|
|
68536
|
-
const artifactVersion = assertSafePathSegment(o.artifactVersion, `${id}.artifactVersion`);
|
|
68537
|
-
if (!Array.isArray(o.artifacts) || o.artifacts.length === 0) {
|
|
68538
|
-
throw new Error(`manifest harness ${id} must list artifacts`);
|
|
68539
|
-
}
|
|
68540
|
-
const seen = /* @__PURE__ */ new Set();
|
|
68541
|
-
const artifacts = o.artifacts.map((a, i) => {
|
|
68542
|
-
if (!a || typeof a !== "object") throw new Error(`manifest ${id} artifacts[${i}] invalid`);
|
|
68543
|
-
const art = a;
|
|
68544
|
-
const platform2 = art.platform;
|
|
68545
|
-
const arch2 = art.arch;
|
|
68546
|
-
const digest = art.digestSha256;
|
|
68547
|
-
if (platform2 !== "darwin" && platform2 !== "linux" && platform2 !== "windows") {
|
|
68548
|
-
throw new Error(`manifest ${id} artifacts[${i}] invalid platform`);
|
|
68549
|
-
}
|
|
68550
|
-
if (arch2 !== "arm64" && arch2 !== "x64") {
|
|
68551
|
-
throw new Error(`manifest ${id} artifacts[${i}] invalid arch`);
|
|
68552
|
-
}
|
|
68553
|
-
if (typeof digest !== "string" || !/^[a-f0-9]{64}$/i.test(digest)) {
|
|
68554
|
-
throw new Error(`manifest ${id} artifacts[${i}] digestSha256 must be 64 hex chars`);
|
|
68555
|
-
}
|
|
68556
|
-
const key = `${platform2}/${arch2}`;
|
|
68557
|
-
if (seen.has(key)) {
|
|
68558
|
-
throw new Error(`manifest ${id} has duplicate artifact pin for ${key}`);
|
|
68559
|
-
}
|
|
68560
|
-
seen.add(key);
|
|
68561
|
-
let fileName;
|
|
68562
|
-
if (typeof art.fileName === "string") {
|
|
68563
|
-
if (art.fileName.includes("/") || art.fileName.includes("\\") || art.fileName.includes("\0")) {
|
|
68564
|
-
throw new Error(`manifest ${id} artifacts[${i}] fileName must not contain path separators`);
|
|
68565
|
-
}
|
|
68566
|
-
fileName = art.fileName.slice(0, 128);
|
|
68567
|
-
}
|
|
68568
|
-
return {
|
|
68569
|
-
platform: platform2,
|
|
68570
|
-
arch: arch2,
|
|
68571
|
-
digestSha256: digest.toLowerCase(),
|
|
68572
|
-
fileName
|
|
68573
|
-
};
|
|
68574
|
-
});
|
|
68575
|
-
return { runtimeVersion, artifactVersion, artifacts };
|
|
68576
|
-
}
|
|
68577
|
-
function loadHarnessReleaseManifest(nodeHome) {
|
|
68578
|
-
const fromEnv = process.env.SUPERONE_HARNESS_MANIFEST;
|
|
68579
|
-
if (fromEnv) {
|
|
68580
|
-
if (!existsSync27(fromEnv)) {
|
|
68581
|
-
throw new Error(`SUPERONE_HARNESS_MANIFEST not found: ${fromEnv}`);
|
|
68582
|
-
}
|
|
68583
|
-
return parseHarnessReleaseManifest(JSON.parse(readFileSync10(fromEnv, "utf8")));
|
|
68584
|
-
}
|
|
68585
|
-
const local = join17(nodeHome, "release-manifest.json");
|
|
68586
|
-
if (existsSync27(local)) {
|
|
68587
|
-
return parseHarnessReleaseManifest(JSON.parse(readFileSync10(local, "utf8")));
|
|
68588
|
-
}
|
|
68589
|
-
return null;
|
|
68590
|
-
}
|
|
68591
|
-
function selectArtifactPin(pin, platform2 = currentHostPlatform(), arch2 = currentHostArch()) {
|
|
68592
|
-
const match = pin.artifacts.find((a) => a.platform === platform2 && a.arch === arch2);
|
|
68593
|
-
if (!match) {
|
|
68594
|
-
throw new Error(
|
|
68595
|
-
`no managed artifact pin for ${platform2}/${arch2} (available: ${pin.artifacts.map((a) => `${a.platform}/${a.arch}`).join(", ")})`
|
|
68596
|
-
);
|
|
68597
|
-
}
|
|
68598
|
-
return match;
|
|
68599
|
-
}
|
|
68600
|
-
async function sha256File(path) {
|
|
68601
|
-
return new Promise((resolveHash, reject) => {
|
|
68602
|
-
const hash2 = createHash6("sha256");
|
|
68603
|
-
const stream = createReadStream(path);
|
|
68604
|
-
stream.on("data", (chunk) => hash2.update(chunk));
|
|
68605
|
-
stream.on("error", reject);
|
|
68606
|
-
stream.on("end", () => resolveHash(hash2.digest("hex")));
|
|
68607
|
-
});
|
|
68608
|
-
}
|
|
68609
|
-
function releasesRoot(nodeHome) {
|
|
68610
|
-
return resolve7(nodeHome, "releases");
|
|
68611
|
-
}
|
|
68612
|
-
function harnessVersionDir(nodeHome, cliVersion, harnessId, artifactVersion) {
|
|
68613
|
-
const cli = assertSafePathSegment(cliVersion, "cliVersion");
|
|
68614
|
-
const ver = assertSafePathSegment(artifactVersion, "artifactVersion");
|
|
68615
|
-
const root = releasesRoot(nodeHome);
|
|
68616
|
-
const dest = resolve7(root, cli, "harnesses", harnessId, ver);
|
|
68617
|
-
assertPathInside(dest, resolve7(root, cli, "harnesses", harnessId), "version install dir");
|
|
68618
|
-
return dest;
|
|
68619
|
-
}
|
|
68620
|
-
function assertPathInside(path, root, label) {
|
|
68621
|
-
const resolvedPath = resolve7(path);
|
|
68622
|
-
const resolvedRoot = resolve7(root);
|
|
68623
|
-
const rel = relative2(resolvedRoot, resolvedPath);
|
|
68624
|
-
if (rel.startsWith("..") || rel === "..") {
|
|
68625
|
-
throw new Error(`${label} escapes install root: ${resolvedPath}`);
|
|
68626
|
-
}
|
|
68627
|
-
if (rel.startsWith("/") || /^[A-Za-z]:/.test(rel)) {
|
|
68628
|
-
throw new Error(`${label} escapes install root: ${resolvedPath}`);
|
|
68629
|
-
}
|
|
68630
|
-
if (resolvedPath !== resolvedRoot && !resolvedPath.startsWith(resolvedRoot + sep4)) {
|
|
68631
|
-
throw new Error(`${label} escapes install root: ${resolvedPath}`);
|
|
68632
|
-
}
|
|
68633
|
-
}
|
|
68634
|
-
function assertStrictChild(path, parent, label) {
|
|
68635
|
-
const resolvedPath = resolve7(path);
|
|
68636
|
-
const resolvedParent = resolve7(parent);
|
|
68637
|
-
if (resolvedPath === resolvedParent) {
|
|
68638
|
-
throw new Error(`${label} must be a child of ${resolvedParent}`);
|
|
68639
|
-
}
|
|
68640
|
-
assertPathInside(resolvedPath, resolvedParent, label);
|
|
68641
|
-
}
|
|
68642
|
-
async function installManagedArtifactFromFile(opts) {
|
|
68643
|
-
const mode = opts.mode ?? "enable";
|
|
68644
|
-
const expected = opts.expectedCliVersion ?? currentCliVersion();
|
|
68645
|
-
if (opts.manifest.cliVersion !== expected) {
|
|
68646
|
-
throw new Error(
|
|
68647
|
-
`release manifest cliVersion ${opts.manifest.cliVersion} does not match CLI ${expected}`
|
|
68648
|
-
);
|
|
68649
|
-
}
|
|
68650
|
-
const pin = opts.manifest.managedHarnesses[opts.harnessId];
|
|
68651
|
-
if (!pin) {
|
|
68652
|
-
throw new Error(`release manifest does not pin managed harness ${opts.harnessId}`);
|
|
68653
|
-
}
|
|
68654
|
-
const art = selectArtifactPin(pin);
|
|
68655
|
-
if (!existsSync27(opts.artifactPath)) {
|
|
68656
|
-
throw new Error(`artifact not found: ${opts.artifactPath}`);
|
|
68657
|
-
}
|
|
68658
|
-
if (!statSync7(opts.artifactPath).isFile()) {
|
|
68659
|
-
throw new Error(`artifact is not a regular file: ${opts.artifactPath}`);
|
|
68660
|
-
}
|
|
68661
|
-
const digest = await sha256File(opts.artifactPath);
|
|
68662
|
-
if (digest !== art.digestSha256) {
|
|
68663
|
-
throw new Error(
|
|
68664
|
-
`artifact digest mismatch for ${opts.harnessId}: expected ${art.digestSha256}, got ${digest}`
|
|
68665
|
-
);
|
|
68666
|
-
}
|
|
68667
|
-
const destDir = harnessVersionDir(
|
|
68668
|
-
opts.nodeHome,
|
|
68669
|
-
opts.manifest.cliVersion,
|
|
68670
|
-
opts.harnessId,
|
|
68671
|
-
pin.artifactVersion
|
|
68672
|
-
);
|
|
68673
|
-
const finalFile = join17(destDir, MANAGED_PAYLOAD_BASENAME);
|
|
68674
|
-
const metaPath = join17(destDir, MANAGED_META_BASENAME);
|
|
68675
|
-
assertStrictChild(finalFile, destDir, "payload path");
|
|
68676
|
-
assertStrictChild(metaPath, destDir, "meta path");
|
|
68677
|
-
const metaBody = JSON.stringify(
|
|
68678
|
-
{
|
|
68679
|
-
harnessId: opts.harnessId,
|
|
68680
|
-
cliVersion: opts.manifest.cliVersion,
|
|
68681
|
-
runtimeVersion: pin.runtimeVersion,
|
|
68682
|
-
artifactVersion: pin.artifactVersion,
|
|
68683
|
-
platform: art.platform,
|
|
68684
|
-
arch: art.arch,
|
|
68685
|
-
digestSha256: art.digestSha256,
|
|
68686
|
-
displayFileName: art.fileName ?? null,
|
|
68687
|
-
installedAt: Date.now()
|
|
68688
|
-
},
|
|
68689
|
-
null,
|
|
68690
|
-
2
|
|
68691
|
-
);
|
|
68692
|
-
let reusedExisting = false;
|
|
68693
|
-
if (existsSync27(destDir)) {
|
|
68694
|
-
const payloadOk = existsSync27(finalFile) && statSync7(finalFile).isFile() && await sha256File(finalFile) === art.digestSha256;
|
|
68695
|
-
if (payloadOk) {
|
|
68696
|
-
reusedExisting = true;
|
|
68697
|
-
} else if (mode === "repair") {
|
|
68698
|
-
await replacePayloadAtomically({
|
|
68699
|
-
destDir,
|
|
68700
|
-
finalFile,
|
|
68701
|
-
metaPath,
|
|
68702
|
-
sourceArtifact: opts.artifactPath,
|
|
68703
|
-
expectedDigest: art.digestSha256,
|
|
68704
|
-
metaBody
|
|
68705
|
-
});
|
|
68706
|
-
reusedExisting = false;
|
|
68707
|
-
} else {
|
|
68708
|
-
throw new Error(
|
|
68709
|
-
`existing install digest mismatch for ${opts.harnessId}@${pin.artifactVersion}: refusing to overwrite (use harness repair)`
|
|
68710
|
-
);
|
|
68711
|
-
}
|
|
68712
|
-
} else {
|
|
68713
|
-
const harnessRoot2 = dirname11(destDir);
|
|
68714
|
-
mkdirSync14(harnessRoot2, { recursive: true });
|
|
68715
|
-
assertPathInside(destDir, harnessRoot2, "version dir");
|
|
68716
|
-
const stagingDir = mkdtempSync(
|
|
68717
|
-
join17(harnessRoot2, `.staging-${opts.harnessId}-${randomBytes4(8).toString("hex")}-`)
|
|
68718
|
-
);
|
|
68719
|
-
assertPathInside(stagingDir, harnessRoot2, "staging dir");
|
|
68720
|
-
const stagingFile = join17(stagingDir, MANAGED_PAYLOAD_BASENAME);
|
|
68721
|
-
const stagingMeta = join17(stagingDir, MANAGED_META_BASENAME);
|
|
68722
|
-
try {
|
|
68723
|
-
copyFileSync(opts.artifactPath, stagingFile);
|
|
68724
|
-
const stagedDigest = await sha256File(stagingFile);
|
|
68725
|
-
if (stagedDigest !== art.digestSha256) {
|
|
68726
|
-
throw new Error(`staged artifact digest mismatch for ${opts.harnessId}`);
|
|
68727
|
-
}
|
|
68728
|
-
writeFileSync11(stagingMeta, metaBody, "utf8");
|
|
68729
|
-
renameSync3(stagingDir, destDir);
|
|
68730
|
-
} catch (err) {
|
|
68731
|
-
rmSync4(stagingDir, { recursive: true, force: true });
|
|
68732
|
-
if (existsSync27(destDir) && existsSync27(finalFile)) {
|
|
68733
|
-
const existingDigest = await sha256File(finalFile);
|
|
68734
|
-
if (existingDigest === art.digestSha256) {
|
|
68735
|
-
reusedExisting = true;
|
|
68736
|
-
} else if (mode === "repair") {
|
|
68737
|
-
await replacePayloadAtomically({
|
|
68738
|
-
destDir,
|
|
68739
|
-
finalFile,
|
|
68740
|
-
metaPath,
|
|
68741
|
-
sourceArtifact: opts.artifactPath,
|
|
68742
|
-
expectedDigest: art.digestSha256,
|
|
68743
|
-
metaBody
|
|
68744
|
-
});
|
|
68745
|
-
} else {
|
|
68746
|
-
throw err;
|
|
68747
|
-
}
|
|
68748
|
-
} else {
|
|
68749
|
-
throw err;
|
|
68750
|
-
}
|
|
68751
|
-
}
|
|
68752
|
-
}
|
|
68753
|
-
const finalDigest = await sha256File(finalFile);
|
|
68754
|
-
if (finalDigest !== art.digestSha256) {
|
|
68755
|
-
throw new Error(`final payload digest mismatch for ${opts.harnessId}`);
|
|
68756
|
-
}
|
|
68757
|
-
const harnessRoot = join17(
|
|
68758
|
-
releasesRoot(opts.nodeHome),
|
|
68759
|
-
opts.manifest.cliVersion,
|
|
68760
|
-
"harnesses",
|
|
68761
|
-
opts.harnessId
|
|
68762
|
-
);
|
|
68763
|
-
assertPathInside(harnessRoot, releasesRoot(opts.nodeHome), "harness root");
|
|
68764
|
-
mkdirSync14(harnessRoot, { recursive: true });
|
|
68765
|
-
const currentPath = join17(harnessRoot, MANAGED_CURRENT_BASENAME);
|
|
68766
|
-
const currentTmp = join17(
|
|
68767
|
-
harnessRoot,
|
|
68768
|
-
`.${MANAGED_CURRENT_BASENAME}.${process.pid}.${randomBytes4(6).toString("hex")}.tmp`
|
|
68769
|
-
);
|
|
68770
|
-
assertStrictChild(currentTmp, harnessRoot, "current pointer temp");
|
|
68771
|
-
try {
|
|
68772
|
-
writeFileSync11(
|
|
68773
|
-
currentTmp,
|
|
68774
|
-
JSON.stringify(
|
|
68775
|
-
{
|
|
68776
|
-
artifactVersion: pin.artifactVersion,
|
|
68777
|
-
installPath: finalFile,
|
|
68778
|
-
digestSha256: art.digestSha256,
|
|
68779
|
-
runtimeVersion: pin.runtimeVersion
|
|
68780
|
-
},
|
|
68781
|
-
null,
|
|
68782
|
-
2
|
|
68783
|
-
),
|
|
68784
|
-
"utf8"
|
|
68785
|
-
);
|
|
68786
|
-
renameSync3(currentTmp, currentPath);
|
|
68787
|
-
} catch (err) {
|
|
68788
|
-
rmSync4(currentTmp, { force: true });
|
|
68789
|
-
throw err;
|
|
68790
|
-
}
|
|
68791
|
-
return {
|
|
68792
|
-
harnessId: opts.harnessId,
|
|
68793
|
-
cliVersion: opts.manifest.cliVersion,
|
|
68794
|
-
runtimeVersion: pin.runtimeVersion,
|
|
68795
|
-
artifactVersion: pin.artifactVersion,
|
|
68796
|
-
digestSha256: art.digestSha256,
|
|
68797
|
-
installPath: finalFile,
|
|
68798
|
-
source: "offline-artifact",
|
|
68799
|
-
reusedExisting
|
|
68800
|
-
};
|
|
68801
|
-
}
|
|
68802
|
-
async function replacePayloadAtomically(opts) {
|
|
68803
|
-
mkdirSync14(opts.destDir, { recursive: true });
|
|
68804
|
-
const nonce = randomBytes4(8).toString("hex");
|
|
68805
|
-
const payloadTmp = join17(opts.destDir, `.${MANAGED_PAYLOAD_BASENAME}.${nonce}.tmp`);
|
|
68806
|
-
const metaTmp = join17(opts.destDir, `.${MANAGED_META_BASENAME}.${nonce}.tmp`);
|
|
68807
|
-
assertStrictChild(payloadTmp, opts.destDir, "payload temp");
|
|
68808
|
-
assertStrictChild(metaTmp, opts.destDir, "meta temp");
|
|
68809
|
-
try {
|
|
68810
|
-
copyFileSync(opts.sourceArtifact, payloadTmp);
|
|
68811
|
-
const d = await sha256File(payloadTmp);
|
|
68812
|
-
if (d !== opts.expectedDigest) {
|
|
68813
|
-
throw new Error(`repair staged digest mismatch: expected ${opts.expectedDigest}, got ${d}`);
|
|
68814
|
-
}
|
|
68815
|
-
writeFileSync11(metaTmp, opts.metaBody, "utf8");
|
|
68816
|
-
renameSync3(payloadTmp, opts.finalFile);
|
|
68817
|
-
renameSync3(metaTmp, opts.metaPath);
|
|
68818
|
-
} catch (err) {
|
|
68819
|
-
rmSync4(payloadTmp, { force: true });
|
|
68820
|
-
rmSync4(metaTmp, { force: true });
|
|
68821
|
-
throw err;
|
|
68822
|
-
}
|
|
68823
|
-
}
|
|
68824
|
-
function describeExpectedArtifact(harnessId, manifest) {
|
|
68825
|
-
const pin = manifest.managedHarnesses[harnessId];
|
|
68826
|
-
if (!pin) return `harness ${harnessId} is not pinned in the release manifest`;
|
|
68827
|
-
try {
|
|
68828
|
-
const art = selectArtifactPin(pin);
|
|
68829
|
-
return `${harnessId} requires offline --artifact matching ${art.platform}/${art.arch} digest ${art.digestSha256} (runtime ${pin.runtimeVersion}, artifact ${pin.artifactVersion}); network download is not enabled in Stage 3`;
|
|
68830
|
-
} catch (err) {
|
|
68831
|
-
return err instanceof Error ? err.message : String(err);
|
|
68832
|
-
}
|
|
68833
|
-
}
|
|
68834
|
-
function requiredRuntimeVersion(harnessId, manifest) {
|
|
68835
|
-
if (harnessId !== "claude" && harnessId !== "codex") return null;
|
|
68836
|
-
return manifest?.managedHarnesses[harnessId]?.runtimeVersion ?? null;
|
|
68837
|
-
}
|
|
68838
|
-
|
|
68839
|
-
// src/session/harness-cli.ts
|
|
68840
69363
|
var DEFERRED_FLAGS = /* @__PURE__ */ new Set([
|
|
68841
69364
|
"--env-file",
|
|
68842
69365
|
"--server-password-stdin",
|
|
@@ -68851,7 +69374,7 @@ function harnessUsage() {
|
|
|
68851
69374
|
Commands:
|
|
68852
69375
|
list [--json]
|
|
68853
69376
|
show <HARNESS_ID> [--json]
|
|
68854
|
-
enable claude|codex --artifact <FILE> [--json]
|
|
69377
|
+
enable claude|codex [--artifact <FILE>] [--json]
|
|
68855
69378
|
enable opencode [--command <ABS_PATH> | --server-url <URL>] [--json]
|
|
68856
69379
|
enable acp-grok [--command <ABS_PATH>] [--arg <VALUE>|--arg=<VALUE>]... [--json]
|
|
68857
69380
|
configure opencode [--command <ABS_PATH> | --server-url <URL>] [--json]
|
|
@@ -68866,7 +69389,7 @@ Notes:
|
|
|
68866
69389
|
No public --home / --data-dir.
|
|
68867
69390
|
Stage 2 deferred (rejected if passed): --env-file, --server-password-stdin,
|
|
68868
69391
|
--clear-server-password, --clear-env, --startup-timeout, --initialize-timeout,
|
|
68869
|
-
managed
|
|
69392
|
+
signed SuperOne artifact CDN (managed enable pulls official npm packages).
|
|
68870
69393
|
`;
|
|
68871
69394
|
}
|
|
68872
69395
|
function subUsage(sub) {
|
|
@@ -68877,7 +69400,7 @@ function subUsage(sub) {
|
|
|
68877
69400
|
return "Usage: superone harness show <HARNESS_ID> [--json]";
|
|
68878
69401
|
case "enable":
|
|
68879
69402
|
return `Usage:
|
|
68880
|
-
superone harness enable claude|codex --artifact <FILE> [--json]
|
|
69403
|
+
superone harness enable claude|codex [--artifact <FILE>] [--json]
|
|
68881
69404
|
superone harness enable opencode [--command <ABS_PATH> | --server-url <URL>] [--json]
|
|
68882
69405
|
superone harness enable acp-grok [--command <ABS_PATH>] [--arg <VALUE>]... [--json]`;
|
|
68883
69406
|
case "configure":
|
|
@@ -69172,88 +69695,12 @@ async function cmdRepair(manager, args) {
|
|
|
69172
69695
|
return fail(err instanceof Error ? err.message : String(err), parsed.json);
|
|
69173
69696
|
}
|
|
69174
69697
|
}
|
|
69175
|
-
async function enableManaged(manager, id, artifact, mode = "enable") {
|
|
69176
|
-
if (!isManagedHarnessId(id)) {
|
|
69177
|
-
throw new Error(`not a managed harness: ${id}`);
|
|
69178
|
-
}
|
|
69179
|
-
const nodeHome = resolveNodeHome(void 0);
|
|
69180
|
-
const manifest = loadHarnessReleaseManifest(nodeHome);
|
|
69181
|
-
if (!manifest) {
|
|
69182
|
-
throw new Error(
|
|
69183
|
-
`no release manifest found (set SUPERONE_HARNESS_MANIFEST or write ${nodeHome}/release-manifest.json)`
|
|
69184
|
-
);
|
|
69185
|
-
}
|
|
69186
|
-
if (!manifest.managedHarnesses[id]) {
|
|
69187
|
-
throw new Error(`release manifest does not pin ${id}`);
|
|
69188
|
-
}
|
|
69189
|
-
if (!artifact) {
|
|
69190
|
-
throw new Error(describeExpectedArtifact(id, manifest));
|
|
69191
|
-
}
|
|
69192
|
-
const abs = requireRegularReadableFile(artifact);
|
|
69193
|
-
const installed = await installManagedArtifactFromFile({
|
|
69194
|
-
nodeHome,
|
|
69195
|
-
harnessId: id,
|
|
69196
|
-
artifactPath: abs,
|
|
69197
|
-
manifest,
|
|
69198
|
-
expectedCliVersion: currentCliVersion(),
|
|
69199
|
-
mode
|
|
69200
|
-
});
|
|
69201
|
-
const def = getNodeHarnessDefinition(id);
|
|
69202
|
-
return manager.update(id, {
|
|
69203
|
-
enabled: true,
|
|
69204
|
-
state: def.requiresAuth ? "needs_auth" : "ready",
|
|
69205
|
-
command: installed.installPath,
|
|
69206
|
-
runtimeVersion: installed.runtimeVersion,
|
|
69207
|
-
diagnosticCode: def.requiresAuth ? "needs_auth" : null,
|
|
69208
|
-
diagnosticFields: def.requiresAuth ? { command: installed.installPath, runtimeVersion: installed.runtimeVersion } : null,
|
|
69209
|
-
lastProbedAt: Date.now(),
|
|
69210
|
-
configJson: JSON.stringify({
|
|
69211
|
-
artifactPath: installed.installPath,
|
|
69212
|
-
source: installed.source,
|
|
69213
|
-
cliVersion: installed.cliVersion,
|
|
69214
|
-
artifactVersion: installed.artifactVersion,
|
|
69215
|
-
digestSha256: installed.digestSha256
|
|
69216
|
-
})
|
|
69217
|
-
});
|
|
69218
|
-
}
|
|
69219
|
-
function enableOpencode(manager, opts) {
|
|
69220
|
-
if (opts.serverUrl) {
|
|
69221
|
-
const safeUrl = validateServerUrl(opts.serverUrl);
|
|
69222
|
-
return manager.update("opencode", {
|
|
69223
|
-
enabled: true,
|
|
69224
|
-
state: "ready",
|
|
69225
|
-
command: null,
|
|
69226
|
-
diagnosticCode: null,
|
|
69227
|
-
lastProbedAt: Date.now(),
|
|
69228
|
-
configJson: JSON.stringify({ serverUrl: safeUrl })
|
|
69229
|
-
});
|
|
69230
|
-
}
|
|
69231
|
-
const resolved = resolveExternalCommand(opts.command, ["opencode"]);
|
|
69232
|
-
if (!resolved) {
|
|
69233
|
-
return manager.update("opencode", {
|
|
69234
|
-
enabled: true,
|
|
69235
|
-
state: "missing",
|
|
69236
|
-
command: null,
|
|
69237
|
-
diagnosticCode: "not_found",
|
|
69238
|
-
lastProbedAt: Date.now(),
|
|
69239
|
-
configJson: JSON.stringify({})
|
|
69240
|
-
});
|
|
69241
|
-
}
|
|
69242
|
-
return manager.update("opencode", {
|
|
69243
|
-
enabled: true,
|
|
69244
|
-
state: "ready",
|
|
69245
|
-
command: resolved,
|
|
69246
|
-
diagnosticCode: null,
|
|
69247
|
-
lastProbedAt: Date.now(),
|
|
69248
|
-
configJson: JSON.stringify({ command: resolved })
|
|
69249
|
-
});
|
|
69250
|
-
}
|
|
69251
69698
|
function configureOpencode(manager, opts) {
|
|
69252
69699
|
if (!opts.command && !opts.serverUrl) {
|
|
69253
69700
|
throw new Error("configure opencode requires --command or --server-url");
|
|
69254
69701
|
}
|
|
69255
69702
|
if (opts.serverUrl) {
|
|
69256
|
-
const safeUrl =
|
|
69703
|
+
const safeUrl = validateServerUrl2(opts.serverUrl);
|
|
69257
69704
|
return manager.update("opencode", {
|
|
69258
69705
|
enabled: true,
|
|
69259
69706
|
state: "ready",
|
|
@@ -69263,7 +69710,7 @@ function configureOpencode(manager, opts) {
|
|
|
69263
69710
|
configJson: JSON.stringify({ serverUrl: safeUrl })
|
|
69264
69711
|
});
|
|
69265
69712
|
}
|
|
69266
|
-
const resolved =
|
|
69713
|
+
const resolved = resolveExternalCommand2(opts.command, []);
|
|
69267
69714
|
if (!resolved) {
|
|
69268
69715
|
throw new Error(
|
|
69269
69716
|
`proposed opencode command is not a usable executable: ${opts.command ?? "(missing)"}`
|
|
@@ -69278,33 +69725,6 @@ function configureOpencode(manager, opts) {
|
|
|
69278
69725
|
configJson: JSON.stringify({ command: resolved })
|
|
69279
69726
|
});
|
|
69280
69727
|
}
|
|
69281
|
-
function enableAcpGrok(manager, opts) {
|
|
69282
|
-
const defaultArgs = ["agent", "stdio"];
|
|
69283
|
-
const args = sanitizeHarnessArgs(opts.args.length > 0 ? opts.args : defaultArgs);
|
|
69284
|
-
const resolved = resolveExternalCommand(opts.command, ["grok"]);
|
|
69285
|
-
if (!resolved) {
|
|
69286
|
-
return manager.update("acp-grok", {
|
|
69287
|
-
enabled: true,
|
|
69288
|
-
state: "missing",
|
|
69289
|
-
command: null,
|
|
69290
|
-
diagnosticCode: "not_found",
|
|
69291
|
-
lastProbedAt: Date.now(),
|
|
69292
|
-
configJson: JSON.stringify({ args, usesDefaultArgs: opts.args.length === 0 })
|
|
69293
|
-
});
|
|
69294
|
-
}
|
|
69295
|
-
return manager.update("acp-grok", {
|
|
69296
|
-
enabled: true,
|
|
69297
|
-
state: "ready",
|
|
69298
|
-
command: resolved,
|
|
69299
|
-
diagnosticCode: null,
|
|
69300
|
-
lastProbedAt: Date.now(),
|
|
69301
|
-
configJson: JSON.stringify({
|
|
69302
|
-
command: resolved,
|
|
69303
|
-
args,
|
|
69304
|
-
usesDefaultArgs: opts.args.length === 0
|
|
69305
|
-
})
|
|
69306
|
-
});
|
|
69307
|
-
}
|
|
69308
69728
|
function configureAcpGrok(manager, opts) {
|
|
69309
69729
|
const current = manager.get("acp-grok");
|
|
69310
69730
|
const raw = manager.readRawRow("acp-grok");
|
|
@@ -69316,12 +69736,12 @@ function configureAcpGrok(manager, opts) {
|
|
|
69316
69736
|
} catch {
|
|
69317
69737
|
}
|
|
69318
69738
|
}
|
|
69319
|
-
const args = opts.defaultArgs ? ["agent", "stdio"] : opts.args.length > 0 ?
|
|
69739
|
+
const args = opts.defaultArgs ? ["agent", "stdio"] : opts.args.length > 0 ? sanitizeHarnessArgs2(opts.args) : previousArgs;
|
|
69320
69740
|
if (!opts.command && opts.args.length === 0 && !opts.defaultArgs) {
|
|
69321
69741
|
throw new Error("configure acp-grok requires --command, --arg, and/or --default-args");
|
|
69322
69742
|
}
|
|
69323
69743
|
const commandToProbe = opts.command ?? current.command ?? void 0;
|
|
69324
|
-
const resolved =
|
|
69744
|
+
const resolved = resolveExternalCommand2(commandToProbe, opts.command ? [] : ["grok"]);
|
|
69325
69745
|
if (!resolved) {
|
|
69326
69746
|
throw new Error(
|
|
69327
69747
|
`proposed acp-grok command is not a usable executable: ${commandToProbe ?? "(missing)"}`
|
|
@@ -69417,7 +69837,7 @@ function buildPublicConfigSummary(id, configJson, status) {
|
|
|
69417
69837
|
}
|
|
69418
69838
|
const out = {};
|
|
69419
69839
|
if (id === "claude" || id === "codex") {
|
|
69420
|
-
if (typeof parsed.artifactPath === "string" &&
|
|
69840
|
+
if (typeof parsed.artifactPath === "string" && isAbsolute4(parsed.artifactPath)) {
|
|
69421
69841
|
out.artifactPath = parsed.artifactPath;
|
|
69422
69842
|
}
|
|
69423
69843
|
if (parsed.source === "offline-artifact") out.source = "offline-artifact";
|
|
@@ -69427,14 +69847,14 @@ function buildPublicConfigSummary(id, configJson, status) {
|
|
|
69427
69847
|
out.digestSha256 = parsed.digestSha256;
|
|
69428
69848
|
}
|
|
69429
69849
|
} else if (id === "opencode") {
|
|
69430
|
-
if (typeof parsed.command === "string" &&
|
|
69850
|
+
if (typeof parsed.command === "string" && isAbsolute4(parsed.command)) {
|
|
69431
69851
|
out.command = parsed.command;
|
|
69432
69852
|
}
|
|
69433
69853
|
if (typeof parsed.serverUrl === "string") {
|
|
69434
69854
|
out.serverUrl = redactServerUrlForDisplay(parsed.serverUrl);
|
|
69435
69855
|
}
|
|
69436
69856
|
} else if (id === "acp-grok") {
|
|
69437
|
-
if (typeof parsed.command === "string" &&
|
|
69857
|
+
if (typeof parsed.command === "string" && isAbsolute4(parsed.command)) {
|
|
69438
69858
|
out.command = parsed.command;
|
|
69439
69859
|
}
|
|
69440
69860
|
if (Array.isArray(parsed.args)) {
|
|
@@ -69446,31 +69866,9 @@ function buildPublicConfigSummary(id, configJson, status) {
|
|
|
69446
69866
|
}
|
|
69447
69867
|
return Object.keys(out).length ? out : null;
|
|
69448
69868
|
}
|
|
69449
|
-
function
|
|
69450
|
-
if (!isAbsolute3(path)) {
|
|
69451
|
-
throw new Error(`path must be absolute: ${path}`);
|
|
69452
|
-
}
|
|
69453
|
-
if (!existsSync28(path)) {
|
|
69454
|
-
throw new Error(`artifact not found: ${path}`);
|
|
69455
|
-
}
|
|
69456
|
-
const st = statSync8(path);
|
|
69457
|
-
if (!st.isFile()) {
|
|
69458
|
-
throw new Error(`artifact is not a regular file: ${path}`);
|
|
69459
|
-
}
|
|
69460
|
-
try {
|
|
69461
|
-
accessSync(path, constants.R_OK);
|
|
69462
|
-
} catch {
|
|
69463
|
-
throw new Error(`artifact not readable: ${path}`);
|
|
69464
|
-
}
|
|
69465
|
-
try {
|
|
69466
|
-
return realpathSync5(path);
|
|
69467
|
-
} catch {
|
|
69468
|
-
return path;
|
|
69469
|
-
}
|
|
69470
|
-
}
|
|
69471
|
-
function resolveExternalCommand(explicit, pathCandidates) {
|
|
69869
|
+
function resolveExternalCommand2(explicit, pathCandidates) {
|
|
69472
69870
|
if (explicit) {
|
|
69473
|
-
if (!
|
|
69871
|
+
if (!isAbsolute4(explicit)) {
|
|
69474
69872
|
return null;
|
|
69475
69873
|
}
|
|
69476
69874
|
return isUsableExecutable(explicit);
|
|
@@ -69486,7 +69884,7 @@ function resolveExternalCommand(explicit, pathCandidates) {
|
|
|
69486
69884
|
];
|
|
69487
69885
|
for (const name of pathCandidates) {
|
|
69488
69886
|
for (const dir of [...dirs, ...extra]) {
|
|
69489
|
-
const candidate =
|
|
69887
|
+
const candidate = resolve10(dir, name);
|
|
69490
69888
|
const ok = isUsableExecutable(candidate);
|
|
69491
69889
|
if (ok) return ok;
|
|
69492
69890
|
}
|
|
@@ -69494,56 +69892,56 @@ function resolveExternalCommand(explicit, pathCandidates) {
|
|
|
69494
69892
|
return null;
|
|
69495
69893
|
}
|
|
69496
69894
|
function isUsableExecutable(path) {
|
|
69497
|
-
if (!
|
|
69895
|
+
if (!existsSync30(path)) return null;
|
|
69498
69896
|
let st;
|
|
69499
69897
|
try {
|
|
69500
|
-
st =
|
|
69898
|
+
st = statSync10(path);
|
|
69501
69899
|
} catch {
|
|
69502
69900
|
return null;
|
|
69503
69901
|
}
|
|
69504
69902
|
if (!st.isFile()) return null;
|
|
69505
69903
|
try {
|
|
69506
|
-
|
|
69904
|
+
accessSync2(path, constants2.X_OK);
|
|
69507
69905
|
} catch {
|
|
69508
69906
|
return null;
|
|
69509
69907
|
}
|
|
69510
69908
|
try {
|
|
69511
|
-
return
|
|
69909
|
+
return realpathSync6(path);
|
|
69512
69910
|
} catch {
|
|
69513
69911
|
return path;
|
|
69514
69912
|
}
|
|
69515
69913
|
}
|
|
69516
69914
|
function probeExecutableIssues(path) {
|
|
69517
|
-
if (!
|
|
69915
|
+
if (!existsSync30(path)) return ["command_missing"];
|
|
69518
69916
|
let st;
|
|
69519
69917
|
try {
|
|
69520
|
-
st =
|
|
69918
|
+
st = statSync10(path);
|
|
69521
69919
|
} catch {
|
|
69522
69920
|
return ["command_missing"];
|
|
69523
69921
|
}
|
|
69524
69922
|
if (!st.isFile()) return ["command_not_file"];
|
|
69525
69923
|
try {
|
|
69526
|
-
|
|
69924
|
+
accessSync2(path, constants2.X_OK);
|
|
69527
69925
|
} catch {
|
|
69528
69926
|
return ["command_not_executable"];
|
|
69529
69927
|
}
|
|
69530
69928
|
return [];
|
|
69531
69929
|
}
|
|
69532
69930
|
function probeReadableFileIssues(path) {
|
|
69533
|
-
if (!
|
|
69931
|
+
if (!existsSync30(path)) return ["artifact_missing"];
|
|
69534
69932
|
try {
|
|
69535
|
-
if (!
|
|
69933
|
+
if (!statSync10(path).isFile()) return ["artifact_not_file"];
|
|
69536
69934
|
} catch {
|
|
69537
69935
|
return ["artifact_missing"];
|
|
69538
69936
|
}
|
|
69539
69937
|
try {
|
|
69540
|
-
|
|
69938
|
+
accessSync2(path, constants2.R_OK);
|
|
69541
69939
|
} catch {
|
|
69542
69940
|
return ["artifact_not_readable"];
|
|
69543
69941
|
}
|
|
69544
69942
|
return [];
|
|
69545
69943
|
}
|
|
69546
|
-
function
|
|
69944
|
+
function validateServerUrl2(raw) {
|
|
69547
69945
|
let url2;
|
|
69548
69946
|
try {
|
|
69549
69947
|
url2 = new URL(raw);
|
|
@@ -69578,15 +69976,15 @@ function redactServerUrlForDisplay(raw) {
|
|
|
69578
69976
|
return "[invalid-url]";
|
|
69579
69977
|
}
|
|
69580
69978
|
}
|
|
69581
|
-
function
|
|
69979
|
+
function sanitizeHarnessArgs2(args) {
|
|
69582
69980
|
for (const a of args) {
|
|
69583
|
-
if (
|
|
69981
|
+
if (looksLikeSecretArg2(a)) {
|
|
69584
69982
|
throw new Error("refusing to store credential-like --arg values");
|
|
69585
69983
|
}
|
|
69586
69984
|
}
|
|
69587
69985
|
return args;
|
|
69588
69986
|
}
|
|
69589
|
-
function
|
|
69987
|
+
function looksLikeSecretArg2(value) {
|
|
69590
69988
|
if (/Bearer\s+\S+/i.test(value)) return true;
|
|
69591
69989
|
if (/\b(password|passwd|token|secret|api[_-]?key)\b\s*=/i.test(value)) return true;
|
|
69592
69990
|
if (/^[A-Z][A-Z0-9_]*(KEY|TOKEN|SECRET|PASSWORD)\s*=/.test(value)) return true;
|
|
@@ -69732,6 +70130,7 @@ Commands:
|
|
|
69732
70130
|
status [--home DIR]
|
|
69733
70131
|
identity [--home DIR]
|
|
69734
70132
|
identity regenerate [--home DIR]
|
|
70133
|
+
version
|
|
69735
70134
|
install-systemd [--home DIR] [--exec PATH] [--host HOST] [--port PORT]
|
|
69736
70135
|
uninstall-systemd
|
|
69737
70136
|
systemd-status
|
|
@@ -69837,7 +70236,8 @@ async function main() {
|
|
|
69837
70236
|
regenerated: true,
|
|
69838
70237
|
environmentId: identity2.environmentId,
|
|
69839
70238
|
nodePublicKeyFingerprint: identity2.publicKeyFingerprint,
|
|
69840
|
-
bindingHash: identity2.bindingHash
|
|
70239
|
+
bindingHash: identity2.bindingHash,
|
|
70240
|
+
cliVersion: resolveCliReleaseVersion()
|
|
69841
70241
|
},
|
|
69842
70242
|
null,
|
|
69843
70243
|
2
|
|
@@ -69853,7 +70253,8 @@ async function main() {
|
|
|
69853
70253
|
nodePublicKeyFingerprint: identity.publicKeyFingerprint,
|
|
69854
70254
|
bindingHash: identity.bindingHash,
|
|
69855
70255
|
label: identity.label,
|
|
69856
|
-
nodeHome
|
|
70256
|
+
nodeHome,
|
|
70257
|
+
cliVersion: resolveCliReleaseVersion()
|
|
69857
70258
|
},
|
|
69858
70259
|
null,
|
|
69859
70260
|
2
|
|
@@ -69861,9 +70262,13 @@ async function main() {
|
|
|
69861
70262
|
);
|
|
69862
70263
|
return;
|
|
69863
70264
|
}
|
|
70265
|
+
if (cmd === "version") {
|
|
70266
|
+
console.log(resolveCliReleaseVersion());
|
|
70267
|
+
return;
|
|
70268
|
+
}
|
|
69864
70269
|
if (cmd === "install-systemd") {
|
|
69865
70270
|
const nodeHome = resolveNodeHome(argValue(rest, "--home"));
|
|
69866
|
-
const execStart = argValue(rest, "--exec") ||
|
|
70271
|
+
const execStart = argValue(rest, "--exec") || resolve11(process.argv[1] || "superone");
|
|
69867
70272
|
const host = argValue(rest, "--host") || DEFAULT_BIND_HOST;
|
|
69868
70273
|
const port = Number(argValue(rest, "--port") || DEFAULT_BIND_PORT);
|
|
69869
70274
|
const result = installSystemdUserService({
|