@kontextmind/kxm 0.7.8 → 0.7.9
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/.claude-plugin/marketplace.json +1 -1
- package/package.json +1 -1
- package/plugins/kxm/.claude-plugin/plugin.json +1 -1
- package/plugins/kxm/dist/cli.js +250 -38
- package/plugins/kxm/dist/mcp-server.js +1 -1
- package/plugins/kxm/dist/runtime.js +108 -33
- package/plugins/kxm/dist/vnext-runtime-supervisor.js +85 -28
- package/plugins/kxm/package.json +1 -1
- package/plugins/kxm/src/cli/system.ts +3 -3
- package/plugins/kxm/src/cli/tasks.ts +2 -2
- package/plugins/kxm/src/cli/vnext.ts +2 -2
- package/plugins/kxm/src/mcp-server.ts +1 -1
- package/plugins/kxm/src/model-inventory.ts +8 -8
- package/plugins/kxm/src/vnext-harness.ts +88 -20
- package/plugins/kxm/src/vnext-oneshot-evidence.ts +39 -7
- package/plugins/kxm/src/vnext-oneshot-process.ts +25 -4
- package/plugins/kxm/src/vnext-oneshot-producer.ts +4 -1
- package/plugins/kxm/src/vnext-pi-producer.ts +11 -7
- package/plugins/kxm/src/vnext-runtime-supervisor.ts +5 -3
|
@@ -15159,6 +15159,7 @@ function defaultSpawn(command, args, options) {
|
|
|
15159
15159
|
let child;
|
|
15160
15160
|
const finish = () => {
|
|
15161
15161
|
if (finished) return;
|
|
15162
|
+
if (stopping && !killSent) return;
|
|
15162
15163
|
finished = true;
|
|
15163
15164
|
for (const timer of [wallTimer, killTimer, drainTimer, reapTimer]) clearTimeout(timer);
|
|
15164
15165
|
options.signal?.removeEventListener("abort", onAbort);
|
|
@@ -15168,7 +15169,18 @@ function defaultSpawn(command, args, options) {
|
|
|
15168
15169
|
child?.unref();
|
|
15169
15170
|
const started = Boolean(child?.pid);
|
|
15170
15171
|
if (started && !observedChildExit) error ??= new Error("process_exit_unobserved");
|
|
15171
|
-
|
|
15172
|
+
const unverifiedDescendants = stopping || started && !observedChildExit;
|
|
15173
|
+
resolve9({
|
|
15174
|
+
stdout: Buffer.concat(stdout).toString("utf8"),
|
|
15175
|
+
stderr: Buffer.concat(stderr).toString("utf8"),
|
|
15176
|
+
code,
|
|
15177
|
+
signal,
|
|
15178
|
+
started,
|
|
15179
|
+
observedChildExit,
|
|
15180
|
+
terminationRequested: stopping,
|
|
15181
|
+
...unverifiedDescendants ? { unverifiedDescendants: true } : {},
|
|
15182
|
+
...error ? { error } : {}
|
|
15183
|
+
});
|
|
15172
15184
|
};
|
|
15173
15185
|
const kill = (requested) => {
|
|
15174
15186
|
killProcessTree(child, requested);
|
|
@@ -15199,7 +15211,7 @@ function defaultSpawn(command, args, options) {
|
|
|
15199
15211
|
cwd: options.cwd,
|
|
15200
15212
|
env: options.env ?? process.env,
|
|
15201
15213
|
stdio: ["pipe", "pipe", "pipe"],
|
|
15202
|
-
shell:
|
|
15214
|
+
shell: options.shell === true,
|
|
15203
15215
|
windowsHide: true,
|
|
15204
15216
|
detached: process.platform !== "win32"
|
|
15205
15217
|
});
|
|
@@ -15243,7 +15255,7 @@ function defaultSpawn(command, args, options) {
|
|
|
15243
15255
|
closed = true;
|
|
15244
15256
|
code = exitCode;
|
|
15245
15257
|
signal = exitSignal;
|
|
15246
|
-
|
|
15258
|
+
finish();
|
|
15247
15259
|
});
|
|
15248
15260
|
options.signal?.addEventListener("abort", onAbort, { once: true });
|
|
15249
15261
|
if (options.signal?.aborted) onAbort();
|
|
@@ -15684,6 +15696,31 @@ function defaultRunner(env) {
|
|
|
15684
15696
|
}
|
|
15685
15697
|
};
|
|
15686
15698
|
}
|
|
15699
|
+
function commandResultFromSpawn(result) {
|
|
15700
|
+
const errno = result.error && "code" in result.error ? result.error.code : void 0;
|
|
15701
|
+
const error = (typeof errno === "string" && errno ? errno : void 0) ?? result.error?.message ?? (result.observedChildExit !== true ? "auth_probe_exit_unobserved" : void 0);
|
|
15702
|
+
return {
|
|
15703
|
+
ok: result.code === 0 && !error,
|
|
15704
|
+
code: result.code,
|
|
15705
|
+
stdout: result.stdout,
|
|
15706
|
+
stderr: result.stderr,
|
|
15707
|
+
...error ? { error } : {}
|
|
15708
|
+
};
|
|
15709
|
+
}
|
|
15710
|
+
function defaultAsyncRunner(env, signal) {
|
|
15711
|
+
return async (command, args, timeoutMs) => {
|
|
15712
|
+
try {
|
|
15713
|
+
return commandResultFromSpawn(await defaultSpawn(command, args, {
|
|
15714
|
+
env,
|
|
15715
|
+
timeoutMs,
|
|
15716
|
+
signal,
|
|
15717
|
+
shell: harnessSpawnUsesShell(command)
|
|
15718
|
+
}));
|
|
15719
|
+
} catch (error) {
|
|
15720
|
+
return { ok: false, code: null, stdout: "", stderr: "", error: error instanceof Error ? error.message : "spawn_failed" };
|
|
15721
|
+
}
|
|
15722
|
+
};
|
|
15723
|
+
}
|
|
15687
15724
|
function firstLine(text) {
|
|
15688
15725
|
const line = text.split(/\r?\n/).map((candidate) => candidate.trim()).find(Boolean);
|
|
15689
15726
|
return line && line.length <= 200 ? line : void 0;
|
|
@@ -15882,6 +15919,13 @@ function probeHarnesses(options = {}) {
|
|
|
15882
15919
|
harnesses: BUILTIN_HARNESSES.map((entry) => probeEntry(entry, runCommand, timeoutMs, platform, options))
|
|
15883
15920
|
};
|
|
15884
15921
|
}
|
|
15922
|
+
async function probeHarnessesAsync(options = {}) {
|
|
15923
|
+
return replayHarnessProbe(
|
|
15924
|
+
options.runCommand ?? defaultAsyncRunner(options.env ?? process.env, options.signal),
|
|
15925
|
+
(runCommand) => probeHarnesses({ ...options, runCommand }),
|
|
15926
|
+
256
|
|
15927
|
+
);
|
|
15928
|
+
}
|
|
15885
15929
|
function eligibleHarnesses(inventory) {
|
|
15886
15930
|
const eligible = inventory.harnesses.filter((entry) => entry !== void 0 && entry.detected && entry.authenticated === true).map((entry) => entry.id);
|
|
15887
15931
|
if (eligible.length === 0) throw new Error("no_authenticated_harness");
|
|
@@ -16118,35 +16162,31 @@ var PendingHarnessCommand = class {
|
|
|
16118
16162
|
this.key = key;
|
|
16119
16163
|
}
|
|
16120
16164
|
};
|
|
16121
|
-
async function
|
|
16165
|
+
async function replayHarnessProbe(run, execute, limit) {
|
|
16122
16166
|
const observed = /* @__PURE__ */ new Map();
|
|
16123
|
-
|
|
16124
|
-
const result = await defaultSpawn(command, args, { env: options.env, timeoutMs, signal: options.signal });
|
|
16125
|
-
const error = result.error?.message ?? (result.observedChildExit !== true ? "auth_probe_exit_unobserved" : void 0);
|
|
16126
|
-
return {
|
|
16127
|
-
ok: result.code === 0 && !error,
|
|
16128
|
-
code: result.code,
|
|
16129
|
-
stdout: result.stdout,
|
|
16130
|
-
stderr: result.stderr,
|
|
16131
|
-
...error ? { error } : {}
|
|
16132
|
-
};
|
|
16133
|
-
});
|
|
16134
|
-
for (let commands = 0; commands <= 32; commands++) {
|
|
16167
|
+
for (let commands = 0; commands <= limit; commands++) {
|
|
16135
16168
|
try {
|
|
16136
|
-
return
|
|
16169
|
+
return execute((command, args, timeoutMs) => {
|
|
16137
16170
|
const key = JSON.stringify([command, args, timeoutMs]);
|
|
16138
16171
|
const result = observed.get(key);
|
|
16139
16172
|
if (result) return result;
|
|
16140
16173
|
throw new PendingHarnessCommand(command, args, timeoutMs, key);
|
|
16141
|
-
}
|
|
16174
|
+
});
|
|
16142
16175
|
} catch (pending) {
|
|
16143
16176
|
if (!(pending instanceof PendingHarnessCommand)) throw pending;
|
|
16144
|
-
if (commands ===
|
|
16177
|
+
if (commands === limit) throw new Error("auth_probe_command_limit");
|
|
16145
16178
|
observed.set(pending.key, await run(pending.command, pending.args, pending.timeoutMs));
|
|
16146
16179
|
}
|
|
16147
16180
|
}
|
|
16148
16181
|
throw new Error("auth_probe_command_limit");
|
|
16149
16182
|
}
|
|
16183
|
+
async function probeHarnessAssignmentAsync(options) {
|
|
16184
|
+
return replayHarnessProbe(
|
|
16185
|
+
options.runCommand ?? defaultAsyncRunner(options.env ?? process.env, options.signal),
|
|
16186
|
+
(runCommand) => probeHarnessAssignment({ ...options, runCommand }),
|
|
16187
|
+
32
|
|
16188
|
+
);
|
|
16189
|
+
}
|
|
16150
16190
|
function probeHarnessesForModel(modelSpec, options = {}) {
|
|
16151
16191
|
const timeoutMs = options.timeoutMs ?? 3e3;
|
|
16152
16192
|
const runCommand = options.runCommand ?? defaultRunner(options.env ?? process.env);
|
|
@@ -16167,6 +16207,13 @@ function probeHarnessesForModel(modelSpec, options = {}) {
|
|
|
16167
16207
|
)
|
|
16168
16208
|
};
|
|
16169
16209
|
}
|
|
16210
|
+
async function probeHarnessesForModelAsync(modelSpec, options = {}) {
|
|
16211
|
+
return replayHarnessProbe(
|
|
16212
|
+
options.runCommand ?? defaultAsyncRunner(options.env ?? process.env, options.signal),
|
|
16213
|
+
(runCommand) => probeHarnessesForModel(modelSpec, { ...options, runCommand }),
|
|
16214
|
+
256
|
|
16215
|
+
);
|
|
16216
|
+
}
|
|
16170
16217
|
function scopesFor(scope, entry) {
|
|
16171
16218
|
if (scope === "self") return ["self"];
|
|
16172
16219
|
if (scope === "extensions") return entry.update.extensions ? ["extensions"] : [];
|
|
@@ -22351,9 +22398,28 @@ import { join as join11 } from "node:path";
|
|
|
22351
22398
|
import { createHash as createHash7, randomUUID as randomUUID3 } from "node:crypto";
|
|
22352
22399
|
import { lstat, mkdir, open, rename } from "node:fs/promises";
|
|
22353
22400
|
import { join as join6 } from "node:path";
|
|
22401
|
+
var ONESHOT_EVIDENCE_SCHEMA = "kxm.oneshot-evidence.v2";
|
|
22402
|
+
var RETIRED_ONESHOT_EVIDENCE_SCHEMAS = /* @__PURE__ */ new Set(["kxm.oneshot-evidence.v1"]);
|
|
22354
22403
|
var TEXT_LIMIT = 4 * 1024 * 1024;
|
|
22404
|
+
var ARGV_LIMIT = 64 * 1024;
|
|
22355
22405
|
var RECORD_LIMIT = 16 * 1024 * 1024;
|
|
22356
22406
|
var digest = (value) => `sha256:${createHash7("sha256").update(value).digest("hex")}`;
|
|
22407
|
+
function parseOneShotEvidenceRecord(bytes) {
|
|
22408
|
+
let parsed;
|
|
22409
|
+
try {
|
|
22410
|
+
parsed = JSON.parse(bytes);
|
|
22411
|
+
} catch {
|
|
22412
|
+
throw new Error("oneshot_evidence_record_invalid");
|
|
22413
|
+
}
|
|
22414
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
22415
|
+
throw new Error("oneshot_evidence_record_invalid");
|
|
22416
|
+
}
|
|
22417
|
+
const schema = parsed.schema;
|
|
22418
|
+
if (typeof schema !== "string") throw new Error("oneshot_evidence_record_invalid");
|
|
22419
|
+
if (RETIRED_ONESHOT_EVIDENCE_SCHEMAS.has(schema)) throw new Error("oneshot_evidence_schema_retired");
|
|
22420
|
+
if (schema !== ONESHOT_EVIDENCE_SCHEMA) throw new Error("oneshot_evidence_schema_unknown");
|
|
22421
|
+
return parsed;
|
|
22422
|
+
}
|
|
22357
22423
|
async function beginOneShotEvidence(root, intent, sensitive) {
|
|
22358
22424
|
await mkdir(root, { recursive: true, mode: 448 });
|
|
22359
22425
|
const stat = await lstat(root);
|
|
@@ -22367,11 +22433,11 @@ async function beginOneShotEvidence(root, intent, sensitive) {
|
|
|
22367
22433
|
const redact = (value) => {
|
|
22368
22434
|
let text = value;
|
|
22369
22435
|
for (const secret of secrets) text = text.replaceAll(secret, "[REDACTED]");
|
|
22370
|
-
return text.replace(/(\b(?:authorization|api[_-]?key|access[_-]?token|refresh[_-]?token|password|secret)\b["']?\s*[:=]\s*["']?)(?:Bearer\s+)?[^\s"',;}]+/gi, "$1[REDACTED]");
|
|
22436
|
+
return text.replace(/(\b(?:authorization|api[_-]?key|access[_-]?token|refresh[_-]?token|password|secret)\b["']?\s*[:=]\s*["']?)(?:Bearer\s+)?[^\s"',;}]+/gi, "$1[REDACTED]").replace(/\bBearer\s+[A-Za-z0-9._~+/=-]+/gi, "Bearer [REDACTED]");
|
|
22371
22437
|
};
|
|
22372
|
-
const bounded = (value) => {
|
|
22438
|
+
const bounded = (value, max = TEXT_LIMIT) => {
|
|
22373
22439
|
const bytes = Buffer.from(redact(value));
|
|
22374
|
-
return { text: bytes.subarray(0,
|
|
22440
|
+
return { text: bytes.subarray(0, max).toString("utf8"), truncated: bytes.length > max, sha256: digest(redact(value)) };
|
|
22375
22441
|
};
|
|
22376
22442
|
const write = async (name, value) => {
|
|
22377
22443
|
const current = await lstat(dir);
|
|
@@ -22380,6 +22446,7 @@ async function beginOneShotEvidence(root, intent, sensitive) {
|
|
|
22380
22446
|
}
|
|
22381
22447
|
const bytes = JSON.stringify(value);
|
|
22382
22448
|
if (Buffer.byteLength(bytes) > RECORD_LIMIT) throw new Error("oneshot_evidence_record_limit");
|
|
22449
|
+
parseOneShotEvidenceRecord(bytes);
|
|
22383
22450
|
const target = join6(dir, name);
|
|
22384
22451
|
const partial = `${target}.partial`;
|
|
22385
22452
|
const file = await open(partial, "wx", 384);
|
|
@@ -22401,7 +22468,7 @@ async function beginOneShotEvidence(root, intent, sensitive) {
|
|
|
22401
22468
|
return digest(bytes);
|
|
22402
22469
|
};
|
|
22403
22470
|
await write("intent.json", {
|
|
22404
|
-
schema:
|
|
22471
|
+
schema: ONESHOT_EVIDENCE_SCHEMA,
|
|
22405
22472
|
id,
|
|
22406
22473
|
recordedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
22407
22474
|
runId: intent.runId,
|
|
@@ -22412,9 +22479,10 @@ async function beginOneShotEvidence(root, intent, sensitive) {
|
|
|
22412
22479
|
provider: intent.provider,
|
|
22413
22480
|
requestedModel: intent.model,
|
|
22414
22481
|
cwd: intent.cwd,
|
|
22415
|
-
command: intent.command,
|
|
22416
|
-
argv: bounded(JSON.stringify(intent.args)),
|
|
22482
|
+
command: redact(intent.command),
|
|
22483
|
+
argv: bounded(JSON.stringify(intent.args), ARGV_LIMIT),
|
|
22417
22484
|
stdin: intent.input === void 0 ? null : bounded(intent.input),
|
|
22485
|
+
env: null,
|
|
22418
22486
|
acceptance: false
|
|
22419
22487
|
});
|
|
22420
22488
|
let finished = false;
|
|
@@ -22424,7 +22492,7 @@ async function beginOneShotEvidence(root, intent, sensitive) {
|
|
|
22424
22492
|
if (finished) throw new Error("oneshot_evidence_already_finished");
|
|
22425
22493
|
finished = true;
|
|
22426
22494
|
return write("result.json", {
|
|
22427
|
-
schema:
|
|
22495
|
+
schema: ONESHOT_EVIDENCE_SCHEMA,
|
|
22428
22496
|
id,
|
|
22429
22497
|
recordedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
22430
22498
|
stdout: bounded(result.stdout),
|
|
@@ -22434,6 +22502,7 @@ async function beginOneShotEvidence(root, intent, sensitive) {
|
|
|
22434
22502
|
started: result.started ?? null,
|
|
22435
22503
|
observedChildExit: result.observedChildExit ?? null,
|
|
22436
22504
|
terminationRequested: result.terminationRequested ?? null,
|
|
22505
|
+
unverifiedDescendants: result.unverifiedDescendants ?? null,
|
|
22437
22506
|
error: result.error ? bounded(result.error.message) : null,
|
|
22438
22507
|
observation: bounded(JSON.stringify(observation)),
|
|
22439
22508
|
acceptance: false
|
|
@@ -26106,7 +26175,8 @@ Return a final JSON object with an "outcome" field chosen from ${JSON.stringify(
|
|
|
26106
26175
|
parsed = { text: "", isError: true };
|
|
26107
26176
|
}
|
|
26108
26177
|
const aborted = request.signal.aborted || procResult.error?.message === "process_aborted";
|
|
26109
|
-
const
|
|
26178
|
+
const unverifiedDescendants = procResult.unverifiedDescendants === true || procResult.terminationRequested === true || procResult.error?.message === "process_exit_unobserved" || procResult.observedChildExit === false && procResult.started !== false;
|
|
26179
|
+
const effectUncertain = unverifiedDescendants || Boolean(procResult.signal);
|
|
26110
26180
|
const transportFailed = procResult.code !== 0 || Boolean(procResult.error) || effectUncertain;
|
|
26111
26181
|
const outcome = aborted ? "cancelled" : transportFailed || parsed.isError ? "failed" : determineOutcome(parsed.text, request.allowedOutcomes);
|
|
26112
26182
|
const providerMetadata = {
|
|
@@ -26118,6 +26188,7 @@ Return a final JSON object with an "outcome" field chosen from ${JSON.stringify(
|
|
|
26118
26188
|
if (procResult.observedChildExit !== void 0) providerMetadata.observedChildExit = procResult.observedChildExit;
|
|
26119
26189
|
if (procResult.started !== void 0) providerMetadata.processStarted = procResult.started;
|
|
26120
26190
|
if (procResult.terminationRequested !== void 0) providerMetadata.terminationRequested = procResult.terminationRequested;
|
|
26191
|
+
if (unverifiedDescendants) providerMetadata.descendantEffects = "unverified";
|
|
26121
26192
|
if (procResult.error) {
|
|
26122
26193
|
const reason = procResult.error.message;
|
|
26123
26194
|
providerMetadata.processError = /^process_(aborted|timeout|output_limit|stdin_error|stdio_error|stdio_unclosed|exit_unobserved)$/.test(reason) ? reason : "process_error";
|
|
@@ -26598,7 +26669,6 @@ async function startVnextRuntimeSupervisorInner(paths, requestedPortOption, now)
|
|
|
26598
26669
|
});
|
|
26599
26670
|
} catch (err) {
|
|
26600
26671
|
earlyError = err;
|
|
26601
|
-
drivePromise = Promise.reject(err);
|
|
26602
26672
|
}
|
|
26603
26673
|
await Promise.resolve();
|
|
26604
26674
|
if (earlyError) {
|
|
@@ -26624,6 +26694,7 @@ async function startVnextRuntimeSupervisorInner(paths, requestedPortOption, now)
|
|
|
26624
26694
|
} catch {
|
|
26625
26695
|
}
|
|
26626
26696
|
}
|
|
26697
|
+
}).catch(() => {
|
|
26627
26698
|
});
|
|
26628
26699
|
sendJson(response, 202, {
|
|
26629
26700
|
ok: true,
|
|
@@ -27109,19 +27180,21 @@ function createVnextPiProducer(options = {}) {
|
|
|
27109
27180
|
const parsed = parseModelString(defaultModel);
|
|
27110
27181
|
return { provider: parsed.provider, model: parsed.model };
|
|
27111
27182
|
}
|
|
27112
|
-
function checkPiAuth(provider, model) {
|
|
27183
|
+
async function checkPiAuth(provider, model, signal) {
|
|
27113
27184
|
if (options.inventory) {
|
|
27114
27185
|
const piEntry = options.inventory.harnesses.find((h) => h.id === "pi");
|
|
27115
27186
|
if (!piEntry || !piEntry.detected || piEntry.authenticated === false) {
|
|
27116
27187
|
throw new Error("pi_not_authenticated: pi harness not authenticated in inventory");
|
|
27117
27188
|
}
|
|
27118
27189
|
}
|
|
27119
|
-
const probeFn = options.probeHarness ??
|
|
27120
|
-
const probe = probeFn({
|
|
27190
|
+
const probeFn = options.probeHarness ?? probeHarnessAssignmentAsync;
|
|
27191
|
+
const probe = await probeFn({
|
|
27121
27192
|
harness: "pi",
|
|
27122
27193
|
provider,
|
|
27123
27194
|
model,
|
|
27124
|
-
env: options.env
|
|
27195
|
+
env: options.env,
|
|
27196
|
+
signal,
|
|
27197
|
+
timeoutMs: 1e4
|
|
27125
27198
|
});
|
|
27126
27199
|
if (!probe.detected) {
|
|
27127
27200
|
throw new Error(`pi_not_authenticated: pi harness not detected (${probe.issues.join(", ")})`);
|
|
@@ -27197,7 +27270,7 @@ function createVnextPiProducer(options = {}) {
|
|
|
27197
27270
|
async produce(request) {
|
|
27198
27271
|
const startTime = Date.now();
|
|
27199
27272
|
const resolved = resolveModelForRequest(request);
|
|
27200
|
-
checkPiAuth(resolved.provider, resolved.model);
|
|
27273
|
+
await checkPiAuth(resolved.provider, resolved.model, request.signal);
|
|
27201
27274
|
const session = await getOrCreateSession(request, resolved.model);
|
|
27202
27275
|
const promptMessage = request.prompt ?? `Execute step ${request.stepId} (attempt ${request.stepAttempt}) for agent ${request.agentId}. Allowed outcomes: ${request.allowedOutcomes.join(", ")}.`;
|
|
27203
27276
|
let promptResult;
|
|
@@ -29131,7 +29204,9 @@ export {
|
|
|
29131
29204
|
probeHarnessAssignment,
|
|
29132
29205
|
probeHarnessAssignmentAsync,
|
|
29133
29206
|
probeHarnesses,
|
|
29207
|
+
probeHarnessesAsync,
|
|
29134
29208
|
probeHarnessesForModel,
|
|
29209
|
+
probeHarnessesForModelAsync,
|
|
29135
29210
|
projectRuntimeKey,
|
|
29136
29211
|
pruneSocketDir,
|
|
29137
29212
|
readVnextRunStatus,
|
|
@@ -15163,6 +15163,7 @@ function defaultSpawn(command, args, options) {
|
|
|
15163
15163
|
let child;
|
|
15164
15164
|
const finish = () => {
|
|
15165
15165
|
if (finished) return;
|
|
15166
|
+
if (stopping && !killSent) return;
|
|
15166
15167
|
finished = true;
|
|
15167
15168
|
for (const timer of [wallTimer, killTimer, drainTimer, reapTimer]) clearTimeout(timer);
|
|
15168
15169
|
options.signal?.removeEventListener("abort", onAbort);
|
|
@@ -15172,7 +15173,18 @@ function defaultSpawn(command, args, options) {
|
|
|
15172
15173
|
child?.unref();
|
|
15173
15174
|
const started = Boolean(child?.pid);
|
|
15174
15175
|
if (started && !observedChildExit) error ??= new Error("process_exit_unobserved");
|
|
15175
|
-
|
|
15176
|
+
const unverifiedDescendants = stopping || started && !observedChildExit;
|
|
15177
|
+
resolve7({
|
|
15178
|
+
stdout: Buffer.concat(stdout).toString("utf8"),
|
|
15179
|
+
stderr: Buffer.concat(stderr).toString("utf8"),
|
|
15180
|
+
code,
|
|
15181
|
+
signal,
|
|
15182
|
+
started,
|
|
15183
|
+
observedChildExit,
|
|
15184
|
+
terminationRequested: stopping,
|
|
15185
|
+
...unverifiedDescendants ? { unverifiedDescendants: true } : {},
|
|
15186
|
+
...error ? { error } : {}
|
|
15187
|
+
});
|
|
15176
15188
|
};
|
|
15177
15189
|
const kill = (requested) => {
|
|
15178
15190
|
killProcessTree(child, requested);
|
|
@@ -15203,7 +15215,7 @@ function defaultSpawn(command, args, options) {
|
|
|
15203
15215
|
cwd: options.cwd,
|
|
15204
15216
|
env: options.env ?? process.env,
|
|
15205
15217
|
stdio: ["pipe", "pipe", "pipe"],
|
|
15206
|
-
shell:
|
|
15218
|
+
shell: options.shell === true,
|
|
15207
15219
|
windowsHide: true,
|
|
15208
15220
|
detached: process.platform !== "win32"
|
|
15209
15221
|
});
|
|
@@ -15247,7 +15259,7 @@ function defaultSpawn(command, args, options) {
|
|
|
15247
15259
|
closed = true;
|
|
15248
15260
|
code = exitCode;
|
|
15249
15261
|
signal = exitSignal;
|
|
15250
|
-
|
|
15262
|
+
finish();
|
|
15251
15263
|
});
|
|
15252
15264
|
options.signal?.addEventListener("abort", onAbort, { once: true });
|
|
15253
15265
|
if (options.signal?.aborted) onAbort();
|
|
@@ -15688,6 +15700,31 @@ function defaultRunner(env) {
|
|
|
15688
15700
|
}
|
|
15689
15701
|
};
|
|
15690
15702
|
}
|
|
15703
|
+
function commandResultFromSpawn(result) {
|
|
15704
|
+
const errno = result.error && "code" in result.error ? result.error.code : void 0;
|
|
15705
|
+
const error = (typeof errno === "string" && errno ? errno : void 0) ?? result.error?.message ?? (result.observedChildExit !== true ? "auth_probe_exit_unobserved" : void 0);
|
|
15706
|
+
return {
|
|
15707
|
+
ok: result.code === 0 && !error,
|
|
15708
|
+
code: result.code,
|
|
15709
|
+
stdout: result.stdout,
|
|
15710
|
+
stderr: result.stderr,
|
|
15711
|
+
...error ? { error } : {}
|
|
15712
|
+
};
|
|
15713
|
+
}
|
|
15714
|
+
function defaultAsyncRunner(env, signal) {
|
|
15715
|
+
return async (command, args, timeoutMs) => {
|
|
15716
|
+
try {
|
|
15717
|
+
return commandResultFromSpawn(await defaultSpawn(command, args, {
|
|
15718
|
+
env,
|
|
15719
|
+
timeoutMs,
|
|
15720
|
+
signal,
|
|
15721
|
+
shell: harnessSpawnUsesShell(command)
|
|
15722
|
+
}));
|
|
15723
|
+
} catch (error) {
|
|
15724
|
+
return { ok: false, code: null, stdout: "", stderr: "", error: error instanceof Error ? error.message : "spawn_failed" };
|
|
15725
|
+
}
|
|
15726
|
+
};
|
|
15727
|
+
}
|
|
15691
15728
|
function firstLine(text) {
|
|
15692
15729
|
const line = text.split(/\r?\n/).map((candidate) => candidate.trim()).find(Boolean);
|
|
15693
15730
|
return line && line.length <= 200 ? line : void 0;
|
|
@@ -16103,35 +16140,31 @@ var PendingHarnessCommand = class {
|
|
|
16103
16140
|
this.key = key;
|
|
16104
16141
|
}
|
|
16105
16142
|
};
|
|
16106
|
-
async function
|
|
16143
|
+
async function replayHarnessProbe(run, execute, limit) {
|
|
16107
16144
|
const observed = /* @__PURE__ */ new Map();
|
|
16108
|
-
|
|
16109
|
-
const result = await defaultSpawn(command, args, { env: options.env, timeoutMs, signal: options.signal });
|
|
16110
|
-
const error = result.error?.message ?? (result.observedChildExit !== true ? "auth_probe_exit_unobserved" : void 0);
|
|
16111
|
-
return {
|
|
16112
|
-
ok: result.code === 0 && !error,
|
|
16113
|
-
code: result.code,
|
|
16114
|
-
stdout: result.stdout,
|
|
16115
|
-
stderr: result.stderr,
|
|
16116
|
-
...error ? { error } : {}
|
|
16117
|
-
};
|
|
16118
|
-
});
|
|
16119
|
-
for (let commands = 0; commands <= 32; commands++) {
|
|
16145
|
+
for (let commands = 0; commands <= limit; commands++) {
|
|
16120
16146
|
try {
|
|
16121
|
-
return
|
|
16147
|
+
return execute((command, args, timeoutMs) => {
|
|
16122
16148
|
const key = JSON.stringify([command, args, timeoutMs]);
|
|
16123
16149
|
const result = observed.get(key);
|
|
16124
16150
|
if (result) return result;
|
|
16125
16151
|
throw new PendingHarnessCommand(command, args, timeoutMs, key);
|
|
16126
|
-
}
|
|
16152
|
+
});
|
|
16127
16153
|
} catch (pending) {
|
|
16128
16154
|
if (!(pending instanceof PendingHarnessCommand)) throw pending;
|
|
16129
|
-
if (commands ===
|
|
16155
|
+
if (commands === limit) throw new Error("auth_probe_command_limit");
|
|
16130
16156
|
observed.set(pending.key, await run(pending.command, pending.args, pending.timeoutMs));
|
|
16131
16157
|
}
|
|
16132
16158
|
}
|
|
16133
16159
|
throw new Error("auth_probe_command_limit");
|
|
16134
16160
|
}
|
|
16161
|
+
async function probeHarnessAssignmentAsync(options) {
|
|
16162
|
+
return replayHarnessProbe(
|
|
16163
|
+
options.runCommand ?? defaultAsyncRunner(options.env ?? process.env, options.signal),
|
|
16164
|
+
(runCommand) => probeHarnessAssignment({ ...options, runCommand }),
|
|
16165
|
+
32
|
|
16166
|
+
);
|
|
16167
|
+
}
|
|
16135
16168
|
|
|
16136
16169
|
// plugins/kxm/src/vnext-config.ts
|
|
16137
16170
|
var VnextConfigError = class extends Error {
|
|
@@ -21904,9 +21937,28 @@ import { join as join11 } from "node:path";
|
|
|
21904
21937
|
import { createHash as createHash6, randomUUID as randomUUID3 } from "node:crypto";
|
|
21905
21938
|
import { lstat, mkdir, open, rename } from "node:fs/promises";
|
|
21906
21939
|
import { join as join6 } from "node:path";
|
|
21940
|
+
var ONESHOT_EVIDENCE_SCHEMA = "kxm.oneshot-evidence.v2";
|
|
21941
|
+
var RETIRED_ONESHOT_EVIDENCE_SCHEMAS = /* @__PURE__ */ new Set(["kxm.oneshot-evidence.v1"]);
|
|
21907
21942
|
var TEXT_LIMIT = 4 * 1024 * 1024;
|
|
21943
|
+
var ARGV_LIMIT = 64 * 1024;
|
|
21908
21944
|
var RECORD_LIMIT = 16 * 1024 * 1024;
|
|
21909
21945
|
var digest = (value) => `sha256:${createHash6("sha256").update(value).digest("hex")}`;
|
|
21946
|
+
function parseOneShotEvidenceRecord(bytes) {
|
|
21947
|
+
let parsed;
|
|
21948
|
+
try {
|
|
21949
|
+
parsed = JSON.parse(bytes);
|
|
21950
|
+
} catch {
|
|
21951
|
+
throw new Error("oneshot_evidence_record_invalid");
|
|
21952
|
+
}
|
|
21953
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
21954
|
+
throw new Error("oneshot_evidence_record_invalid");
|
|
21955
|
+
}
|
|
21956
|
+
const schema = parsed.schema;
|
|
21957
|
+
if (typeof schema !== "string") throw new Error("oneshot_evidence_record_invalid");
|
|
21958
|
+
if (RETIRED_ONESHOT_EVIDENCE_SCHEMAS.has(schema)) throw new Error("oneshot_evidence_schema_retired");
|
|
21959
|
+
if (schema !== ONESHOT_EVIDENCE_SCHEMA) throw new Error("oneshot_evidence_schema_unknown");
|
|
21960
|
+
return parsed;
|
|
21961
|
+
}
|
|
21910
21962
|
async function beginOneShotEvidence(root, intent, sensitive) {
|
|
21911
21963
|
await mkdir(root, { recursive: true, mode: 448 });
|
|
21912
21964
|
const stat = await lstat(root);
|
|
@@ -21920,11 +21972,11 @@ async function beginOneShotEvidence(root, intent, sensitive) {
|
|
|
21920
21972
|
const redact = (value) => {
|
|
21921
21973
|
let text = value;
|
|
21922
21974
|
for (const secret of secrets) text = text.replaceAll(secret, "[REDACTED]");
|
|
21923
|
-
return text.replace(/(\b(?:authorization|api[_-]?key|access[_-]?token|refresh[_-]?token|password|secret)\b["']?\s*[:=]\s*["']?)(?:Bearer\s+)?[^\s"',;}]+/gi, "$1[REDACTED]");
|
|
21975
|
+
return text.replace(/(\b(?:authorization|api[_-]?key|access[_-]?token|refresh[_-]?token|password|secret)\b["']?\s*[:=]\s*["']?)(?:Bearer\s+)?[^\s"',;}]+/gi, "$1[REDACTED]").replace(/\bBearer\s+[A-Za-z0-9._~+/=-]+/gi, "Bearer [REDACTED]");
|
|
21924
21976
|
};
|
|
21925
|
-
const bounded = (value) => {
|
|
21977
|
+
const bounded = (value, max = TEXT_LIMIT) => {
|
|
21926
21978
|
const bytes = Buffer.from(redact(value));
|
|
21927
|
-
return { text: bytes.subarray(0,
|
|
21979
|
+
return { text: bytes.subarray(0, max).toString("utf8"), truncated: bytes.length > max, sha256: digest(redact(value)) };
|
|
21928
21980
|
};
|
|
21929
21981
|
const write = async (name, value) => {
|
|
21930
21982
|
const current = await lstat(dir);
|
|
@@ -21933,6 +21985,7 @@ async function beginOneShotEvidence(root, intent, sensitive) {
|
|
|
21933
21985
|
}
|
|
21934
21986
|
const bytes = JSON.stringify(value);
|
|
21935
21987
|
if (Buffer.byteLength(bytes) > RECORD_LIMIT) throw new Error("oneshot_evidence_record_limit");
|
|
21988
|
+
parseOneShotEvidenceRecord(bytes);
|
|
21936
21989
|
const target = join6(dir, name);
|
|
21937
21990
|
const partial = `${target}.partial`;
|
|
21938
21991
|
const file = await open(partial, "wx", 384);
|
|
@@ -21954,7 +22007,7 @@ async function beginOneShotEvidence(root, intent, sensitive) {
|
|
|
21954
22007
|
return digest(bytes);
|
|
21955
22008
|
};
|
|
21956
22009
|
await write("intent.json", {
|
|
21957
|
-
schema:
|
|
22010
|
+
schema: ONESHOT_EVIDENCE_SCHEMA,
|
|
21958
22011
|
id,
|
|
21959
22012
|
recordedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
21960
22013
|
runId: intent.runId,
|
|
@@ -21965,9 +22018,10 @@ async function beginOneShotEvidence(root, intent, sensitive) {
|
|
|
21965
22018
|
provider: intent.provider,
|
|
21966
22019
|
requestedModel: intent.model,
|
|
21967
22020
|
cwd: intent.cwd,
|
|
21968
|
-
command: intent.command,
|
|
21969
|
-
argv: bounded(JSON.stringify(intent.args)),
|
|
22021
|
+
command: redact(intent.command),
|
|
22022
|
+
argv: bounded(JSON.stringify(intent.args), ARGV_LIMIT),
|
|
21970
22023
|
stdin: intent.input === void 0 ? null : bounded(intent.input),
|
|
22024
|
+
env: null,
|
|
21971
22025
|
acceptance: false
|
|
21972
22026
|
});
|
|
21973
22027
|
let finished = false;
|
|
@@ -21977,7 +22031,7 @@ async function beginOneShotEvidence(root, intent, sensitive) {
|
|
|
21977
22031
|
if (finished) throw new Error("oneshot_evidence_already_finished");
|
|
21978
22032
|
finished = true;
|
|
21979
22033
|
return write("result.json", {
|
|
21980
|
-
schema:
|
|
22034
|
+
schema: ONESHOT_EVIDENCE_SCHEMA,
|
|
21981
22035
|
id,
|
|
21982
22036
|
recordedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
21983
22037
|
stdout: bounded(result.stdout),
|
|
@@ -21987,6 +22041,7 @@ async function beginOneShotEvidence(root, intent, sensitive) {
|
|
|
21987
22041
|
started: result.started ?? null,
|
|
21988
22042
|
observedChildExit: result.observedChildExit ?? null,
|
|
21989
22043
|
terminationRequested: result.terminationRequested ?? null,
|
|
22044
|
+
unverifiedDescendants: result.unverifiedDescendants ?? null,
|
|
21990
22045
|
error: result.error ? bounded(result.error.message) : null,
|
|
21991
22046
|
observation: bounded(JSON.stringify(observation)),
|
|
21992
22047
|
acceptance: false
|
|
@@ -25648,7 +25703,8 @@ Return a final JSON object with an "outcome" field chosen from ${JSON.stringify(
|
|
|
25648
25703
|
parsed = { text: "", isError: true };
|
|
25649
25704
|
}
|
|
25650
25705
|
const aborted = request.signal.aborted || procResult.error?.message === "process_aborted";
|
|
25651
|
-
const
|
|
25706
|
+
const unverifiedDescendants = procResult.unverifiedDescendants === true || procResult.terminationRequested === true || procResult.error?.message === "process_exit_unobserved" || procResult.observedChildExit === false && procResult.started !== false;
|
|
25707
|
+
const effectUncertain = unverifiedDescendants || Boolean(procResult.signal);
|
|
25652
25708
|
const transportFailed = procResult.code !== 0 || Boolean(procResult.error) || effectUncertain;
|
|
25653
25709
|
const outcome = aborted ? "cancelled" : transportFailed || parsed.isError ? "failed" : determineOutcome(parsed.text, request.allowedOutcomes);
|
|
25654
25710
|
const providerMetadata = {
|
|
@@ -25660,6 +25716,7 @@ Return a final JSON object with an "outcome" field chosen from ${JSON.stringify(
|
|
|
25660
25716
|
if (procResult.observedChildExit !== void 0) providerMetadata.observedChildExit = procResult.observedChildExit;
|
|
25661
25717
|
if (procResult.started !== void 0) providerMetadata.processStarted = procResult.started;
|
|
25662
25718
|
if (procResult.terminationRequested !== void 0) providerMetadata.terminationRequested = procResult.terminationRequested;
|
|
25719
|
+
if (unverifiedDescendants) providerMetadata.descendantEffects = "unverified";
|
|
25663
25720
|
if (procResult.error) {
|
|
25664
25721
|
const reason = procResult.error.message;
|
|
25665
25722
|
providerMetadata.processError = /^process_(aborted|timeout|output_limit|stdin_error|stdio_error|stdio_unclosed|exit_unobserved)$/.test(reason) ? reason : "process_error";
|
|
@@ -26140,7 +26197,6 @@ async function startVnextRuntimeSupervisorInner(paths, requestedPortOption, now)
|
|
|
26140
26197
|
});
|
|
26141
26198
|
} catch (err) {
|
|
26142
26199
|
earlyError = err;
|
|
26143
|
-
drivePromise = Promise.reject(err);
|
|
26144
26200
|
}
|
|
26145
26201
|
await Promise.resolve();
|
|
26146
26202
|
if (earlyError) {
|
|
@@ -26166,6 +26222,7 @@ async function startVnextRuntimeSupervisorInner(paths, requestedPortOption, now)
|
|
|
26166
26222
|
} catch {
|
|
26167
26223
|
}
|
|
26168
26224
|
}
|
|
26225
|
+
}).catch(() => {
|
|
26169
26226
|
});
|
|
26170
26227
|
sendJson(response, 202, {
|
|
26171
26228
|
ok: true,
|
package/plugins/kxm/package.json
CHANGED
|
@@ -81,7 +81,7 @@ import { loadKxmUpdateConfig } from "../kxm-update-config.ts";
|
|
|
81
81
|
import {
|
|
82
82
|
formatHarnessUpdate,
|
|
83
83
|
planHarnessUpdate,
|
|
84
|
-
|
|
84
|
+
probeHarnessesAsync,
|
|
85
85
|
runHarnessUpdate,
|
|
86
86
|
type HarnessUpdateScope,
|
|
87
87
|
} from "../vnext-harness.ts";
|
|
@@ -399,7 +399,7 @@ export async function cmdUpdate(runtime: Runtime, harness: string | undefined, o
|
|
|
399
399
|
return kxmApply?.ok === false ? 1 : 0;
|
|
400
400
|
}
|
|
401
401
|
const scope: HarnessUpdateScope = options.self ? "self" : options.extensions ? "extensions" : options.models ? "models" : "all";
|
|
402
|
-
const inventory =
|
|
402
|
+
const inventory = await probeHarnessesAsync({ env: runtime.env });
|
|
403
403
|
const planned = planHarnessUpdate(inventory, { ...(harness ? { harness } : {}), scope });
|
|
404
404
|
const steps = runHarnessUpdate(planned, { env: runtime.env, dryRun: runtime.dryRun });
|
|
405
405
|
const failed = steps.some((step) => step.outcome === "failed") || kxmApply?.ok === false;
|
|
@@ -755,7 +755,7 @@ export async function maybeOfferGuideSetup(runtime: Runtime): Promise<void> {
|
|
|
755
755
|
if (runtime.env[GUIDE_SETUP_OPT_OUT_ENV]?.trim()) return;
|
|
756
756
|
let inventory;
|
|
757
757
|
try {
|
|
758
|
-
inventory =
|
|
758
|
+
inventory = await probeHarnessesAsync({ env: runtime.env });
|
|
759
759
|
} catch {
|
|
760
760
|
return;
|
|
761
761
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { existsSync, readFileSync, readdirSync } from "node:fs";
|
|
2
2
|
import { basename, join, resolve } from "node:path";
|
|
3
3
|
import { parse as parseYaml } from "yaml";
|
|
4
|
-
import {
|
|
4
|
+
import { probeHarnessesAsync } from "../vnext-harness.ts";
|
|
5
5
|
import { suggestWorkflowAndRoles } from "../suggest.ts";
|
|
6
6
|
import {
|
|
7
7
|
createGoal,
|
|
@@ -32,7 +32,7 @@ export async function cmdSuggest(runtime: Runtime, promptParts: string[]): Promi
|
|
|
32
32
|
runtime.io.stderr("prompt must be non-empty\n");
|
|
33
33
|
return 2;
|
|
34
34
|
}
|
|
35
|
-
const inventory =
|
|
35
|
+
const inventory = await probeHarnessesAsync({ env: runtime.env });
|
|
36
36
|
const availableHarnesses = inventory.harnesses.map((h) => ({
|
|
37
37
|
harness: h.id,
|
|
38
38
|
auth: h.authenticated === true ? "authenticated" : "unauthenticated",
|
|
@@ -25,7 +25,7 @@ import {
|
|
|
25
25
|
import { vnextRuntimePaths } from "../vnext-runtime-store.ts";
|
|
26
26
|
import {
|
|
27
27
|
formatHarnessInventory,
|
|
28
|
-
|
|
28
|
+
probeHarnessesAsync,
|
|
29
29
|
} from "../vnext-harness.ts";
|
|
30
30
|
import {
|
|
31
31
|
fetchLatestKxmVersion,
|
|
@@ -580,7 +580,7 @@ export async function cmdVnextRunList(runtime: Runtime): Promise<number> {
|
|
|
580
580
|
}
|
|
581
581
|
|
|
582
582
|
export async function cmdHarnessList(runtime: Runtime): Promise<number> {
|
|
583
|
-
const inventory =
|
|
583
|
+
const inventory = await probeHarnessesAsync({ env: runtime.env });
|
|
584
584
|
print(runtime.io, runtime.json, { ok: true, command: "harness list", ...inventory }, formatHarnessInventory(inventory));
|
|
585
585
|
return 0;
|
|
586
586
|
}
|
|
@@ -7,7 +7,7 @@ import { AGENT_COMMANDS_MAP, enforceToolPolicy, getMcpTools, reconcileInbox } fr
|
|
|
7
7
|
import { deliverInboxNotification } from "./inbox.ts";
|
|
8
8
|
import type { HubEvent, MessageRecord } from "./protocol.ts";
|
|
9
9
|
|
|
10
|
-
const VERSION = "0.7.
|
|
10
|
+
const VERSION = "0.7.9";
|
|
11
11
|
const inbox = new Map<string, MessageRecord>();
|
|
12
12
|
const notifiedInbox = new Set<string>();
|
|
13
13
|
let meshClient: HubClient | undefined;
|