flavor-code 1.2.17 → 1.2.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/README.zh-CN.md +2 -2
- package/dist/{app-F4P7RV2X.js → app-5D5RSGQX.js} +47 -20
- package/dist/{chunk-YRIPE5K5.js → chunk-A7PMQ22O.js} +1 -1
- package/dist/{chunk-QQCXJC4U.js → chunk-AXLUVJKC.js} +784 -405
- package/dist/cli.js +3 -3
- package/dist/desktop/main.js +1063 -685
- package/dist/desktop/plugin-worker-entry.js +230 -0
- package/dist/evolve/loader.d.ts +1 -1
- package/dist/plugin-worker-entry.js +233 -0
- package/dist/plugins/host.d.ts +2 -3
- package/dist/plugins/sandbox-protocol.d.ts +72 -0
- package/dist/plugins/types.d.ts +3 -0
- package/dist/plugins/worker-host.d.ts +19 -0
- package/dist/production.d.ts +8 -0
- package/dist/sdk/index.js +2 -2
- package/dist/skills/arguments.d.ts +8 -0
- package/dist/skills/tool.d.ts +5 -0
- package/dist/ui/session.d.ts +1 -0
- package/dist/utils/async.d.ts +14 -0
- package/package.json +5 -4
|
@@ -62,6 +62,52 @@ function normalizeProviderError(error) {
|
|
|
62
62
|
return { code, message: message2 };
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
+
// src/utils/async.ts
|
|
66
|
+
function withTimeout(promise, ms) {
|
|
67
|
+
return new Promise((resolve26, reject) => {
|
|
68
|
+
let settled = false;
|
|
69
|
+
const timer = setTimeout(() => {
|
|
70
|
+
if (settled) return;
|
|
71
|
+
settled = true;
|
|
72
|
+
resolve26({ timedOut: true, value: void 0 });
|
|
73
|
+
}, ms);
|
|
74
|
+
timer.unref?.();
|
|
75
|
+
promise.then(
|
|
76
|
+
(value) => {
|
|
77
|
+
if (!settled) {
|
|
78
|
+
settled = true;
|
|
79
|
+
clearTimeout(timer);
|
|
80
|
+
resolve26({ timedOut: false, value });
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
(error) => {
|
|
84
|
+
if (!settled) {
|
|
85
|
+
settled = true;
|
|
86
|
+
clearTimeout(timer);
|
|
87
|
+
reject(error);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
);
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
function awaitWithSignal(promise, signal) {
|
|
94
|
+
signal.throwIfAborted();
|
|
95
|
+
return new Promise((resolve26, reject) => {
|
|
96
|
+
const onAbort = () => reject(signal.reason);
|
|
97
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
98
|
+
promise.then(
|
|
99
|
+
(value) => {
|
|
100
|
+
signal.removeEventListener("abort", onAbort);
|
|
101
|
+
resolve26(value);
|
|
102
|
+
},
|
|
103
|
+
(error) => {
|
|
104
|
+
signal.removeEventListener("abort", onAbort);
|
|
105
|
+
reject(error);
|
|
106
|
+
}
|
|
107
|
+
);
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
|
|
65
111
|
// src/utils/error.ts
|
|
66
112
|
function message(error) {
|
|
67
113
|
return error instanceof Error ? error.message : String(error);
|
|
@@ -3403,7 +3449,8 @@ var FlavorSession = class {
|
|
|
3403
3449
|
version: 1,
|
|
3404
3450
|
type: "SessionStart",
|
|
3405
3451
|
payload: { workspace: this.#services.workspace }
|
|
3406
|
-
}).then(() => {
|
|
3452
|
+
}).then(async (decision) => {
|
|
3453
|
+
if (decision.additionalContext !== void 0) await this.#services.addContext?.(decision.additionalContext);
|
|
3407
3454
|
this.#started = true;
|
|
3408
3455
|
});
|
|
3409
3456
|
return this.#startPromise;
|
|
@@ -5058,25 +5105,6 @@ function hasCycle(nodes) {
|
|
|
5058
5105
|
return visited !== nodes.length;
|
|
5059
5106
|
}
|
|
5060
5107
|
|
|
5061
|
-
// src/utils/async.ts
|
|
5062
|
-
function awaitWithSignal(promise, signal) {
|
|
5063
|
-
signal.throwIfAborted();
|
|
5064
|
-
return new Promise((resolve26, reject) => {
|
|
5065
|
-
const onAbort = () => reject(signal.reason);
|
|
5066
|
-
signal.addEventListener("abort", onAbort, { once: true });
|
|
5067
|
-
promise.then(
|
|
5068
|
-
(value) => {
|
|
5069
|
-
signal.removeEventListener("abort", onAbort);
|
|
5070
|
-
resolve26(value);
|
|
5071
|
-
},
|
|
5072
|
-
(error) => {
|
|
5073
|
-
signal.removeEventListener("abort", onAbort);
|
|
5074
|
-
reject(error);
|
|
5075
|
-
}
|
|
5076
|
-
);
|
|
5077
|
-
});
|
|
5078
|
-
}
|
|
5079
|
-
|
|
5080
5108
|
// src/agent/subagents.ts
|
|
5081
5109
|
var SubagentResultSchema = z5.object({
|
|
5082
5110
|
taskId: z5.string().min(1),
|
|
@@ -8030,7 +8058,7 @@ function createIncidentReporter(options) {
|
|
|
8030
8058
|
import { spawn as spawn5 } from "child_process";
|
|
8031
8059
|
import { writeFile as writeFile8 } from "fs/promises";
|
|
8032
8060
|
import { join as join10 } from "path";
|
|
8033
|
-
import { z as
|
|
8061
|
+
import { z as z13 } from "zod";
|
|
8034
8062
|
|
|
8035
8063
|
// src/evolve/loader.ts
|
|
8036
8064
|
import { cp, mkdir as mkdir8, mkdtemp, readdir as readdir4, rm as rm2, stat as stat4, writeFile as writeFile6 } from "fs/promises";
|
|
@@ -8039,9 +8067,10 @@ import { join as join8, resolve as resolve9 } from "path";
|
|
|
8039
8067
|
|
|
8040
8068
|
// src/plugins/host.ts
|
|
8041
8069
|
import { lstatSync, realpathSync as realpathSync2 } from "fs";
|
|
8042
|
-
import { lstat as lstat5, open as open5, readdir as readdir3, realpath as
|
|
8070
|
+
import { lstat as lstat5, open as open5, readdir as readdir3, realpath as realpath4, stat as stat3, writeFile as writeFile5 } from "fs/promises";
|
|
8043
8071
|
import { isAbsolute as isAbsolute5, relative as relative7, resolve as resolve8, sep as sep7 } from "path";
|
|
8044
8072
|
import { pathToFileURL } from "url";
|
|
8073
|
+
import { z as z12 } from "zod";
|
|
8045
8074
|
|
|
8046
8075
|
// src/plugins/types.ts
|
|
8047
8076
|
import { z as z11 } from "zod";
|
|
@@ -8071,10 +8100,188 @@ var PluginManifestSchema = z11.object({
|
|
|
8071
8100
|
}).strict()
|
|
8072
8101
|
}).strict();
|
|
8073
8102
|
|
|
8103
|
+
// src/plugins/worker-host.ts
|
|
8104
|
+
import { realpath as realpath3 } from "fs/promises";
|
|
8105
|
+
import { dirname as dirname10 } from "path";
|
|
8106
|
+
import { Worker } from "worker_threads";
|
|
8107
|
+
var DEFAULT_ACTIVATION_TIMEOUT_MS = 1e4;
|
|
8108
|
+
var DEFAULT_INVOCATION_TIMEOUT_MS = 3e4;
|
|
8109
|
+
var DEFAULT_MAX_OLD_SPACE_MB = 128;
|
|
8110
|
+
var DEFAULT_SHUTDOWN_TIMEOUT_MS = 5e3;
|
|
8111
|
+
async function startPluginSandbox(options) {
|
|
8112
|
+
const entryPath = await realpath3(options.entryPath);
|
|
8113
|
+
const pluginRoot = await realpath3(options.pluginRoot ?? dirname10(entryPath));
|
|
8114
|
+
const activationTimeoutMs = options.activationTimeoutMs ?? DEFAULT_ACTIVATION_TIMEOUT_MS;
|
|
8115
|
+
const invocationTimeoutMs = options.invocationTimeoutMs ?? DEFAULT_INVOCATION_TIMEOUT_MS;
|
|
8116
|
+
let configJson;
|
|
8117
|
+
try {
|
|
8118
|
+
configJson = JSON.stringify(options.config ?? {});
|
|
8119
|
+
} catch (error) {
|
|
8120
|
+
throw new Error(`Plugin sandbox config is not serializable: ${String(error)}`);
|
|
8121
|
+
}
|
|
8122
|
+
const workerEntry = new URL(import.meta.url.endsWith(".ts") ? "./plugin-worker-entry.ts" : "./plugin-worker-entry.js", import.meta.url);
|
|
8123
|
+
const worker = new Worker(workerEntry, {
|
|
8124
|
+
workerData: { entryPath, pluginRoot, pluginName: options.pluginName, pluginVersion: options.pluginVersion, configJson },
|
|
8125
|
+
execArgv: ["--experimental-vm-modules", "--no-warnings"],
|
|
8126
|
+
resourceLimits: {
|
|
8127
|
+
maxOldGenerationSizeMb: options.maxOldSpaceMb ?? DEFAULT_MAX_OLD_SPACE_MB,
|
|
8128
|
+
maxYoungGenerationSizeMb: 16,
|
|
8129
|
+
codeRangeSizeMb: 16,
|
|
8130
|
+
stackSizeMb: 4
|
|
8131
|
+
}
|
|
8132
|
+
});
|
|
8133
|
+
let closed = false;
|
|
8134
|
+
let nextId = 1;
|
|
8135
|
+
const pending = /* @__PURE__ */ new Map();
|
|
8136
|
+
let disposeResolve;
|
|
8137
|
+
let disposeReject;
|
|
8138
|
+
let failWorker;
|
|
8139
|
+
const ready = await new Promise((resolveReady, rejectReady) => {
|
|
8140
|
+
let settled = false;
|
|
8141
|
+
const timer = setTimeout(() => {
|
|
8142
|
+
settled = true;
|
|
8143
|
+
closed = true;
|
|
8144
|
+
void worker.terminate();
|
|
8145
|
+
rejectReady(new Error(`Plugin activation sandbox timed out after ${activationTimeoutMs}ms`));
|
|
8146
|
+
}, activationTimeoutMs);
|
|
8147
|
+
const fail = (error) => {
|
|
8148
|
+
if (closed && settled) return;
|
|
8149
|
+
closed = true;
|
|
8150
|
+
clearTimeout(timer);
|
|
8151
|
+
for (const request of pending.values()) {
|
|
8152
|
+
clearTimeout(request.timer);
|
|
8153
|
+
request.reject(error);
|
|
8154
|
+
}
|
|
8155
|
+
pending.clear();
|
|
8156
|
+
disposeReject?.(error);
|
|
8157
|
+
if (!settled) {
|
|
8158
|
+
settled = true;
|
|
8159
|
+
rejectReady(error);
|
|
8160
|
+
}
|
|
8161
|
+
void worker.terminate();
|
|
8162
|
+
};
|
|
8163
|
+
failWorker = fail;
|
|
8164
|
+
worker.on("message", (raw) => {
|
|
8165
|
+
if (!isWorkerMessage(raw)) {
|
|
8166
|
+
fail(new Error("Plugin sandbox sent an invalid protocol message"));
|
|
8167
|
+
return;
|
|
8168
|
+
}
|
|
8169
|
+
const message2 = raw;
|
|
8170
|
+
if (message2.type === "fatal") {
|
|
8171
|
+
fail(new Error(message2.error));
|
|
8172
|
+
return;
|
|
8173
|
+
}
|
|
8174
|
+
if (message2.type === "ready") {
|
|
8175
|
+
if (settled || !isSandboxResult(message2.result)) {
|
|
8176
|
+
fail(new Error("Plugin sandbox sent an invalid or duplicate ready message"));
|
|
8177
|
+
return;
|
|
8178
|
+
}
|
|
8179
|
+
settled = true;
|
|
8180
|
+
clearTimeout(timer);
|
|
8181
|
+
resolveReady(message2.result);
|
|
8182
|
+
return;
|
|
8183
|
+
}
|
|
8184
|
+
if (!settled) {
|
|
8185
|
+
fail(new Error(`Plugin sandbox sent ${message2.type} before ready`));
|
|
8186
|
+
return;
|
|
8187
|
+
}
|
|
8188
|
+
if (message2.type === "response") {
|
|
8189
|
+
const request = pending.get(message2.id);
|
|
8190
|
+
if (request === void 0) {
|
|
8191
|
+
fail(new Error("Plugin sandbox sent a response for an unknown request"));
|
|
8192
|
+
return;
|
|
8193
|
+
}
|
|
8194
|
+
pending.delete(message2.id);
|
|
8195
|
+
clearTimeout(request.timer);
|
|
8196
|
+
if (message2.ok) {
|
|
8197
|
+
try {
|
|
8198
|
+
request.resolve(JSON.parse(message2.valueJson));
|
|
8199
|
+
} catch {
|
|
8200
|
+
fail(new Error("Plugin sandbox returned invalid JSON"));
|
|
8201
|
+
}
|
|
8202
|
+
} else request.reject(new Error(message2.error));
|
|
8203
|
+
return;
|
|
8204
|
+
}
|
|
8205
|
+
if (message2.type === "disposed") {
|
|
8206
|
+
closed = true;
|
|
8207
|
+
disposeResolve?.();
|
|
8208
|
+
void worker.terminate();
|
|
8209
|
+
}
|
|
8210
|
+
});
|
|
8211
|
+
worker.once("error", fail);
|
|
8212
|
+
worker.once("exit", (code) => {
|
|
8213
|
+
if (!closed) fail(new Error(`Plugin worker exited with code ${code}`));
|
|
8214
|
+
});
|
|
8215
|
+
});
|
|
8216
|
+
return {
|
|
8217
|
+
result: ready,
|
|
8218
|
+
invoke(kind, name, args) {
|
|
8219
|
+
if (closed) return Promise.reject(new Error("Plugin sandbox is closed"));
|
|
8220
|
+
let argsJson;
|
|
8221
|
+
try {
|
|
8222
|
+
argsJson = JSON.stringify(args);
|
|
8223
|
+
} catch (error) {
|
|
8224
|
+
return Promise.reject(new Error(`Plugin sandbox arguments are not serializable: ${String(error)}`));
|
|
8225
|
+
}
|
|
8226
|
+
const id = nextId++;
|
|
8227
|
+
return new Promise((resolveInvoke, rejectInvoke) => {
|
|
8228
|
+
const timer = setTimeout(() => {
|
|
8229
|
+
const error = new Error(`Plugin sandbox invocation timed out after ${invocationTimeoutMs}ms`);
|
|
8230
|
+
failWorker(error);
|
|
8231
|
+
}, invocationTimeoutMs);
|
|
8232
|
+
pending.set(id, { resolve: (value) => resolveInvoke(value), reject: rejectInvoke, timer });
|
|
8233
|
+
worker.postMessage({ type: "invoke", id, kind, name, argsJson });
|
|
8234
|
+
});
|
|
8235
|
+
},
|
|
8236
|
+
dispose() {
|
|
8237
|
+
if (closed) return Promise.resolve();
|
|
8238
|
+
return new Promise((resolveDispose, rejectDispose) => {
|
|
8239
|
+
const timer = setTimeout(() => {
|
|
8240
|
+
const error = new Error(`Plugin sandbox shutdown timed out after ${DEFAULT_SHUTDOWN_TIMEOUT_MS}ms`);
|
|
8241
|
+
failWorker(error);
|
|
8242
|
+
}, DEFAULT_SHUTDOWN_TIMEOUT_MS);
|
|
8243
|
+
disposeResolve = () => {
|
|
8244
|
+
clearTimeout(timer);
|
|
8245
|
+
resolveDispose();
|
|
8246
|
+
};
|
|
8247
|
+
disposeReject = (error) => {
|
|
8248
|
+
clearTimeout(timer);
|
|
8249
|
+
rejectDispose(error);
|
|
8250
|
+
};
|
|
8251
|
+
worker.postMessage({ type: "shutdown" });
|
|
8252
|
+
});
|
|
8253
|
+
}
|
|
8254
|
+
};
|
|
8255
|
+
}
|
|
8256
|
+
function isWorkerMessage(value) {
|
|
8257
|
+
if (typeof value !== "object" || value === null || !("type" in value)) return false;
|
|
8258
|
+
const type = value.type;
|
|
8259
|
+
if (type === "disposed") return true;
|
|
8260
|
+
if (type === "fatal") return typeof value.error === "string";
|
|
8261
|
+
if (type === "ready") return "result" in value;
|
|
8262
|
+
if (type !== "response") return false;
|
|
8263
|
+
const response = value;
|
|
8264
|
+
return Number.isSafeInteger(response.id) && typeof response.ok === "boolean" && (response.ok ? typeof response.valueJson === "string" : typeof response.error === "string");
|
|
8265
|
+
}
|
|
8266
|
+
function isSandboxResult(value) {
|
|
8267
|
+
if (typeof value !== "object" || value === null) return false;
|
|
8268
|
+
const result = value;
|
|
8269
|
+
if (!(result.ok === true && typeof result.name === "string" && typeof result.version === "string" && Array.isArray(result.registeredTools) && result.registeredTools.every((item) => typeof item === "string") && Array.isArray(result.registeredCommands) && result.registeredCommands.every((item) => typeof item === "string") && Array.isArray(result.registeredHooks) && result.registeredHooks.every((item) => typeof item === "string") && Array.isArray(result.registeredSkillRoots) && result.registeredSkillRoots.every((item) => typeof item === "string") && Array.isArray(result.registeredModelAdapters) && result.registeredModelAdapters.every((item) => typeof item === "string") && typeof result.contributions === "object" && result.contributions !== null)) return false;
|
|
8270
|
+
const contributions = result.contributions;
|
|
8271
|
+
const named = (item) => typeof item === "object" && item !== null && typeof item.name === "string";
|
|
8272
|
+
if (!Array.isArray(contributions.commands) || !contributions.commands.every((item) => named(item) && (item.description === void 0 || typeof item.description === "string"))) return false;
|
|
8273
|
+
if (!Array.isArray(contributions.tools) || !contributions.tools.every((item) => named(item) && typeof item.toolName === "string" && typeof item.description === "string" && (item.modelInputSchema === void 0 || typeof item.modelInputSchema === "object" && item.modelInputSchema !== null) && (item.readOnly === void 0 || typeof item.readOnly === "boolean"))) return false;
|
|
8274
|
+
if (!Array.isArray(contributions.hooks) || !contributions.hooks.every(named)) return false;
|
|
8275
|
+
if (!Array.isArray(contributions.skillRoots) || !contributions.skillRoots.every((item) => named(item) && typeof item.root === "string")) return false;
|
|
8276
|
+
if (!Array.isArray(contributions.modelAdapters) || !contributions.modelAdapters.every(named)) return false;
|
|
8277
|
+
const same = (left, right) => left.length === right.length && left.every((name, index) => name === right[index]?.name);
|
|
8278
|
+
return same(result.registeredCommands, contributions.commands) && same(result.registeredTools, contributions.tools) && same(result.registeredHooks, contributions.hooks) && same(result.registeredSkillRoots, contributions.skillRoots) && same(result.registeredModelAdapters, contributions.modelAdapters);
|
|
8279
|
+
}
|
|
8280
|
+
|
|
8074
8281
|
// src/plugins/host.ts
|
|
8075
8282
|
var MANIFEST = "flavor-plugin.json";
|
|
8076
8283
|
var MAX_MANIFEST_BYTES2 = 64 * 1024;
|
|
8077
|
-
var
|
|
8284
|
+
var DEFAULT_ACTIVATION_TIMEOUT_MS2 = 1e4;
|
|
8078
8285
|
var DEFAULT_UNLOAD_TIMEOUT_MS = 5e3;
|
|
8079
8286
|
var silentLogger = { debug() {
|
|
8080
8287
|
}, info() {
|
|
@@ -8091,7 +8298,7 @@ var PluginHost = class {
|
|
|
8091
8298
|
#loaded = false;
|
|
8092
8299
|
constructor(options) {
|
|
8093
8300
|
this.#options = options;
|
|
8094
|
-
this.#activationTimeoutMs = positiveTimeout(options.activationTimeoutMs,
|
|
8301
|
+
this.#activationTimeoutMs = positiveTimeout(options.activationTimeoutMs, DEFAULT_ACTIVATION_TIMEOUT_MS2, "activationTimeoutMs");
|
|
8095
8302
|
this.#unloadTimeoutMs = positiveTimeout(options.unloadTimeoutMs, DEFAULT_UNLOAD_TIMEOUT_MS, "unloadTimeoutMs");
|
|
8096
8303
|
}
|
|
8097
8304
|
get diagnostics() {
|
|
@@ -8205,7 +8412,7 @@ var PluginHost = class {
|
|
|
8205
8412
|
try {
|
|
8206
8413
|
const rootInfo = await lstat5(inputRoot);
|
|
8207
8414
|
if (!rootInfo.isDirectory() || rootInfo.isSymbolicLink()) throw new Error("Plugin root must be a static directory");
|
|
8208
|
-
const root = await
|
|
8415
|
+
const root = await realpath4(inputRoot);
|
|
8209
8416
|
const rawManifest = await readManifest(resolve8(root, MANIFEST));
|
|
8210
8417
|
if (typeof rawManifest === "object" && rawManifest !== null && "name" in rawManifest && typeof rawManifest.name === "string") {
|
|
8211
8418
|
diagnosticLabel = rawManifest.name;
|
|
@@ -8225,18 +8432,79 @@ var PluginHost = class {
|
|
|
8225
8432
|
const claimed = [];
|
|
8226
8433
|
const state = { active: true, controller: new AbortController() };
|
|
8227
8434
|
let activation;
|
|
8435
|
+
const useSandbox = this.#options.sandbox === true;
|
|
8228
8436
|
try {
|
|
8229
8437
|
await verifyEntry(candidate.root, candidate.entry, candidate.entrySnapshot);
|
|
8230
|
-
|
|
8231
|
-
|
|
8232
|
-
|
|
8233
|
-
|
|
8234
|
-
|
|
8235
|
-
|
|
8236
|
-
|
|
8237
|
-
|
|
8238
|
-
|
|
8239
|
-
|
|
8438
|
+
if (useSandbox) {
|
|
8439
|
+
const session = await bounded(
|
|
8440
|
+
startPluginSandbox({
|
|
8441
|
+
entryPath: candidate.entrySnapshot.physicalPath,
|
|
8442
|
+
pluginRoot: candidate.root,
|
|
8443
|
+
pluginName: plugin,
|
|
8444
|
+
pluginVersion: candidate.manifest.version,
|
|
8445
|
+
config: redactConfig(this.#options.config ?? {}),
|
|
8446
|
+
activationTimeoutMs: this.#activationTimeoutMs
|
|
8447
|
+
}),
|
|
8448
|
+
this.#activationTimeoutMs + 1e3,
|
|
8449
|
+
"Plugin sandbox activation"
|
|
8450
|
+
);
|
|
8451
|
+
disposers.push(() => session.dispose());
|
|
8452
|
+
const result = session.result;
|
|
8453
|
+
if (!result.ok) throw new Error(result.error ?? `Plugin "${plugin}" sandbox execution failed`);
|
|
8454
|
+
const context = this.#context(candidate, disposers, claimed, state);
|
|
8455
|
+
for (const command of result.contributions.commands) {
|
|
8456
|
+
context.registerCommand(command.name, (args, commandContext) => session.invoke("command", command.name, [
|
|
8457
|
+
args,
|
|
8458
|
+
{ workspace: commandContext.workspace }
|
|
8459
|
+
]), command.description);
|
|
8460
|
+
}
|
|
8461
|
+
for (const contribution of result.contributions.tools) {
|
|
8462
|
+
const tool = {
|
|
8463
|
+
name: contribution.toolName,
|
|
8464
|
+
description: contribution.description,
|
|
8465
|
+
inputSchema: z12.unknown(),
|
|
8466
|
+
...contribution.modelInputSchema === void 0 ? {} : { modelInputSchema: contribution.modelInputSchema },
|
|
8467
|
+
...contribution.readOnly === void 0 ? {} : { readOnly: contribution.readOnly },
|
|
8468
|
+
paths: () => [],
|
|
8469
|
+
execute: (input, _signal, toolContext) => session.invoke("tool", contribution.name, [
|
|
8470
|
+
input,
|
|
8471
|
+
toolContext === void 0 ? void 0 : { agent: toolContext.agent, ownerId: toolContext.ownerId }
|
|
8472
|
+
])
|
|
8473
|
+
};
|
|
8474
|
+
context.registerTool(contribution.name, tool);
|
|
8475
|
+
}
|
|
8476
|
+
for (const hook of result.contributions.hooks) {
|
|
8477
|
+
context.registerHook(
|
|
8478
|
+
hook.name,
|
|
8479
|
+
(event) => session.invoke("hook", hook.name, [event]),
|
|
8480
|
+
hook.options
|
|
8481
|
+
);
|
|
8482
|
+
}
|
|
8483
|
+
for (const skill of result.contributions.skillRoots) {
|
|
8484
|
+
context.registerSkillRoot(skill.name, skill.root);
|
|
8485
|
+
}
|
|
8486
|
+
for (const adapter of result.contributions.modelAdapters) {
|
|
8487
|
+
context.registerModelAdapter(adapter.name, {
|
|
8488
|
+
async *stream(request) {
|
|
8489
|
+
const safeRequest = { ...request, signal: void 0 };
|
|
8490
|
+
const events = await session.invoke("modelAdapter", adapter.name, [safeRequest]);
|
|
8491
|
+
for (const event of events) yield event;
|
|
8492
|
+
}
|
|
8493
|
+
});
|
|
8494
|
+
}
|
|
8495
|
+
await verifyEntry(candidate.root, candidate.entry, candidate.entrySnapshot);
|
|
8496
|
+
} else {
|
|
8497
|
+
const imported = import(`${pathToFileURL(candidate.entrySnapshot.physicalPath).href}?flavor=${encodeURIComponent(plugin)}&v=${Date.now()}`);
|
|
8498
|
+
const module = await bounded(imported, this.#activationTimeoutMs, "Plugin import");
|
|
8499
|
+
await verifyEntry(candidate.root, candidate.entry, candidate.entrySnapshot);
|
|
8500
|
+
if (typeof module.activate !== "function") throw new Error("Plugin entry must export activate(context)");
|
|
8501
|
+
const context = this.#context(candidate, disposers, claimed, state);
|
|
8502
|
+
activation = Promise.resolve().then(() => module.activate(context));
|
|
8503
|
+
const deactivate = await bounded(activation, this.#activationTimeoutMs, "Plugin activation");
|
|
8504
|
+
if (deactivate !== void 0) {
|
|
8505
|
+
if (typeof deactivate !== "function") throw new Error("Plugin activate result must be a disposer or undefined");
|
|
8506
|
+
disposers.push(deactivate);
|
|
8507
|
+
}
|
|
8240
8508
|
}
|
|
8241
8509
|
this.#assertAllDeclaredRegistered(candidate, claimed);
|
|
8242
8510
|
const metadata = { name: plugin, version: candidate.manifest.version, source: candidate.source, root: candidate.root };
|
|
@@ -8400,7 +8668,7 @@ async function readManifest(path) {
|
|
|
8400
8668
|
async function snapshotEntry(root, entry2) {
|
|
8401
8669
|
const lexicalStats = await lstat5(entry2, { bigint: true });
|
|
8402
8670
|
if (!lexicalStats.isFile() && !lexicalStats.isSymbolicLink()) throw new Error("Plugin entry must be a file");
|
|
8403
|
-
const physicalPath = await
|
|
8671
|
+
const physicalPath = await realpath4(entry2);
|
|
8404
8672
|
assertContained(root, physicalPath, "Plugin entry symlink");
|
|
8405
8673
|
const physicalStats = await stat3(physicalPath, { bigint: true });
|
|
8406
8674
|
if (!physicalStats.isFile()) throw new Error("Plugin entry must resolve to a regular file");
|
|
@@ -8516,6 +8784,8 @@ var SCAFFOLD_ENTRY = (name) => `// ${name} \u2014 generated by /evolve improve <
|
|
|
8516
8784
|
// - context: { signal, config, logger, services, registerCommand,
|
|
8517
8785
|
// registerTool, registerHook, registerSkillRoot, registerModelAdapter }
|
|
8518
8786
|
// - every contribution you register MUST be declared in contributes
|
|
8787
|
+
// - sandbox verification only permits relative JS modules inside this plugin root;
|
|
8788
|
+
// Node.js built-ins, package imports, filesystem, and network APIs are unavailable
|
|
8519
8789
|
//
|
|
8520
8790
|
// Implement your fix here. Example \u2014 observe tool failures:
|
|
8521
8791
|
// ctx.registerHook("PostToolUseFailure", (event) => {
|
|
@@ -8555,7 +8825,9 @@ async function verifyFixPlugin(workspace, name) {
|
|
|
8555
8825
|
await cp(pluginRoot, join8(sandbox, name), { recursive: true });
|
|
8556
8826
|
const host = new PluginHost({
|
|
8557
8827
|
projectPluginDirs: [sandbox],
|
|
8828
|
+
sandbox: true,
|
|
8558
8829
|
config: {},
|
|
8830
|
+
activationTimeoutMs: 5e3,
|
|
8559
8831
|
registrations: {
|
|
8560
8832
|
command: (commandName) => {
|
|
8561
8833
|
collected.commands.push(commandName);
|
|
@@ -8569,12 +8841,11 @@ async function verifyFixPlugin(workspace, name) {
|
|
|
8569
8841
|
skillRoot: () => () => void 0,
|
|
8570
8842
|
modelAdapter: () => () => void 0
|
|
8571
8843
|
},
|
|
8572
|
-
logger: {
|
|
8573
|
-
|
|
8574
|
-
|
|
8575
|
-
|
|
8576
|
-
|
|
8577
|
-
}
|
|
8844
|
+
logger: { debug() {
|
|
8845
|
+
}, info() {
|
|
8846
|
+
}, warn() {
|
|
8847
|
+
}, error() {
|
|
8848
|
+
} }
|
|
8578
8849
|
});
|
|
8579
8850
|
await host.loadAll();
|
|
8580
8851
|
const loaded = host.loadedPlugins;
|
|
@@ -8633,7 +8904,7 @@ async function revertFixPlugin(workspace, name) {
|
|
|
8633
8904
|
// src/evolve/store.ts
|
|
8634
8905
|
import { createHash as createHash5 } from "crypto";
|
|
8635
8906
|
import { appendFile, mkdir as mkdir9, readFile as readFile7, rm as rm3, writeFile as writeFile7 } from "fs/promises";
|
|
8636
|
-
import { dirname as
|
|
8907
|
+
import { dirname as dirname11, join as join9 } from "path";
|
|
8637
8908
|
function normalizeError(message2) {
|
|
8638
8909
|
return String(message2 ?? "").replace(/\s+/g, " ").replace(/"[^"]*"/g, '"\u2026"').replace(/`[^`]*`/g, '"\u2026"').trim().slice(0, 160);
|
|
8639
8910
|
}
|
|
@@ -8662,7 +8933,7 @@ async function readJsonLines(file) {
|
|
|
8662
8933
|
}
|
|
8663
8934
|
}
|
|
8664
8935
|
async function writeJsonLines(file, records) {
|
|
8665
|
-
await mkdir9(
|
|
8936
|
+
await mkdir9(dirname11(file), { recursive: true, mode: 448 });
|
|
8666
8937
|
const body = records.map((record) => JSON.stringify(record)).join("\n");
|
|
8667
8938
|
await writeFile7(file, body.length > 0 ? `${body}
|
|
8668
8939
|
` : "", { encoding: "utf8", mode: 384 });
|
|
@@ -8690,7 +8961,7 @@ async function readRules(file) {
|
|
|
8690
8961
|
}
|
|
8691
8962
|
}
|
|
8692
8963
|
async function writeRules(file, rules) {
|
|
8693
|
-
await mkdir9(
|
|
8964
|
+
await mkdir9(dirname11(file), { recursive: true, mode: 448 });
|
|
8694
8965
|
await writeFile7(file, JSON.stringify(rules, null, 2), { encoding: "utf8", mode: 384 });
|
|
8695
8966
|
}
|
|
8696
8967
|
var EvolveStore = class {
|
|
@@ -9312,10 +9583,10 @@ ${result.stderr.slice(-4e3)}` : ""}`;
|
|
|
9312
9583
|
return USAGE;
|
|
9313
9584
|
},
|
|
9314
9585
|
toolDefinition() {
|
|
9315
|
-
const inputSchema =
|
|
9316
|
-
suggestionId:
|
|
9317
|
-
implementation:
|
|
9318
|
-
kind:
|
|
9586
|
+
const inputSchema = z13.object({
|
|
9587
|
+
suggestionId: z13.string().min(1).describe("Signal id from the evolve suggestions"),
|
|
9588
|
+
implementation: z13.string().min(1).describe("Concise description of the fix to implement (plugin plan, or the guardrail rule text when kind is prompt_rule)"),
|
|
9589
|
+
kind: z13.enum(["plugin", "prompt_rule"]).optional().describe(
|
|
9319
9590
|
"plugin (default): scaffold a fix plugin; prompt_rule: store a guardrail rule that is injected into future system prompts"
|
|
9320
9591
|
)
|
|
9321
9592
|
});
|
|
@@ -9381,8 +9652,8 @@ function buildLoopCyclePrompt(input) {
|
|
|
9381
9652
|
}
|
|
9382
9653
|
|
|
9383
9654
|
// src/loop/types.ts
|
|
9384
|
-
import { z as
|
|
9385
|
-
var LoopStatusSchema =
|
|
9655
|
+
import { z as z14 } from "zod";
|
|
9656
|
+
var LoopStatusSchema = z14.enum([
|
|
9386
9657
|
"running",
|
|
9387
9658
|
"succeeded",
|
|
9388
9659
|
"failed",
|
|
@@ -9392,65 +9663,65 @@ var LoopStatusSchema = z13.enum([
|
|
|
9392
9663
|
"no_progress",
|
|
9393
9664
|
"needs_human"
|
|
9394
9665
|
]);
|
|
9395
|
-
var LoopApprovalSchema =
|
|
9396
|
-
dimension:
|
|
9397
|
-
previousCheckpoint:
|
|
9398
|
-
newCheckpoint:
|
|
9399
|
-
usage:
|
|
9400
|
-
approvedAt:
|
|
9666
|
+
var LoopApprovalSchema = z14.object({
|
|
9667
|
+
dimension: z14.enum(["cycles", "tokens"]),
|
|
9668
|
+
previousCheckpoint: z14.number().int().nonnegative(),
|
|
9669
|
+
newCheckpoint: z14.number().int().positive(),
|
|
9670
|
+
usage: z14.number().int().nonnegative(),
|
|
9671
|
+
approvedAt: z14.string().datetime({ offset: true })
|
|
9401
9672
|
}).strict();
|
|
9402
|
-
var LoopVerificationCommandSchema =
|
|
9403
|
-
command:
|
|
9404
|
-
args:
|
|
9405
|
-
exitCode:
|
|
9406
|
-
stdout:
|
|
9407
|
-
stderr:
|
|
9408
|
-
truncated:
|
|
9673
|
+
var LoopVerificationCommandSchema = z14.object({
|
|
9674
|
+
command: z14.string().min(1),
|
|
9675
|
+
args: z14.array(z14.string()),
|
|
9676
|
+
exitCode: z14.number().int().nullable(),
|
|
9677
|
+
stdout: z14.string(),
|
|
9678
|
+
stderr: z14.string(),
|
|
9679
|
+
truncated: z14.boolean()
|
|
9409
9680
|
}).strict();
|
|
9410
|
-
var LoopVerificationEvidenceSchema =
|
|
9411
|
-
passed:
|
|
9412
|
-
commands:
|
|
9413
|
-
summary:
|
|
9681
|
+
var LoopVerificationEvidenceSchema = z14.object({
|
|
9682
|
+
passed: z14.boolean(),
|
|
9683
|
+
commands: z14.array(LoopVerificationCommandSchema),
|
|
9684
|
+
summary: z14.string()
|
|
9414
9685
|
}).strict();
|
|
9415
|
-
var LoopCycleEvidenceSchema =
|
|
9416
|
-
cycle:
|
|
9417
|
-
startedAt:
|
|
9418
|
-
completedAt:
|
|
9419
|
-
inputTokens:
|
|
9420
|
-
outputTokens:
|
|
9421
|
-
workspaceFingerprint:
|
|
9686
|
+
var LoopCycleEvidenceSchema = z14.object({
|
|
9687
|
+
cycle: z14.number().int().positive(),
|
|
9688
|
+
startedAt: z14.string().datetime({ offset: true }),
|
|
9689
|
+
completedAt: z14.string().datetime({ offset: true }),
|
|
9690
|
+
inputTokens: z14.number().int().nonnegative(),
|
|
9691
|
+
outputTokens: z14.number().int().nonnegative(),
|
|
9692
|
+
workspaceFingerprint: z14.string(),
|
|
9422
9693
|
verification: LoopVerificationEvidenceSchema
|
|
9423
9694
|
}).strict();
|
|
9424
|
-
var LoopStateSchema =
|
|
9425
|
-
version:
|
|
9426
|
-
loopId:
|
|
9427
|
-
goal:
|
|
9428
|
-
workspace:
|
|
9429
|
-
createdAt:
|
|
9430
|
-
updatedAt:
|
|
9695
|
+
var LoopStateSchema = z14.object({
|
|
9696
|
+
version: z14.literal(1),
|
|
9697
|
+
loopId: z14.string().regex(/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/),
|
|
9698
|
+
goal: z14.string().trim().min(1),
|
|
9699
|
+
workspace: z14.string().min(1),
|
|
9700
|
+
createdAt: z14.string().datetime({ offset: true }),
|
|
9701
|
+
updatedAt: z14.string().datetime({ offset: true }),
|
|
9431
9702
|
status: LoopStatusSchema,
|
|
9432
|
-
config:
|
|
9433
|
-
cycleStep:
|
|
9434
|
-
tokenStep:
|
|
9435
|
-
isolation:
|
|
9703
|
+
config: z14.object({
|
|
9704
|
+
cycleStep: z14.number().int().positive(),
|
|
9705
|
+
tokenStep: z14.number().int().positive(),
|
|
9706
|
+
isolation: z14.literal("auto")
|
|
9436
9707
|
}).strict(),
|
|
9437
|
-
budget:
|
|
9438
|
-
cyclesUsed:
|
|
9439
|
-
inputTokens:
|
|
9440
|
-
outputTokens:
|
|
9441
|
-
cycleCheckpoint:
|
|
9442
|
-
tokenCheckpoint:
|
|
9443
|
-
approvals:
|
|
9708
|
+
budget: z14.object({
|
|
9709
|
+
cyclesUsed: z14.number().int().nonnegative(),
|
|
9710
|
+
inputTokens: z14.number().int().nonnegative(),
|
|
9711
|
+
outputTokens: z14.number().int().nonnegative(),
|
|
9712
|
+
cycleCheckpoint: z14.number().int().positive(),
|
|
9713
|
+
tokenCheckpoint: z14.number().int().positive(),
|
|
9714
|
+
approvals: z14.array(LoopApprovalSchema)
|
|
9444
9715
|
}).strict(),
|
|
9445
|
-
cycles:
|
|
9446
|
-
terminalReason:
|
|
9716
|
+
cycles: z14.array(LoopCycleEvidenceSchema),
|
|
9717
|
+
terminalReason: z14.string().optional()
|
|
9447
9718
|
}).strict();
|
|
9448
|
-
var LoopEventSchema =
|
|
9449
|
-
version:
|
|
9450
|
-
type:
|
|
9451
|
-
timestamp:
|
|
9452
|
-
loopId:
|
|
9453
|
-
payload:
|
|
9719
|
+
var LoopEventSchema = z14.object({
|
|
9720
|
+
version: z14.literal(1),
|
|
9721
|
+
type: z14.enum(["created", "cycle_started", "cycle_completed", "verification", "budget_approved", "terminal"]),
|
|
9722
|
+
timestamp: z14.string().datetime({ offset: true }),
|
|
9723
|
+
loopId: z14.string().regex(/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/),
|
|
9724
|
+
payload: z14.record(z14.string(), z14.unknown())
|
|
9454
9725
|
}).strict();
|
|
9455
9726
|
|
|
9456
9727
|
// src/loop/budget.ts
|
|
@@ -9766,15 +10037,15 @@ import { writeFile as writeFile9, mkdir as mkdir10 } from "fs/promises";
|
|
|
9766
10037
|
import { join as join12 } from "path";
|
|
9767
10038
|
|
|
9768
10039
|
// src/goal/types.ts
|
|
9769
|
-
import { z as
|
|
9770
|
-
var GoalPhaseSchema =
|
|
10040
|
+
import { z as z15 } from "zod";
|
|
10041
|
+
var GoalPhaseSchema = z15.enum([
|
|
9771
10042
|
"idle",
|
|
9772
10043
|
"planning",
|
|
9773
10044
|
"executing",
|
|
9774
10045
|
"verifying",
|
|
9775
10046
|
"complete"
|
|
9776
10047
|
]);
|
|
9777
|
-
var GoalStatusSchema =
|
|
10048
|
+
var GoalStatusSchema = z15.enum([
|
|
9778
10049
|
"active",
|
|
9779
10050
|
"paused",
|
|
9780
10051
|
"achieved",
|
|
@@ -9782,43 +10053,43 @@ var GoalStatusSchema = z14.enum([
|
|
|
9782
10053
|
"blocked",
|
|
9783
10054
|
"failed"
|
|
9784
10055
|
]);
|
|
9785
|
-
var AcceptanceCriterionSchema =
|
|
9786
|
-
id:
|
|
9787
|
-
description:
|
|
9788
|
-
type:
|
|
10056
|
+
var AcceptanceCriterionSchema = z15.object({
|
|
10057
|
+
id: z15.number().int().positive(),
|
|
10058
|
+
description: z15.string().min(1),
|
|
10059
|
+
type: z15.enum(["gating", "evidence"])
|
|
9789
10060
|
}).strict();
|
|
9790
|
-
var PlanSchema =
|
|
9791
|
-
kind:
|
|
9792
|
-
criteria:
|
|
9793
|
-
verificationPlan:
|
|
9794
|
-
nonGoals:
|
|
9795
|
-
assumedScope:
|
|
9796
|
-
approach:
|
|
9797
|
-
checklist:
|
|
10061
|
+
var PlanSchema = z15.object({
|
|
10062
|
+
kind: z15.enum(["code-change", "analysis", "research"]),
|
|
10063
|
+
criteria: z15.array(AcceptanceCriterionSchema).min(1).max(32),
|
|
10064
|
+
verificationPlan: z15.string().min(1),
|
|
10065
|
+
nonGoals: z15.array(z15.string()).max(16),
|
|
10066
|
+
assumedScope: z15.array(z15.string()).max(16),
|
|
10067
|
+
approach: z15.string().optional(),
|
|
10068
|
+
checklist: z15.array(z15.string()).max(32).optional()
|
|
9798
10069
|
}).strict();
|
|
9799
|
-
var GapSchema =
|
|
9800
|
-
criterion:
|
|
9801
|
-
description:
|
|
9802
|
-
blocking:
|
|
10070
|
+
var GapSchema = z15.object({
|
|
10071
|
+
criterion: z15.string().min(1),
|
|
10072
|
+
description: z15.string().min(1),
|
|
10073
|
+
blocking: z15.enum(["model_fixable", "contradiction", "unverifiable"])
|
|
9803
10074
|
}).strict();
|
|
9804
|
-
var VerdictSchema =
|
|
9805
|
-
refuted:
|
|
9806
|
-
gaps:
|
|
10075
|
+
var VerdictSchema = z15.object({
|
|
10076
|
+
refuted: z15.boolean(),
|
|
10077
|
+
gaps: z15.array(GapSchema)
|
|
9807
10078
|
}).strict();
|
|
9808
|
-
var GoalStateSchema =
|
|
9809
|
-
id:
|
|
9810
|
-
objective:
|
|
10079
|
+
var GoalStateSchema = z15.object({
|
|
10080
|
+
id: z15.string().regex(/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/),
|
|
10081
|
+
objective: z15.string().min(1),
|
|
9811
10082
|
phase: GoalPhaseSchema,
|
|
9812
10083
|
status: GoalStatusSchema,
|
|
9813
10084
|
plan: PlanSchema.nullable(),
|
|
9814
|
-
planPath:
|
|
9815
|
-
verifyRounds:
|
|
9816
|
-
workerRounds:
|
|
9817
|
-
lastGaps:
|
|
9818
|
-
gapFingerprint:
|
|
9819
|
-
stallStreak:
|
|
9820
|
-
createdAt:
|
|
9821
|
-
updatedAt:
|
|
10085
|
+
planPath: z15.string().nullable(),
|
|
10086
|
+
verifyRounds: z15.number().int().min(0),
|
|
10087
|
+
workerRounds: z15.number().int().min(0),
|
|
10088
|
+
lastGaps: z15.array(GapSchema),
|
|
10089
|
+
gapFingerprint: z15.string(),
|
|
10090
|
+
stallStreak: z15.number().int().min(0),
|
|
10091
|
+
createdAt: z15.string().datetime({ offset: true }),
|
|
10092
|
+
updatedAt: z15.string().datetime({ offset: true })
|
|
9822
10093
|
}).strict();
|
|
9823
10094
|
|
|
9824
10095
|
// src/goal/planner.ts
|
|
@@ -10379,7 +10650,7 @@ function formatPriorGaps(gaps) {
|
|
|
10379
10650
|
import { constants } from "fs";
|
|
10380
10651
|
import { randomUUID as randomUUID7 } from "crypto";
|
|
10381
10652
|
import { lstat as lstat6, mkdir as mkdir11, open as open6, rename as rename4, rm as rm4 } from "fs/promises";
|
|
10382
|
-
import { dirname as
|
|
10653
|
+
import { dirname as dirname12, join as join13, relative as relative9, resolve as resolve10, sep as sep8 } from "path";
|
|
10383
10654
|
var DEFAULT_MAX_BYTES = 1024 * 1024;
|
|
10384
10655
|
var GoalStore = class {
|
|
10385
10656
|
#workspace;
|
|
@@ -10392,7 +10663,7 @@ var GoalStore = class {
|
|
|
10392
10663
|
}
|
|
10393
10664
|
async save(input) {
|
|
10394
10665
|
const state = GoalStateSchema.parse(input);
|
|
10395
|
-
await assertNoSymlink(this.#workspace,
|
|
10666
|
+
await assertNoSymlink(this.#workspace, dirname12(this.#root));
|
|
10396
10667
|
await mkdir11(this.#root, { recursive: true, mode: 448 });
|
|
10397
10668
|
await assertNoSymlink(this.#workspace, this.#root);
|
|
10398
10669
|
const target = join13(this.#root, `${state.id}.json`);
|
|
@@ -10426,7 +10697,7 @@ async function assertNoSymlink(root, target) {
|
|
|
10426
10697
|
const chain = [];
|
|
10427
10698
|
while (cursor !== stop) {
|
|
10428
10699
|
chain.push(cursor);
|
|
10429
|
-
cursor =
|
|
10700
|
+
cursor = dirname12(cursor);
|
|
10430
10701
|
}
|
|
10431
10702
|
for (const path of chain.reverse()) {
|
|
10432
10703
|
try {
|
|
@@ -10512,8 +10783,8 @@ async function ensureWorktreeDirectoryIgnored(root) {
|
|
|
10512
10783
|
|
|
10513
10784
|
// src/loop/store.ts
|
|
10514
10785
|
import { constants as constants2 } from "fs";
|
|
10515
|
-
import { lstat as lstat7, mkdir as mkdir13, open as open7, readFile as readFile10, realpath as
|
|
10516
|
-
import { dirname as
|
|
10786
|
+
import { lstat as lstat7, mkdir as mkdir13, open as open7, readFile as readFile10, realpath as realpath5, rename as rename5, rm as rm5, stat as stat5 } from "fs/promises";
|
|
10787
|
+
import { dirname as dirname13, join as join15, relative as relative10, resolve as resolve12, sep as sep9 } from "path";
|
|
10517
10788
|
import { randomUUID as randomUUID8 } from "crypto";
|
|
10518
10789
|
var LOOP_ID = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
|
|
10519
10790
|
var DEFAULT_MAX_BYTES2 = 5 * 1024 * 1024;
|
|
@@ -10595,7 +10866,7 @@ var LoopStore = class {
|
|
|
10595
10866
|
}
|
|
10596
10867
|
async #prepare(loopId) {
|
|
10597
10868
|
validateId(loopId);
|
|
10598
|
-
await assertNoSymlink2(this.#workspace,
|
|
10869
|
+
await assertNoSymlink2(this.#workspace, dirname13(this.#root));
|
|
10599
10870
|
await mkdir13(this.#root, { recursive: true, mode: 448 });
|
|
10600
10871
|
await assertNoSymlink2(this.#workspace, this.#root);
|
|
10601
10872
|
const directory = join15(this.#root, loopId);
|
|
@@ -10628,7 +10899,7 @@ async function assertNoSymlink2(root, target) {
|
|
|
10628
10899
|
const chain = [];
|
|
10629
10900
|
while (cursor !== stop) {
|
|
10630
10901
|
chain.push(cursor);
|
|
10631
|
-
cursor =
|
|
10902
|
+
cursor = dirname13(cursor);
|
|
10632
10903
|
}
|
|
10633
10904
|
for (const path of chain.reverse()) {
|
|
10634
10905
|
try {
|
|
@@ -10644,7 +10915,7 @@ function isWithin2(root, path) {
|
|
|
10644
10915
|
}
|
|
10645
10916
|
async function canonical(path) {
|
|
10646
10917
|
try {
|
|
10647
|
-
return await
|
|
10918
|
+
return await realpath5(resolve12(path));
|
|
10648
10919
|
} catch {
|
|
10649
10920
|
return resolve12(path);
|
|
10650
10921
|
}
|
|
@@ -10660,19 +10931,19 @@ import { join as join16 } from "path";
|
|
|
10660
10931
|
// src/tools/shell.ts
|
|
10661
10932
|
import { spawn as spawn6, spawnSync } from "child_process";
|
|
10662
10933
|
import { isAbsolute as isAbsolute6, relative as relative11, resolve as resolve13, sep as sep10 } from "path";
|
|
10663
|
-
import { z as
|
|
10934
|
+
import { z as z17 } from "zod";
|
|
10664
10935
|
|
|
10665
10936
|
// src/tools/jobs.ts
|
|
10666
|
-
import { z as
|
|
10667
|
-
var JobId =
|
|
10668
|
-
var ReadInput =
|
|
10669
|
-
var IdInput =
|
|
10937
|
+
import { z as z16 } from "zod";
|
|
10938
|
+
var JobId = z16.string().regex(/^job-[a-f0-9-]+$/);
|
|
10939
|
+
var ReadInput = z16.object({ id: JobId, cursor: z16.coerce.number().int().min(0).optional() });
|
|
10940
|
+
var IdInput = z16.object({ id: JobId });
|
|
10670
10941
|
function createJobTools(registry) {
|
|
10671
10942
|
const tools = [
|
|
10672
10943
|
{
|
|
10673
10944
|
name: "JobList",
|
|
10674
10945
|
description: "List background jobs owned by this agent",
|
|
10675
|
-
inputSchema:
|
|
10946
|
+
inputSchema: z16.object({}),
|
|
10676
10947
|
paths: () => [],
|
|
10677
10948
|
execute: async (_input, _signal, context) => registry.list(owner(context)),
|
|
10678
10949
|
presentResult: (output) => jobListPresentation(output)
|
|
@@ -10747,14 +11018,14 @@ var ELLIPSIS = "\u2026";
|
|
|
10747
11018
|
var TERMINATION_GRACE_MS = 250;
|
|
10748
11019
|
var TERMINATION_FAILURE_MS = 5e3;
|
|
10749
11020
|
var STREAM_CLOSE_GRACE_MS = 500;
|
|
10750
|
-
var ShellInput =
|
|
10751
|
-
command:
|
|
10752
|
-
args:
|
|
10753
|
-
cwd:
|
|
10754
|
-
timeoutMs:
|
|
11021
|
+
var ShellInput = z17.object({
|
|
11022
|
+
command: z17.string().min(1),
|
|
11023
|
+
args: z17.array(z17.string()),
|
|
11024
|
+
cwd: z17.string().min(1).nullable().optional(),
|
|
11025
|
+
timeoutMs: z17.coerce.number().int().positive().max(864e5).nullable().optional(),
|
|
10755
11026
|
// Accepts booleans and their string forms (weak-typed models emit "true");
|
|
10756
11027
|
// kept transform-free so the schema converts to JSON Schema for providers.
|
|
10757
|
-
background:
|
|
11028
|
+
background: z17.union([z17.boolean(), z17.string().refine((value) => value === "true" || value === "false")]).optional()
|
|
10758
11029
|
});
|
|
10759
11030
|
function normalizeShellCommand(input) {
|
|
10760
11031
|
const { command, args } = input;
|
|
@@ -11923,7 +12194,7 @@ var ModelRegistry = class {
|
|
|
11923
12194
|
|
|
11924
12195
|
// src/mcp/client.ts
|
|
11925
12196
|
import { createHash as createHash7 } from "crypto";
|
|
11926
|
-
import { z as
|
|
12197
|
+
import { z as z18 } from "zod";
|
|
11927
12198
|
var McpManager = class {
|
|
11928
12199
|
#workspace;
|
|
11929
12200
|
#clientFactory;
|
|
@@ -12059,7 +12330,7 @@ async function listAllTools(client) {
|
|
|
12059
12330
|
function createMcpToolDefinition(serverName, timeoutMs, client, remote) {
|
|
12060
12331
|
if (remote.name.length === 0) throw new Error("MCP tool name must not be empty");
|
|
12061
12332
|
if (!isRecord3(remote.inputSchema)) throw new Error(`MCP tool "${remote.name}" has no JSON object input schema`);
|
|
12062
|
-
const inputSchema =
|
|
12333
|
+
const inputSchema = z18.fromJSONSchema(
|
|
12063
12334
|
remote.inputSchema
|
|
12064
12335
|
);
|
|
12065
12336
|
return {
|
|
@@ -12469,7 +12740,7 @@ function escapeHtml(text) {
|
|
|
12469
12740
|
}
|
|
12470
12741
|
|
|
12471
12742
|
// src/auth/store.ts
|
|
12472
|
-
import { dirname as
|
|
12743
|
+
import { dirname as dirname14 } from "path";
|
|
12473
12744
|
async function retainOnlyCredentials(store, keepCredentialId) {
|
|
12474
12745
|
const tokens = await store.load();
|
|
12475
12746
|
const retained = Object.fromEntries(Object.entries(tokens).filter(([id]) => id === keepCredentialId));
|
|
@@ -12480,7 +12751,7 @@ function createFileTokenStore(filePath) {
|
|
|
12480
12751
|
const store = {
|
|
12481
12752
|
tokens: {},
|
|
12482
12753
|
async load() {
|
|
12483
|
-
const key = await loadOrCreateConfigKey(
|
|
12754
|
+
const key = await loadOrCreateConfigKey(dirname14(filePath));
|
|
12484
12755
|
const result = await readRecoverableFile(filePath, (raw) => parseTokens(decryptDocument(raw, key)));
|
|
12485
12756
|
const tokens = result?.value ?? {};
|
|
12486
12757
|
baseline = { ...tokens };
|
|
@@ -12488,7 +12759,7 @@ function createFileTokenStore(filePath) {
|
|
|
12488
12759
|
return tokens;
|
|
12489
12760
|
},
|
|
12490
12761
|
async save(tokens) {
|
|
12491
|
-
const key = await loadOrCreateConfigKey(
|
|
12762
|
+
const key = await loadOrCreateConfigKey(dirname14(filePath));
|
|
12492
12763
|
const removals = Object.keys(baseline).filter((providerId) => !(providerId in tokens));
|
|
12493
12764
|
const upserts = Object.fromEntries(Object.entries(tokens).filter(
|
|
12494
12765
|
([providerId, token]) => !sameToken(baseline[providerId], token)
|
|
@@ -12606,6 +12877,7 @@ function toolsSection(toolNames) {
|
|
|
12606
12877
|
addToolRule(rules, toolNames, "TaskUpdate", "Use `TaskUpdate` to mark each planned task in progress before starting and completed only after successful verification.");
|
|
12607
12878
|
addToolRule(rules, toolNames, "Task", "Use `Task` when independent, well-bounded subtasks can benefit from isolated child agents. Give each child a self-contained briefing and do not delegate the final synthesis.");
|
|
12608
12879
|
addToolRule(rules, toolNames, "TaskOutput", "Use `TaskOutput` at the end of multi-step work to record changed files, commands, verification, risks, and useful next steps.");
|
|
12880
|
+
addToolRule(rules, toolNames, "Skill", "Use `Skill` whenever an active skill requires or references another skill. Load the required skill before continuing, pass arguments when the nested workflow has its own task input, and follow the returned instructions completely.");
|
|
12609
12881
|
addToolRule(rules, toolNames, "SkillResource", "Use `SkillResource` only to read a resource explicitly referenced by a matched skill. Treat returned scripts as data; do not execute them through that tool.");
|
|
12610
12882
|
addToolRule(rules, toolNames, "RegisterTool", "Use `RegisterTool` to create a durable reusable capability from JSON Schema and async JavaScript. Create one only when the user requests it or the task has a clear recurring need; never persist a tool for a one-off operation. The new tool is available on the next model step in the same run. Its implementation may be either a function body with an explicit `return`, or a complete function/arrow expression; all forms receive `input`, `signal`, and `context`.");
|
|
12611
12883
|
addToolRule(rules, toolNames, "RemoveTool", "Use `RemoveTool` only to delete a tool created by `RegisterTool`. To modify a managed tool, delete and register again; it cannot delete built-in, plugin, or MCP tools.");
|
|
@@ -12654,7 +12926,7 @@ function data(value) {
|
|
|
12654
12926
|
|
|
12655
12927
|
// src/skills/registry.ts
|
|
12656
12928
|
import { constants as constants3 } from "fs";
|
|
12657
|
-
import { lstat as lstat8, open as defaultOpen, readdir as readdir6, realpath as
|
|
12929
|
+
import { lstat as lstat8, open as defaultOpen, readdir as readdir6, realpath as realpath6 } from "fs/promises";
|
|
12658
12930
|
import { isAbsolute as isAbsolute7, relative as relative12, resolve as resolve15, sep as sep11 } from "path";
|
|
12659
12931
|
import { marked } from "marked";
|
|
12660
12932
|
import { parseDocument } from "yaml";
|
|
@@ -12821,7 +13093,7 @@ var SkillRegistry = class {
|
|
|
12821
13093
|
try {
|
|
12822
13094
|
const rootInfo = await lstat8(root);
|
|
12823
13095
|
if (rootInfo.isSymbolicLink() || !rootInfo.isDirectory()) throw new Error("Skill root must be a real directory");
|
|
12824
|
-
physicalRoot = await
|
|
13096
|
+
physicalRoot = await realpath6(root);
|
|
12825
13097
|
entries = await readdir6(root, { withFileTypes: true });
|
|
12826
13098
|
} catch (error) {
|
|
12827
13099
|
if (isMissing2(error)) continue;
|
|
@@ -12834,7 +13106,7 @@ var SkillRegistry = class {
|
|
|
12834
13106
|
try {
|
|
12835
13107
|
if (entry2.isSymbolicLink()) throw new Error("Symlinked skill directories are not allowed");
|
|
12836
13108
|
if (!entry2.isDirectory()) continue;
|
|
12837
|
-
const physicalSkillRoot = await
|
|
13109
|
+
const physicalSkillRoot = await realpath6(skillRoot);
|
|
12838
13110
|
if (!isWithin3(physicalRoot, physicalSkillRoot)) throw new Error("Skill directory escapes its registry root");
|
|
12839
13111
|
const skillFile = resolve15(skillRoot, "SKILL.md");
|
|
12840
13112
|
const parsed = await readFrontmatterFile(
|
|
@@ -12976,7 +13248,7 @@ async function openVerifiedFile(path, root, label, opener, expected) {
|
|
|
12976
13248
|
const initial = await lstat8(path, { bigint: true });
|
|
12977
13249
|
if (initial.isSymbolicLink()) throw new Error(`${label} symlinks are not allowed`);
|
|
12978
13250
|
assertRegular(initial, label);
|
|
12979
|
-
const canonical3 = await
|
|
13251
|
+
const canonical3 = await realpath6(path);
|
|
12980
13252
|
if (!isWithin3(root, canonical3)) throw new Error(`${label} escapes the skill root`);
|
|
12981
13253
|
const noFollow = typeof constants3.O_NOFOLLOW === "number" ? constants3.O_NOFOLLOW : 0;
|
|
12982
13254
|
const handle = await opener(canonical3, constants3.O_RDONLY | noFollow);
|
|
@@ -13085,11 +13357,97 @@ function score(metadata, query) {
|
|
|
13085
13357
|
}
|
|
13086
13358
|
|
|
13087
13359
|
// src/skills/tool.ts
|
|
13088
|
-
import { z as
|
|
13089
|
-
|
|
13090
|
-
|
|
13091
|
-
|
|
13360
|
+
import { z as z19 } from "zod";
|
|
13361
|
+
|
|
13362
|
+
// src/skills/arguments.ts
|
|
13363
|
+
function expandSkillArguments(body, argumentsText) {
|
|
13364
|
+
const values = splitSkillArguments(argumentsText);
|
|
13365
|
+
const hasPlaceholder = /\$ARGUMENTS(?:\[\d+\])?|\$\d+/.test(body);
|
|
13366
|
+
let expanded = body.replace(/\$ARGUMENTS\[(\d+)\]/g, (_match, index) => values[Number(index)] ?? "");
|
|
13367
|
+
expanded = expanded.replace(/\$(\d+)/g, (_match, index) => values[Number(index)] ?? "");
|
|
13368
|
+
expanded = expanded.replace(/\$ARGUMENTS/g, argumentsText);
|
|
13369
|
+
if (!hasPlaceholder && argumentsText.trim() !== "") {
|
|
13370
|
+
expanded = `${expanded.trimEnd()}
|
|
13371
|
+
|
|
13372
|
+
ARGUMENTS: ${argumentsText}`;
|
|
13373
|
+
}
|
|
13374
|
+
return expanded;
|
|
13375
|
+
}
|
|
13376
|
+
function splitSkillArguments(input) {
|
|
13377
|
+
const result = [];
|
|
13378
|
+
let current = "";
|
|
13379
|
+
let quote;
|
|
13380
|
+
let started = false;
|
|
13381
|
+
for (let index = 0; index < input.length; index += 1) {
|
|
13382
|
+
const character = input[index] ?? "";
|
|
13383
|
+
const next = input[index + 1];
|
|
13384
|
+
if (character === "\\" && quote !== "'" && next !== void 0 && (/\s/u.test(next) || next === "\\" || next === '"' || quote === void 0 && next === "'")) {
|
|
13385
|
+
current += next;
|
|
13386
|
+
index += 1;
|
|
13387
|
+
started = true;
|
|
13388
|
+
continue;
|
|
13389
|
+
}
|
|
13390
|
+
if (quote !== void 0) {
|
|
13391
|
+
if (character === quote) quote = void 0;
|
|
13392
|
+
else current += character;
|
|
13393
|
+
started = true;
|
|
13394
|
+
continue;
|
|
13395
|
+
}
|
|
13396
|
+
if (character === "'" || character === '"') {
|
|
13397
|
+
quote = character;
|
|
13398
|
+
started = true;
|
|
13399
|
+
continue;
|
|
13400
|
+
}
|
|
13401
|
+
if (/\s/u.test(character)) {
|
|
13402
|
+
if (started) {
|
|
13403
|
+
result.push(current);
|
|
13404
|
+
current = "";
|
|
13405
|
+
started = false;
|
|
13406
|
+
}
|
|
13407
|
+
continue;
|
|
13408
|
+
}
|
|
13409
|
+
current += character;
|
|
13410
|
+
started = true;
|
|
13411
|
+
}
|
|
13412
|
+
if (started) result.push(current);
|
|
13413
|
+
return result;
|
|
13414
|
+
}
|
|
13415
|
+
|
|
13416
|
+
// src/skills/tool.ts
|
|
13417
|
+
var SkillInput = z19.object({
|
|
13418
|
+
skill: z19.string().min(1),
|
|
13419
|
+
arguments: z19.string().optional()
|
|
13420
|
+
}).strict();
|
|
13421
|
+
var SkillResourceInput = z19.object({
|
|
13422
|
+
skill: z19.string().min(1),
|
|
13423
|
+
reference: z19.string().min(1)
|
|
13092
13424
|
}).strict();
|
|
13425
|
+
function createSkillTool(registry) {
|
|
13426
|
+
return {
|
|
13427
|
+
name: "Skill",
|
|
13428
|
+
description: "Load another discovered skill by name so composable workflows can follow its complete instructions; optional arguments use Claude-compatible $ARGUMENTS substitution",
|
|
13429
|
+
inputSchema: SkillInput,
|
|
13430
|
+
readOnly: true,
|
|
13431
|
+
paths: () => [],
|
|
13432
|
+
summarize: ({ skill }) => skill,
|
|
13433
|
+
renderForModel: (output) => {
|
|
13434
|
+
const value = output;
|
|
13435
|
+
return `Matched skill: ${value.skill}
|
|
13436
|
+
${value.content}`;
|
|
13437
|
+
},
|
|
13438
|
+
execute: async (input, signal) => {
|
|
13439
|
+
signal.throwIfAborted();
|
|
13440
|
+
const discovered = await registry.discover();
|
|
13441
|
+
const requested = input.skill.trim();
|
|
13442
|
+
const alias = requested.includes(":") ? requested.slice(requested.lastIndexOf(":") + 1) : requested;
|
|
13443
|
+
const skill = discovered.find((candidate) => candidate.name === requested) ?? discovered.find((candidate) => candidate.name === alias);
|
|
13444
|
+
if (skill === void 0) throw new Error(`Unknown skill: ${input.skill}`);
|
|
13445
|
+
const content = expandSkillArguments(await registry.loadBody(skill), input.arguments ?? "");
|
|
13446
|
+
signal.throwIfAborted();
|
|
13447
|
+
return { skill: skill.name, content };
|
|
13448
|
+
}
|
|
13449
|
+
};
|
|
13450
|
+
}
|
|
13093
13451
|
function createSkillResourceTool(registry) {
|
|
13094
13452
|
return {
|
|
13095
13453
|
name: "SkillResource",
|
|
@@ -13115,97 +13473,97 @@ function createSkillResourceTool(registry) {
|
|
|
13115
13473
|
|
|
13116
13474
|
// src/session/store.ts
|
|
13117
13475
|
import { constants as constants4 } from "fs";
|
|
13118
|
-
import { lstat as lstat9, mkdir as mkdir14, open as open8, readFile as readFile14, readdir as readdir7, realpath as
|
|
13119
|
-
import { basename as basename3, dirname as
|
|
13476
|
+
import { lstat as lstat9, mkdir as mkdir14, open as open8, readFile as readFile14, readdir as readdir7, realpath as realpath7, rename as rename6, rm as rm6, stat as stat6 } from "fs/promises";
|
|
13477
|
+
import { basename as basename3, dirname as dirname15, join as join17, relative as relative13, resolve as resolve16, sep as sep12 } from "path";
|
|
13120
13478
|
import { randomUUID as randomUUID9 } from "crypto";
|
|
13121
|
-
import { z as
|
|
13479
|
+
import { z as z20 } from "zod";
|
|
13122
13480
|
var SESSION_VERSION = 3;
|
|
13123
13481
|
var DEFAULT_MAX_SESSION_BYTES = 5 * 1024 * 1024;
|
|
13124
|
-
var SessionIdSchema =
|
|
13125
|
-
var IsoDateSchema =
|
|
13126
|
-
var ToolCallSchema =
|
|
13127
|
-
id:
|
|
13128
|
-
name:
|
|
13129
|
-
input:
|
|
13482
|
+
var SessionIdSchema = z20.string().regex(/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/, "Invalid session id");
|
|
13483
|
+
var IsoDateSchema = z20.string().datetime({ offset: true });
|
|
13484
|
+
var ToolCallSchema = z20.object({
|
|
13485
|
+
id: z20.string().min(1).max(256),
|
|
13486
|
+
name: z20.string().min(1).max(256),
|
|
13487
|
+
input: z20.unknown()
|
|
13130
13488
|
}).strict();
|
|
13131
|
-
var TextContentBlockSchema =
|
|
13132
|
-
type:
|
|
13133
|
-
text:
|
|
13489
|
+
var TextContentBlockSchema = z20.object({
|
|
13490
|
+
type: z20.literal("text"),
|
|
13491
|
+
text: z20.string().max(DEFAULT_MAX_SESSION_BYTES)
|
|
13134
13492
|
}).strict();
|
|
13135
|
-
var ImageContentBlockSchema =
|
|
13136
|
-
type:
|
|
13137
|
-
source:
|
|
13138
|
-
mediaType:
|
|
13139
|
-
sha256:
|
|
13140
|
-
bytes:
|
|
13141
|
-
name:
|
|
13493
|
+
var ImageContentBlockSchema = z20.object({
|
|
13494
|
+
type: z20.literal("image"),
|
|
13495
|
+
source: z20.object({ type: z20.literal("file"), path: z20.string().min(1).max(32768) }).strict(),
|
|
13496
|
+
mediaType: z20.enum(["image/png", "image/jpeg", "image/webp"]),
|
|
13497
|
+
sha256: z20.string().regex(/^[a-f0-9]{64}$/),
|
|
13498
|
+
bytes: z20.number().int().positive().max(20 * 1024 * 1024),
|
|
13499
|
+
name: z20.string().min(1).max(255).optional()
|
|
13142
13500
|
}).strict();
|
|
13143
|
-
var UserContentSchema =
|
|
13144
|
-
|
|
13145
|
-
|
|
13501
|
+
var UserContentSchema = z20.union([
|
|
13502
|
+
z20.string().max(DEFAULT_MAX_SESSION_BYTES),
|
|
13503
|
+
z20.array(z20.discriminatedUnion("type", [TextContentBlockSchema, ImageContentBlockSchema])).min(1).max(100)
|
|
13146
13504
|
]);
|
|
13147
13505
|
var MessageMetadataShape = {
|
|
13148
|
-
toolCallId:
|
|
13149
|
-
toolCalls:
|
|
13506
|
+
toolCallId: z20.string().min(1).max(256).optional(),
|
|
13507
|
+
toolCalls: z20.array(ToolCallSchema).max(1e3).optional()
|
|
13150
13508
|
};
|
|
13151
|
-
var MessageSchema =
|
|
13152
|
-
|
|
13153
|
-
|
|
13154
|
-
|
|
13509
|
+
var MessageSchema = z20.discriminatedUnion("role", [
|
|
13510
|
+
z20.object({ role: z20.literal("user"), content: UserContentSchema, ...MessageMetadataShape }).strict(),
|
|
13511
|
+
z20.object({ role: z20.literal("assistant"), content: z20.string().max(DEFAULT_MAX_SESSION_BYTES), ...MessageMetadataShape }).strict(),
|
|
13512
|
+
z20.object({ role: z20.literal("tool"), content: z20.string().max(DEFAULT_MAX_SESSION_BYTES), ...MessageMetadataShape }).strict()
|
|
13155
13513
|
]);
|
|
13156
|
-
var LegacySummarySchema =
|
|
13157
|
-
var CompactBoundarySchema =
|
|
13158
|
-
summary:
|
|
13514
|
+
var LegacySummarySchema = z20.object({ role: z20.literal("system"), content: z20.string().max(DEFAULT_MAX_SESSION_BYTES) }).strict();
|
|
13515
|
+
var CompactBoundarySchema = z20.object({
|
|
13516
|
+
summary: z20.string().min(1).max(DEFAULT_MAX_SESSION_BYTES),
|
|
13159
13517
|
compactedAt: IsoDateSchema
|
|
13160
13518
|
}).strict();
|
|
13161
|
-
var StateSchema =
|
|
13162
|
-
var MemoryLifecycleSchema =
|
|
13163
|
-
status:
|
|
13164
|
-
taskId:
|
|
13165
|
-
messageStart:
|
|
13519
|
+
var StateSchema = z20.enum(["pending", "running", "completed", "failed", "blocked", "cancelled"]);
|
|
13520
|
+
var MemoryLifecycleSchema = z20.object({
|
|
13521
|
+
status: z20.enum(["active", "completed", "abandoned"]),
|
|
13522
|
+
taskId: z20.string().regex(/^memory-[A-Za-z0-9._-]{1,120}$/).optional(),
|
|
13523
|
+
messageStart: z20.number().int().min(0).max(5e4).optional(),
|
|
13166
13524
|
finalizedAt: IsoDateSchema.optional(),
|
|
13167
|
-
transcriptHash:
|
|
13525
|
+
transcriptHash: z20.string().regex(/^[a-f0-9]{64}$/).optional()
|
|
13168
13526
|
}).strict();
|
|
13169
|
-
var SessionBaseSchema =
|
|
13527
|
+
var SessionBaseSchema = z20.object({
|
|
13170
13528
|
sessionId: SessionIdSchema,
|
|
13171
13529
|
createdAt: IsoDateSchema,
|
|
13172
13530
|
updatedAt: IsoDateSchema,
|
|
13173
|
-
workspace:
|
|
13174
|
-
tasks:
|
|
13531
|
+
workspace: z20.object({ path: z20.string().min(1).max(32768) }).strict(),
|
|
13532
|
+
tasks: z20.object({
|
|
13175
13533
|
plan: TaskPlanSchema.optional(),
|
|
13176
13534
|
graph: TaskGraphSchema.optional(),
|
|
13177
|
-
states:
|
|
13178
|
-
results:
|
|
13535
|
+
states: z20.record(z20.string(), StateSchema),
|
|
13536
|
+
results: z20.record(z20.string(), SubagentResultSchema)
|
|
13179
13537
|
}).strict(),
|
|
13180
|
-
models:
|
|
13538
|
+
models: z20.object({ main: z20.string().min(1).max(1024), subagent: z20.string().min(1).max(1024) }).strict(),
|
|
13181
13539
|
permissionMode: PermissionModeSchema,
|
|
13182
13540
|
memory: MemoryLifecycleSchema.optional()
|
|
13183
13541
|
}).strict();
|
|
13184
13542
|
var SessionDocumentV1Schema = SessionBaseSchema.extend({
|
|
13185
|
-
version:
|
|
13186
|
-
conversation:
|
|
13543
|
+
version: z20.literal(1),
|
|
13544
|
+
conversation: z20.object({
|
|
13187
13545
|
summary: LegacySummarySchema.optional(),
|
|
13188
|
-
messages:
|
|
13546
|
+
messages: z20.array(MessageSchema).max(5e4)
|
|
13189
13547
|
}).strict()
|
|
13190
13548
|
}).strict();
|
|
13191
|
-
var ConversationSchema =
|
|
13549
|
+
var ConversationSchema = z20.object({
|
|
13192
13550
|
compact: CompactBoundarySchema.optional(),
|
|
13193
|
-
messages:
|
|
13551
|
+
messages: z20.array(MessageSchema).max(5e4)
|
|
13194
13552
|
}).strict();
|
|
13195
13553
|
var SessionDocumentV2Schema = SessionBaseSchema.extend({
|
|
13196
|
-
version:
|
|
13554
|
+
version: z20.literal(2),
|
|
13197
13555
|
conversation: ConversationSchema
|
|
13198
13556
|
}).strict();
|
|
13199
|
-
var TranscriptStateSchema =
|
|
13200
|
-
var TimelineSchema =
|
|
13201
|
-
version:
|
|
13557
|
+
var TranscriptStateSchema = z20.custom(isTranscriptState, "Invalid transcript state");
|
|
13558
|
+
var TimelineSchema = z20.object({
|
|
13559
|
+
version: z20.literal(1),
|
|
13202
13560
|
state: TranscriptStateSchema
|
|
13203
13561
|
}).strict();
|
|
13204
13562
|
var SessionDocumentSchema = SessionBaseSchema.extend({
|
|
13205
|
-
version:
|
|
13206
|
-
conversation:
|
|
13563
|
+
version: z20.literal(SESSION_VERSION),
|
|
13564
|
+
conversation: z20.object({
|
|
13207
13565
|
compact: CompactBoundarySchema.optional(),
|
|
13208
|
-
messages:
|
|
13566
|
+
messages: z20.array(MessageSchema).max(5e4)
|
|
13209
13567
|
}).strict(),
|
|
13210
13568
|
timeline: TimelineSchema
|
|
13211
13569
|
}).strict();
|
|
@@ -13381,14 +13739,14 @@ var SessionStore = class {
|
|
|
13381
13739
|
}
|
|
13382
13740
|
}
|
|
13383
13741
|
async #prepareDirectory() {
|
|
13384
|
-
await assertNoSymlink3(this.#workspace,
|
|
13742
|
+
await assertNoSymlink3(this.#workspace, dirname15(this.#sessions));
|
|
13385
13743
|
await mkdir14(this.#sessions, { recursive: true, mode: 448 });
|
|
13386
13744
|
await this.#assertSafeExistingDirectory();
|
|
13387
13745
|
}
|
|
13388
13746
|
async #assertSafeExistingDirectory() {
|
|
13389
13747
|
await assertNoSymlink3(this.#workspace, this.#sessions);
|
|
13390
|
-
const canonicalRoot = await
|
|
13391
|
-
const canonicalSessions = await
|
|
13748
|
+
const canonicalRoot = await realpath7(this.#workspace);
|
|
13749
|
+
const canonicalSessions = await realpath7(this.#sessions);
|
|
13392
13750
|
if (!isWithin4(canonicalRoot, canonicalSessions)) throw new Error("Session directory escapes the workspace");
|
|
13393
13751
|
}
|
|
13394
13752
|
async #quarantine(path) {
|
|
@@ -13545,7 +13903,7 @@ async function assertNoSymlink3(root, target) {
|
|
|
13545
13903
|
const chain = [];
|
|
13546
13904
|
while (cursor !== stop) {
|
|
13547
13905
|
chain.push(cursor);
|
|
13548
|
-
cursor =
|
|
13906
|
+
cursor = dirname15(cursor);
|
|
13549
13907
|
}
|
|
13550
13908
|
for (const path of chain.reverse()) {
|
|
13551
13909
|
try {
|
|
@@ -13561,7 +13919,7 @@ function isWithin4(root, path) {
|
|
|
13561
13919
|
}
|
|
13562
13920
|
async function canonical2(path) {
|
|
13563
13921
|
try {
|
|
13564
|
-
return await
|
|
13922
|
+
return await realpath7(resolve16(path));
|
|
13565
13923
|
} catch {
|
|
13566
13924
|
return resolve16(path);
|
|
13567
13925
|
}
|
|
@@ -13590,45 +13948,45 @@ function sanitize2(input, seen = /* @__PURE__ */ new WeakSet()) {
|
|
|
13590
13948
|
// src/sleep/organizer.ts
|
|
13591
13949
|
import { constants as constants5 } from "fs";
|
|
13592
13950
|
import { randomUUID as randomUUID10 } from "crypto";
|
|
13593
|
-
import { lstat as lstat10, mkdir as mkdir15, open as open9, readdir as readdir8, realpath as
|
|
13951
|
+
import { lstat as lstat10, mkdir as mkdir15, open as open9, readdir as readdir8, realpath as realpath8, rename as rename7, rm as rm7 } from "fs/promises";
|
|
13594
13952
|
import { isAbsolute as isAbsolute8, join as join18, relative as relative14, resolve as resolve17, sep as sep13 } from "path";
|
|
13595
|
-
import { z as
|
|
13596
|
-
var DateKeySchema =
|
|
13597
|
-
var ReviewSchema =
|
|
13598
|
-
title:
|
|
13599
|
-
taskSummary:
|
|
13600
|
-
executionReflection:
|
|
13601
|
-
decisionsAndLearnings:
|
|
13602
|
-
openQuestionsAndRisks:
|
|
13603
|
-
tomorrowPlan:
|
|
13604
|
-
toolUsage:
|
|
13605
|
-
totalCalls:
|
|
13606
|
-
shell:
|
|
13607
|
-
fileRead:
|
|
13608
|
-
fileWrite:
|
|
13609
|
-
search:
|
|
13610
|
-
lsp:
|
|
13611
|
-
subagent:
|
|
13612
|
-
other:
|
|
13953
|
+
import { z as z21 } from "zod";
|
|
13954
|
+
var DateKeySchema = z21.string().regex(/^\d{4}-\d{2}-\d{2}$/);
|
|
13955
|
+
var ReviewSchema = z21.object({
|
|
13956
|
+
title: z21.string().min(1).max(120),
|
|
13957
|
+
taskSummary: z21.array(z21.string().min(1)).min(1).max(20),
|
|
13958
|
+
executionReflection: z21.array(z21.string().min(1)).min(1).max(20),
|
|
13959
|
+
decisionsAndLearnings: z21.array(z21.string().min(1)).max(20),
|
|
13960
|
+
openQuestionsAndRisks: z21.array(z21.string().min(1)).max(20),
|
|
13961
|
+
tomorrowPlan: z21.array(z21.string().min(1)).min(1).max(20),
|
|
13962
|
+
toolUsage: z21.object({
|
|
13963
|
+
totalCalls: z21.number().int().min(0),
|
|
13964
|
+
shell: z21.number().int().min(0),
|
|
13965
|
+
fileRead: z21.number().int().min(0),
|
|
13966
|
+
fileWrite: z21.number().int().min(0),
|
|
13967
|
+
search: z21.number().int().min(0),
|
|
13968
|
+
lsp: z21.number().int().min(0),
|
|
13969
|
+
subagent: z21.number().int().min(0),
|
|
13970
|
+
other: z21.number().int().min(0)
|
|
13613
13971
|
}).strict(),
|
|
13614
|
-
tokenEstimate:
|
|
13615
|
-
estimatedInput:
|
|
13616
|
-
estimatedOutput:
|
|
13617
|
-
notes:
|
|
13972
|
+
tokenEstimate: z21.object({
|
|
13973
|
+
estimatedInput: z21.number().int().min(0),
|
|
13974
|
+
estimatedOutput: z21.number().int().min(0),
|
|
13975
|
+
notes: z21.string().max(200)
|
|
13618
13976
|
}).strict(),
|
|
13619
|
-
humanIntervention:
|
|
13620
|
-
approvalRequests:
|
|
13621
|
-
questionsAsked:
|
|
13622
|
-
summary:
|
|
13977
|
+
humanIntervention: z21.object({
|
|
13978
|
+
approvalRequests: z21.number().int().min(0),
|
|
13979
|
+
questionsAsked: z21.number().int().min(0),
|
|
13980
|
+
summary: z21.string().max(300)
|
|
13623
13981
|
}).strict(),
|
|
13624
|
-
qualityIndicators:
|
|
13625
|
-
hallucinationAlerts:
|
|
13626
|
-
failuresAndRetries:
|
|
13627
|
-
codeChangeSummary:
|
|
13628
|
-
overallAssessment:
|
|
13982
|
+
qualityIndicators: z21.object({
|
|
13983
|
+
hallucinationAlerts: z21.array(z21.string().min(1)).max(10),
|
|
13984
|
+
failuresAndRetries: z21.array(z21.string().min(1)).max(10),
|
|
13985
|
+
codeChangeSummary: z21.string().max(500),
|
|
13986
|
+
overallAssessment: z21.string().max(200)
|
|
13629
13987
|
}).strict(),
|
|
13630
|
-
knowledgeDeposits:
|
|
13631
|
-
worthRemembering:
|
|
13988
|
+
knowledgeDeposits: z21.object({
|
|
13989
|
+
worthRemembering: z21.array(z21.string().min(1)).max(10)
|
|
13632
13990
|
}).strict()
|
|
13633
13991
|
}).strict();
|
|
13634
13992
|
function localDateKey(date) {
|
|
@@ -13737,8 +14095,8 @@ Previous output was invalid. Repair it and return strict JSON only.`;
|
|
|
13737
14095
|
await mkdir15(flavorDirectory, { recursive: true, mode: 448 });
|
|
13738
14096
|
await assertNotSymlink(this.#sleepDirectory);
|
|
13739
14097
|
await mkdir15(this.#sleepDirectory, { recursive: true, mode: 448 });
|
|
13740
|
-
const root = await
|
|
13741
|
-
const target = await
|
|
14098
|
+
const root = await realpath8(this.#workspace);
|
|
14099
|
+
const target = await realpath8(this.#sleepDirectory);
|
|
13742
14100
|
if (!isWithin5(root, target)) throw new Error("Sleep directory escapes the workspace");
|
|
13743
14101
|
}
|
|
13744
14102
|
async #hasReport(date) {
|
|
@@ -14120,10 +14478,10 @@ function computeSessionStats(documents) {
|
|
|
14120
14478
|
|
|
14121
14479
|
// src/tools/files.ts
|
|
14122
14480
|
import { constants as constants6 } from "fs";
|
|
14123
|
-
import { mkdir as mkdir16, open as open10, readFile as readFile15, realpath as
|
|
14124
|
-
import { dirname as
|
|
14481
|
+
import { mkdir as mkdir16, open as open10, readFile as readFile15, realpath as realpath9, rename as rename8, rm as rm8, stat as stat7 } from "fs/promises";
|
|
14482
|
+
import { dirname as dirname16, isAbsolute as isAbsolute9, relative as relative15, resolve as resolve18, sep as sep14 } from "path";
|
|
14125
14483
|
import { randomUUID as randomUUID11 } from "crypto";
|
|
14126
|
-
import { z as
|
|
14484
|
+
import { z as z22 } from "zod";
|
|
14127
14485
|
|
|
14128
14486
|
// src/tools/file-diff.ts
|
|
14129
14487
|
var MAX_DIFF_PREVIEW_LINES = 120;
|
|
@@ -14229,18 +14587,18 @@ function truncateLines(lines) {
|
|
|
14229
14587
|
|
|
14230
14588
|
// src/tools/files.ts
|
|
14231
14589
|
var MAX_READ_BYTES = 1048576;
|
|
14232
|
-
var ReadInput2 =
|
|
14233
|
-
path:
|
|
14234
|
-
maxBytes:
|
|
14235
|
-
startLine:
|
|
14236
|
-
endLine:
|
|
14590
|
+
var ReadInput2 = z22.object({
|
|
14591
|
+
path: z22.string().min(1),
|
|
14592
|
+
maxBytes: z22.coerce.number().int().positive().max(MAX_READ_BYTES).nullable().optional(),
|
|
14593
|
+
startLine: z22.coerce.number().int().positive().nullable().optional(),
|
|
14594
|
+
endLine: z22.coerce.number().int().positive().nullable().optional(),
|
|
14237
14595
|
// Accepts booleans and their string forms (weak-typed models emit "true");
|
|
14238
14596
|
// kept transform-free so the schema converts to JSON Schema for providers.
|
|
14239
|
-
force:
|
|
14597
|
+
force: z22.union([z22.boolean(), z22.string().refine((value) => value === "true" || value === "false")]).nullable().optional()
|
|
14240
14598
|
});
|
|
14241
|
-
var WriteInput =
|
|
14242
|
-
var EditInput =
|
|
14243
|
-
var ApplyPatchInput =
|
|
14599
|
+
var WriteInput = z22.object({ path: z22.string().min(1), content: z22.string() });
|
|
14600
|
+
var EditInput = z22.object({ path: z22.string().min(1), oldText: z22.string().min(1), newText: z22.string() });
|
|
14601
|
+
var ApplyPatchInput = z22.object({ patch: z22.string().min(1) });
|
|
14244
14602
|
var FileObservationStore = class {
|
|
14245
14603
|
#versions = /* @__PURE__ */ new Map();
|
|
14246
14604
|
get(path) {
|
|
@@ -14448,22 +14806,22 @@ function createPathGuard(workspace) {
|
|
|
14448
14806
|
lexical,
|
|
14449
14807
|
existing: async (input) => {
|
|
14450
14808
|
const candidate = lexical(input);
|
|
14451
|
-
const physical = await
|
|
14452
|
-
if (!within2(await
|
|
14809
|
+
const physical = await realpath9(candidate);
|
|
14810
|
+
if (!within2(await realpath9(root), physical)) throw new Error("Path escapes the workspace through a symlink");
|
|
14453
14811
|
return physical;
|
|
14454
14812
|
},
|
|
14455
14813
|
destination: async (input) => {
|
|
14456
14814
|
const candidate = lexical(input);
|
|
14457
|
-
const physicalRoot = await
|
|
14815
|
+
const physicalRoot = await realpath9(root);
|
|
14458
14816
|
let ancestor = candidate;
|
|
14459
14817
|
while (true) {
|
|
14460
14818
|
try {
|
|
14461
|
-
const physical = await
|
|
14819
|
+
const physical = await realpath9(ancestor);
|
|
14462
14820
|
if (!within2(physicalRoot, physical)) throw new Error("Path escapes the workspace through a symlink");
|
|
14463
14821
|
break;
|
|
14464
14822
|
} catch (error) {
|
|
14465
14823
|
if (!isMissing3(error)) throw error;
|
|
14466
|
-
const parent =
|
|
14824
|
+
const parent = dirname16(ancestor);
|
|
14467
14825
|
if (parent === ancestor) throw error;
|
|
14468
14826
|
ancestor = parent;
|
|
14469
14827
|
}
|
|
@@ -14474,7 +14832,7 @@ function createPathGuard(workspace) {
|
|
|
14474
14832
|
}
|
|
14475
14833
|
async function atomicWrite(path, content, signal, expectedVersion) {
|
|
14476
14834
|
abortIfNeeded(signal);
|
|
14477
|
-
await mkdir16(
|
|
14835
|
+
await mkdir16(dirname16(path), { recursive: true });
|
|
14478
14836
|
const temporary = `${path}.${randomUUID11()}.tmp`;
|
|
14479
14837
|
try {
|
|
14480
14838
|
const handle = await open10(temporary, constants6.O_CREAT | constants6.O_EXCL | constants6.O_WRONLY, 384);
|
|
@@ -14836,22 +15194,22 @@ import { lookup } from "dns/promises";
|
|
|
14836
15194
|
import { isIP } from "net";
|
|
14837
15195
|
import { request as httpRequest } from "http";
|
|
14838
15196
|
import { request as httpsRequest } from "https";
|
|
14839
|
-
import { z as
|
|
14840
|
-
var WebFetchInput =
|
|
14841
|
-
url:
|
|
14842
|
-
timeoutMs:
|
|
14843
|
-
maxBytes:
|
|
15197
|
+
import { z as z23 } from "zod";
|
|
15198
|
+
var WebFetchInput = z23.object({
|
|
15199
|
+
url: z23.string().url().max(8192),
|
|
15200
|
+
timeoutMs: z23.coerce.number().int().positive().max(12e4).optional(),
|
|
15201
|
+
maxBytes: z23.coerce.number().int().positive().max(10 * 1024 * 1024).optional()
|
|
14844
15202
|
});
|
|
14845
|
-
var WebSearchInput =
|
|
14846
|
-
query:
|
|
14847
|
-
maxResults:
|
|
15203
|
+
var WebSearchInput = z23.object({
|
|
15204
|
+
query: z23.string().trim().min(1).max(1e3),
|
|
15205
|
+
maxResults: z23.coerce.number().int().min(1).max(20).optional()
|
|
14848
15206
|
});
|
|
14849
15207
|
function createWebFetchTool() {
|
|
14850
15208
|
return {
|
|
14851
15209
|
name: "WebFetch",
|
|
14852
15210
|
description: "Fetch a public HTTP(S) page with SSRF protection and return readable text",
|
|
14853
15211
|
inputSchema: WebFetchInput,
|
|
14854
|
-
outputSchema:
|
|
15212
|
+
outputSchema: z23.object({ url: z23.string(), status: z23.number(), contentType: z23.string(), content: z23.string(), truncated: z23.boolean() }),
|
|
14855
15213
|
paths: () => [],
|
|
14856
15214
|
summarize: (input) => input.url,
|
|
14857
15215
|
presentCall: (input) => ({ kind: "web", title: `Fetching ${new URL(input.url).hostname}`, url: input.url }),
|
|
@@ -14877,7 +15235,7 @@ function createWebSearchTool(provider = createDefaultWebSearchProvider()) {
|
|
|
14877
15235
|
name: "WebSearch",
|
|
14878
15236
|
description: "Search the public web and return titles, URLs, and snippets",
|
|
14879
15237
|
inputSchema: WebSearchInput,
|
|
14880
|
-
outputSchema:
|
|
15238
|
+
outputSchema: z23.object({ query: z23.string(), results: z23.array(z23.object({ title: z23.string(), url: z23.string(), snippet: z23.string() })) }),
|
|
14881
15239
|
paths: () => [],
|
|
14882
15240
|
summarize: (input) => input.query,
|
|
14883
15241
|
presentCall: (input) => ({ kind: "web", title: `Searching: ${input.query}` }),
|
|
@@ -15143,9 +15501,9 @@ function charset(contentType) {
|
|
|
15143
15501
|
import { spawn as spawn7 } from "child_process";
|
|
15144
15502
|
import { existsSync as existsSync2 } from "fs";
|
|
15145
15503
|
import { access, constants as constants7, readFile as readFile16 } from "fs/promises";
|
|
15146
|
-
import { basename as basename4, dirname as
|
|
15504
|
+
import { basename as basename4, dirname as dirname17, extname, isAbsolute as isAbsolute10, relative as relative16, resolve as resolve19, sep as sep15 } from "path";
|
|
15147
15505
|
import { fileURLToPath as fileURLToPath3, pathToFileURL as pathToFileURL2 } from "url";
|
|
15148
|
-
import { z as
|
|
15506
|
+
import { z as z24 } from "zod";
|
|
15149
15507
|
var LSP_REQUEST_TIMEOUT_MS = 15e3;
|
|
15150
15508
|
var LspConnection = class {
|
|
15151
15509
|
#process;
|
|
@@ -15360,7 +15718,7 @@ var LspBuffer = class {
|
|
|
15360
15718
|
}
|
|
15361
15719
|
};
|
|
15362
15720
|
var TYPESCRIPT_CLI = resolve19(
|
|
15363
|
-
|
|
15721
|
+
dirname17(fileURLToPath3(import.meta.resolve("typescript/package.json"))),
|
|
15364
15722
|
"lib",
|
|
15365
15723
|
"tsc.js"
|
|
15366
15724
|
);
|
|
@@ -15479,18 +15837,18 @@ var RealLspManager = class {
|
|
|
15479
15837
|
return connection;
|
|
15480
15838
|
}
|
|
15481
15839
|
};
|
|
15482
|
-
var LspFindRefsInput =
|
|
15483
|
-
file:
|
|
15484
|
-
line:
|
|
15485
|
-
character:
|
|
15840
|
+
var LspFindRefsInput = z24.object({
|
|
15841
|
+
file: z24.string().min(1),
|
|
15842
|
+
line: z24.coerce.number().int().nonnegative(),
|
|
15843
|
+
character: z24.coerce.number().int().nonnegative()
|
|
15486
15844
|
});
|
|
15487
|
-
var LspHoverInput =
|
|
15488
|
-
file:
|
|
15489
|
-
line:
|
|
15490
|
-
character:
|
|
15845
|
+
var LspHoverInput = z24.object({
|
|
15846
|
+
file: z24.string().min(1),
|
|
15847
|
+
line: z24.coerce.number().int().nonnegative(),
|
|
15848
|
+
character: z24.coerce.number().int().nonnegative()
|
|
15491
15849
|
});
|
|
15492
|
-
var LspDiagnosticsInput =
|
|
15493
|
-
file:
|
|
15850
|
+
var LspDiagnosticsInput = z24.object({
|
|
15851
|
+
file: z24.string().min(1)
|
|
15494
15852
|
});
|
|
15495
15853
|
function createLspTools(workspace, options = {}) {
|
|
15496
15854
|
const root = resolve19(workspace);
|
|
@@ -15716,7 +16074,7 @@ async function gitMarker(workspace) {
|
|
|
15716
16074
|
}
|
|
15717
16075
|
|
|
15718
16076
|
// src/git/insights.ts
|
|
15719
|
-
import { z as
|
|
16077
|
+
import { z as z25 } from "zod";
|
|
15720
16078
|
async function suggestCommitMessage(options, input, signal) {
|
|
15721
16079
|
const prompt = [
|
|
15722
16080
|
"Write a git commit message for the staged changes below.",
|
|
@@ -15755,17 +16113,17 @@ function cleanCommitMessage(raw) {
|
|
|
15755
16113
|
}
|
|
15756
16114
|
return kept.join("\n").trim().slice(0, 2e3);
|
|
15757
16115
|
}
|
|
15758
|
-
var ReviewFindingSchema =
|
|
15759
|
-
severity:
|
|
15760
|
-
file:
|
|
15761
|
-
line:
|
|
15762
|
-
issue:
|
|
15763
|
-
suggestion:
|
|
16116
|
+
var ReviewFindingSchema = z25.object({
|
|
16117
|
+
severity: z25.enum(["critical", "warning", "nit"]),
|
|
16118
|
+
file: z25.string(),
|
|
16119
|
+
line: z25.string().describe('Line number or hunk header the finding refers to, e.g. "42" or "@@ -10,4 +10,6 @@"'),
|
|
16120
|
+
issue: z25.string(),
|
|
16121
|
+
suggestion: z25.string()
|
|
15764
16122
|
}).strict();
|
|
15765
|
-
var ReviewReportSchema =
|
|
15766
|
-
summary:
|
|
15767
|
-
verdict:
|
|
15768
|
-
findings:
|
|
16123
|
+
var ReviewReportSchema = z25.object({
|
|
16124
|
+
summary: z25.string().describe("One-paragraph overall assessment of the change"),
|
|
16125
|
+
verdict: z25.enum(["ship", "ship-with-fixes", "needs-work"]),
|
|
16126
|
+
findings: z25.array(ReviewFindingSchema).max(20)
|
|
15769
16127
|
}).strict();
|
|
15770
16128
|
async function reviewDiff(options, input, signal) {
|
|
15771
16129
|
const prompt = [
|
|
@@ -15809,10 +16167,10 @@ function formatReviewReport(report) {
|
|
|
15809
16167
|
}
|
|
15810
16168
|
|
|
15811
16169
|
// src/git/tools.ts
|
|
15812
|
-
import { z as
|
|
15813
|
-
var GitHistoryInput =
|
|
15814
|
-
path:
|
|
15815
|
-
limit:
|
|
16170
|
+
import { z as z26 } from "zod";
|
|
16171
|
+
var GitHistoryInput = z26.object({
|
|
16172
|
+
path: z26.string().describe("File to inspect; omit for the whole repository history").optional(),
|
|
16173
|
+
limit: z26.number().int().min(1).max(50).describe("Maximum number of commits to return (default 20)").optional()
|
|
15816
16174
|
});
|
|
15817
16175
|
function createGitHistoryTool(workspace) {
|
|
15818
16176
|
return {
|
|
@@ -15841,18 +16199,18 @@ function createGitHistoryTool(workspace) {
|
|
|
15841
16199
|
}
|
|
15842
16200
|
|
|
15843
16201
|
// src/tools/ask-user-question.ts
|
|
15844
|
-
import { z as
|
|
15845
|
-
var QuestionOptionSchema =
|
|
15846
|
-
label:
|
|
15847
|
-
description:
|
|
16202
|
+
import { z as z27 } from "zod";
|
|
16203
|
+
var QuestionOptionSchema = z27.object({
|
|
16204
|
+
label: z27.string().trim().min(1),
|
|
16205
|
+
description: z27.string().trim().min(1)
|
|
15848
16206
|
});
|
|
15849
|
-
var QuestionSchema =
|
|
15850
|
-
question:
|
|
15851
|
-
header:
|
|
15852
|
-
options:
|
|
16207
|
+
var QuestionSchema = z27.object({
|
|
16208
|
+
question: z27.string().trim().min(1),
|
|
16209
|
+
header: z27.string().trim().min(1),
|
|
16210
|
+
options: z27.array(QuestionOptionSchema).min(1).max(4)
|
|
15853
16211
|
});
|
|
15854
|
-
var AskUserQuestionInput =
|
|
15855
|
-
questions:
|
|
16212
|
+
var AskUserQuestionInput = z27.object({
|
|
16213
|
+
questions: z27.array(QuestionSchema).min(1).max(4)
|
|
15856
16214
|
});
|
|
15857
16215
|
function hookAnswersFromUpdatedInput(updatedInput, questions) {
|
|
15858
16216
|
if (typeof updatedInput !== "object" || updatedInput === null) return void 0;
|
|
@@ -15936,20 +16294,20 @@ function createAskUserQuestionTool(handler) {
|
|
|
15936
16294
|
}
|
|
15937
16295
|
|
|
15938
16296
|
// src/tools/todo-write.ts
|
|
15939
|
-
import { z as
|
|
15940
|
-
var TodoStatusSchema =
|
|
16297
|
+
import { z as z28 } from "zod";
|
|
16298
|
+
var TodoStatusSchema = z28.enum([
|
|
15941
16299
|
"pending",
|
|
15942
16300
|
"in_progress",
|
|
15943
16301
|
"completed",
|
|
15944
16302
|
"cancelled"
|
|
15945
16303
|
]);
|
|
15946
|
-
var TodoItemSchema =
|
|
15947
|
-
content:
|
|
16304
|
+
var TodoItemSchema = z28.object({
|
|
16305
|
+
content: z28.string().trim().min(1),
|
|
15948
16306
|
status: TodoStatusSchema,
|
|
15949
|
-
activeForm:
|
|
16307
|
+
activeForm: z28.string().trim().min(1)
|
|
15950
16308
|
});
|
|
15951
|
-
var TodoWriteInput =
|
|
15952
|
-
todos:
|
|
16309
|
+
var TodoWriteInput = z28.object({
|
|
16310
|
+
todos: z28.array(TodoItemSchema).min(1).max(50)
|
|
15953
16311
|
});
|
|
15954
16312
|
function createTodoWriteTool() {
|
|
15955
16313
|
return {
|
|
@@ -15985,37 +16343,37 @@ function createTodoWriteTool() {
|
|
|
15985
16343
|
// src/tools/managed.ts
|
|
15986
16344
|
import { randomUUID as randomUUID12 } from "crypto";
|
|
15987
16345
|
import { link as link2, lstat as lstat11, mkdir as mkdir17, readFile as readFile17, readdir as readdir9, unlink as unlink4, writeFile as writeFile10 } from "fs/promises";
|
|
15988
|
-
import { dirname as
|
|
15989
|
-
import { z as
|
|
16346
|
+
import { dirname as dirname18, join as join19, resolve as resolve20 } from "path";
|
|
16347
|
+
import { z as z29 } from "zod";
|
|
15990
16348
|
var MANAGED_TOOL_VERSION = 1;
|
|
15991
16349
|
var MAX_RECORD_BYTES = 256 * 1024;
|
|
15992
16350
|
var TOOL_NAME = /^[A-Za-z][A-Za-z0-9_]{0,63}$/;
|
|
15993
|
-
var JsonSchemaObject =
|
|
16351
|
+
var JsonSchemaObject = z29.record(z29.string(), z29.unknown()).superRefine((schema, context) => {
|
|
15994
16352
|
if (schema.type !== "object") {
|
|
15995
16353
|
context.addIssue({ code: "custom", message: "Tool input JSON Schema must have type object" });
|
|
15996
16354
|
}
|
|
15997
16355
|
});
|
|
15998
|
-
var RegisterManagedToolInputSchema =
|
|
15999
|
-
name:
|
|
16000
|
-
description:
|
|
16356
|
+
var RegisterManagedToolInputSchema = z29.object({
|
|
16357
|
+
name: z29.string().regex(TOOL_NAME).describe("Unique callable tool name using letters, digits, and underscores"),
|
|
16358
|
+
description: z29.string().min(1).max(4096).describe("Purpose and appropriate use of the generated tool"),
|
|
16001
16359
|
inputSchema: JsonSchemaObject.describe("Provider-facing JSON Schema with an object at the root"),
|
|
16002
|
-
implementation:
|
|
16360
|
+
implementation: z29.string().min(1).max(64 * 1024).describe(
|
|
16003
16361
|
"Async JavaScript function body, or complete function/arrow expression, receiving input, signal, and context; return the tool result"
|
|
16004
16362
|
),
|
|
16005
|
-
scope:
|
|
16363
|
+
scope: z29.enum(["project", "global"]).default("project").describe(
|
|
16006
16364
|
"Project persists in the current workspace; global persists for every workspace"
|
|
16007
16365
|
),
|
|
16008
|
-
agents:
|
|
16366
|
+
agents: z29.array(z29.enum(["main", "subagent"])).min(1).max(2).optional().describe(
|
|
16009
16367
|
"Agent roles allowed to call the generated tool; omit to allow both"
|
|
16010
16368
|
)
|
|
16011
16369
|
}).strict();
|
|
16012
|
-
var RemoveManagedToolInputSchema =
|
|
16013
|
-
name:
|
|
16014
|
-
scope:
|
|
16370
|
+
var RemoveManagedToolInputSchema = z29.object({
|
|
16371
|
+
name: z29.string().regex(TOOL_NAME).describe("Managed tool name to remove"),
|
|
16372
|
+
scope: z29.enum(["project", "global"]).optional().describe("Required only when the same name exists in both scopes")
|
|
16015
16373
|
}).strict();
|
|
16016
16374
|
var ManagedToolRecordSchema = RegisterManagedToolInputSchema.extend({
|
|
16017
|
-
version:
|
|
16018
|
-
createdAt:
|
|
16375
|
+
version: z29.literal(MANAGED_TOOL_VERSION),
|
|
16376
|
+
createdAt: z29.string().datetime()
|
|
16019
16377
|
}).strict();
|
|
16020
16378
|
var AsyncFunction = Object.getPrototypeOf(async function() {
|
|
16021
16379
|
}).constructor;
|
|
@@ -16202,7 +16560,7 @@ function createManagedToolManagementTools(options) {
|
|
|
16202
16560
|
const listTools = {
|
|
16203
16561
|
name: "ListRegisteredTools",
|
|
16204
16562
|
description: "List durable tools created through RegisterTool, including scope, path, and active precedence",
|
|
16205
|
-
inputSchema:
|
|
16563
|
+
inputSchema: z29.object({}).strict(),
|
|
16206
16564
|
agents: mainOnly,
|
|
16207
16565
|
paths: () => [],
|
|
16208
16566
|
execute: async (_input, signal) => {
|
|
@@ -16215,7 +16573,7 @@ function createManagedToolManagementTools(options) {
|
|
|
16215
16573
|
function compileDefinition(record, scope2, workspace) {
|
|
16216
16574
|
let inputSchema;
|
|
16217
16575
|
try {
|
|
16218
|
-
inputSchema =
|
|
16576
|
+
inputSchema = z29.fromJSONSchema(record.inputSchema);
|
|
16219
16577
|
} catch (error) {
|
|
16220
16578
|
throw new Error(`Invalid input schema for managed tool "${record.name}": ${message(error)}`);
|
|
16221
16579
|
}
|
|
@@ -16269,7 +16627,7 @@ ${sourceUrl}`
|
|
|
16269
16627
|
}
|
|
16270
16628
|
}
|
|
16271
16629
|
async function writeExclusive(path, content) {
|
|
16272
|
-
await mkdir17(
|
|
16630
|
+
await mkdir17(dirname18(path), { recursive: true });
|
|
16273
16631
|
const temporary = `${path}.${randomUUID12()}.tmp`;
|
|
16274
16632
|
try {
|
|
16275
16633
|
await writeFile10(temporary, content, { encoding: "utf8", flag: "wx", mode: 384 });
|
|
@@ -16315,7 +16673,7 @@ function isMissing4(error) {
|
|
|
16315
16673
|
}
|
|
16316
16674
|
|
|
16317
16675
|
// src/hallucination/confidence.ts
|
|
16318
|
-
import { z as
|
|
16676
|
+
import { z as z30 } from "zod";
|
|
16319
16677
|
|
|
16320
16678
|
// src/hallucination/types.ts
|
|
16321
16679
|
var DEFAULT_SLIDING_WINDOW_SIZE = 20;
|
|
@@ -16328,12 +16686,12 @@ var DEFAULT_EVALUATION_TIMEOUT_MS = 2e3;
|
|
|
16328
16686
|
var MAX_QUERY_CHARS = 5e3;
|
|
16329
16687
|
var MAX_OUTPUT_CHARS = 1e4;
|
|
16330
16688
|
var MAX_EVIDENCE_CHARS = 6e3;
|
|
16331
|
-
var ConfidenceSchema =
|
|
16332
|
-
taskAlignment:
|
|
16333
|
-
evidenceGrounding:
|
|
16334
|
-
processReliability:
|
|
16335
|
-
reason:
|
|
16336
|
-
unsupportedClaims:
|
|
16689
|
+
var ConfidenceSchema = z30.object({
|
|
16690
|
+
taskAlignment: z30.number(),
|
|
16691
|
+
evidenceGrounding: z30.number(),
|
|
16692
|
+
processReliability: z30.number(),
|
|
16693
|
+
reason: z30.string(),
|
|
16694
|
+
unsupportedClaims: z30.array(z30.string()).max(3)
|
|
16337
16695
|
});
|
|
16338
16696
|
var PROMPT = `You are a fast, evidence-aware task-completion verifier.
|
|
16339
16697
|
|
|
@@ -18332,15 +18690,15 @@ function workspacePath(root, input) {
|
|
|
18332
18690
|
}
|
|
18333
18691
|
|
|
18334
18692
|
// src/tools/terminal.ts
|
|
18335
|
-
import { z as
|
|
18693
|
+
import { z as z31 } from "zod";
|
|
18336
18694
|
import { resolve as resolve24 } from "path";
|
|
18337
|
-
var Id =
|
|
18338
|
-
var OpenInput =
|
|
18339
|
-
var OptionalBoolean =
|
|
18340
|
-
var WriteInput2 =
|
|
18341
|
-
var ReadInput3 =
|
|
18342
|
-
var ResizeInput =
|
|
18343
|
-
var CloseInput =
|
|
18695
|
+
var Id = z31.string().regex(/^term-[a-f0-9-]+$/);
|
|
18696
|
+
var OpenInput = z31.object({ cwd: z31.string().optional(), shell: z31.string().optional(), args: z31.array(z31.string()).optional(), columns: z31.coerce.number().int().min(10).max(500).optional(), rows: z31.coerce.number().int().min(2).max(300).optional() });
|
|
18697
|
+
var OptionalBoolean = z31.union([z31.boolean(), z31.string().refine((value) => value === "true" || value === "false")]);
|
|
18698
|
+
var WriteInput2 = z31.object({ id: Id, data: z31.string().max(1e5), enter: OptionalBoolean.optional() });
|
|
18699
|
+
var ReadInput3 = z31.object({ id: Id, cursor: z31.coerce.number().int().min(0).optional() });
|
|
18700
|
+
var ResizeInput = z31.object({ id: Id, columns: z31.coerce.number().int().min(10).max(500), rows: z31.coerce.number().int().min(2).max(300) });
|
|
18701
|
+
var CloseInput = z31.object({ id: Id });
|
|
18344
18702
|
function createTerminalTools(terminals, workspace = process.cwd()) {
|
|
18345
18703
|
const tools = [
|
|
18346
18704
|
{
|
|
@@ -18416,7 +18774,7 @@ function createTerminalTools(terminals, workspace = process.cwd()) {
|
|
|
18416
18774
|
{
|
|
18417
18775
|
name: "TerminalList",
|
|
18418
18776
|
description: "List persistent terminals owned by this agent",
|
|
18419
|
-
inputSchema:
|
|
18777
|
+
inputSchema: z31.object({}),
|
|
18420
18778
|
paths: () => [],
|
|
18421
18779
|
execute: async (_input, _signal, context) => terminals.list(owner(context))
|
|
18422
18780
|
}
|
|
@@ -18795,7 +19153,7 @@ var PalClient = class {
|
|
|
18795
19153
|
};
|
|
18796
19154
|
|
|
18797
19155
|
// src/pals/tools.ts
|
|
18798
|
-
import { z as
|
|
19156
|
+
import { z as z32 } from "zod";
|
|
18799
19157
|
var DEFAULT_SHARE_BUDGET_BYTES = 128 * 1024;
|
|
18800
19158
|
var CollaborationShareGuard = class {
|
|
18801
19159
|
redact;
|
|
@@ -18816,25 +19174,25 @@ var CollaborationShareGuard = class {
|
|
|
18816
19174
|
return redacted;
|
|
18817
19175
|
}
|
|
18818
19176
|
};
|
|
18819
|
-
var Uuid =
|
|
18820
|
-
var Hash =
|
|
19177
|
+
var Uuid = z32.uuid();
|
|
19178
|
+
var Hash = z32.string().regex(/^[a-f0-9]{64}$/);
|
|
18821
19179
|
var Target = PalTargetSchema;
|
|
18822
|
-
var BoundedText =
|
|
19180
|
+
var BoundedText = z32.string().trim().min(1).refine(
|
|
18823
19181
|
(value) => Buffer.byteLength(value, "utf8") <= MAX_MESSAGE_BYTES,
|
|
18824
19182
|
`Text must not exceed ${MAX_MESSAGE_BYTES} UTF-8 bytes`
|
|
18825
19183
|
);
|
|
18826
|
-
var CompletionEvidence =
|
|
19184
|
+
var CompletionEvidence = z32.string().trim().min(1).refine(
|
|
18827
19185
|
(value) => Buffer.byteLength(value, "utf8") <= MAX_COMPLETION_DETAIL_BYTES,
|
|
18828
19186
|
`Completion evidence must not exceed ${MAX_COMPLETION_DETAIL_BYTES} UTF-8 bytes`
|
|
18829
19187
|
);
|
|
18830
|
-
var EmptyInput =
|
|
18831
|
-
var StateInput =
|
|
18832
|
-
var TokenInput =
|
|
18833
|
-
var SendInput =
|
|
18834
|
-
var PlanInput =
|
|
18835
|
-
var ProgressInput =
|
|
18836
|
-
var CompleteInput = TokenInput.extend({ passed:
|
|
18837
|
-
var IntegrateInput = TokenInput.extend({ passed:
|
|
19188
|
+
var EmptyInput = z32.object({}).strict();
|
|
19189
|
+
var StateInput = z32.object({ coWorkId: Uuid }).strict();
|
|
19190
|
+
var TokenInput = z32.object({ coWorkId: Uuid, epoch: z32.number().int().positive(), planHash: Hash }).strict();
|
|
19191
|
+
var SendInput = z32.object({ target: Target, message: BoundedText, coWorkId: Uuid.optional() }).strict();
|
|
19192
|
+
var PlanInput = z32.object({ plan: CoWorkPlanSchema }).strict();
|
|
19193
|
+
var ProgressInput = z32.object({ coWorkId: Uuid, target: Target, detail: BoundedText }).strict();
|
|
19194
|
+
var CompleteInput = TokenInput.extend({ passed: z32.boolean(), detail: CompletionEvidence }).strict();
|
|
19195
|
+
var IntegrateInput = TokenInput.extend({ passed: z32.boolean(), evidence: CompletionEvidence }).strict();
|
|
18838
19196
|
var sharedBytes = (...values) => values.reduce((total, value) => total + Buffer.byteLength(value, "utf8"), 0);
|
|
18839
19197
|
function resolvePresence(presences, target) {
|
|
18840
19198
|
const normalized = normalizePalIdentity(target);
|
|
@@ -18993,6 +19351,7 @@ var INTERRUPTED_TASK_PLAN_CONTEXT = [
|
|
|
18993
19351
|
"Reassess the current query independently.",
|
|
18994
19352
|
"If the current work needs a plan, create a fresh one with TaskPlan before using TaskUpdate."
|
|
18995
19353
|
].join(" ");
|
|
19354
|
+
var DEFAULT_SHUTDOWN_STEP_TIMEOUT_MS = 3e3;
|
|
18996
19355
|
function createPromptEnvironment(input = {}) {
|
|
18997
19356
|
const now = input.now ?? /* @__PURE__ */ new Date();
|
|
18998
19357
|
return {
|
|
@@ -19450,7 +19809,7 @@ async function createProductionRuntime(options) {
|
|
|
19450
19809
|
});
|
|
19451
19810
|
const skillsReady = skills.discover();
|
|
19452
19811
|
skillsReady.catch(() => void 0);
|
|
19453
|
-
tools.push(createSkillResourceTool(skills));
|
|
19812
|
+
tools.push(createSkillTool(skills), createSkillResourceTool(skills));
|
|
19454
19813
|
if (options.extraTools !== void 0) tools.push(...options.extraTools);
|
|
19455
19814
|
const flavor = await optionalText2(join22(workspace, "FLAVOR.md"));
|
|
19456
19815
|
const instructionBaseline = await workspaceInstructions.baseline();
|
|
@@ -20152,6 +20511,10 @@ async function createProductionRuntime(options) {
|
|
|
20152
20511
|
subagentModel: () => childModel,
|
|
20153
20512
|
llmServiceName: () => effectiveLlm?.serviceName,
|
|
20154
20513
|
permissionMode: () => harness.permissionMode,
|
|
20514
|
+
addContext: (content) => {
|
|
20515
|
+
const duplicate = harness.main.context.snapshot().messages.some((entry2) => entry2.role === "system" && entry2.content === content);
|
|
20516
|
+
if (!duplicate) harness.main.context.append({ role: "system", content });
|
|
20517
|
+
},
|
|
20155
20518
|
...palServices === void 0 ? {} : { pals: palServices },
|
|
20156
20519
|
run: (prompt, signal, runOptions) => {
|
|
20157
20520
|
interruptedTaskPlanNeedsReassessment = false;
|
|
@@ -20561,23 +20924,24 @@ ${renderMemoryDocument(entries)}`;
|
|
|
20561
20924
|
async dispose() {
|
|
20562
20925
|
if (disposed) return;
|
|
20563
20926
|
disposed = true;
|
|
20927
|
+
const stepTimeoutMs = options.shutdownStepTimeoutMs ?? DEFAULT_SHUTDOWN_STEP_TIMEOUT_MS;
|
|
20564
20928
|
collaborationEventsOpen = false;
|
|
20565
20929
|
unsubscribeCollaboration?.();
|
|
20566
|
-
await collaborationEventPump;
|
|
20930
|
+
if (collaborationEventPump !== void 0) await boundedStep(stepTimeoutMs, diagnostics, "collaboration-event-pump", collaborationEventPump);
|
|
20567
20931
|
mcpDiscarded = true;
|
|
20568
|
-
await sleepScheduler
|
|
20569
|
-
await memoryCoordinator
|
|
20570
|
-
await persist();
|
|
20571
|
-
await persistTail;
|
|
20572
|
-
if (ideSessionId !== void 0) await ide.endSession(ideSessionId);
|
|
20573
|
-
await executionEnvironment
|
|
20932
|
+
if (sleepScheduler !== void 0) await boundedStep(stepTimeoutMs, diagnostics, "sleep-scheduler", sleepScheduler.dispose());
|
|
20933
|
+
if (memoryCoordinator !== void 0) await boundedStep(stepTimeoutMs, diagnostics, "memory-flush", memoryCoordinator.flush());
|
|
20934
|
+
await boundedStep(stepTimeoutMs, diagnostics, "persist", persist());
|
|
20935
|
+
if (persistTail !== void 0) await boundedStep(stepTimeoutMs, diagnostics, "persist-tail", persistTail);
|
|
20936
|
+
if (ideSessionId !== void 0) await boundedStep(stepTimeoutMs, diagnostics, "ide-end-session", ide.endSession(ideSessionId));
|
|
20937
|
+
if (executionEnvironment !== void 0) await boundedStep(stepTimeoutMs, diagnostics, "execution-environment", executionEnvironment.dispose());
|
|
20574
20938
|
terminals.dispose();
|
|
20575
|
-
await jobs.dispose();
|
|
20939
|
+
await boundedStep(stepTimeoutMs, diagnostics, "jobs", jobs.dispose());
|
|
20576
20940
|
auditLogger.close();
|
|
20577
20941
|
evolveService.dispose();
|
|
20578
20942
|
memoryReviews.dispose();
|
|
20579
|
-
await collaborationClient
|
|
20580
|
-
await cleanupProduction(approvals, questions, pluginHost, mcpManager, harness);
|
|
20943
|
+
if (collaborationClient !== void 0) await boundedStep(stepTimeoutMs, diagnostics, "collaboration-close", collaborationClient.close());
|
|
20944
|
+
await cleanupProduction(approvals, questions, pluginHost, mcpManager, harness, { stepTimeoutMs });
|
|
20581
20945
|
}
|
|
20582
20946
|
};
|
|
20583
20947
|
} catch (primaryError) {
|
|
@@ -20585,16 +20949,17 @@ ${renderMemoryDocument(entries)}`;
|
|
|
20585
20949
|
mcpDiscarded = true;
|
|
20586
20950
|
memoryReviews.dispose();
|
|
20587
20951
|
try {
|
|
20588
|
-
|
|
20589
|
-
await
|
|
20590
|
-
await
|
|
20952
|
+
const stepTimeoutMs = options.shutdownStepTimeoutMs ?? DEFAULT_SHUTDOWN_STEP_TIMEOUT_MS;
|
|
20953
|
+
if (ideSessionId !== void 0) await boundedStep(stepTimeoutMs, diagnostics, "ide-end-session", ide.endSession(ideSessionId));
|
|
20954
|
+
if (sleepScheduler !== void 0) await boundedStep(stepTimeoutMs, diagnostics, "sleep-scheduler", sleepScheduler.dispose());
|
|
20955
|
+
if (executionEnvironment !== void 0) await boundedStep(stepTimeoutMs, diagnostics, "execution-environment", executionEnvironment.dispose());
|
|
20591
20956
|
terminals.dispose();
|
|
20592
|
-
await jobs.dispose();
|
|
20957
|
+
await boundedStep(stepTimeoutMs, diagnostics, "jobs", jobs.dispose());
|
|
20593
20958
|
unsubscribeCollaboration?.();
|
|
20594
20959
|
pendingCollaborationEvents.length = 0;
|
|
20595
|
-
await collaborationEventPump;
|
|
20596
|
-
await collaborationClient
|
|
20597
|
-
await cleanupProduction(approvals, questions, pluginHost, mcpManager, harnessCreated ? harness : void 0);
|
|
20960
|
+
if (collaborationEventPump !== void 0) await boundedStep(stepTimeoutMs, diagnostics, "collaboration-event-pump", collaborationEventPump);
|
|
20961
|
+
if (collaborationClient !== void 0) await boundedStep(stepTimeoutMs, diagnostics, "collaboration-close", collaborationClient.close());
|
|
20962
|
+
await cleanupProduction(approvals, questions, pluginHost, mcpManager, harnessCreated ? harness : void 0, { stepTimeoutMs });
|
|
20598
20963
|
} catch (cleanupError) {
|
|
20599
20964
|
attachCleanupError(primaryError, cleanupError);
|
|
20600
20965
|
}
|
|
@@ -20763,7 +21128,7 @@ async function* runMain(harness, skills, prompt, signal, setupError, memory, get
|
|
|
20763
21128
|
if (ideContext !== void 0) contexts.push(ideContext);
|
|
20764
21129
|
const skill = await skills.match(prompt);
|
|
20765
21130
|
if (skill !== void 0) contexts.push(`Matched skill: ${skill.name}
|
|
20766
|
-
${await skills.loadBody(skill)}`);
|
|
21131
|
+
${expandSkillArguments(await skills.loadBody(skill), prompt)}`);
|
|
20767
21132
|
const additionalContext = contexts.length === 0 ? void 0 : contexts.join("\n\n");
|
|
20768
21133
|
for await (const event of harness.main.loop.run({
|
|
20769
21134
|
prompt,
|
|
@@ -20798,7 +21163,7 @@ async function* runExplicitSkill(harness, skills, skillName, prompt, signal, set
|
|
|
20798
21163
|
}
|
|
20799
21164
|
const userPrompt = prompt || `Apply the ${skillName} skill.`;
|
|
20800
21165
|
const additionalContext = `Matched skill: ${skill.name}
|
|
20801
|
-
${await skills.loadBody(skill)}`;
|
|
21166
|
+
${expandSkillArguments(await skills.loadBody(skill), prompt)}`;
|
|
20802
21167
|
yield* harness.main.loop.run({ prompt: userPrompt, signal, additionalContext });
|
|
20803
21168
|
} catch (error) {
|
|
20804
21169
|
yield { type: "error", error: { code: "unknown", message: message(error) } };
|
|
@@ -21215,7 +21580,8 @@ function storedConversation(snapshot4) {
|
|
|
21215
21580
|
})
|
|
21216
21581
|
};
|
|
21217
21582
|
}
|
|
21218
|
-
async function cleanupProduction(approvals, questions, pluginHost, mcpManager, harness) {
|
|
21583
|
+
async function cleanupProduction(approvals, questions, pluginHost, mcpManager, harness, cleanupOptions = { stepTimeoutMs: DEFAULT_SHUTDOWN_STEP_TIMEOUT_MS }) {
|
|
21584
|
+
const { stepTimeoutMs } = cleanupOptions;
|
|
21219
21585
|
let primary;
|
|
21220
21586
|
try {
|
|
21221
21587
|
approvals.resolve("deny");
|
|
@@ -21229,7 +21595,8 @@ async function cleanupProduction(approvals, questions, pluginHost, mcpManager, h
|
|
|
21229
21595
|
else attachCleanupError(primary, error);
|
|
21230
21596
|
}
|
|
21231
21597
|
try {
|
|
21232
|
-
await pluginHost.unloadAll();
|
|
21598
|
+
const outcome = await withTimeout(pluginHost.unloadAll(), stepTimeoutMs);
|
|
21599
|
+
if (outcome.timedOut) primary = new Error(`Plugin unload timed out after ${stepTimeoutMs}ms`);
|
|
21233
21600
|
} catch (error) {
|
|
21234
21601
|
if (primary === void 0) primary = error;
|
|
21235
21602
|
else attachCleanupError(primary, error);
|
|
@@ -21241,7 +21608,14 @@ async function cleanupProduction(approvals, questions, pluginHost, mcpManager, h
|
|
|
21241
21608
|
else attachCleanupError(primary, error);
|
|
21242
21609
|
}
|
|
21243
21610
|
try {
|
|
21244
|
-
|
|
21611
|
+
if (mcpManager !== void 0) {
|
|
21612
|
+
const outcome = await withTimeout(mcpManager.close(), stepTimeoutMs);
|
|
21613
|
+
if (outcome.timedOut) {
|
|
21614
|
+
const timeoutError = new Error(`MCP shutdown timed out after ${stepTimeoutMs}ms`);
|
|
21615
|
+
if (primary === void 0) primary = timeoutError;
|
|
21616
|
+
else attachCleanupError(primary, timeoutError);
|
|
21617
|
+
}
|
|
21618
|
+
}
|
|
21245
21619
|
} catch (error) {
|
|
21246
21620
|
if (primary === void 0) primary = error;
|
|
21247
21621
|
else attachCleanupError(primary, error);
|
|
@@ -21249,6 +21623,10 @@ async function cleanupProduction(approvals, questions, pluginHost, mcpManager, h
|
|
|
21249
21623
|
}
|
|
21250
21624
|
if (primary !== void 0) throw primary;
|
|
21251
21625
|
}
|
|
21626
|
+
async function boundedStep(timeoutMs, diagnostics, name, step) {
|
|
21627
|
+
const outcome = await withTimeout(step, timeoutMs);
|
|
21628
|
+
if (outcome.timedOut) diagnostics.push(`Shutdown step "${name}" timed out after ${timeoutMs}ms and was abandoned.`);
|
|
21629
|
+
}
|
|
21252
21630
|
function attachCleanupError(primary, cleanup) {
|
|
21253
21631
|
if (typeof primary !== "object" && typeof primary !== "function" || primary === null || !Object.isExtensible(primary)) return;
|
|
21254
21632
|
try {
|
|
@@ -21334,6 +21712,7 @@ function createMemoryTaskId() {
|
|
|
21334
21712
|
|
|
21335
21713
|
export {
|
|
21336
21714
|
modelContentTranscriptText,
|
|
21715
|
+
withTimeout,
|
|
21337
21716
|
message,
|
|
21338
21717
|
isDestructiveTool,
|
|
21339
21718
|
redactErrorText,
|