@centralu/host-linux-arm64 0.1.0-beta.28 → 0.1.0-beta.29
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/host/bundle-info.json +2 -2
- package/host/centralu-package.json +5 -5
- package/host/main.mjs +500 -373
- package/host/schema.sql +0 -16
- package/package.json +1 -1
package/host/main.mjs
CHANGED
|
@@ -42892,6 +42892,23 @@ function takeLaunchEnv(env = process.env) {
|
|
|
42892
42892
|
return launch2;
|
|
42893
42893
|
}
|
|
42894
42894
|
|
|
42895
|
+
// packages/agent-host/src/json-value.ts
|
|
42896
|
+
var isObj = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
42897
|
+
var asObj = (v) => isObj(v) ? v : {};
|
|
42898
|
+
var str = (v, fallback = "") => typeof v === "string" ? v : fallback;
|
|
42899
|
+
var isFilled = (v) => typeof v === "string" && v.length > 0;
|
|
42900
|
+
var filled = (v) => isFilled(v) ? v : null;
|
|
42901
|
+
var trimmed = (v) => typeof v === "string" && v.trim() ? v.trim() : void 0;
|
|
42902
|
+
var finite = (v) => typeof v === "number" && Number.isFinite(v) ? v : void 0;
|
|
42903
|
+
var jsonObject = (v) => {
|
|
42904
|
+
if (typeof v !== "string") return asObj(v);
|
|
42905
|
+
try {
|
|
42906
|
+
return jsonObject(JSON.parse(v));
|
|
42907
|
+
} catch {
|
|
42908
|
+
return {};
|
|
42909
|
+
}
|
|
42910
|
+
};
|
|
42911
|
+
|
|
42895
42912
|
// packages/agent-host/src/lifecycle/handed-token.ts
|
|
42896
42913
|
var HANDED_TOKEN_WAIT_MS = 1e4;
|
|
42897
42914
|
var MAX_TOKEN_LINE = 4096;
|
|
@@ -42903,7 +42920,7 @@ async function readHandedToken(input, waitMs = HANDED_TOKEN_WAIT_MS) {
|
|
|
42903
42920
|
} catch {
|
|
42904
42921
|
throw new Error("the token line on stdin is not JSON");
|
|
42905
42922
|
}
|
|
42906
|
-
const token2 =
|
|
42923
|
+
const token2 = asObj(parsed).token;
|
|
42907
42924
|
if (typeof token2 !== "string" || token2.trim() === "") throw new Error("the token line on stdin has no token");
|
|
42908
42925
|
return token2;
|
|
42909
42926
|
}
|
|
@@ -43012,7 +43029,7 @@ import { mkdirSync as mkdirSync15, writeSync as writeSync3 } from "node:fs";
|
|
|
43012
43029
|
|
|
43013
43030
|
// packages/protocol/src/brand.ts
|
|
43014
43031
|
var APP_NAME = "Centralu";
|
|
43015
|
-
var APP_VERSION = "0.1.0-beta.
|
|
43032
|
+
var APP_VERSION = "0.1.0-beta.29";
|
|
43016
43033
|
var APP_SLUG = "centralu";
|
|
43017
43034
|
var CLIENT_INFO = { name: APP_SLUG, title: APP_NAME, version: APP_VERSION };
|
|
43018
43035
|
var DATA_DIR = ".centralu";
|
|
@@ -58461,15 +58478,15 @@ var ApprovalDetail = ApprovalDetailKinds.catch((ctx) => unknownApprovalCard(ctx.
|
|
|
58461
58478
|
var UNKNOWN_CARD = "unknown_card";
|
|
58462
58479
|
var UNKNOWN_CARD_NOTE = "A newer Centralu may have sent it. Allow it only if you know what it asks; updating Centralu shows it in full.";
|
|
58463
58480
|
var UNREADABLE_CARD_NOTE = "It may come from a newer Centralu, or be malformed. Allow it only if you know what it asks.";
|
|
58464
|
-
var
|
|
58481
|
+
var str2 = (v) => typeof v === "string" && v.trim() !== "" ? v.trim() : void 0;
|
|
58465
58482
|
var quoted = (v, max = 500) => {
|
|
58466
58483
|
const cut = (t) => t.length > max ? `${t.slice(0, max)}\u2026` : t;
|
|
58467
58484
|
return typeof v === "string" ? JSON.stringify(cut(v)) : cut(JSON.stringify(v) ?? String(v));
|
|
58468
58485
|
};
|
|
58469
|
-
var nameOf = (v) => typeof v === "object" && v !== null ?
|
|
58486
|
+
var nameOf = (v) => typeof v === "object" && v !== null ? str2(v.name) : void 0;
|
|
58470
58487
|
function unknownApprovalCard(raw) {
|
|
58471
58488
|
const card = typeof raw === "object" && raw !== null ? raw : {};
|
|
58472
|
-
const kind =
|
|
58489
|
+
const kind = str2(card.kind)?.slice(0, 60);
|
|
58473
58490
|
const branch = kind ? ApprovalDetailKinds.options.find((o) => o.shape.kind.value === kind) : void 0;
|
|
58474
58491
|
const lines = [];
|
|
58475
58492
|
let problems = "";
|
|
@@ -58490,11 +58507,11 @@ function unknownApprovalCard(raw) {
|
|
|
58490
58507
|
const named = [
|
|
58491
58508
|
nameOf(card.project) && `project ${quoted(nameOf(card.project), 80)}`,
|
|
58492
58509
|
nameOf(card.app) && `app ${quoted(nameOf(card.app), 80)}`,
|
|
58493
|
-
|
|
58510
|
+
str2(card.machine) && `machine ${quoted(str2(card.machine), 80)}`
|
|
58494
58511
|
].filter(Boolean);
|
|
58495
58512
|
if (named.length) lines.push(`It names ${named.join(", ")}.`);
|
|
58496
58513
|
for (const [key, label] of [["text", "Its text"], ["raw", "Its text"], ["command", "The command"], ["path", "The file"]]) {
|
|
58497
|
-
const v =
|
|
58514
|
+
const v = str2(card[key]);
|
|
58498
58515
|
if (v) lines.push(`${label}, as the request gives it (not checked by Centralu): ${quoted(v)}`);
|
|
58499
58516
|
}
|
|
58500
58517
|
lines.push(branch ? UNREADABLE_CARD_NOTE : UNKNOWN_CARD_NOTE);
|
|
@@ -61529,10 +61546,16 @@ var sessionMethods = {
|
|
|
61529
61546
|
* the apps' broker has a trash or purge verb. `agents.deleteSession` is the way in.
|
|
61530
61547
|
*
|
|
61531
61548
|
* `bytes` is the total of every session's `bytes` — shown because nothing empties the trash on its own.
|
|
61549
|
+
* `unreached`: the linked machines whose trash could not be read this time (#841 item 4), so the list says it is
|
|
61550
|
+
* not the whole trash. Absent when every machine answered, and from a host before it.
|
|
61532
61551
|
*/
|
|
61533
61552
|
"trash.list": {
|
|
61534
61553
|
params: external_exports.object({}),
|
|
61535
|
-
result: external_exports.object({
|
|
61554
|
+
result: external_exports.object({
|
|
61555
|
+
sessions: external_exports.array(TrashedSession),
|
|
61556
|
+
bytes: external_exports.number(),
|
|
61557
|
+
unreached: external_exports.array(external_exports.object({ machineId: external_exports.string(), name: external_exports.string() })).optional()
|
|
61558
|
+
})
|
|
61536
61559
|
},
|
|
61537
61560
|
/** A trashed conversation, read-only — the same page shape as `messages.load` */
|
|
61538
61561
|
"trash.read": {
|
|
@@ -62058,6 +62081,9 @@ function appKeyOf(projectId, appId, machine) {
|
|
|
62058
62081
|
function appLabel(ref) {
|
|
62059
62082
|
return `${ref.projectId === null ? "user" : ref.projectId.slice(0, 8)}/${ref.appId}`;
|
|
62060
62083
|
}
|
|
62084
|
+
function noSuchAppText(ref) {
|
|
62085
|
+
return `There is no such app: ${ref.projectId ?? "user"}/${ref.appId}`;
|
|
62086
|
+
}
|
|
62061
62087
|
|
|
62062
62088
|
// packages/protocol/src/app-frames.ts
|
|
62063
62089
|
function frameField(value) {
|
|
@@ -63178,23 +63204,6 @@ function keeperPtyModule(keeper) {
|
|
|
63178
63204
|
};
|
|
63179
63205
|
}
|
|
63180
63206
|
|
|
63181
|
-
// packages/agent-host/src/json-value.ts
|
|
63182
|
-
var isObj = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
63183
|
-
var asObj = (v) => isObj(v) ? v : {};
|
|
63184
|
-
var str2 = (v, fallback = "") => typeof v === "string" ? v : fallback;
|
|
63185
|
-
var isFilled = (v) => typeof v === "string" && v.length > 0;
|
|
63186
|
-
var filled = (v) => isFilled(v) ? v : null;
|
|
63187
|
-
var trimmed = (v) => typeof v === "string" && v.trim() ? v.trim() : void 0;
|
|
63188
|
-
var finite = (v) => typeof v === "number" && Number.isFinite(v) ? v : void 0;
|
|
63189
|
-
var jsonObject = (v) => {
|
|
63190
|
-
if (typeof v !== "string") return asObj(v);
|
|
63191
|
-
try {
|
|
63192
|
-
return jsonObject(JSON.parse(v));
|
|
63193
|
-
} catch {
|
|
63194
|
-
return {};
|
|
63195
|
-
}
|
|
63196
|
-
};
|
|
63197
|
-
|
|
63198
63207
|
// packages/agent-host/src/keeper/tags.ts
|
|
63199
63208
|
function parseTag(raw) {
|
|
63200
63209
|
if (typeof raw !== "object" || raw === null) return null;
|
|
@@ -64722,18 +64731,23 @@ function proxyPageHtml(config2) {
|
|
|
64722
64731
|
|
|
64723
64732
|
// packages/agent-host/src/views/view-document.ts
|
|
64724
64733
|
var VIEW_MIME_TYPE = "text/html;profile=mcp-app";
|
|
64734
|
+
function isViewMimeType(mimeType) {
|
|
64735
|
+
return typeof mimeType === "string" && mimeType.replace(/\s+/g, "").toLowerCase() === VIEW_MIME_TYPE;
|
|
64736
|
+
}
|
|
64737
|
+
function viewHtmlOf(item) {
|
|
64738
|
+
if (typeof item.text === "string") return item.text;
|
|
64739
|
+
if (typeof item.blob === "string") return Buffer.from(item.blob, "base64").toString("utf8");
|
|
64740
|
+
return null;
|
|
64741
|
+
}
|
|
64725
64742
|
function viewDocumentFromResource(result, uri) {
|
|
64726
64743
|
const contents = result?.contents;
|
|
64727
64744
|
if (!Array.isArray(contents) || contents.length === 0) throw new Error(`${uri}: the app returned no content for this view`);
|
|
64728
64745
|
const item = contents.find((c) => c?.uri === uri) ?? contents[0];
|
|
64729
|
-
|
|
64730
|
-
if (mime !== VIEW_MIME_TYPE) {
|
|
64746
|
+
if (!isViewMimeType(item.mimeType)) {
|
|
64731
64747
|
throw new Error(`${uri}: not an app view (mimeType ${JSON.stringify(item.mimeType ?? null)}, expected ${VIEW_MIME_TYPE})`);
|
|
64732
64748
|
}
|
|
64733
|
-
|
|
64734
|
-
if (
|
|
64735
|
-
else if (typeof item.blob === "string") html = Buffer.from(item.blob, "base64").toString("utf8");
|
|
64736
|
-
else throw new Error(`${uri}: the view has neither text nor blob`);
|
|
64749
|
+
const html = viewHtmlOf(item);
|
|
64750
|
+
if (html === null) throw new Error(`${uri}: the view has neither text nor blob`);
|
|
64737
64751
|
const ui2 = item._meta?.ui;
|
|
64738
64752
|
const csp = ui2?.csp && typeof ui2.csp === "object" ? ui2.csp : void 0;
|
|
64739
64753
|
const permissions = ui2?.permissions && typeof ui2.permissions === "object" ? ui2.permissions : void 0;
|
|
@@ -77435,13 +77449,13 @@ function fillCacheFields(method, result) {
|
|
|
77435
77449
|
const provided = result;
|
|
77436
77450
|
const ttlMs = isValidCacheTtlMs(provided["ttlMs"]) ? provided["ttlMs"] : resolveTtlMs(fallback);
|
|
77437
77451
|
const cacheScope = isValidCacheScope(provided["cacheScope"]) ? provided["cacheScope"] : resolveCacheScope(fallback);
|
|
77438
|
-
const
|
|
77452
|
+
const filled2 = {
|
|
77439
77453
|
...provided,
|
|
77440
77454
|
ttlMs,
|
|
77441
77455
|
cacheScope
|
|
77442
77456
|
};
|
|
77443
|
-
delete
|
|
77444
|
-
return
|
|
77457
|
+
delete filled2[RESULT_CACHE_HINT_FALLBACK];
|
|
77458
|
+
return filled2;
|
|
77445
77459
|
}
|
|
77446
77460
|
function isPlainObject$5(value) {
|
|
77447
77461
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
@@ -82171,7 +82185,6 @@ function resourceUriOf(tool) {
|
|
|
82171
82185
|
}
|
|
82172
82186
|
|
|
82173
82187
|
// packages/agent-host/src/apps/external/check.ts
|
|
82174
|
-
var UI_MIME = "text/html;profile=mcp-app";
|
|
82175
82188
|
var BRIDGE_TAG = "centralu:mcp-app.js";
|
|
82176
82189
|
var problem = (where, message) => ({ level: "problem", where, message });
|
|
82177
82190
|
var warning = (where, message) => ({ level: "warning", where, message });
|
|
@@ -82228,13 +82241,13 @@ function checkScreen(uri, read) {
|
|
|
82228
82241
|
const content = read.contents.find((c) => c.uri === uri) ?? read.contents[0];
|
|
82229
82242
|
if (!content) return { findings: [problem(where, "it was read but came back empty (no contents)")], chars: 0 };
|
|
82230
82243
|
const findings = [];
|
|
82231
|
-
if (content.mimeType
|
|
82232
|
-
findings.push(problem(where, `its mimeType is ${JSON.stringify(content.mimeType ?? null)} \u2014 a screen must be "${
|
|
82244
|
+
if (!isViewMimeType(content.mimeType)) {
|
|
82245
|
+
findings.push(problem(where, `its mimeType is ${JSON.stringify(content.mimeType ?? null)} \u2014 a screen must be "${VIEW_MIME_TYPE}" (centralu.uiResource sets it)`));
|
|
82233
82246
|
}
|
|
82234
|
-
const text2 =
|
|
82235
|
-
if (text2 === null) {
|
|
82247
|
+
const text2 = viewHtmlOf(content);
|
|
82248
|
+
if (text2 === null) return { findings: [...findings, problem(where, "it has neither text nor a blob, so it cannot be shown")], chars: 0 };
|
|
82249
|
+
if (!("text" in content) || typeof content.text !== "string") {
|
|
82236
82250
|
findings.push(warning(where, "the HTML came as a blob, not as text \u2014 Centralu's template sends text"));
|
|
82237
|
-
return { findings, chars: 0 };
|
|
82238
82251
|
}
|
|
82239
82252
|
if (!text2.trim()) findings.push(problem(where, "the HTML is empty"));
|
|
82240
82253
|
if (text2.includes(BRIDGE_TAG)) {
|
|
@@ -85224,13 +85237,13 @@ function fillCacheFields2(method, result) {
|
|
|
85224
85237
|
const provided = result;
|
|
85225
85238
|
const ttlMs = isValidCacheTtlMs2(provided["ttlMs"]) ? provided["ttlMs"] : resolveTtlMs2(fallback);
|
|
85226
85239
|
const cacheScope = isValidCacheScope2(provided["cacheScope"]) ? provided["cacheScope"] : resolveCacheScope2(fallback);
|
|
85227
|
-
const
|
|
85240
|
+
const filled2 = {
|
|
85228
85241
|
...provided,
|
|
85229
85242
|
ttlMs,
|
|
85230
85243
|
cacheScope
|
|
85231
85244
|
};
|
|
85232
|
-
delete
|
|
85233
|
-
return
|
|
85245
|
+
delete filled2[RESULT_CACHE_HINT_FALLBACK2];
|
|
85246
|
+
return filled2;
|
|
85234
85247
|
}
|
|
85235
85248
|
function isPlainObject$42(value) {
|
|
85236
85249
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
@@ -97229,7 +97242,7 @@ var AppProcess = class _AppProcess {
|
|
|
97229
97242
|
});
|
|
97230
97243
|
} catch (e) {
|
|
97231
97244
|
const shim = /\.(cmd|bat)$/i.test(launch2.command) ? " (a .cmd or .bat that is not a package manager shim needs a shell: name the program it starts)" : "";
|
|
97232
|
-
const head = `could not run ${launch2.command}: ${e.message}${shim}
|
|
97245
|
+
const head = spec.redact(`could not run ${launch2.command}: ${e.message}${shim}`);
|
|
97233
97246
|
log.note(head);
|
|
97234
97247
|
log.close();
|
|
97235
97248
|
throw new AppStartError(head, head, []);
|
|
@@ -97244,7 +97257,7 @@ var AppProcess = class _AppProcess {
|
|
|
97244
97257
|
return proc;
|
|
97245
97258
|
} catch (e) {
|
|
97246
97259
|
await proc.waitExit(spec.exitWaitMs);
|
|
97247
|
-
const head = proc.exit ? `exited before it was ready (${describeExit(proc.exit)})` : e.message;
|
|
97260
|
+
const head = proc.exit ? `exited before it was ready (${describeExit(proc.exit)})` : spec.redact(e.message);
|
|
97248
97261
|
const reason = proc.reason(head);
|
|
97249
97262
|
const stderr = proc.log.tailLines();
|
|
97250
97263
|
await proc.stop(0);
|
|
@@ -98529,14 +98542,17 @@ function readZipEntries(buf, maxEntries) {
|
|
|
98529
98542
|
if (name.includes("\uFFFD")) throw new ZipError("An entry name is not UTF-8; re-create the archive with UTF-8 names");
|
|
98530
98543
|
if (flags & 1) throw new ZipError(`Encrypted entries are not supported: ${name}`);
|
|
98531
98544
|
if (compressedSize === 4294967295 || size === 4294967295 || offset === 4294967295) throw new ZipError("ZIP64 archives are not supported");
|
|
98532
|
-
|
|
98545
|
+
const mode = unixMode(madeBy, external);
|
|
98546
|
+
out.push({ name, kind: kindOf(name, mode, external), mode, method, compressedSize, size, crc, offset });
|
|
98533
98547
|
p = nameEnd + extraLen + commentLen;
|
|
98534
98548
|
}
|
|
98535
98549
|
return out;
|
|
98536
98550
|
}
|
|
98537
|
-
function
|
|
98551
|
+
function unixMode(madeBy, external) {
|
|
98538
98552
|
const host = madeBy >> 8;
|
|
98539
|
-
|
|
98553
|
+
return host === 3 || host === 19 ? external >>> 16 : 0;
|
|
98554
|
+
}
|
|
98555
|
+
function kindOf(name, mode, external) {
|
|
98540
98556
|
const type = mode & 61440;
|
|
98541
98557
|
if (type === 40960) return "link";
|
|
98542
98558
|
if (name.endsWith("/") || type === 16384 || (external & 16) !== 0) return "dir";
|
|
@@ -98858,7 +98874,7 @@ function stageZip(buf, dest, limits) {
|
|
|
98858
98874
|
} catch (err) {
|
|
98859
98875
|
throw new ImportRefused(err instanceof ZipError ? err.message : `Could not unpack ${wireJoin(...parts)}: ${err.message}`);
|
|
98860
98876
|
}
|
|
98861
|
-
writeFileSync4(out, data, { mode:
|
|
98877
|
+
writeFileSync4(out, data, { mode: execBits(e.mode) });
|
|
98862
98878
|
}
|
|
98863
98879
|
t.out.files.sort((a, b2) => a.path < b2.path ? -1 : a.path > b2.path ? 1 : 0);
|
|
98864
98880
|
return t.out;
|
|
@@ -99316,7 +99332,7 @@ var AppHandover = class {
|
|
|
99316
99332
|
/** An id that already exists — even a folder standing there with an invalid manifest belongs to the person. Never overwritten (the same rule as a new app) */
|
|
99317
99333
|
refuseTaken(id3) {
|
|
99318
99334
|
this.host.rescanUser();
|
|
99319
|
-
if (this.host.userApp(id3) || existsSync9(join19(this.host.dataRoot,
|
|
99335
|
+
if (this.host.userApp(id3) || existsSync9(join19(this.host.dataRoot, ...USER_APPS_PARTS, id3))) {
|
|
99320
99336
|
throw new ImportRefused(`An app with the id "${id3}" is already in your apps. Remove it first, or change the id in its manifest`);
|
|
99321
99337
|
}
|
|
99322
99338
|
}
|
|
@@ -99897,7 +99913,7 @@ var ExternalApps = class {
|
|
|
99897
99913
|
// ── Discovery ──────────────────────────────────────────────────────────────────────
|
|
99898
99914
|
require(ref) {
|
|
99899
99915
|
const e = this.find(ref);
|
|
99900
|
-
if (!e) throw new AppUnavailableError(
|
|
99916
|
+
if (!e) throw new AppUnavailableError(noSuchAppText(ref));
|
|
99901
99917
|
return e;
|
|
99902
99918
|
}
|
|
99903
99919
|
find(ref) {
|
|
@@ -101172,8 +101188,8 @@ Answer with agent_session(sessionId="${r.sessionId}", action="answer", card=\u20
|
|
|
101172
101188
|
}
|
|
101173
101189
|
var NO_POLLING = "Do not check on it with status meanwhile. With nothing else to do, wait is the one call that blocks until the end:";
|
|
101174
101190
|
var NEW_ROLE_NEW_AGENT = "For another kind of work (say, editing files after read-only research), start a new agent instead, with the task written in full: it starts without this one's context, and this one's name and role came from its first task.";
|
|
101175
|
-
function cleanUpLine(sessionId) {
|
|
101176
|
-
return `Once you have used its answer and need nothing more from it, delete it:
|
|
101191
|
+
function cleanUpLine(sessionId, call2 = `agent_session(sessionId="${sessionId}", action="delete")`) {
|
|
101192
|
+
return `Once you have used its answer and need nothing more from it, delete it: ${call2}. Work not on the trunk is kept in the trash.`;
|
|
101177
101193
|
}
|
|
101178
101194
|
function agentListText(r) {
|
|
101179
101195
|
if (!r.ok) return { text: r.error, isError: true };
|
|
@@ -101749,7 +101765,6 @@ function orchestratorToolSchemas(profile = "orchestrator") {
|
|
|
101749
101765
|
}
|
|
101750
101766
|
|
|
101751
101767
|
// packages/agent-host/src/sessions/orchestrator-tools.ts
|
|
101752
|
-
var filled2 = (v) => v?.trim() ? v.trim() : void 0;
|
|
101753
101768
|
function issuesText(error51) {
|
|
101754
101769
|
return error51.issues.map((i) => `${i.path.join(".") || "(args)"}: ${i.message}`).join("; ");
|
|
101755
101770
|
}
|
|
@@ -101811,20 +101826,20 @@ var HANDLERS = {
|
|
|
101811
101826
|
const project2 = args.project.trim();
|
|
101812
101827
|
if (!project2) return { text: "Give a project \u2014 the name of another Centralu project.", isError: true };
|
|
101813
101828
|
const task = args.task?.trim() ? args.task : void 0;
|
|
101814
|
-
const session2 =
|
|
101829
|
+
const session2 = trimmed(args.session);
|
|
101815
101830
|
const { ifBusy } = args;
|
|
101816
101831
|
return askProjectText(await tools.askProject({ project: project2, ...session2 ? { session: session2 } : {}, ...task ? { task } : {}, ...ifBusy ? { ifBusy } : {} }, signal));
|
|
101817
101832
|
},
|
|
101818
101833
|
async start_agent(args, { tools, signal, caller }) {
|
|
101819
101834
|
const task = args.task.trim() ? args.task : void 0;
|
|
101820
101835
|
if (!task) return { text: "Give a task: what the new session should do.", isError: true };
|
|
101821
|
-
const tool =
|
|
101822
|
-
const model =
|
|
101823
|
-
const effort =
|
|
101836
|
+
const tool = trimmed(args.tool);
|
|
101837
|
+
const model = trimmed(args.model);
|
|
101838
|
+
const effort = trimmed(args.effort);
|
|
101824
101839
|
const { difficulty } = args;
|
|
101825
|
-
const branch =
|
|
101826
|
-
const name =
|
|
101827
|
-
const machine =
|
|
101840
|
+
const branch = trimmed(args.branch);
|
|
101841
|
+
const name = trimmed(args.name);
|
|
101842
|
+
const machine = trimmed(args.machine);
|
|
101828
101843
|
return agentCallsFor(caller, agentRunText(
|
|
101829
101844
|
await tools.startAgent(
|
|
101830
101845
|
{
|
|
@@ -101845,14 +101860,14 @@ var HANDLERS = {
|
|
|
101845
101860
|
));
|
|
101846
101861
|
},
|
|
101847
101862
|
async agent_session(args, { tools, signal, caller }) {
|
|
101848
|
-
const sessionId =
|
|
101863
|
+
const sessionId = trimmed(args.sessionId);
|
|
101849
101864
|
const { action, ifBusy } = args;
|
|
101850
101865
|
if (action === "list") return agentCallsFor(caller, agentListText(await tools.listAgents()));
|
|
101851
101866
|
if (!sessionId) return { text: "Give the sessionId start_agent returned.", isError: true };
|
|
101852
101867
|
const text2 = args.text?.trim() ? args.text : void 0;
|
|
101853
101868
|
if (action === "send" && !text2) return { text: "Give text: what to send it.", isError: true };
|
|
101854
101869
|
if (action === "answer" && !text2) return { text: "Give text: the answer.", isError: true };
|
|
101855
|
-
const card =
|
|
101870
|
+
const card = trimmed(args.card);
|
|
101856
101871
|
return agentCallsFor(caller, agentRunText(await tools.agentSession({ sessionId, action, ...text2 ? { text: text2 } : {}, ...card ? { card } : {}, ...ifBusy ? { ifBusy } : {} }, signal)));
|
|
101857
101872
|
},
|
|
101858
101873
|
async recall({ query, limit }, { tools }) {
|
|
@@ -101872,13 +101887,13 @@ Not searched: ${r.notSearched.join("; ")}.` : "";
|
|
|
101872
101887
|
const sessionId = args.sessionId.trim();
|
|
101873
101888
|
const text2 = args.text.trim();
|
|
101874
101889
|
if (!sessionId || !text2) return { text: "Give sessionId and text: the session and your answer.", isError: true };
|
|
101875
|
-
const card =
|
|
101890
|
+
const card = trimmed(args.card);
|
|
101876
101891
|
const r = await tools.answerQuestion({ sessionId, text: text2, ...card ? { card } : {} });
|
|
101877
101892
|
if (!r.ok) return { text: r.error, isError: true };
|
|
101878
101893
|
return { text: `Answered card ${r.state === "answered" ? r.card : ""} in "${r.sessionName}" [${r.sessionId}]; it goes on.` };
|
|
101879
101894
|
},
|
|
101880
101895
|
async read_session(args, { tools, caller }) {
|
|
101881
|
-
if (caller.profile === "reader" && !args.sessionId) return listSessionsText(tools, caller,
|
|
101896
|
+
if (caller.profile === "reader" && !args.sessionId) return listSessionsText(tools, caller, trimmed(args.project));
|
|
101882
101897
|
const r = await tools.readSession(args.sessionId ?? "", args.limit, {
|
|
101883
101898
|
around: args.around,
|
|
101884
101899
|
tools: args.tools === true
|
|
@@ -101897,12 +101912,12 @@ ${cardsText(r.cards)}
|
|
|
101897
101912
|
},
|
|
101898
101913
|
async create_project(args, { tools, signal }) {
|
|
101899
101914
|
const folder = args.name ?? "";
|
|
101900
|
-
const git2 =
|
|
101915
|
+
const git2 = trimmed(args.git);
|
|
101901
101916
|
if (!folder.trim() && !git2) return { text: "Give a name \u2014 the new folder is named by it, and so is the project.", isError: true };
|
|
101902
|
-
const parent =
|
|
101903
|
-
const branch = git2 ?
|
|
101917
|
+
const parent = trimmed(args.parent);
|
|
101918
|
+
const branch = git2 ? trimmed(args.branch) : void 0;
|
|
101904
101919
|
const source = git2 ? { git: git2, ...branch ? { branch } : {} } : void 0;
|
|
101905
|
-
const machine =
|
|
101920
|
+
const machine = trimmed(args.machine);
|
|
101906
101921
|
const r = await tools.createProject({ name: folder, ...parent ? { parent } : {}, ...source ? { source } : {}, ...machine ? { machine } : {} }, signal);
|
|
101907
101922
|
if (!r.ok) return { text: `No project was made: ${r.error}`, isError: true };
|
|
101908
101923
|
return {
|
|
@@ -101911,7 +101926,7 @@ ${cardsText(r.cards)}
|
|
|
101911
101926
|
},
|
|
101912
101927
|
async handoff_session(args, { tools, caller, signal }) {
|
|
101913
101928
|
const sessionId = args.sessionId?.trim() ?? "";
|
|
101914
|
-
const waitFor =
|
|
101929
|
+
const waitFor = trimmed(args.waitFor);
|
|
101915
101930
|
if (!sessionId && !waitFor) return { text: "Give sessionId: the session to hand off, from list_sessions.", isError: true };
|
|
101916
101931
|
const { tool, mode } = args;
|
|
101917
101932
|
const instructions = args.instructions?.trim() ? args.instructions : void 0;
|
|
@@ -101955,7 +101970,7 @@ ${cardsText(r.cards)}
|
|
|
101955
101970
|
return { text: r.text };
|
|
101956
101971
|
},
|
|
101957
101972
|
async create_app(args, { tools }) {
|
|
101958
|
-
const spec = { id: args.id.trim(), name: args.name.trim(), project:
|
|
101973
|
+
const spec = { id: args.id.trim(), name: args.name.trim(), project: trimmed(args.project), description: args.description, tool: args.tool };
|
|
101959
101974
|
if (!spec.id || !spec.name) return { text: "Give id and name \u2014 a folder name and a name to show the person are needed for the app to stand.", isError: true };
|
|
101960
101975
|
const r = await tools.createApp(spec);
|
|
101961
101976
|
if (!r.ok) return { text: `Could not create it \u2014 ${r.error}`, isError: true };
|
|
@@ -102335,10 +102350,15 @@ async function isRepo(cwd) {
|
|
|
102335
102350
|
try {
|
|
102336
102351
|
await git(cwd, ["rev-parse", "--git-dir"]);
|
|
102337
102352
|
return true;
|
|
102338
|
-
} catch {
|
|
102339
|
-
return false;
|
|
102353
|
+
} catch (e) {
|
|
102354
|
+
if (notARepository(e)) return false;
|
|
102355
|
+
throw e;
|
|
102340
102356
|
}
|
|
102341
102357
|
}
|
|
102358
|
+
function notARepository(e) {
|
|
102359
|
+
const err = e;
|
|
102360
|
+
return /not a git repository/i.test(String(err.stderr || err.message || "")) || err.code === "ENOENT";
|
|
102361
|
+
}
|
|
102342
102362
|
var SUMMARY_CAP = 1e4;
|
|
102343
102363
|
async function gitSummary(cwd, trust = {}, limits = {}) {
|
|
102344
102364
|
const cap = limits.cap ?? SUMMARY_CAP;
|
|
@@ -102374,7 +102394,7 @@ async function gitSummary(cwd, trust = {}, limits = {}) {
|
|
|
102374
102394
|
const err = e;
|
|
102375
102395
|
const msg = String(err.stderr || err.message || "");
|
|
102376
102396
|
if (/Operation not permitted|EPERM|EACCES|permission denied/i.test(msg)) return { isRepo: true, branch: "", changedFiles: 0, denied: true };
|
|
102377
|
-
if (
|
|
102397
|
+
if (notARepository(e)) return { isRepo: false, branch: "", changedFiles: 0 };
|
|
102378
102398
|
return { isRepo: true, branch: "", changedFiles: 0, unknown: true };
|
|
102379
102399
|
}
|
|
102380
102400
|
}
|
|
@@ -103003,8 +103023,8 @@ var WorktreeSessions = class {
|
|
|
103003
103023
|
const fromTrunk = trunk && await gitRevParse(params.cwd, trunk) ? trunk : null;
|
|
103004
103024
|
if (trunk && !fromTrunk) console.error(`[worktree] trunk not found, forking from HEAD instead: ${trunk}`);
|
|
103005
103025
|
const from = asked ?? fromTrunk;
|
|
103006
|
-
const baseSha = from ? await gitRevParse(params.cwd, from) : await gitHeadSha(params.cwd);
|
|
103007
103026
|
try {
|
|
103027
|
+
const baseSha = from ? await gitRevParse(params.cwd, from) : await gitHeadSha(params.cwd);
|
|
103008
103028
|
worktree = await gitWorktreeAdd(params.cwd, path2, branch, from ?? void 0, { trusted: true });
|
|
103009
103029
|
if (baseSha) worktree = { ...worktree, base: baseSha };
|
|
103010
103030
|
} catch (err) {
|
|
@@ -103753,7 +103773,7 @@ ${text2}` : text2 });
|
|
|
103753
103773
|
const remote = remoteOf(sessionId);
|
|
103754
103774
|
if (remote) {
|
|
103755
103775
|
const earlier = host.children.linkedReports.get(sessionId);
|
|
103756
|
-
const mine = reportBack ? { orchestratorId, busy: false } : void 0;
|
|
103776
|
+
const mine = reportBack ? { orchestratorId, busy: false, instruction: text2 } : void 0;
|
|
103757
103777
|
if (mine) host.children.setLinkedReport(sessionId, mine);
|
|
103758
103778
|
const r = await remote.send(sessionId, text2, host.meta.get(orchestratorId)?.name ?? "Orchestrator");
|
|
103759
103779
|
const current = host.children.linkedReports.get(sessionId);
|
|
@@ -103769,6 +103789,10 @@ ${text2}` : text2 });
|
|
|
103769
103789
|
} else if (mine) failedSends.add(mine);
|
|
103770
103790
|
return r;
|
|
103771
103791
|
}
|
|
103792
|
+
if (mine?.instruction !== void 0) {
|
|
103793
|
+
console.error(`[links] ${sessionId}: the machine's record of the instruction was not heard; the next turn end reports`);
|
|
103794
|
+
delete mine.instruction;
|
|
103795
|
+
}
|
|
103772
103796
|
if (!reportBack && earlier?.orchestratorId === orchestratorId && current === earlier) host.children.dropLinkedReport(sessionId);
|
|
103773
103797
|
return { ok: true };
|
|
103774
103798
|
}
|
|
@@ -106790,7 +106814,7 @@ var RemoteAgents = class {
|
|
|
106790
106814
|
this.save([...this.records(), rec]);
|
|
106791
106815
|
const waiting = opts.wait === false ? void 0 : this.openWait(rec.sessionId);
|
|
106792
106816
|
if (!waiting) this.host.children.setLinkedReport(rec.sessionId, { orchestratorId: callerId, busy: false });
|
|
106793
|
-
const label = labelOf(this.host.store, caller);
|
|
106817
|
+
const label = labelOf(this.host.store.messages, caller);
|
|
106794
106818
|
const sent = await reader.send(rec.sessionId, remoteAgentFrame(label, opts.task), label, { depth: depthOf(this.host, callerId) + 1 });
|
|
106795
106819
|
if (!sent.ok) {
|
|
106796
106820
|
if (waiting && this.waits.get(rec.sessionId) === waiting) this.waits.delete(rec.sessionId);
|
|
@@ -106812,7 +106836,7 @@ var RemoteAgents = class {
|
|
|
106812
106836
|
if (rec.callerId !== callerId) return { ok: false, error: `${rec.sessionId} is not a session this session started. agent_session works only on sessions start_agent started from here.` };
|
|
106813
106837
|
const reader = this.host.linkedReader;
|
|
106814
106838
|
if (!reader) return { ok: false, error: `${rec.sessionId} is on ${rec.machine}, and no machine is linked to this computer now.` };
|
|
106815
|
-
const label = labelOf(this.host.store, this.host.meta.get(callerId));
|
|
106839
|
+
const label = labelOf(this.host.store.messages, this.host.meta.get(callerId));
|
|
106816
106840
|
const stateOf = async () => {
|
|
106817
106841
|
const r = await reader.read(rec.sessionId, 1);
|
|
106818
106842
|
return r.ok ? { ok: true, state: r.state ?? "idle" } : { ok: false, error: `${rec.machine} cannot be asked about "${rec.name}" now: ${r.error ?? "no answer"}` };
|
|
@@ -107084,8 +107108,10 @@ var RemoteAgents = class {
|
|
|
107084
107108
|
}
|
|
107085
107109
|
};
|
|
107086
107110
|
|
|
107087
|
-
// packages/agent-host/src/sessions/
|
|
107111
|
+
// packages/agent-host/src/sessions/hub-sender.ts
|
|
107088
107112
|
var HUB_SENDER = "_hub-orchestrator";
|
|
107113
|
+
|
|
107114
|
+
// packages/agent-host/src/sessions/delegation-flow.ts
|
|
107089
107115
|
var DelegationFlow = class {
|
|
107090
107116
|
constructor(host) {
|
|
107091
107117
|
this.host = host;
|
|
@@ -107252,8 +107278,9 @@ var DelegationFlow = class {
|
|
|
107252
107278
|
};
|
|
107253
107279
|
|
|
107254
107280
|
// packages/agent-host/src/sessions/child-reports.ts
|
|
107255
|
-
function pausedReportLine(running2,
|
|
107256
|
-
return `[Centralu] The assigned work paused: its turn ended while its own background work is still running (${taskList(running2)}). If that work is a server or watcher it leaves running, the answer below may be its final one. A final report follows only if that work ends` + (
|
|
107281
|
+
function pausedReportLine(running2, stop) {
|
|
107282
|
+
return `[Centralu] The assigned work paused: its turn ended while its own background work is still running (${taskList(running2)}). If that work is a server or watcher it leaves running, the answer below may be its final one. A final report follows only if that work ends` + (stop ? `; ${stop} on it stops that work and ends the wait.
|
|
107283
|
+
` : ".\n");
|
|
107257
107284
|
}
|
|
107258
107285
|
function linkLostReportLine(machine, paused) {
|
|
107259
107286
|
return `[Centralu] The assigned work paused on its own background work (${taskList(paused)}), and the link to ${frameField(machine)} dropped before that work ended, so its end will not be reported. It may still be running there; read the session once the link is back.
|
|
@@ -107382,7 +107409,7 @@ var ChildReports = class {
|
|
|
107382
107409
|
async deliverReport(orchestratorId, sessionId, name, project2, preview, ending, work) {
|
|
107383
107410
|
const stop = this.host.meta.get(sessionId)?.interruption;
|
|
107384
107411
|
const cutShort = stop?.reason === "network" || stop?.reason === "interrupted" || stop?.reason === "quit";
|
|
107385
|
-
const outcome = work && "machineRemoved" in work ? machineRemovedReportLine(work.machineRemoved, work.paused) : work && "linkLost" in work ? linkLostReportLine(work.linkLost, work.paused) : work && "paused" in work ? pausedReportLine(work.paused, work.stoppable) : work && "settled" in work ? settledReportLine(work.settled) : stop?.reason === "network" ? `[Centralu] The assigned work stopped before finishing: a network error ended its turn.
|
|
107412
|
+
const outcome = work && "machineRemoved" in work ? machineRemovedReportLine(work.machineRemoved, work.paused) : work && "linkLost" in work ? linkLostReportLine(work.linkLost, work.paused) : work && "paused" in work ? pausedReportLine(work.paused, work.stoppable ? this.agentCall(orchestratorId, { action: "stop" }) : void 0) : work && "settled" in work ? settledReportLine(work.settled) : stop?.reason === "network" ? `[Centralu] The assigned work stopped before finishing: a network error ended its turn.
|
|
107386
107413
|
` : stop?.reason === "interrupted" ? `[Centralu] The assigned work stopped before finishing: its tool interrupted the turn.
|
|
107387
107414
|
` : stop?.reason === "quit" ? `[Centralu] The assigned work stopped before finishing: Centralu quit or restarted during its turn.
|
|
107388
107415
|
` : ending.type === "error" ? `[Centralu] The assigned work failed.
|
|
@@ -107423,8 +107450,17 @@ If you need more, you can read that session's recent conversation with read_sess
|
|
|
107423
107450
|
if (!child || !cleanUpDue(child, parentId)) return "";
|
|
107424
107451
|
const others = ownAgents(this.host, parentId).filter((s) => s.id !== childId && agentState(this.host, s) === "finished").length;
|
|
107425
107452
|
return `
|
|
107426
|
-
${cleanUpLine(childId)}` + (others ? `
|
|
107427
|
-
${others} other finished session${others === 1 ? "" : "s"} you started remain${others === 1 ? "s" : ""}:
|
|
107453
|
+
${cleanUpLine(childId, this.agentCall(parentId, { sessionId: childId, action: "delete" }))}` + (others ? `
|
|
107454
|
+
${others} other finished session${others === 1 ? "" : "s"} you started remain${others === 1 ? "s" : ""}: ${this.agentCall(parentId, { action: "list" })} shows them.` : "");
|
|
107455
|
+
}
|
|
107456
|
+
/**
|
|
107457
|
+
* An agent_session call a report names, in the form its receiver calls it (#850): the orchestrator reaches agent_session
|
|
107458
|
+
* only through centralu_run in the `commands` tier, where the bare call it would copy from the report is refused. A
|
|
107459
|
+
* seat without the tool keeps the bare form the reports always named.
|
|
107460
|
+
*/
|
|
107461
|
+
agentCall(receiverId, args) {
|
|
107462
|
+
const bare2 = `agent_session(${Object.entries(args).map(([k2, v]) => `${k2}=${JSON.stringify(v)}`).join(", ")})`;
|
|
107463
|
+
return callForm(this.host.toolProfileOf(receiverId), "agent_session", args) ?? bare2;
|
|
107428
107464
|
}
|
|
107429
107465
|
/**
|
|
107430
107466
|
* Tells a session something in its conversation (#428): a report, or Centralu's word on a request, a note or a queued
|
|
@@ -108746,7 +108782,7 @@ function failure(text2) {
|
|
|
108746
108782
|
|
|
108747
108783
|
// packages/agent-host/src/sessions/app-access.ts
|
|
108748
108784
|
var KEY = (sessionId) => `session_apps:${sessionId}`;
|
|
108749
|
-
var SHARED_KEY = (ref) => `app_shared:${ref.projectId
|
|
108785
|
+
var SHARED_KEY = (ref) => `app_shared:${appKeyOf(ref.projectId, ref.appId)}`;
|
|
108750
108786
|
var UNUSABLE2 = /* @__PURE__ */ new Set(["invalid", "untrusted", "unconfirmed", "failed"]);
|
|
108751
108787
|
function readShared(store2, ref) {
|
|
108752
108788
|
return ref.projectId !== null && store2.appSetting(SHARED_KEY({ projectId: ref.projectId, appId: ref.appId })) === "1";
|
|
@@ -108902,7 +108938,7 @@ var AppAccess = class {
|
|
|
108902
108938
|
return { ok: true, app: app2 };
|
|
108903
108939
|
}
|
|
108904
108940
|
match(mine, ref) {
|
|
108905
|
-
return mine.find((r) => r.server === ref || this.refOf(r) === ref || r.projectId !== null &&
|
|
108941
|
+
return mine.find((r) => r.server === ref || this.refOf(r) === ref || r.projectId !== null && appKeyOf(r.projectId, r.appId) === ref) ?? mine.find((r) => r.appId === ref);
|
|
108906
108942
|
}
|
|
108907
108943
|
describe(a) {
|
|
108908
108944
|
const known = this.deps.hub.rt.knownTools({ projectId: a.projectId, appId: a.appId }, "model");
|
|
@@ -110656,6 +110692,10 @@ ${attachments.map((a) => `@${a.path}`).join("\n")}` : text2;
|
|
|
110656
110692
|
};
|
|
110657
110693
|
|
|
110658
110694
|
// packages/agent-host/src/sessions/linked-reports.ts
|
|
110695
|
+
function fromHub(from) {
|
|
110696
|
+
const id3 = from?.sessionId;
|
|
110697
|
+
return typeof id3 === "string" && id3.endsWith(`.${HUB_SENDER}`);
|
|
110698
|
+
}
|
|
110659
110699
|
var LinkedReports = class {
|
|
110660
110700
|
constructor(host) {
|
|
110661
110701
|
this.host = host;
|
|
@@ -110701,6 +110741,10 @@ var LinkedReports = class {
|
|
|
110701
110741
|
if (wait.paused) this.settleLater(sessionId, wait);
|
|
110702
110742
|
return;
|
|
110703
110743
|
}
|
|
110744
|
+
if (wait.instruction !== void 0) {
|
|
110745
|
+
if (e.type === "user_message" && e.text === wait.instruction && fromHub(e.from)) delete wait.instruction;
|
|
110746
|
+
return;
|
|
110747
|
+
}
|
|
110704
110748
|
const step = linkedTurnEnd(wait.busy, e);
|
|
110705
110749
|
if (step?.step === "busy") {
|
|
110706
110750
|
wait.busy = true;
|
|
@@ -111622,7 +111666,7 @@ function isCentraluTool(call2, tool) {
|
|
|
111622
111666
|
return call2.tool === tool && (!call2.server || call2.server === ORCHESTRATOR_MCP_NAME);
|
|
111623
111667
|
}
|
|
111624
111668
|
function centraluRunCommand(args) {
|
|
111625
|
-
const command =
|
|
111669
|
+
const command = str(args.command).trim();
|
|
111626
111670
|
if (!/^[a-z]+(?:_[a-z]+)*$/.test(command)) return null;
|
|
111627
111671
|
return { command, args: jsonObject(args.args) };
|
|
111628
111672
|
}
|
|
@@ -111819,16 +111863,16 @@ var ClaudeSchedules = class _ClaudeSchedules {
|
|
|
111819
111863
|
push(m) {
|
|
111820
111864
|
const content = m.message?.content ?? [];
|
|
111821
111865
|
if (!Array.isArray(content)) return this.prune();
|
|
111822
|
-
if (
|
|
111866
|
+
if (str(m.type) === "assistant") {
|
|
111823
111867
|
for (const b2 of content) {
|
|
111824
|
-
if (
|
|
111868
|
+
if (str(b2.type) === "tool_use" && SCHEDULE_TOOLS.has(str(b2.name))) this.calls.set(str(b2.id), { name: str(b2.name), input: b2.input ?? {} });
|
|
111825
111869
|
}
|
|
111826
111870
|
return this.prune();
|
|
111827
111871
|
}
|
|
111828
|
-
const results = content.filter((b2) =>
|
|
111872
|
+
const results = content.filter((b2) => str(b2.type) === "tool_result");
|
|
111829
111873
|
let changed = this.prune();
|
|
111830
111874
|
for (const b2 of results) {
|
|
111831
|
-
const id3 =
|
|
111875
|
+
const id3 = str(b2.tool_use_id);
|
|
111832
111876
|
const call2 = this.calls.get(id3);
|
|
111833
111877
|
if (!call2) continue;
|
|
111834
111878
|
this.calls.delete(id3);
|
|
@@ -111848,32 +111892,32 @@ var ClaudeSchedules = class _ClaudeSchedules {
|
|
|
111848
111892
|
}
|
|
111849
111893
|
const asked = typeof call2.input.delaySeconds === "number" ? Math.min(Math.max(call2.input.delaySeconds, 60), WAKEUP_MAX_S) : WAKEUP_MAX_S;
|
|
111850
111894
|
const due2 = typeof out.scheduledFor === "number" ? out.scheduledFor : now + asked * 1e3;
|
|
111851
|
-
const reason =
|
|
111895
|
+
const reason = str(call2.input.reason);
|
|
111852
111896
|
this.wakeups.set(callId, { id: `schedule-wakeup-${callId}`, due: due2, description: `Wakes itself at ${clock(due2)} (/loop)${reason ? `: ${reason}` : ""}` });
|
|
111853
111897
|
return true;
|
|
111854
111898
|
}
|
|
111855
111899
|
if (call2.name === "CronCreate") {
|
|
111856
|
-
const jobId =
|
|
111857
|
-
if (!
|
|
111858
|
-
const when =
|
|
111900
|
+
const jobId = str(out.id) || callId;
|
|
111901
|
+
if (!str(out.id)) this.unnamed.add(jobId);
|
|
111902
|
+
const when = str(out.humanSchedule) || str(call2.input.cron);
|
|
111859
111903
|
this.crons.set(jobId, { id: `schedule-cron-${jobId}`, due: now + CRON_EXPIRY_MS, description: `Scheduled prompt, ${when}` });
|
|
111860
111904
|
return true;
|
|
111861
111905
|
}
|
|
111862
111906
|
if (call2.name === "CronDelete") {
|
|
111863
|
-
if (this.crons.delete(
|
|
111907
|
+
if (this.crons.delete(str(call2.input.id) || str(out.id))) return true;
|
|
111864
111908
|
const guess = [...this.unnamed].find((k2) => this.crons.has(k2));
|
|
111865
111909
|
if (!guess) return false;
|
|
111866
111910
|
this.unnamed.delete(guess);
|
|
111867
111911
|
return this.crons.delete(guess);
|
|
111868
111912
|
}
|
|
111869
111913
|
if (call2.name === "CronList" && Array.isArray(out.jobs)) {
|
|
111870
|
-
const listed = new Set(out.jobs.map((j2) =>
|
|
111914
|
+
const listed = new Set(out.jobs.map((j2) => str(j2.id)));
|
|
111871
111915
|
let changed = false;
|
|
111872
111916
|
for (const id3 of [...this.crons.keys()]) if (!listed.has(id3)) changed = this.crons.delete(id3) || changed;
|
|
111873
111917
|
for (const j2 of out.jobs) {
|
|
111874
|
-
const id3 =
|
|
111918
|
+
const id3 = str(j2.id);
|
|
111875
111919
|
if (!id3 || this.crons.has(id3)) continue;
|
|
111876
|
-
this.crons.set(id3, { id: `schedule-cron-${id3}`, due: now + CRON_EXPIRY_MS, description: `Scheduled prompt, ${
|
|
111920
|
+
this.crons.set(id3, { id: `schedule-cron-${id3}`, due: now + CRON_EXPIRY_MS, description: `Scheduled prompt, ${str(j2.humanSchedule) || str(j2.cron)}` });
|
|
111877
111921
|
changed = true;
|
|
111878
111922
|
}
|
|
111879
111923
|
return changed;
|
|
@@ -111938,6 +111982,34 @@ var ClaudeSchedules = class _ClaudeSchedules {
|
|
|
111938
111982
|
}
|
|
111939
111983
|
};
|
|
111940
111984
|
|
|
111985
|
+
// packages/agent-host/src/adapters/background-events.ts
|
|
111986
|
+
var BACKGROUND_SUMMARY_CHARS = 300;
|
|
111987
|
+
function endedSummary(text2) {
|
|
111988
|
+
const summary = (text2 ?? "").slice(0, BACKGROUND_SUMMARY_CHARS);
|
|
111989
|
+
return summary ? { summary } : {};
|
|
111990
|
+
}
|
|
111991
|
+
var BackgroundEvents = class {
|
|
111992
|
+
constructor(sessionId) {
|
|
111993
|
+
this.sessionId = sessionId;
|
|
111994
|
+
}
|
|
111995
|
+
sessionId;
|
|
111996
|
+
last = "[]";
|
|
111997
|
+
event(live2, ended = [], snapshot2 = false) {
|
|
111998
|
+
const key = JSON.stringify(live2);
|
|
111999
|
+
if (key === this.last && ended.length === 0 && !snapshot2) return [];
|
|
112000
|
+
this.last = key;
|
|
112001
|
+
return [
|
|
112002
|
+
{
|
|
112003
|
+
type: "background_tasks",
|
|
112004
|
+
...snapshot2 ? { snapshot: true } : {},
|
|
112005
|
+
sessionId: this.sessionId,
|
|
112006
|
+
live: live2,
|
|
112007
|
+
...ended.length ? { ended } : {}
|
|
112008
|
+
}
|
|
112009
|
+
];
|
|
112010
|
+
}
|
|
112011
|
+
};
|
|
112012
|
+
|
|
111941
112013
|
// packages/agent-host/src/adapters/claude/background-tracker.ts
|
|
111942
112014
|
function taskKind(type) {
|
|
111943
112015
|
if (/agent|teammate/.test(type)) return "agent";
|
|
@@ -111946,11 +112018,6 @@ function taskKind(type) {
|
|
|
111946
112018
|
return "other";
|
|
111947
112019
|
}
|
|
111948
112020
|
var ClaudeBackgroundTracker = class {
|
|
111949
|
-
constructor(sessionId, now = Date.now) {
|
|
111950
|
-
this.sessionId = sessionId;
|
|
111951
|
-
this.schedules = new ClaudeSchedules(now);
|
|
111952
|
-
}
|
|
111953
|
-
sessionId;
|
|
111954
112021
|
/** Ids in the last level, in its order. */
|
|
111955
112022
|
live = [];
|
|
111956
112023
|
/** Every id the level ever listed — only those are background work (a foreground task's ending is its card's). */
|
|
@@ -111958,6 +112025,12 @@ var ClaudeBackgroundTracker = class {
|
|
|
111958
112025
|
info = /* @__PURE__ */ new Map();
|
|
111959
112026
|
/** Timers the CLI holds in this process for the session (`ClaudeSchedules`), listed with the tasks */
|
|
111960
112027
|
schedules;
|
|
112028
|
+
/** The events, by the rule both adapters share (`BackgroundEvents`): a repeat of the last list is not sent */
|
|
112029
|
+
events;
|
|
112030
|
+
constructor(sessionId, now = Date.now) {
|
|
112031
|
+
this.schedules = new ClaudeSchedules(now);
|
|
112032
|
+
this.events = new BackgroundEvents(sessionId);
|
|
112033
|
+
}
|
|
111961
112034
|
/** When the earliest scheduled wake-up is due (epoch ms), for a look then (`tick`); null with none */
|
|
111962
112035
|
nextDue() {
|
|
111963
112036
|
return this.schedules.nextDue();
|
|
@@ -111967,7 +112040,7 @@ var ClaudeBackgroundTracker = class {
|
|
|
111967
112040
|
* (`ClaudeSchedules.recover`); the new level when that found any
|
|
111968
112041
|
*/
|
|
111969
112042
|
recover(messages2) {
|
|
111970
|
-
return this.schedules.recover(messages2) ?
|
|
112043
|
+
return this.schedules.recover(messages2) ? this.event() : [];
|
|
111971
112044
|
}
|
|
111972
112045
|
/**
|
|
111973
112046
|
* The tasks the previous host last saw running in an adopted process (#648, `ProcessSource.adopt.backgroundTasks`).
|
|
@@ -111993,66 +112066,65 @@ var ClaudeBackgroundTracker = class {
|
|
|
111993
112066
|
}
|
|
111994
112067
|
/** Drops the wake-ups whose time has passed; the new level when that changed anything */
|
|
111995
112068
|
tick() {
|
|
111996
|
-
return this.schedules.prune() ?
|
|
112069
|
+
return this.schedules.prune() ? this.event() : [];
|
|
111997
112070
|
}
|
|
111998
112071
|
push(m) {
|
|
111999
|
-
if (
|
|
112072
|
+
if (str(m.type) === "assistant" || str(m.type) === "user") {
|
|
112000
112073
|
const changed = this.schedules.push(m);
|
|
112001
|
-
return changed ?
|
|
112074
|
+
return changed ? this.event() : [];
|
|
112002
112075
|
}
|
|
112003
|
-
if (
|
|
112004
|
-
const subtype =
|
|
112076
|
+
if (str(m.type) !== "system") return [];
|
|
112077
|
+
const subtype = str(m.subtype);
|
|
112005
112078
|
if (subtype === "background_tasks_changed") {
|
|
112006
112079
|
const tasks = Array.isArray(m.tasks) ? m.tasks : [];
|
|
112007
112080
|
this.live = [];
|
|
112008
112081
|
for (const t of tasks) {
|
|
112009
|
-
const id3 =
|
|
112082
|
+
const id3 = str(t.task_id);
|
|
112010
112083
|
if (!id3) continue;
|
|
112011
112084
|
const prev = this.info.get(id3);
|
|
112012
112085
|
this.info.set(id3, {
|
|
112013
112086
|
...prev,
|
|
112014
|
-
kind: taskKind(
|
|
112015
|
-
description:
|
|
112087
|
+
kind: taskKind(str(t.task_type)),
|
|
112088
|
+
description: str(t.description, prev?.description ?? ""),
|
|
112016
112089
|
...t.ambient === true ? { ambient: true } : { ambient: void 0 }
|
|
112017
112090
|
});
|
|
112018
112091
|
this.live.push(id3);
|
|
112019
112092
|
this.seen.add(id3);
|
|
112020
112093
|
}
|
|
112021
|
-
return
|
|
112094
|
+
return this.event(void 0, true);
|
|
112022
112095
|
}
|
|
112023
112096
|
if (subtype === "task_started" || subtype === "task_updated") {
|
|
112024
|
-
const id3 =
|
|
112097
|
+
const id3 = str(m.task_id);
|
|
112025
112098
|
const prev = this.info.get(id3);
|
|
112026
112099
|
if (!id3) return [];
|
|
112027
112100
|
if (subtype === "task_started") {
|
|
112028
|
-
const callId =
|
|
112101
|
+
const callId = str(m.tool_use_id);
|
|
112029
112102
|
const depth = typeof m.spawn_depth === "number" ? m.spawn_depth : 1;
|
|
112030
112103
|
this.info.set(id3, {
|
|
112031
112104
|
...prev,
|
|
112032
|
-
kind:
|
|
112033
|
-
description: prev?.description ||
|
|
112105
|
+
kind: str(m.task_type) ? taskKind(str(m.task_type)) : prev?.kind ?? "other",
|
|
112106
|
+
description: prev?.description || str(m.description),
|
|
112034
112107
|
...callId ? { parentCallId: callId } : {},
|
|
112035
112108
|
...m.owned_by_subagent === true || depth > 1 ? { nested: true } : {},
|
|
112036
112109
|
...m.ambient === true ? { ambient: true } : {}
|
|
112037
112110
|
});
|
|
112038
112111
|
} else {
|
|
112039
|
-
const description =
|
|
112112
|
+
const description = str(m.patch?.description);
|
|
112040
112113
|
if (!prev || !description) return [];
|
|
112041
112114
|
this.info.set(id3, { ...prev, description });
|
|
112042
112115
|
}
|
|
112043
|
-
return this.live.includes(id3) ?
|
|
112116
|
+
return this.live.includes(id3) ? this.event() : [];
|
|
112044
112117
|
}
|
|
112045
112118
|
if (subtype === "task_notification") {
|
|
112046
|
-
const id3 =
|
|
112119
|
+
const id3 = str(m.task_id);
|
|
112047
112120
|
const known = this.info.get(id3);
|
|
112048
112121
|
this.info.delete(id3);
|
|
112049
112122
|
if (!this.seen.has(id3)) return [];
|
|
112050
112123
|
this.seen.delete(id3);
|
|
112051
112124
|
this.live = this.live.filter((x) => x !== id3);
|
|
112052
|
-
const raw =
|
|
112125
|
+
const raw = str(m.status);
|
|
112053
112126
|
const status = raw === "failed" || raw === "stopped" ? raw : "completed";
|
|
112054
|
-
|
|
112055
|
-
return [this.event([{ ...this.entry(id3, known), status, ...summary ? { summary } : {} }])];
|
|
112127
|
+
return this.event([{ ...this.entry(id3, known), status, ...endedSummary(str(m.summary)) }]);
|
|
112056
112128
|
}
|
|
112057
112129
|
return [];
|
|
112058
112130
|
}
|
|
@@ -112068,7 +112140,7 @@ var ClaudeBackgroundTracker = class {
|
|
|
112068
112140
|
this.live = [];
|
|
112069
112141
|
this.info.clear();
|
|
112070
112142
|
this.seen.clear();
|
|
112071
|
-
return
|
|
112143
|
+
return this.event(ended);
|
|
112072
112144
|
}
|
|
112073
112145
|
entry(id3, i) {
|
|
112074
112146
|
const kind = i?.kind ?? "other";
|
|
@@ -112085,20 +112157,14 @@ var ClaudeBackgroundTracker = class {
|
|
|
112085
112157
|
};
|
|
112086
112158
|
}
|
|
112087
112159
|
event(ended, snapshot2) {
|
|
112088
|
-
return
|
|
112089
|
-
type: "background_tasks",
|
|
112090
|
-
...snapshot2 ? { snapshot: snapshot2 } : {},
|
|
112091
|
-
sessionId: this.sessionId,
|
|
112092
|
-
live: [...this.live.map((id3) => this.entry(id3, this.info.get(id3))), ...this.schedules.live()],
|
|
112093
|
-
...ended ? { ended } : {}
|
|
112094
|
-
};
|
|
112160
|
+
return this.events.event([...this.live.map((id3) => this.entry(id3, this.info.get(id3))), ...this.schedules.live()], ended, snapshot2);
|
|
112095
112161
|
}
|
|
112096
112162
|
};
|
|
112097
112163
|
|
|
112098
112164
|
// packages/agent-host/src/adapters/claude/cli-messages.ts
|
|
112099
112165
|
function conversationResetEvents(m, sessionId) {
|
|
112100
112166
|
const out = [];
|
|
112101
|
-
const trigger =
|
|
112167
|
+
const trigger = str(m.trigger);
|
|
112102
112168
|
out.push({ type: "conversation_reset", sessionId, ...trigger ? { trigger } : {} });
|
|
112103
112169
|
return out;
|
|
112104
112170
|
}
|
|
@@ -112109,16 +112175,16 @@ function activeGoalEvents(m, sessionId) {
|
|
|
112109
112175
|
type: "goal",
|
|
112110
112176
|
sessionId,
|
|
112111
112177
|
goal: v ? {
|
|
112112
|
-
objective:
|
|
112178
|
+
objective: str(v.condition),
|
|
112113
112179
|
status: "active",
|
|
112114
112180
|
...typeof v.iterations === "number" ? { iterations: v.iterations } : {},
|
|
112115
|
-
...
|
|
112181
|
+
...str(v.last_reason) ? { reason: str(v.last_reason) } : {}
|
|
112116
112182
|
} : null
|
|
112117
112183
|
});
|
|
112118
112184
|
return out;
|
|
112119
112185
|
}
|
|
112120
112186
|
function systemEvents(m, sessionId) {
|
|
112121
|
-
switch (
|
|
112187
|
+
switch (str(m.subtype)) {
|
|
112122
112188
|
case "informational":
|
|
112123
112189
|
return informationalEvents(m, sessionId);
|
|
112124
112190
|
case "notification":
|
|
@@ -112137,8 +112203,8 @@ function systemEvents(m, sessionId) {
|
|
|
112137
112203
|
}
|
|
112138
112204
|
function informationalEvents(m, sessionId) {
|
|
112139
112205
|
const out = [];
|
|
112140
|
-
const text2 =
|
|
112141
|
-
const level =
|
|
112206
|
+
const text2 = str(m.content).trim();
|
|
112207
|
+
const level = str(m.level);
|
|
112142
112208
|
if (text2 && level !== "info") {
|
|
112143
112209
|
const hook = /\bblocked by hook\b/.test(text2);
|
|
112144
112210
|
out.push({
|
|
@@ -112155,10 +112221,10 @@ function informationalEvents(m, sessionId) {
|
|
|
112155
112221
|
}
|
|
112156
112222
|
function notificationEvents(m, sessionId) {
|
|
112157
112223
|
const out = [];
|
|
112158
|
-
const text2 =
|
|
112159
|
-
if (!text2 ||
|
|
112160
|
-
const color =
|
|
112161
|
-
const priority =
|
|
112224
|
+
const text2 = str(m.text).trim();
|
|
112225
|
+
if (!text2 || str(m.key) === "error-compacting-conversation") return out;
|
|
112226
|
+
const color = str(m.color);
|
|
112227
|
+
const priority = str(m.priority);
|
|
112162
112228
|
const level = color === "error" ? "error" : color === "warning" || priority === "high" || priority === "immediate" ? "warning" : "info";
|
|
112163
112229
|
out.push({ type: "notice", sessionId, level, text: text2, from: "Claude Code", label: "notice" });
|
|
112164
112230
|
return out;
|
|
@@ -112168,7 +112234,7 @@ function apiRetryEvents(m, sessionId) {
|
|
|
112168
112234
|
const status = typeof m.error_status === "number" ? `${m.error_status} ` : "";
|
|
112169
112235
|
const delay = typeof m.retry_delay_ms === "number" ? ` in ${m.retry_delay_ms}ms` : "";
|
|
112170
112236
|
console.error(
|
|
112171
|
-
`[claude] ${sessionId.slice(0, 8)} retrying after: ${status}${
|
|
112237
|
+
`[claude] ${sessionId.slice(0, 8)} retrying after: ${status}${str(m.error, "connection error")} (attempt ${String(m.attempt ?? "?")}/${String(m.max_retries ?? "?")}${delay})`
|
|
112172
112238
|
);
|
|
112173
112239
|
out.push({ type: "activity", sessionId, activity: "retrying" });
|
|
112174
112240
|
return out;
|
|
@@ -112176,14 +112242,14 @@ function apiRetryEvents(m, sessionId) {
|
|
|
112176
112242
|
function statusEvents(m, sessionId) {
|
|
112177
112243
|
const out = [];
|
|
112178
112244
|
out.push({ type: "activity", sessionId, activity: m.status === "compacting" ? "compacting" : null });
|
|
112179
|
-
if (
|
|
112180
|
-
out.push({ type: "compaction", sessionId, failed: true, reason:
|
|
112245
|
+
if (str(m.compact_result) === "failed") {
|
|
112246
|
+
out.push({ type: "compaction", sessionId, failed: true, reason: str(m.compact_error, "Unknown reason") });
|
|
112181
112247
|
}
|
|
112182
112248
|
return out;
|
|
112183
112249
|
}
|
|
112184
112250
|
function localCommandOutputEvents(m, sessionId) {
|
|
112185
112251
|
const out = [];
|
|
112186
|
-
const content =
|
|
112252
|
+
const content = str(m.content);
|
|
112187
112253
|
if (content) out.push({ type: "message_delta", sessionId, role: "assistant", text: content });
|
|
112188
112254
|
return out;
|
|
112189
112255
|
}
|
|
@@ -112204,7 +112270,7 @@ function compactBoundaryEvents(m, sessionId) {
|
|
|
112204
112270
|
function textOfContent(content) {
|
|
112205
112271
|
if (typeof content === "string") return content;
|
|
112206
112272
|
if (!Array.isArray(content)) return "";
|
|
112207
|
-
return content.filter((b2) =>
|
|
112273
|
+
return content.filter((b2) => str(b2?.type) === "text").map((b2) => str(b2.text)).join("");
|
|
112208
112274
|
}
|
|
112209
112275
|
var ClaudeGoalTracker = class {
|
|
112210
112276
|
constructor(sessionId) {
|
|
@@ -112232,13 +112298,13 @@ var ClaudeGoalTracker = class {
|
|
|
112232
112298
|
}
|
|
112233
112299
|
/** Reads one parent-stream message. `streamed`: this assistant message's body came as deltas, i.e. a model call. */
|
|
112234
112300
|
push(m, opts) {
|
|
112235
|
-
const type =
|
|
112301
|
+
const type = str(m.type);
|
|
112236
112302
|
if (type === "active_goal") {
|
|
112237
112303
|
this.announced = true;
|
|
112238
112304
|
return [];
|
|
112239
112305
|
}
|
|
112240
112306
|
if (this.announced) return [];
|
|
112241
|
-
if (type === "stream_event" &&
|
|
112307
|
+
if (type === "stream_event" && str(m.event?.type) === "message_start") {
|
|
112242
112308
|
if (this.goal) this.drove = true;
|
|
112243
112309
|
return [];
|
|
112244
112310
|
}
|
|
@@ -112260,7 +112326,7 @@ var ClaudeGoalTracker = class {
|
|
|
112260
112326
|
if (type === "result") {
|
|
112261
112327
|
const drove = this.drove;
|
|
112262
112328
|
this.drove = false;
|
|
112263
|
-
const success2 =
|
|
112329
|
+
const success2 = str(m.subtype) === "success" && m.is_error !== true;
|
|
112264
112330
|
if (this.goal && drove && success2 && !opts.interrupted) return this.set(null);
|
|
112265
112331
|
}
|
|
112266
112332
|
return [];
|
|
@@ -112318,7 +112384,7 @@ function mcpImageEvents(sessionId, content) {
|
|
|
112318
112384
|
if (!Array.isArray(content)) return [];
|
|
112319
112385
|
const out = [];
|
|
112320
112386
|
for (const raw of content) {
|
|
112321
|
-
const part =
|
|
112387
|
+
const part = asObj(raw);
|
|
112322
112388
|
if (part.type !== "image") continue;
|
|
112323
112389
|
const data = typeof part.data === "string" ? part.data : "";
|
|
112324
112390
|
const mime = typeof part.mimeType === "string" ? part.mimeType : "";
|
|
@@ -112348,7 +112414,7 @@ function stepStatus(raw) {
|
|
|
112348
112414
|
}
|
|
112349
112415
|
function planUpdate(sessionId, raw, textField) {
|
|
112350
112416
|
const steps = (Array.isArray(raw) ? raw : []).map((s) => {
|
|
112351
|
-
const it2 =
|
|
112417
|
+
const it2 = asObj(s);
|
|
112352
112418
|
const text2 = it2[textField];
|
|
112353
112419
|
return { text: typeof text2 === "string" ? text2 : "", status: stepStatus(it2.status) };
|
|
112354
112420
|
});
|
|
@@ -112356,7 +112422,7 @@ function planUpdate(sessionId, raw, textField) {
|
|
|
112356
112422
|
}
|
|
112357
112423
|
function todoWritePlan(sessionId, name, input) {
|
|
112358
112424
|
if (name !== "TodoWrite") return [];
|
|
112359
|
-
const todos = (
|
|
112425
|
+
const todos = asObj(input).todos;
|
|
112360
112426
|
return Array.isArray(todos) ? [planUpdate(sessionId, todos, "content")] : [];
|
|
112361
112427
|
}
|
|
112362
112428
|
|
|
@@ -112372,14 +112438,14 @@ function toolSummary(name, input) {
|
|
|
112372
112438
|
if (run4) return toolSummary(run4.name, run4.input);
|
|
112373
112439
|
const paths = [];
|
|
112374
112440
|
let title = name;
|
|
112375
|
-
if (name === "Bash") title =
|
|
112441
|
+
if (name === "Bash") title = str(input.command, name);
|
|
112376
112442
|
else if (FILE_EDIT_TOOLS.has(name) || name === "Read") {
|
|
112377
|
-
const p =
|
|
112443
|
+
const p = str(input.file_path ?? input.notebook_path);
|
|
112378
112444
|
if (p) paths.push(p);
|
|
112379
112445
|
title = `${name}: ${p || "?"}`;
|
|
112380
|
-
} else if (name === "Grep" || name === "Glob") title = `${name}: ${
|
|
112381
|
-
else if (isCentraluTool({ name }, "ask_project")) title =
|
|
112382
|
-
else if (launchesSubagent(name)) title =
|
|
112446
|
+
} else if (name === "Grep" || name === "Glob") title = `${name}: ${str(input.pattern)}`;
|
|
112447
|
+
else if (isCentraluTool({ name }, "ask_project")) title = str(input.project).trim() || name;
|
|
112448
|
+
else if (launchesSubagent(name)) title = str(input.description, name);
|
|
112383
112449
|
const parts = mcpNameParts(name);
|
|
112384
112450
|
const mark = parts ? centraluMark(parts.server, parts.tool, input) : null;
|
|
112385
112451
|
return { tool: name, title: mark?.title ?? title, paths, ...mark ? { centralu: mark.centralu } : {} };
|
|
@@ -112405,29 +112471,29 @@ ${report}` : report;
|
|
|
112405
112471
|
function resultOutput(content) {
|
|
112406
112472
|
if (typeof content === "string") return content;
|
|
112407
112473
|
if (!Array.isArray(content)) return content == null ? "" : JSON.stringify(content);
|
|
112408
|
-
return content.filter((b2) =>
|
|
112474
|
+
return content.filter((b2) => str(b2?.type) !== "image" && str(b2?.source?.type) !== "base64").map((b2) => str(b2?.type) === "text" ? str(b2.text) : JSON.stringify(b2)).join("\n");
|
|
112409
112475
|
}
|
|
112410
112476
|
function claudeFileChange(name, input, isNew) {
|
|
112411
|
-
const path2 =
|
|
112477
|
+
const path2 = str(input.file_path ?? input.notebook_path);
|
|
112412
112478
|
if (name === "Edit") {
|
|
112413
|
-
const diff2 = [diffLines("-",
|
|
112479
|
+
const diff2 = [diffLines("-", str(input.old_string)), diffLines("+", str(input.new_string))].filter(Boolean).join("\n");
|
|
112414
112480
|
return { path: path2, diff: input.replace_all === true && diff2 ? `(every occurrence)
|
|
112415
112481
|
${diff2}` : diff2 };
|
|
112416
112482
|
}
|
|
112417
112483
|
if (name === "Write") {
|
|
112418
|
-
const content =
|
|
112484
|
+
const content = str(input.content);
|
|
112419
112485
|
if (isNew === true) return { path: path2, diff: diffLines("+", content), change: "add" };
|
|
112420
112486
|
const head = isNew === false ? "(replaces the whole file)" : "(writes the whole file)";
|
|
112421
112487
|
return { path: path2, diff: content ? `${head}
|
|
112422
112488
|
${content.replace(/\n$/, "")}` : "" };
|
|
112423
112489
|
}
|
|
112424
|
-
const mode =
|
|
112425
|
-
const diff = diffLines("+",
|
|
112426
|
-
return { path: path2, diff: mode === "delete" ? `(deletes cell ${
|
|
112490
|
+
const mode = str(input.edit_mode);
|
|
112491
|
+
const diff = diffLines("+", str(input.new_source));
|
|
112492
|
+
return { path: path2, diff: mode === "delete" ? `(deletes cell ${str(input.cell_id) || "?"})` : mode === "insert" ? `(inserts a cell)
|
|
112427
112493
|
${diff}` : diff };
|
|
112428
112494
|
}
|
|
112429
112495
|
function approvalDetail(name, input, cwd, isNew) {
|
|
112430
|
-
if (name === "Bash") return { kind: "command", command:
|
|
112496
|
+
if (name === "Bash") return { kind: "command", command: str(input.command), cwd, ...input.dangerouslyDisableSandbox === true ? { unsandboxed: true } : {} };
|
|
112431
112497
|
if (FILE_EDIT_TOOLS.has(name)) {
|
|
112432
112498
|
const change = claudeFileChange(name, input, isNew);
|
|
112433
112499
|
return fileEditDetail([change.diff ? change : { ...change, diff: JSON.stringify(input) }]);
|
|
@@ -112438,20 +112504,20 @@ function approvalDetail(name, input, cwd, isNew) {
|
|
|
112438
112504
|
// packages/agent-host/src/adapters/claude/model-messages.ts
|
|
112439
112505
|
function backgroundLaunch(m) {
|
|
112440
112506
|
const r = m.tool_use_result ?? {};
|
|
112441
|
-
if (
|
|
112442
|
-
const blocks = (m.message?.content ?? []).filter((b2) =>
|
|
112443
|
-
return blocks.length === 1 ?
|
|
112507
|
+
if (str(r.status) !== "async_launched" || !str(r.agentId)) return null;
|
|
112508
|
+
const blocks = (m.message?.content ?? []).filter((b2) => str(b2.type) === "tool_result");
|
|
112509
|
+
return blocks.length === 1 ? str(blocks[0]?.tool_use_id) || null : null;
|
|
112444
112510
|
}
|
|
112445
112511
|
function streamEventEvents(m, sessionId) {
|
|
112446
112512
|
const out = [];
|
|
112447
112513
|
const e = m.event;
|
|
112448
|
-
if (
|
|
112514
|
+
if (str(e?.type) === "content_block_delta") {
|
|
112449
112515
|
const d2 = e?.delta;
|
|
112450
|
-
if (
|
|
112451
|
-
out.push({ type: "message_delta", sessionId, role: "assistant", text:
|
|
112516
|
+
if (str(d2?.type) === "text_delta") {
|
|
112517
|
+
out.push({ type: "message_delta", sessionId, role: "assistant", text: str(d2?.text) });
|
|
112452
112518
|
}
|
|
112453
|
-
if (
|
|
112454
|
-
const text2 =
|
|
112519
|
+
if (str(d2?.type) === "thinking_delta") {
|
|
112520
|
+
const text2 = str(d2?.thinking);
|
|
112455
112521
|
const estTokens = typeof d2?.estimated_tokens === "number" ? d2.estimated_tokens : void 0;
|
|
112456
112522
|
if (text2 || estTokens) {
|
|
112457
112523
|
out.push({ type: "reasoning_delta", sessionId, ...text2 ? { text: text2 } : {}, ...estTokens ? { estTokens } : {} });
|
|
@@ -112464,21 +112530,21 @@ function assistantEvents(m, sessionId, opts) {
|
|
|
112464
112530
|
const out = [];
|
|
112465
112531
|
const content = m.message?.content ?? [];
|
|
112466
112532
|
if (!opts?.reasoningStreamed) {
|
|
112467
|
-
const thinking = content.filter((b2) =>
|
|
112533
|
+
const thinking = content.filter((b2) => str(b2.type) === "thinking").map((b2) => str(b2.thinking)).join("");
|
|
112468
112534
|
if (thinking) out.push({ type: "reasoning_delta", sessionId, text: thinking });
|
|
112469
112535
|
}
|
|
112470
112536
|
if (!opts?.textStreamed) {
|
|
112471
|
-
const text2 = content.filter((b2) =>
|
|
112537
|
+
const text2 = content.filter((b2) => str(b2.type) === "text").map((b2) => str(b2.text)).join("");
|
|
112472
112538
|
if (text2) out.push({ type: "message_delta", sessionId, role: "assistant", text: text2 });
|
|
112473
112539
|
}
|
|
112474
112540
|
for (const block of content) {
|
|
112475
|
-
if (
|
|
112476
|
-
const name =
|
|
112541
|
+
if (str(block.type) === "tool_use") {
|
|
112542
|
+
const name = str(block.name);
|
|
112477
112543
|
const input = block.input ?? {};
|
|
112478
112544
|
out.push({
|
|
112479
112545
|
type: "tool_call",
|
|
112480
112546
|
sessionId,
|
|
112481
|
-
callId:
|
|
112547
|
+
callId: str(block.id),
|
|
112482
112548
|
summary: toolSummary(name, input),
|
|
112483
112549
|
...block.input !== void 0 ? { input: block.input } : {}
|
|
112484
112550
|
});
|
|
@@ -112490,39 +112556,41 @@ function assistantEvents(m, sessionId, opts) {
|
|
|
112490
112556
|
out.push({
|
|
112491
112557
|
type: "usage_update",
|
|
112492
112558
|
sessionId,
|
|
112493
|
-
tokens: {
|
|
112494
|
-
inputTokens: tokenCount(usage.input_tokens),
|
|
112495
|
-
outputTokens: tokenCount(usage.output_tokens),
|
|
112496
|
-
cacheReadTokens: tokenCount(usage.cache_read_input_tokens),
|
|
112497
|
-
cacheCreationTokens: tokenCount(usage.cache_creation_input_tokens)
|
|
112498
|
-
}
|
|
112559
|
+
tokens: { ...requestInputTokens(usage), outputTokens: tokenCount(usage.output_tokens) }
|
|
112499
112560
|
});
|
|
112500
112561
|
}
|
|
112501
112562
|
return out;
|
|
112502
112563
|
}
|
|
112564
|
+
function requestInputTokens(usage) {
|
|
112565
|
+
return {
|
|
112566
|
+
inputTokens: tokenCount(usage.input_tokens),
|
|
112567
|
+
cacheReadTokens: tokenCount(usage.cache_read_input_tokens),
|
|
112568
|
+
cacheCreationTokens: tokenCount(usage.cache_creation_input_tokens)
|
|
112569
|
+
};
|
|
112570
|
+
}
|
|
112503
112571
|
function userEvents(m, sessionId) {
|
|
112504
112572
|
const out = [];
|
|
112505
112573
|
const content = m.message?.content ?? [];
|
|
112506
112574
|
const launched = backgroundLaunch(m);
|
|
112507
112575
|
if (launched) return [{ type: "tool_output_delta", sessionId, callId: launched, text: "Running in the background\n" }];
|
|
112508
112576
|
const agent = m.tool_use_result ?? {};
|
|
112509
|
-
const agentDone =
|
|
112510
|
-
agent.content.map((b2) =>
|
|
112577
|
+
const agentDone = str(agent.status) === "completed" && str(agent.agentId) && Array.isArray(agent.content) && content.filter((b2) => str(b2.type) === "tool_result").length === 1 ? agentReport(
|
|
112578
|
+
agent.content.map((b2) => str(b2.text)).join("\n"),
|
|
112511
112579
|
agentStats(agent.totalToolUseCount, agent.totalDurationMs)
|
|
112512
112580
|
) : null;
|
|
112513
112581
|
for (const block of content) {
|
|
112514
|
-
if (
|
|
112582
|
+
if (str(block.type) === "tool_result") {
|
|
112515
112583
|
const c = block.content;
|
|
112516
|
-
out.push(toolResultEvent(sessionId,
|
|
112584
|
+
out.push(toolResultEvent(sessionId, str(block.tool_use_id), block.is_error !== true, agentDone ?? resultOutput(c)));
|
|
112517
112585
|
if (Array.isArray(c)) {
|
|
112518
112586
|
for (const part of c) {
|
|
112519
|
-
if (
|
|
112587
|
+
if (str(part.type) !== "image") continue;
|
|
112520
112588
|
const source = part.source ?? {};
|
|
112521
|
-
if (
|
|
112522
|
-
out.push(undrawnImageEvent(sessionId, `Cannot display an image of this format yet (source: ${
|
|
112589
|
+
if (str(source.type) !== "base64" || !str(source.data)) {
|
|
112590
|
+
out.push(undrawnImageEvent(sessionId, `Cannot display an image of this format yet (source: ${str(source.type) || "none"})`));
|
|
112523
112591
|
continue;
|
|
112524
112592
|
}
|
|
112525
|
-
out.push(inlineImageEvent(sessionId,
|
|
112593
|
+
out.push(inlineImageEvent(sessionId, str(source.media_type), str(source.data)));
|
|
112526
112594
|
}
|
|
112527
112595
|
}
|
|
112528
112596
|
}
|
|
@@ -112543,7 +112611,7 @@ var ClaudeTaskPlan = class {
|
|
|
112543
112611
|
/** A call was made; the plan tools are remembered until their result */
|
|
112544
112612
|
call(callId, name, input) {
|
|
112545
112613
|
if (name !== "TaskCreate" && name !== "TaskUpdate" && name !== "TaskList") return;
|
|
112546
|
-
this.open.set(callId, { name, input:
|
|
112614
|
+
this.open.set(callId, { name, input: asObj(input) });
|
|
112547
112615
|
if (this.open.size > 64) this.open.delete(this.open.keys().next().value);
|
|
112548
112616
|
}
|
|
112549
112617
|
/**
|
|
@@ -112557,21 +112625,21 @@ var ClaudeTaskPlan = class {
|
|
|
112557
112625
|
if (!ok) return [];
|
|
112558
112626
|
if (call2.name === "TaskCreate") {
|
|
112559
112627
|
const task = record2?.task ?? {};
|
|
112560
|
-
const id3 =
|
|
112628
|
+
const id3 = str(task.id) || /^Task #(\S+) created/.exec(output)?.[1] || "";
|
|
112561
112629
|
if (!id3) return [];
|
|
112562
|
-
this.tasks.set(id3, { text:
|
|
112630
|
+
this.tasks.set(id3, { text: str(call2.input.subject) || str(task.subject), status: "pending" });
|
|
112563
112631
|
} else if (call2.name === "TaskUpdate") {
|
|
112564
|
-
const id3 =
|
|
112565
|
-
const status =
|
|
112632
|
+
const id3 = str(call2.input.taskId);
|
|
112633
|
+
const status = str(call2.input.status);
|
|
112566
112634
|
const known = this.tasks.get(id3);
|
|
112567
112635
|
if (status === "deleted") this.tasks.delete(id3);
|
|
112568
|
-
else if (known) this.tasks.set(id3, { text:
|
|
112569
|
-
else if (
|
|
112636
|
+
else if (known) this.tasks.set(id3, { text: str(call2.input.subject) || known.text, status: status || known.status });
|
|
112637
|
+
else if (str(call2.input.subject)) this.tasks.set(id3, { text: str(call2.input.subject), status: status || "pending" });
|
|
112570
112638
|
else return [];
|
|
112571
112639
|
} else {
|
|
112572
112640
|
if (!Array.isArray(record2?.tasks)) return [];
|
|
112573
112641
|
this.tasks.clear();
|
|
112574
|
-
for (const t of record2.tasks) if (
|
|
112642
|
+
for (const t of record2.tasks) if (str(t.id)) this.tasks.set(str(t.id), { text: str(t.subject), status: str(t.status) });
|
|
112575
112643
|
}
|
|
112576
112644
|
return [planUpdate(this.sessionId, [...this.tasks.values()], "text")];
|
|
112577
112645
|
}
|
|
@@ -112581,13 +112649,13 @@ var ClaudeTaskPlan = class {
|
|
|
112581
112649
|
function rateLimitEvents(m, sessionId) {
|
|
112582
112650
|
const out = [];
|
|
112583
112651
|
const info = m.rate_limit_info ?? {};
|
|
112584
|
-
if (
|
|
112652
|
+
if (str(info.status) === "rejected") {
|
|
112585
112653
|
const resetsAt = typeof info.resetsAt === "number" ? new Date(info.resetsAt * 1e3).toISOString() : void 0;
|
|
112586
112654
|
out.push({
|
|
112587
112655
|
type: "limit_reached",
|
|
112588
112656
|
sessionId,
|
|
112589
112657
|
resumeAt: resetsAt,
|
|
112590
|
-
windowMins:
|
|
112658
|
+
windowMins: str(info.rateLimitType) === "five_hour" ? 300 : void 0
|
|
112591
112659
|
});
|
|
112592
112660
|
}
|
|
112593
112661
|
return out;
|
|
@@ -112610,12 +112678,12 @@ function resultEvents(m, sessionId) {
|
|
|
112610
112678
|
}
|
|
112611
112679
|
});
|
|
112612
112680
|
}
|
|
112613
|
-
if (
|
|
112681
|
+
if (str(m.subtype) !== "success" || m.is_error === true) {
|
|
112614
112682
|
const errors = Array.isArray(m.errors) ? m.errors.filter((x) => typeof x === "string" && x.length > 0) : [];
|
|
112615
112683
|
out.push({
|
|
112616
112684
|
type: "error",
|
|
112617
112685
|
sessionId,
|
|
112618
|
-
error: { code: "internal", message:
|
|
112686
|
+
error: { code: "internal", message: str(m.result) || errors.join("\n") || `Turn failed: ${str(m.subtype)}`, retryable: true }
|
|
112619
112687
|
});
|
|
112620
112688
|
} else {
|
|
112621
112689
|
out.push(m.structured_output === void 0 ? { type: "turn_complete", sessionId } : { type: "turn_complete", sessionId, output: m.structured_output });
|
|
@@ -112626,9 +112694,9 @@ function resultEvents(m, sessionId) {
|
|
|
112626
112694
|
// packages/agent-host/src/adapters/claude/normalize.ts
|
|
112627
112695
|
function normalizeMessage(msg, sessionId, opts) {
|
|
112628
112696
|
const m = msg;
|
|
112629
|
-
const type =
|
|
112697
|
+
const type = str(m.type);
|
|
112630
112698
|
const out = [];
|
|
112631
|
-
const parent =
|
|
112699
|
+
const parent = str(m.parent_tool_use_id);
|
|
112632
112700
|
if (parent && (type === "assistant" || type === "user" || type === "stream_event")) {
|
|
112633
112701
|
if (type === "stream_event") return out;
|
|
112634
112702
|
return subagentSteps(sessionId, parent, normalizeMessage({ ...m, parent_tool_use_id: null }, sessionId));
|
|
@@ -112782,21 +112850,21 @@ var ClaudeStreamNormalizer = class {
|
|
|
112782
112850
|
* falls back to the refusal's explanation, then its category.
|
|
112783
112851
|
*/
|
|
112784
112852
|
refusalEvents(m) {
|
|
112785
|
-
const subtype =
|
|
112786
|
-
const explanation =
|
|
112853
|
+
const subtype = str(m.subtype);
|
|
112854
|
+
const explanation = str(m.api_refusal_explanation);
|
|
112787
112855
|
if (subtype === "model_refusal_no_fallback") {
|
|
112788
|
-
const category =
|
|
112789
|
-
this.refusal =
|
|
112856
|
+
const category = str(m.api_refusal_category);
|
|
112857
|
+
this.refusal = str(m.content).trim() || explanation || `The model declined to answer${category ? ` (${category})` : ""}`;
|
|
112790
112858
|
return [];
|
|
112791
112859
|
}
|
|
112792
|
-
const from =
|
|
112793
|
-
const to =
|
|
112794
|
-
if (
|
|
112860
|
+
const from = str(m.original_model, "the model");
|
|
112861
|
+
const to = str(m.fallback_model);
|
|
112862
|
+
if (str(m.scope) === "local") {
|
|
112795
112863
|
console.error(`[claude] ${this.sessionId.slice(0, 8)} a subagent's answer came from ${to} after ${from} declined`);
|
|
112796
112864
|
return [];
|
|
112797
112865
|
}
|
|
112798
112866
|
if (!to) return [];
|
|
112799
|
-
const text2 =
|
|
112867
|
+
const text2 = str(m.content).trim() || `${from} declined to answer, so Claude Code switched this session to ${to}${explanation ? `: ${explanation}` : ""}`;
|
|
112800
112868
|
return [
|
|
112801
112869
|
{ type: "notice", sessionId: this.sessionId, level: "warning", text: text2, from: "Claude Code", label: "model switch" },
|
|
112802
112870
|
{ type: "settings_changed", sessionId: this.sessionId, ...this.settings(), model: to, by: "tool" }
|
|
@@ -112814,7 +112882,7 @@ var ClaudeStreamNormalizer = class {
|
|
|
112814
112882
|
*/
|
|
112815
112883
|
withRequest(m, events2, subagent) {
|
|
112816
112884
|
const message = m.message ?? {};
|
|
112817
|
-
const id3 =
|
|
112885
|
+
const id3 = str(message.id);
|
|
112818
112886
|
const usage = message.usage;
|
|
112819
112887
|
const fresh = !!usage && !(id3 && this.requestsSeen.includes(id3));
|
|
112820
112888
|
if (!subagent) {
|
|
@@ -112830,10 +112898,8 @@ var ClaudeStreamNormalizer = class {
|
|
|
112830
112898
|
this.requestsSeen.push(id3);
|
|
112831
112899
|
if (this.requestsSeen.length > 32) this.requestsSeen.shift();
|
|
112832
112900
|
const request = {
|
|
112833
|
-
|
|
112834
|
-
|
|
112835
|
-
cacheCreationTokens: tokenCount(usage.cache_creation_input_tokens),
|
|
112836
|
-
...subagent ? { agent: str2(m.parent_tool_use_id) } : {},
|
|
112901
|
+
...requestInputTokens(usage),
|
|
112902
|
+
...subagent ? { agent: str(m.parent_tool_use_id) } : {},
|
|
112837
112903
|
...ttlOf(usage.cache_creation)
|
|
112838
112904
|
};
|
|
112839
112905
|
if (subagent) {
|
|
@@ -112860,7 +112926,7 @@ var ClaudeStreamNormalizer = class {
|
|
|
112860
112926
|
* session's plan. The message's `tool_use_result` is read only when it carries one result.
|
|
112861
112927
|
*/
|
|
112862
112928
|
followTasks(m, events2) {
|
|
112863
|
-
const results = (m.message?.content ?? []).filter((b2) =>
|
|
112929
|
+
const results = (m.message?.content ?? []).filter((b2) => str(b2?.type) === "tool_result");
|
|
112864
112930
|
const record2 = results.length === 1 && typeof m.tool_use_result === "object" && m.tool_use_result !== null ? m.tool_use_result : void 0;
|
|
112865
112931
|
const out = [];
|
|
112866
112932
|
for (const e of events2) {
|
|
@@ -112888,16 +112954,16 @@ var ClaudeStreamNormalizer = class {
|
|
|
112888
112954
|
}
|
|
112889
112955
|
push(msg) {
|
|
112890
112956
|
const m = msg;
|
|
112891
|
-
const type =
|
|
112892
|
-
const subagent =
|
|
112893
|
-
this.unmapped.note(type === "system" ? `system/${
|
|
112957
|
+
const type = str(m.type);
|
|
112958
|
+
const subagent = str(m.parent_tool_use_id) !== "";
|
|
112959
|
+
this.unmapped.note(type === "system" ? `system/${str(m.subtype)}` : type);
|
|
112894
112960
|
const tasks = this.tasks.push(m);
|
|
112895
|
-
if (type === "system" &&
|
|
112896
|
-
const callId =
|
|
112961
|
+
if (type === "system" && str(m.subtype) === "task_notification") {
|
|
112962
|
+
const callId = str(m.tool_use_id);
|
|
112897
112963
|
if (!this.background.delete(callId)) return tasks;
|
|
112898
|
-
const status =
|
|
112964
|
+
const status = str(m.status, "completed");
|
|
112899
112965
|
const usage = m.usage ?? {};
|
|
112900
|
-
const output = agentReport(
|
|
112966
|
+
const output = agentReport(str(m.summary), agentStats(usage.tool_uses, usage.duration_ms, status));
|
|
112901
112967
|
const done = toolResultEvent(this.sessionId, callId, status === "completed", output);
|
|
112902
112968
|
if (!this.textStreamed && !this.reasoningStreamed) return [...tasks, done];
|
|
112903
112969
|
this.deferred.push(done);
|
|
@@ -112907,7 +112973,7 @@ var ClaudeStreamNormalizer = class {
|
|
|
112907
112973
|
const launched = backgroundLaunch(m);
|
|
112908
112974
|
if (launched) this.background.add(launched);
|
|
112909
112975
|
}
|
|
112910
|
-
if (type === "system" && /^model_refusal_(no_)?fallback$/.test(
|
|
112976
|
+
if (type === "system" && /^model_refusal_(no_)?fallback$/.test(str(m.subtype))) return [...tasks, ...this.refusalEvents(m)];
|
|
112911
112977
|
let events2 = [
|
|
112912
112978
|
...tasks,
|
|
112913
112979
|
...normalizeMessage(msg, this.sessionId, {
|
|
@@ -112936,9 +113002,9 @@ var ClaudeStreamNormalizer = class {
|
|
|
112936
113002
|
}
|
|
112937
113003
|
if (type === "stream_event") {
|
|
112938
113004
|
const e = m.event ?? {};
|
|
112939
|
-
if (
|
|
113005
|
+
if (str(e.type) === "message_start") this.streamMessageId = str(e.message?.id) || void 0;
|
|
112940
113006
|
}
|
|
112941
|
-
const wholeId = type === "assistant" ?
|
|
113007
|
+
const wholeId = type === "assistant" ? str(m.message?.id) || void 0 : void 0;
|
|
112942
113008
|
const messageId = type === "stream_event" ? this.streamMessageId : wholeId;
|
|
112943
113009
|
if (messageId) events2 = events2.map((e) => e.type === "message_delta" && !e.messageId ? { ...e, messageId } : e);
|
|
112944
113010
|
events2.push(
|
|
@@ -112955,7 +113021,7 @@ var ClaudeStreamNormalizer = class {
|
|
|
112955
113021
|
}
|
|
112956
113022
|
if (type === "result" && this.stopping) {
|
|
112957
113023
|
this.stopping = false;
|
|
112958
|
-
if (
|
|
113024
|
+
if (str(m.subtype) === "error_during_execution") events2 = events2.filter((e) => e.type !== "error");
|
|
112959
113025
|
}
|
|
112960
113026
|
if ((type === "assistant" || type === "result") && this.deferred.length > 0) events2.push(...this.deferred.splice(0));
|
|
112961
113027
|
return events2;
|
|
@@ -115291,13 +115357,13 @@ async function lastCompactSummary(threadId, sessionsDir) {
|
|
|
115291
115357
|
|
|
115292
115358
|
// packages/agent-host/src/adapters/codex/items.ts
|
|
115293
115359
|
function resultSummary(item) {
|
|
115294
|
-
const direct =
|
|
115360
|
+
const direct = str(item.aggregatedOutput) || str(item.output);
|
|
115295
115361
|
if (direct) return direct;
|
|
115296
|
-
const err =
|
|
115362
|
+
const err = str(asObj(item.error).message);
|
|
115297
115363
|
if (err) return err;
|
|
115298
115364
|
const content = asObj(item.result).content;
|
|
115299
115365
|
if (Array.isArray(content)) {
|
|
115300
|
-
const text2 = content.map((c) =>
|
|
115366
|
+
const text2 = content.map((c) => str(asObj(c).text)).filter(Boolean).join("\n");
|
|
115301
115367
|
if (text2) return text2;
|
|
115302
115368
|
}
|
|
115303
115369
|
const structured = asObj(item.result).structuredContent;
|
|
@@ -115311,7 +115377,7 @@ function resultSummary(item) {
|
|
|
115311
115377
|
return "";
|
|
115312
115378
|
}
|
|
115313
115379
|
function codexItemOk(item) {
|
|
115314
|
-
const status =
|
|
115380
|
+
const status = str(item.status);
|
|
115315
115381
|
return status !== "failed" && status !== "declined" && status !== "interrupted" && item.success !== false;
|
|
115316
115382
|
}
|
|
115317
115383
|
var ITEM_OUTCOME = /* @__PURE__ */ new Set([
|
|
@@ -115335,9 +115401,9 @@ function itemInput(item) {
|
|
|
115335
115401
|
return Object.fromEntries(Object.entries(item).filter(([k2, v]) => !ITEM_OUTCOME.has(k2) && v !== null && v !== void 0));
|
|
115336
115402
|
}
|
|
115337
115403
|
function itemSummary(item) {
|
|
115338
|
-
const type =
|
|
115404
|
+
const type = str(item.type);
|
|
115339
115405
|
if (type === "commandExecution") {
|
|
115340
|
-
const cmd =
|
|
115406
|
+
const cmd = str(item.command);
|
|
115341
115407
|
return { tool: "Bash", title: cmd, paths: [] };
|
|
115342
115408
|
}
|
|
115343
115409
|
if (type === "fileChange") {
|
|
@@ -115345,8 +115411,8 @@ function itemSummary(item) {
|
|
|
115345
115411
|
return { tool: "Edit", title: paths.join(", ") || "Edit files", paths };
|
|
115346
115412
|
}
|
|
115347
115413
|
if (type === "mcpToolCall") {
|
|
115348
|
-
const tool =
|
|
115349
|
-
const server2 =
|
|
115414
|
+
const tool = str(item.tool) || str(asObj(item.invocation).tool);
|
|
115415
|
+
const server2 = str(item.server);
|
|
115350
115416
|
if (isCentraluTool({ server: server2, tool }, "centralu_run")) {
|
|
115351
115417
|
const run4 = centraluRunCommand(jsonObject(item.arguments ?? asObj(item.invocation).arguments));
|
|
115352
115418
|
if (run4) {
|
|
@@ -115354,12 +115420,12 @@ function itemSummary(item) {
|
|
|
115354
115420
|
}
|
|
115355
115421
|
}
|
|
115356
115422
|
if (isCentraluTool({ server: server2, tool }, "ask_project")) {
|
|
115357
|
-
const project2 =
|
|
115423
|
+
const project2 = str(jsonObject(item.arguments ?? asObj(item.invocation).arguments).project);
|
|
115358
115424
|
const mark2 = centraluMark(server2, tool, {});
|
|
115359
115425
|
return { tool, title: project2 || tool, paths: [], ...mark2 ? { centralu: mark2.centralu } : {} };
|
|
115360
115426
|
}
|
|
115361
115427
|
const args = argsPreview(item.arguments ?? asObj(item.invocation).arguments);
|
|
115362
|
-
const name = [server2, tool].filter(Boolean).join(": ") ||
|
|
115428
|
+
const name = [server2, tool].filter(Boolean).join(": ") || str(item.title) || "MCP tool";
|
|
115363
115429
|
const mark = tool ? centraluMark(server2, tool, jsonObject(item.arguments ?? asObj(item.invocation).arguments)) : null;
|
|
115364
115430
|
return {
|
|
115365
115431
|
tool: tool || "MCP",
|
|
@@ -115369,13 +115435,13 @@ function itemSummary(item) {
|
|
|
115369
115435
|
};
|
|
115370
115436
|
}
|
|
115371
115437
|
if (type === "webSearch") {
|
|
115372
|
-
return { tool: "WebSearch", title:
|
|
115438
|
+
return { tool: "WebSearch", title: str(item.query), paths: [] };
|
|
115373
115439
|
}
|
|
115374
115440
|
if (type === "collabAgentToolCall") {
|
|
115375
|
-
const tool =
|
|
115376
|
-
return { tool, title: firstLine2(
|
|
115441
|
+
const tool = str(item.tool) || type;
|
|
115442
|
+
return { tool, title: firstLine2(str(item.prompt)) || tool, paths: [] };
|
|
115377
115443
|
}
|
|
115378
|
-
return { tool: type || "tool", title:
|
|
115444
|
+
return { tool: type || "tool", title: str(item.title) || type, paths: [] };
|
|
115379
115445
|
}
|
|
115380
115446
|
function argsPreview(raw) {
|
|
115381
115447
|
let value = raw;
|
|
@@ -115394,12 +115460,12 @@ function argsPreview(raw) {
|
|
|
115394
115460
|
}
|
|
115395
115461
|
function fileChangesOf(item) {
|
|
115396
115462
|
const changes = Array.isArray(item.changes) ? item.changes : [];
|
|
115397
|
-
return changes.map((c) => ({ path:
|
|
115463
|
+
return changes.map((c) => ({ path: str(asObj(c).path), diff: str(asObj(c).diff), ...changeKindOf(asObj(asObj(c).kind)) }));
|
|
115398
115464
|
}
|
|
115399
115465
|
function changeKindOf(kind) {
|
|
115400
|
-
const type =
|
|
115466
|
+
const type = str(kind.type);
|
|
115401
115467
|
if (type === "add" || type === "delete") return { change: type };
|
|
115402
|
-
if (type === "update") return
|
|
115468
|
+
if (type === "update") return str(kind.move_path) ? { change: "move", movePath: str(kind.move_path) } : { change: "update" };
|
|
115403
115469
|
return {};
|
|
115404
115470
|
}
|
|
115405
115471
|
|
|
@@ -115533,10 +115599,10 @@ function warnImpossibleContext(used, window2) {
|
|
|
115533
115599
|
|
|
115534
115600
|
// packages/agent-host/src/adapters/codex/normalize.ts
|
|
115535
115601
|
function goalFromCodex(g5) {
|
|
115536
|
-
if (
|
|
115602
|
+
if (str(g5.status) === "complete") return null;
|
|
115537
115603
|
return {
|
|
115538
|
-
objective:
|
|
115539
|
-
status:
|
|
115604
|
+
objective: str(g5.objective),
|
|
115605
|
+
status: str(g5.status) || "active",
|
|
115540
115606
|
...typeof g5.tokenBudget === "number" ? { tokenBudget: g5.tokenBudget } : {},
|
|
115541
115607
|
...typeof g5.tokensUsed === "number" ? { tokensUsed: g5.tokensUsed } : {}
|
|
115542
115608
|
};
|
|
@@ -115547,7 +115613,7 @@ var CompactionMarks = class {
|
|
|
115547
115613
|
/** Whether this notification's compaction marker should be emitted */
|
|
115548
115614
|
admit(n) {
|
|
115549
115615
|
const kind = n.method === "thread/compacted" ? "notice" : "item";
|
|
115550
|
-
const turn =
|
|
115616
|
+
const turn = str(asObj(n.params).turnId);
|
|
115551
115617
|
const waiting = this.open.get(turn);
|
|
115552
115618
|
if (waiting && waiting.kind !== kind) {
|
|
115553
115619
|
if (--waiting.count === 0) this.open.delete(turn);
|
|
@@ -115573,7 +115639,7 @@ function normalizeNotification(sessionId, n) {
|
|
|
115573
115639
|
* polling it again."
|
|
115574
115640
|
*/
|
|
115575
115641
|
case "item/agentMessage/delta":
|
|
115576
|
-
return [{ type: "message_delta", sessionId, role: "assistant", text:
|
|
115642
|
+
return [{ type: "message_delta", sessionId, role: "assistant", text: str(p.delta) || str(p.text), ...messageIdOf(p.itemId) }];
|
|
115577
115643
|
/*
|
|
115578
115644
|
* Reasoning summary (measured for #58). This stream only arrives if model_reasoning_summary
|
|
115579
115645
|
* is turned on in the thread settings — index.ts turns it on. Measured shape:
|
|
@@ -115584,7 +115650,7 @@ function normalizeNotification(sessionId, n) {
|
|
|
115584
115650
|
* twice (the same rule as agentMessage).
|
|
115585
115651
|
*/
|
|
115586
115652
|
case "item/reasoning/summaryTextDelta": {
|
|
115587
|
-
const text2 =
|
|
115653
|
+
const text2 = str(p.delta);
|
|
115588
115654
|
return text2 ? [{ type: "reasoning_delta", sessionId, text: text2 }] : [];
|
|
115589
115655
|
}
|
|
115590
115656
|
case "item/reasoning/summaryPartAdded":
|
|
@@ -115607,25 +115673,25 @@ function normalizeNotification(sessionId, n) {
|
|
|
115607
115673
|
* the assumption that summing the deltas equals the full output does not hold.)
|
|
115608
115674
|
*/
|
|
115609
115675
|
case "item/commandExecution/outputDelta": {
|
|
115610
|
-
const text2 =
|
|
115611
|
-
return text2 ? [{ type: "tool_output_delta", sessionId, callId:
|
|
115676
|
+
const text2 = str(p.delta);
|
|
115677
|
+
return text2 ? [{ type: "tool_output_delta", sessionId, callId: str(p.itemId), text: text2 }] : [];
|
|
115612
115678
|
}
|
|
115613
115679
|
case "item/started": {
|
|
115614
115680
|
const item = asObj(p.item);
|
|
115615
|
-
const type =
|
|
115681
|
+
const type = str(item.type);
|
|
115616
115682
|
if (type === "userMessage" || type === "reasoning" || type === "agentMessage") return [];
|
|
115617
115683
|
if (type === "contextCompaction") return [{ type: "activity", sessionId, activity: "compacting" }];
|
|
115618
115684
|
if (type === "enteredReviewMode") return [{ type: "activity", sessionId, activity: "reviewing" }];
|
|
115619
115685
|
if (type === "exitedReviewMode") return [{ type: "activity", sessionId, activity: null }];
|
|
115620
115686
|
if (type === "imageView") return [];
|
|
115621
115687
|
const s = itemSummary(item);
|
|
115622
|
-
return [{ type: "tool_call", sessionId, callId:
|
|
115688
|
+
return [{ type: "tool_call", sessionId, callId: str(item.id), summary: s, input: itemInput(item) }];
|
|
115623
115689
|
}
|
|
115624
115690
|
case "item/completed": {
|
|
115625
115691
|
const item = asObj(p.item);
|
|
115626
|
-
const type =
|
|
115692
|
+
const type = str(item.type);
|
|
115627
115693
|
if (type === "agentMessage") {
|
|
115628
|
-
return
|
|
115694
|
+
return str(item.text) ? [{ type: "message_delta", sessionId, role: "assistant", text: "", ...messageIdOf(item.id) }] : [];
|
|
115629
115695
|
}
|
|
115630
115696
|
if (type === "userMessage" || type === "reasoning") return [];
|
|
115631
115697
|
if (type === "contextCompaction") {
|
|
@@ -115637,16 +115703,16 @@ function normalizeNotification(sessionId, n) {
|
|
|
115637
115703
|
if (type === "exitedReviewMode") return [{ type: "activity", sessionId, activity: null }];
|
|
115638
115704
|
if (type === "enteredReviewMode") return [];
|
|
115639
115705
|
if (type === "imageView") {
|
|
115640
|
-
const path2 =
|
|
115706
|
+
const path2 = str(item.path);
|
|
115641
115707
|
return path2 ? [{ type: "message_image", sessionId, mime: "", data: "", path: path2 }] : [];
|
|
115642
115708
|
}
|
|
115643
115709
|
const s = itemSummary(item);
|
|
115644
|
-
const ending =
|
|
115645
|
-
const out = [toolResultEvent(sessionId,
|
|
115710
|
+
const ending = str(item.status) === "declined" ? "declined" : str(item.status) === "interrupted" ? "interrupted" : void 0;
|
|
115711
|
+
const out = [toolResultEvent(sessionId, str(item.id), codexItemOk(item), resultSummary(item), ending)];
|
|
115646
115712
|
if (type === "mcpToolCall") out.push(...mcpImageEvents(sessionId, asObj(item.result).content));
|
|
115647
115713
|
const moved = type === "fileChange" ? fileChangesOf(item).flatMap((c) => c.movePath ? [c.movePath] : []) : [];
|
|
115648
115714
|
const paths = [...s.paths, ...moved];
|
|
115649
|
-
if (paths.length > 0 &&
|
|
115715
|
+
if (paths.length > 0 && str(item.status) !== "declined") out.push({ type: "files_touched", sessionId, paths });
|
|
115650
115716
|
return out;
|
|
115651
115717
|
}
|
|
115652
115718
|
/*
|
|
@@ -115673,16 +115739,16 @@ function normalizeNotification(sessionId, n) {
|
|
|
115673
115739
|
case "turn/completed": {
|
|
115674
115740
|
const turn = asObj(p.turn);
|
|
115675
115741
|
const failure3 = asObj(turn.error);
|
|
115676
|
-
if (
|
|
115677
|
-
if (
|
|
115678
|
-
const detail =
|
|
115742
|
+
if (str(turn.status) === "interrupted" && !failure3.message) return [{ type: "state_change", sessionId, state: "waiting_input", reason: "interrupted" }];
|
|
115743
|
+
if (str(turn.status) !== "failed" && !failure3.message) return [{ type: "turn_complete", sessionId }];
|
|
115744
|
+
const detail = str(failure3.additionalDetails);
|
|
115679
115745
|
return [
|
|
115680
115746
|
{
|
|
115681
115747
|
type: "error",
|
|
115682
115748
|
sessionId,
|
|
115683
115749
|
error: {
|
|
115684
115750
|
code: "internal",
|
|
115685
|
-
message: [
|
|
115751
|
+
message: [str(failure3.message) || "The turn failed", detail].filter(Boolean).join("\n"),
|
|
115686
115752
|
retryable: true
|
|
115687
115753
|
}
|
|
115688
115754
|
}
|
|
@@ -115707,7 +115773,7 @@ function normalizeNotification(sessionId, n) {
|
|
|
115707
115773
|
*/
|
|
115708
115774
|
case "account/rateLimits/updated": {
|
|
115709
115775
|
const snapshot2 = asObj(p.rateLimits);
|
|
115710
|
-
const reached =
|
|
115776
|
+
const reached = str(snapshot2.rateLimitReachedType) !== "" || snapshot2.spendControlReached === true;
|
|
115711
115777
|
if (!reached) return [];
|
|
115712
115778
|
const primary = asObj(snapshot2.primary);
|
|
115713
115779
|
const resetsAt = finite(primary.resetsAt);
|
|
@@ -115722,7 +115788,7 @@ function normalizeNotification(sessionId, n) {
|
|
|
115722
115788
|
];
|
|
115723
115789
|
}
|
|
115724
115790
|
case "thread/name/updated":
|
|
115725
|
-
return [{ type: "session_title", sessionId, title:
|
|
115791
|
+
return [{ type: "session_title", sessionId, title: str(p.name), auto: true }];
|
|
115726
115792
|
// Deprecated (0.160.0's binding) and not sent in any measured run — kept for a CLI that still does (#303)
|
|
115727
115793
|
case "thread/compacted":
|
|
115728
115794
|
return [{ type: "compaction", sessionId, failed: false }];
|
|
@@ -115749,17 +115815,17 @@ function normalizeNotification(sessionId, n) {
|
|
|
115749
115815
|
* (`noticeWords`, #342).
|
|
115750
115816
|
*/
|
|
115751
115817
|
case "warning": {
|
|
115752
|
-
const text2 =
|
|
115818
|
+
const text2 = str(p.message).trim();
|
|
115753
115819
|
return text2 ? [{ type: "notice", sessionId, level: "warning", text: text2, oncePerSession: true, ...noticeWords("warning", text2) }] : [];
|
|
115754
115820
|
}
|
|
115755
115821
|
case "configWarning":
|
|
115756
115822
|
case "deprecationNotice": {
|
|
115757
|
-
const text2 = [
|
|
115823
|
+
const text2 = [str(p.summary).trim(), str(p.details).trim()].filter(Boolean).join("\n");
|
|
115758
115824
|
return text2 ? [{ type: "notice", sessionId, level: "warning", text: text2, oncePerSession: true, ...noticeWords(n.method, text2) }] : [];
|
|
115759
115825
|
}
|
|
115760
115826
|
// The auto-review guardian's warning about an action (generated/v2/GuardianWarningNotification.ts); not exercised
|
|
115761
115827
|
case "guardianWarning": {
|
|
115762
|
-
const text2 =
|
|
115828
|
+
const text2 = str(p.message).trim();
|
|
115763
115829
|
return text2 ? [{ type: "notice", sessionId, level: "warning", text: text2, ...noticeWords("guardianWarning", text2) }] : [];
|
|
115764
115830
|
}
|
|
115765
115831
|
/*
|
|
@@ -115769,10 +115835,10 @@ function normalizeNotification(sessionId, n) {
|
|
|
115769
115835
|
* conversation and leaves the model the person picked alone.
|
|
115770
115836
|
*/
|
|
115771
115837
|
case "model/rerouted": {
|
|
115772
|
-
const to =
|
|
115838
|
+
const to = str(p.toModel);
|
|
115773
115839
|
if (!to) return [];
|
|
115774
|
-
const reason =
|
|
115775
|
-
const text2 = `Codex answered this turn with ${to} instead of ${
|
|
115840
|
+
const reason = str(p.reason) === "highRiskCyberActivity" ? "it was flagged as high-risk cyber activity" : str(p.reason);
|
|
115841
|
+
const text2 = `Codex answered this turn with ${to} instead of ${str(p.fromModel) || "the selected model"}${reason ? ` because ${reason}` : ""}`;
|
|
115776
115842
|
return [{ type: "notice", sessionId, level: "warning", text: text2, ...noticeWords("model/rerouted", text2) }];
|
|
115777
115843
|
}
|
|
115778
115844
|
/*
|
|
@@ -115783,11 +115849,11 @@ function normalizeNotification(sessionId, n) {
|
|
|
115783
115849
|
* simply had no such tools. The adapter keeps one line per server until it starts again (index.ts).
|
|
115784
115850
|
*/
|
|
115785
115851
|
case "mcpServer/startupStatus/updated": {
|
|
115786
|
-
if (
|
|
115787
|
-
const name =
|
|
115788
|
-
const reauth =
|
|
115789
|
-
const text2 = `${
|
|
115790
|
-
return [{ type: "notice", sessionId, level: "warning", text: text2, ...noticeWords("mcpStartup", text2,
|
|
115852
|
+
if (str(p.status) !== "failed") return [];
|
|
115853
|
+
const name = str(p.name) || "an MCP server";
|
|
115854
|
+
const reauth = str(p.failureReason) === "reauthenticationRequired" ? " (it needs you to sign in again)" : "";
|
|
115855
|
+
const text2 = `${str(p.error).trim() || `MCP server \`${name}\` failed to start`}${reauth}`;
|
|
115856
|
+
return [{ type: "notice", sessionId, level: "warning", text: text2, ...noticeWords("mcpStartup", text2, str(p.name)) }];
|
|
115791
115857
|
}
|
|
115792
115858
|
/*
|
|
115793
115859
|
* The `error` notification has the shape `{ error, willRetry, threadId, turnId }` (generated
|
|
@@ -115812,13 +115878,13 @@ function normalizeNotification(sessionId, n) {
|
|
|
115812
115878
|
* and sent the last two only.
|
|
115813
115879
|
*/
|
|
115814
115880
|
case "error": {
|
|
115815
|
-
const message =
|
|
115881
|
+
const message = str(asObj(p.error).message) || str(p.message) || "Unknown error";
|
|
115816
115882
|
if (p.willRetry === true) {
|
|
115817
|
-
const why =
|
|
115883
|
+
const why = str(asObj(p.error).additionalDetails);
|
|
115818
115884
|
console.error(`[codex] ${sessionId.slice(0, 8)} retrying after: ${message}${why ? ` (${why})` : ""}`);
|
|
115819
115885
|
return [{ type: "activity", sessionId, activity: "retrying" }];
|
|
115820
115886
|
}
|
|
115821
|
-
if (
|
|
115887
|
+
if (str(p.turnId)) return [];
|
|
115822
115888
|
return [{ type: "error", sessionId, error: { code: "internal", message, retryable: true } }];
|
|
115823
115889
|
}
|
|
115824
115890
|
default:
|
|
@@ -116103,13 +116169,13 @@ function threadIdOf(res) {
|
|
|
116103
116169
|
function childSteps(sessionId, parentCallId, n) {
|
|
116104
116170
|
if (n.method !== "item/started" && n.method !== "item/completed") return [];
|
|
116105
116171
|
const item = asObj(asObj(n.params).item);
|
|
116106
|
-
const type =
|
|
116172
|
+
const type = str(item.type);
|
|
116107
116173
|
if (type === "agentMessage") {
|
|
116108
|
-
const text2 = n.method === "item/completed" ?
|
|
116174
|
+
const text2 = n.method === "item/completed" ? str(item.text) : "";
|
|
116109
116175
|
return text2 ? subagentSteps(sessionId, parentCallId, [{ type: "message_delta", sessionId, role: "assistant", text: text2, ...messageIdOf(item.id) }]) : [];
|
|
116110
116176
|
}
|
|
116111
116177
|
if (type === "reasoning") {
|
|
116112
|
-
const parts = n.method === "item/completed" && Array.isArray(item.summary) ? item.summary.map((x) =>
|
|
116178
|
+
const parts = n.method === "item/completed" && Array.isArray(item.summary) ? item.summary.map((x) => str(x)).filter(Boolean) : [];
|
|
116113
116179
|
return parts.length ? subagentSteps(sessionId, parentCallId, [{ type: "reasoning_delta", sessionId, text: parts.join("\n\n") }]) : [];
|
|
116114
116180
|
}
|
|
116115
116181
|
return subagentSteps(sessionId, parentCallId, normalizeNotification(sessionId, n));
|
|
@@ -116117,18 +116183,20 @@ function childSteps(sessionId, parentCallId, n) {
|
|
|
116117
116183
|
function launchedThreads(n) {
|
|
116118
116184
|
if (n.method !== "item/completed") return [];
|
|
116119
116185
|
const item = asObj(asObj(n.params).item);
|
|
116120
|
-
if (
|
|
116186
|
+
if (str(item.type) !== "collabAgentToolCall" || str(item.tool) !== "spawnAgent" || !codexItemOk(item)) return [];
|
|
116121
116187
|
return (Array.isArray(item.receiverThreadIds) ? item.receiverThreadIds : []).filter((t) => typeof t === "string" && t !== "");
|
|
116122
116188
|
}
|
|
116123
116189
|
var CodexChildTracker = class {
|
|
116124
116190
|
constructor(sessionId) {
|
|
116125
116191
|
this.sessionId = sessionId;
|
|
116192
|
+
this.events = new BackgroundEvents(sessionId);
|
|
116126
116193
|
}
|
|
116127
116194
|
sessionId;
|
|
116128
116195
|
threads = /* @__PURE__ */ new Map();
|
|
116129
116196
|
/** Linked children: thread to its launch call and description. Only these are listed. */
|
|
116130
116197
|
linked = /* @__PURE__ */ new Map();
|
|
116131
|
-
|
|
116198
|
+
/** The events, by the rule both adapters share (`BackgroundEvents`): a repeat of the last list is not sent */
|
|
116199
|
+
events;
|
|
116132
116200
|
/**
|
|
116133
116201
|
* Launch cards held open while the children they started run (#843). A `spawnAgent` item completes the moment the
|
|
116134
116202
|
* child starts (measured: its `item/completed` names the child's thread before the child has done anything), so its
|
|
@@ -116169,7 +116237,7 @@ var CodexChildTracker = class {
|
|
|
116169
116237
|
const t = this.threads.get(thread) ?? { active: false, turnId: null };
|
|
116170
116238
|
this.threads.set(thread, t);
|
|
116171
116239
|
if (n.method === "thread/status/changed") {
|
|
116172
|
-
const type =
|
|
116240
|
+
const type = str(asObj(p.status).type);
|
|
116173
116241
|
if (type === "active") t.active = true;
|
|
116174
116242
|
else if (type === "systemError") {
|
|
116175
116243
|
const was = t.active;
|
|
@@ -116181,15 +116249,15 @@ var CodexChildTracker = class {
|
|
|
116181
116249
|
}
|
|
116182
116250
|
if (n.method === "turn/started") {
|
|
116183
116251
|
t.active = true;
|
|
116184
|
-
t.turnId =
|
|
116252
|
+
t.turnId = str(asObj(p.turn).id) || t.turnId;
|
|
116185
116253
|
return this.changed();
|
|
116186
116254
|
}
|
|
116187
116255
|
if (n.method === "turn/completed") {
|
|
116188
|
-
const raw =
|
|
116256
|
+
const raw = str(asObj(p.turn).status);
|
|
116189
116257
|
t.active = false;
|
|
116190
116258
|
t.turnId = null;
|
|
116191
116259
|
const status = raw === "interrupted" ? "stopped" : raw === "failed" ? "failed" : "completed";
|
|
116192
|
-
const message =
|
|
116260
|
+
const message = str(asObj(asObj(p.turn).error).message);
|
|
116193
116261
|
return [...this.changed([this.ended(thread, status, message || void 0)]), ...this.finished(thread)];
|
|
116194
116262
|
}
|
|
116195
116263
|
return [];
|
|
@@ -116212,7 +116280,7 @@ var CodexChildTracker = class {
|
|
|
116212
116280
|
}
|
|
116213
116281
|
ended(thread, status, summary) {
|
|
116214
116282
|
const task = this.task(thread);
|
|
116215
|
-
return task ? { ...task, status, ...summary
|
|
116283
|
+
return task ? { ...task, status, ...endedSummary(summary) } : null;
|
|
116216
116284
|
}
|
|
116217
116285
|
task(thread) {
|
|
116218
116286
|
const link = this.linked.get(thread);
|
|
@@ -116238,12 +116306,10 @@ var CodexChildTracker = class {
|
|
|
116238
116306
|
}
|
|
116239
116307
|
/** The event when the live set or an ending moved; nothing when neither did. */
|
|
116240
116308
|
changed(ended = []) {
|
|
116241
|
-
|
|
116242
|
-
|
|
116243
|
-
|
|
116244
|
-
|
|
116245
|
-
this.lastLive = key;
|
|
116246
|
-
return [{ type: "background_tasks", sessionId: this.sessionId, live: live2, ...done.length ? { ended: done } : {} }];
|
|
116309
|
+
return this.events.event(
|
|
116310
|
+
this.live(),
|
|
116311
|
+
ended.filter((t) => t !== null)
|
|
116312
|
+
);
|
|
116247
116313
|
}
|
|
116248
116314
|
};
|
|
116249
116315
|
|
|
@@ -116337,20 +116403,20 @@ var CODEX_KNOWN_NOTIFICATIONS = /* @__PURE__ */ new Set([
|
|
|
116337
116403
|
function threadSettingsOf(res) {
|
|
116338
116404
|
if (!res) return null;
|
|
116339
116405
|
const thread = asObj(res.thread);
|
|
116340
|
-
const model =
|
|
116406
|
+
const model = str(res.model) || str(thread.model);
|
|
116341
116407
|
if (!model) return null;
|
|
116342
116408
|
return {
|
|
116343
116409
|
model,
|
|
116344
|
-
effort:
|
|
116345
|
-
serviceTier:
|
|
116410
|
+
effort: str(res.reasoningEffort) || str(thread.reasoningEffort) || null,
|
|
116411
|
+
serviceTier: str(res.serviceTier) || null
|
|
116346
116412
|
};
|
|
116347
116413
|
}
|
|
116348
116414
|
function threadSettingsChanged(sessionId, before, params, launched) {
|
|
116349
116415
|
const s = asObj(asObj(params).threadSettings);
|
|
116350
116416
|
const next = {
|
|
116351
|
-
model:
|
|
116352
|
-
effort:
|
|
116353
|
-
serviceTier:
|
|
116417
|
+
model: str(s.model) || null,
|
|
116418
|
+
effort: str(s.effort) || null,
|
|
116419
|
+
serviceTier: str(s.serviceTier) || null
|
|
116354
116420
|
};
|
|
116355
116421
|
if (!next.model) return { next: before, events: [] };
|
|
116356
116422
|
if (!before) return { next, events: [] };
|
|
@@ -116410,18 +116476,18 @@ function approvalDetailFrom(method, params, itemChanges) {
|
|
|
116410
116476
|
const net2 = asObj(params.networkApprovalContext);
|
|
116411
116477
|
return {
|
|
116412
116478
|
kind: "command",
|
|
116413
|
-
command:
|
|
116414
|
-
cwd:
|
|
116415
|
-
...
|
|
116416
|
-
...
|
|
116417
|
-
...
|
|
116479
|
+
command: str(item.command) || str(params.command),
|
|
116480
|
+
cwd: str(item.cwd) || str(params.cwd),
|
|
116481
|
+
...str(params.reason) ? { reason: str(params.reason) } : {},
|
|
116482
|
+
...str(net2.host) ? { network: { host: str(net2.host), protocol: str(net2.protocol) } } : {},
|
|
116483
|
+
...str(params.kind) === "writeStdin" ? { stdin: true } : {}
|
|
116418
116484
|
};
|
|
116419
116485
|
}
|
|
116420
116486
|
if (method === "item/fileChange/requestApproval") return fileEditDetail(itemChanges ?? []);
|
|
116421
116487
|
if (method === "applyPatchApproval") {
|
|
116422
116488
|
const changes = Object.entries(asObj(params.fileChanges)).map(([path2, c]) => ({
|
|
116423
116489
|
path: path2,
|
|
116424
|
-
diff:
|
|
116490
|
+
diff: str(asObj(c).unified_diff) || str(asObj(c).content),
|
|
116425
116491
|
// generated FileChange: the same `type` (add, delete, update with move_path) as the v2 kind
|
|
116426
116492
|
...changeKindOf(asObj(c))
|
|
116427
116493
|
}));
|
|
@@ -116565,7 +116631,7 @@ function approvalKindOf(meta3) {
|
|
|
116565
116631
|
return typeof kind === "string" ? kind : null;
|
|
116566
116632
|
}
|
|
116567
116633
|
function appApprovalDetail(server2, message, meta3) {
|
|
116568
|
-
const m =
|
|
116634
|
+
const m = asObj(meta3);
|
|
116569
116635
|
const title = typeof m.tool_title === "string" && m.tool_title ? m.tool_title : typeof message === "string" ? message : "";
|
|
116570
116636
|
const params = m.tool_params === void 0 ? "" : ` ${JSON.stringify(m.tool_params).slice(0, 1e3)}`;
|
|
116571
116637
|
return { kind: "other", raw: `${server2} \xB7 ${title}${params}` };
|
|
@@ -117461,7 +117527,7 @@ var CodexSession = class {
|
|
|
117461
117527
|
for (const e of normalizeNotification(this.sessionId, n)) {
|
|
117462
117528
|
if (e.type === "error" && this.inputReceipts.size) this.interrupt(new Error(e.error.message));
|
|
117463
117529
|
if (e.type === "message_image" && !e.data && e.path) {
|
|
117464
|
-
void imageEventFromDisk(this.sessionId, e.path).then((
|
|
117530
|
+
void imageEventFromDisk(this.sessionId, e.path).then((filled2) => this.emit(filled2));
|
|
117465
117531
|
continue;
|
|
117466
117532
|
}
|
|
117467
117533
|
if (e.type === "compaction" && !this.compactions.admit(n)) continue;
|
|
@@ -118291,6 +118357,7 @@ var HandoffMarkers = class {
|
|
|
118291
118357
|
};
|
|
118292
118358
|
|
|
118293
118359
|
// packages/agent-host/src/dev-services/store/settings.ts
|
|
118360
|
+
var SESSION_SETTING_OF = `length(key) > length(@sessionId) + 1 AND substr(key, -length(@sessionId) - 1) = ':' || @sessionId`;
|
|
118294
118361
|
function flagSetting(settings, key, byDefault) {
|
|
118295
118362
|
return {
|
|
118296
118363
|
read: () => {
|
|
@@ -118691,13 +118758,26 @@ var MessageRecords = class {
|
|
|
118691
118758
|
import Database from "better-sqlite3";
|
|
118692
118759
|
import { existsSync as existsSync16 } from "node:fs";
|
|
118693
118760
|
|
|
118694
|
-
// packages/agent-host/src/dev-services/store/
|
|
118761
|
+
// packages/agent-host/src/dev-services/store/store-keys.ts
|
|
118695
118762
|
var APP_SETTINGS_DDL = `
|
|
118696
118763
|
CREATE TABLE IF NOT EXISTS app_settings (
|
|
118697
118764
|
key TEXT PRIMARY KEY,
|
|
118698
118765
|
value TEXT NOT NULL
|
|
118699
118766
|
);
|
|
118700
118767
|
`;
|
|
118768
|
+
function readStoreKey(db, key) {
|
|
118769
|
+
const table = db.prepare(`SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'app_settings'`).get();
|
|
118770
|
+
if (!table) return null;
|
|
118771
|
+
const row = db.prepare(`SELECT value FROM app_settings WHERE key = ?`).get(key);
|
|
118772
|
+
return row?.value ?? null;
|
|
118773
|
+
}
|
|
118774
|
+
function writeStoreKey(db, key, value) {
|
|
118775
|
+
db.exec(APP_SETTINGS_DDL);
|
|
118776
|
+
if (value === null) db.prepare(`DELETE FROM app_settings WHERE key = ?`).run(key);
|
|
118777
|
+
else db.prepare(`INSERT INTO app_settings (key, value) VALUES (?, ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value`).run(key, value);
|
|
118778
|
+
}
|
|
118779
|
+
|
|
118780
|
+
// packages/agent-host/src/dev-services/store/migrations/context.ts
|
|
118701
118781
|
var MigrationRange = class {
|
|
118702
118782
|
constructor(host) {
|
|
118703
118783
|
this.host = host;
|
|
@@ -118753,15 +118833,12 @@ var ReaderGate = class {
|
|
|
118753
118833
|
}
|
|
118754
118834
|
/** null when nothing is recorded yet: a new store, or one last opened by a host from before #292 */
|
|
118755
118835
|
storedMinReader() {
|
|
118756
|
-
const
|
|
118757
|
-
|
|
118758
|
-
const row = this.db.prepare(`SELECT value FROM app_settings WHERE key = ?`).get(MIN_READER_KEY);
|
|
118759
|
-
const n = row ? Number(row.value) : NaN;
|
|
118836
|
+
const raw = readStoreKey(this.db, MIN_READER_KEY);
|
|
118837
|
+
const n = raw !== null ? Number(raw) : NaN;
|
|
118760
118838
|
return Number.isInteger(n) && n >= 0 ? n : null;
|
|
118761
118839
|
}
|
|
118762
118840
|
writeMinReader(version2) {
|
|
118763
|
-
this.db
|
|
118764
|
-
this.db.prepare(`INSERT INTO app_settings (key, value) VALUES (?, ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value`).run(MIN_READER_KEY, String(version2));
|
|
118841
|
+
writeStoreKey(this.db, MIN_READER_KEY, String(version2));
|
|
118765
118842
|
}
|
|
118766
118843
|
};
|
|
118767
118844
|
|
|
@@ -118776,8 +118853,7 @@ var OwedVacuum = class {
|
|
|
118776
118853
|
db;
|
|
118777
118854
|
/** A `VACUUM` a step queued has not run yet: the host was stopped during it (#396) */
|
|
118778
118855
|
get vacuumOwed() {
|
|
118779
|
-
|
|
118780
|
-
return !!table && !!this.db.prepare(`SELECT 1 FROM app_settings WHERE key = ?`).get(VACUUM_OWED_KEY);
|
|
118856
|
+
return readStoreKey(this.db, VACUUM_OWED_KEY) !== null;
|
|
118781
118857
|
}
|
|
118782
118858
|
/**
|
|
118783
118859
|
* Runs the owed `VACUUM` and deletes the record of it. `why`, when given, is said in host.log on success.
|
|
@@ -118798,7 +118874,7 @@ var OwedVacuum = class {
|
|
|
118798
118874
|
console.error(`[store] could not vacuum; ${mb(free)} stay free in the file: ${err.message}`);
|
|
118799
118875
|
return null;
|
|
118800
118876
|
} finally {
|
|
118801
|
-
this.db
|
|
118877
|
+
writeStoreKey(this.db, VACUUM_OWED_KEY, null);
|
|
118802
118878
|
}
|
|
118803
118879
|
const done = { before, after: size(), ms: Date.now() - t02 };
|
|
118804
118880
|
if (why) console.error(`[store] vacuumed ${mb(done.before)} -> ${mb(done.after)} (${done.ms}ms): ${why}`);
|
|
@@ -118925,8 +119001,7 @@ var MigrationRunner = class extends ReaderGate {
|
|
|
118925
119001
|
* what the vacuum did when it ran.
|
|
118926
119002
|
*/
|
|
118927
119003
|
vacuumAfterStep(report) {
|
|
118928
|
-
this.db
|
|
118929
|
-
this.db.prepare(`INSERT INTO app_settings (key, value) VALUES (?, '1') ON CONFLICT(key) DO UPDATE SET value = excluded.value`).run(VACUUM_OWED_KEY);
|
|
119004
|
+
writeStoreKey(this.db, VACUUM_OWED_KEY, "1");
|
|
118930
119005
|
this.afterStep(() => {
|
|
118931
119006
|
const done = this.runOwedVacuum();
|
|
118932
119007
|
if (done) report?.(done);
|
|
@@ -119004,18 +119079,10 @@ var MigrationRunner = class extends ReaderGate {
|
|
|
119004
119079
|
}
|
|
119005
119080
|
}
|
|
119006
119081
|
storedDeferred() {
|
|
119007
|
-
|
|
119008
|
-
if (!table) return [];
|
|
119009
|
-
const row = this.db.prepare(`SELECT value FROM app_settings WHERE key = ?`).get(DEFERRED_KEY);
|
|
119010
|
-
return readJsonList(row?.value, external_exports.number().int().positive());
|
|
119082
|
+
return readJsonList(readStoreKey(this.db, DEFERRED_KEY), external_exports.number().int().positive());
|
|
119011
119083
|
}
|
|
119012
119084
|
writeDeferred(steps) {
|
|
119013
|
-
this.db.
|
|
119014
|
-
if (steps.length === 0) {
|
|
119015
|
-
this.db.prepare(`DELETE FROM app_settings WHERE key = ?`).run(DEFERRED_KEY);
|
|
119016
|
-
return;
|
|
119017
|
-
}
|
|
119018
|
-
this.db.prepare(`INSERT INTO app_settings (key, value) VALUES (?, ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value`).run(DEFERRED_KEY, JSON.stringify([...steps].sort((a, b2) => a - b2)));
|
|
119085
|
+
writeStoreKey(this.db, DEFERRED_KEY, steps.length === 0 ? null : JSON.stringify([...steps].sort((a, b2) => a - b2)));
|
|
119019
119086
|
}
|
|
119020
119087
|
};
|
|
119021
119088
|
|
|
@@ -120388,6 +120455,22 @@ var StepsV55 = class extends MigrationRange {
|
|
|
120388
120455
|
END`
|
|
120389
120456
|
).run({ mark: ASK_PROJECT_MARK });
|
|
120390
120457
|
}
|
|
120458
|
+
},
|
|
120459
|
+
{
|
|
120460
|
+
to: 56,
|
|
120461
|
+
// Drops `usage_facts`: an older schema.sql recreates it empty, and builds up to beta.10 still ran DELETE FROM it
|
|
120462
|
+
breaksOlderReaders: true,
|
|
120463
|
+
/**
|
|
120464
|
+
* The unused usage aggregate goes (#423). It was planned for the first milestone and never built: no build ever
|
|
120465
|
+
* wrote a row. Deleting a project was the last statement that named it, and #420 removed that; the table has
|
|
120466
|
+
* been left alone by every release since, which is the "one release later" that §5.1 rule 2 asks for.
|
|
120467
|
+
*
|
|
120468
|
+
* `schema.sql` no longer creates it either, so a new store and a migrated one end with the same tables. Nothing
|
|
120469
|
+
* is lost: there is no row to keep. `IF EXISTS` because a fresh store never had the table.
|
|
120470
|
+
*/
|
|
120471
|
+
run: () => {
|
|
120472
|
+
this.db.exec(`DROP TABLE IF EXISTS usage_facts`);
|
|
120473
|
+
}
|
|
120391
120474
|
}
|
|
120392
120475
|
];
|
|
120393
120476
|
}
|
|
@@ -120875,14 +120958,13 @@ var SessionRecords = class {
|
|
|
120875
120958
|
// packages/agent-host/src/dev-services/store/trash.ts
|
|
120876
120959
|
function parseTrashRecord(json2) {
|
|
120877
120960
|
const r = asObj(parseJson(json2));
|
|
120878
|
-
const str3 = (v) => typeof v === "string" && v ? v : null;
|
|
120879
120961
|
return {
|
|
120880
|
-
projectId:
|
|
120881
|
-
projectName:
|
|
120882
|
-
projectPath:
|
|
120962
|
+
projectId: filled(r.projectId),
|
|
120963
|
+
projectName: filled(r.projectName),
|
|
120964
|
+
projectPath: filled(r.projectPath),
|
|
120883
120965
|
removeExternal: r.removeExternal === true,
|
|
120884
120966
|
removeWorktree: r.removeWorktree === true,
|
|
120885
|
-
...r.recovery && typeof r.recovery
|
|
120967
|
+
...isObj(r.recovery) && typeof r.recovery.snapshot === "string" && typeof r.recovery.tip === "string" && typeof r.recovery.changedFiles === "number" && typeof r.recovery.commits === "number" ? { recovery: r.recovery } : {}
|
|
120886
120968
|
};
|
|
120887
120969
|
}
|
|
120888
120970
|
var DELETE_CHUNK = 250;
|
|
@@ -120964,6 +121046,10 @@ var TrashRecords = class {
|
|
|
120964
121046
|
* the whole took 4.1s, with the event loop turning 231 times). The rows that are not messages, and the session row, go in the same
|
|
120965
121047
|
* transaction as the last chunk, so a purge cut short leaves the session in the trash with fewer messages, to be
|
|
120966
121048
|
* purged again, and never messages without a session.
|
|
121049
|
+
*
|
|
121050
|
+
* The settings kept per session go too, all of them by their shape (`SESSION_SETTING_OF`) rather than by name: the
|
|
121051
|
+
* purge used to name two of them, and every key added since stayed behind for good (a process's tool prefix and launch
|
|
121052
|
+
* settings, its fresh-start mark, its last import, a paused report).
|
|
120967
121053
|
*/
|
|
120968
121054
|
async purgeSession(sessionId, chunk = DELETE_CHUNK) {
|
|
120969
121055
|
if (!this.isTrashed(sessionId)) return false;
|
|
@@ -120990,8 +121076,7 @@ var TrashRecords = class {
|
|
|
120990
121076
|
this.db.prepare(`DELETE FROM agent_start_requests WHERE caller_session_id = ?`).run(sessionId);
|
|
120991
121077
|
this.db.prepare(`DELETE FROM delegated_turns WHERE session_id = ? OR caller_session_id = ?`).run(sessionId, sessionId);
|
|
120992
121078
|
this.db.prepare(`DELETE FROM queued_requests WHERE session_id = ? OR caller_session_id = ?`).run(sessionId, sessionId);
|
|
120993
|
-
this.db.prepare(`DELETE FROM app_settings WHERE
|
|
120994
|
-
this.db.prepare(`DELETE FROM app_settings WHERE key = ?`).run(`hub_ask_depth:${sessionId}`);
|
|
121079
|
+
this.db.prepare(`DELETE FROM app_settings WHERE ${SESSION_SETTING_OF}`).run({ sessionId });
|
|
120995
121080
|
this.db.prepare(`DELETE FROM sessions WHERE id = ? AND deleted_at IS NOT NULL`).run(sessionId);
|
|
120996
121081
|
return true;
|
|
120997
121082
|
});
|
|
@@ -121063,8 +121148,7 @@ var TrashRecords = class {
|
|
|
121063
121148
|
* of a session caught here are dropped by hand — a session in the trash must not turn up in a search.
|
|
121064
121149
|
*
|
|
121065
121150
|
* The rows that belong to the project go with it as before: project-scope rules, the answers given to its apps, and
|
|
121066
|
-
* the app runs and commit links that point at no session still here.
|
|
121067
|
-
* wrote a row to it, and this build is the first that leaves it alone, so a later step can drop it; schema.sql.) Rows that point at a session in the trash stay with that session until it is
|
|
121151
|
+
* the app runs and commit links that point at no session still here. Rows that point at a session in the trash stay with that session until it is
|
|
121068
121152
|
* deleted for good: its own rules, its commit links, the app runs it started or ran in. A restore that registers
|
|
121069
121153
|
* the folder again under the same id finds them where they were.
|
|
121070
121154
|
*/
|
|
@@ -121211,22 +121295,6 @@ var Store = class extends MigrationRunner {
|
|
|
121211
121295
|
this.checkpoint();
|
|
121212
121296
|
this.db.close();
|
|
121213
121297
|
}
|
|
121214
|
-
/*
|
|
121215
|
-
* Everything below only passes the call on to the module named in its heading. They are the last pass-throughs: #1099,
|
|
121216
|
-
* in the merge queue, still calls them on `Store` and hands the whole store to `labelOf` (#428), and they go once it
|
|
121217
|
-
* lands. New code names the module.
|
|
121218
|
-
*/
|
|
121219
|
-
// ── MessageRecords (store/messages.ts) ──
|
|
121220
|
-
loadMessages(sessionId, limit, beforeSeq, opts) {
|
|
121221
|
-
return this.messages.loadMessages(sessionId, limit, beforeSeq, opts);
|
|
121222
|
-
}
|
|
121223
|
-
loadMessagesFrom(sessionId, afterSeq, limit, opts) {
|
|
121224
|
-
return this.messages.loadMessagesFrom(sessionId, afterSeq, limit, opts);
|
|
121225
|
-
}
|
|
121226
|
-
// ── SettingsRecords (store/settings.ts) ──
|
|
121227
|
-
appSetting(key) {
|
|
121228
|
-
return this.settings.appSetting(key);
|
|
121229
|
-
}
|
|
121230
121298
|
};
|
|
121231
121299
|
var WAL_SIZE_LIMIT = 64 * 1024 * 1024;
|
|
121232
121300
|
|
|
@@ -121314,6 +121382,16 @@ function appSettingRests(settings) {
|
|
|
121314
121382
|
|
|
121315
121383
|
// packages/agent-host/src/dev-services/git-pr.ts
|
|
121316
121384
|
var OK2 = { timeout: 1e4, maxBuffer: 32 * 1024 * 1024 };
|
|
121385
|
+
var GH_STDERR_KEEP = 4096;
|
|
121386
|
+
var ghFailuresSaid = /* @__PURE__ */ new Set();
|
|
121387
|
+
function noteGhFailure(branch, e) {
|
|
121388
|
+
const lines = String(e.stderr ?? "").split(/\r?\n/).map((l) => l.trim()).filter(Boolean);
|
|
121389
|
+
if (!lines.length || lines.some((l) => /no pull requests? found/i.test(l))) return;
|
|
121390
|
+
const why = lines[0].slice(0, 300);
|
|
121391
|
+
if (ghFailuresSaid.has(why)) return;
|
|
121392
|
+
ghFailuresSaid.add(why);
|
|
121393
|
+
console.error(`[git] gh could not read the pull request of ${branch}: ${why}`);
|
|
121394
|
+
}
|
|
121317
121395
|
async function gitBranchPr(projectCwd, branch, signal, timeoutMs = OK2.timeout) {
|
|
121318
121396
|
const { child } = spawnGrouped(programPath("gh"), ["pr", "view", branch, "--json", "number,state,url,headRefOid"], {
|
|
121319
121397
|
cwd: projectCwd,
|
|
@@ -121325,10 +121403,13 @@ async function gitBranchPr(projectCwd, branch, signal, timeoutMs = OK2.timeout)
|
|
|
121325
121403
|
outBytes += chunk.length;
|
|
121326
121404
|
if (outBytes <= OK2.maxBuffer) out.push(chunk);
|
|
121327
121405
|
});
|
|
121328
|
-
|
|
121406
|
+
let err = "";
|
|
121407
|
+
child.stderr.on("data", (chunk) => {
|
|
121408
|
+
err = (err + chunk.toString("utf8")).slice(-GH_STDERR_KEEP);
|
|
121409
|
+
});
|
|
121329
121410
|
const run4 = new Promise((resolve18, reject) => {
|
|
121330
121411
|
child.once("error", reject);
|
|
121331
|
-
child.once("close", (code2) => code2 === 0 ? resolve18(Buffer.concat(out).toString("utf8")) : reject(Object.assign(new Error(`gh exited with ${code2}`), { code: code2 })));
|
|
121412
|
+
child.once("close", (code2) => code2 === 0 ? resolve18(Buffer.concat(out).toString("utf8")) : reject(Object.assign(new Error(`gh exited with ${code2}`), { code: code2, stderr: err })));
|
|
121332
121413
|
});
|
|
121333
121414
|
const closed = new Promise((done) => child.once("close", () => done()));
|
|
121334
121415
|
const exited = new Promise((done) => child.once("exit", () => done()));
|
|
@@ -121359,7 +121440,9 @@ async function gitBranchPr(projectCwd, branch, signal, timeoutMs = OK2.timeout)
|
|
|
121359
121440
|
...typeof j2.headRefOid === "string" && j2.headRefOid ? { headOid: j2.headRefOid } : {}
|
|
121360
121441
|
};
|
|
121361
121442
|
} catch (e) {
|
|
121362
|
-
|
|
121443
|
+
if (e.code === "ENOENT") return "unavailable";
|
|
121444
|
+
noteGhFailure(branch, e);
|
|
121445
|
+
return null;
|
|
121363
121446
|
} finally {
|
|
121364
121447
|
clearTimeout(timer);
|
|
121365
121448
|
if (onAbort) signal?.removeEventListener("abort", onAbort);
|
|
@@ -122948,7 +123031,7 @@ var AppSessions = class {
|
|
|
122948
123031
|
const rt2 = this.host.appsHub?.rt;
|
|
122949
123032
|
if (!rt2) throw rpcError("External apps are unavailable");
|
|
122950
123033
|
const app2 = rt2.list().find((a) => a.appId === ref.appId && a.projectId === ref.projectId);
|
|
122951
|
-
if (!app2) throw rpcError(
|
|
123034
|
+
if (!app2) throw rpcError(noSuchAppText(ref));
|
|
122952
123035
|
if (!app2.trusted) {
|
|
122953
123036
|
throw rpcError("Centralu does not give a builder to an app in a project it does not trust \u2014 trust the project, and the app can start and be tested");
|
|
122954
123037
|
}
|
|
@@ -126416,7 +126499,7 @@ function createRpcHandler(mgr2, adapters2, { terminals: terminals2, updates: upd
|
|
|
126416
126499
|
if (projectId === null) return { kind: "snapshots", snapshots: apps.snapshots({ appId, projectId }).map(({ stamp: _stamp, depth: _depth, ...s }) => s) };
|
|
126417
126500
|
const project2 = (await mgr2.listProjects()).find((x) => x.id === projectId);
|
|
126418
126501
|
const app2 = apps.list().find((a) => a.appId === appId && a.projectId === projectId);
|
|
126419
|
-
if (!project2 || !app2) throw rpcError(
|
|
126502
|
+
if (!project2 || !app2) throw rpcError(noSuchAppText({ projectId, appId }));
|
|
126420
126503
|
const { repo, commits } = await gitLogPath(project2.path, relative6(project2.path, app2.dir), 20);
|
|
126421
126504
|
return { kind: "git", repo, commits };
|
|
126422
126505
|
},
|
|
@@ -129277,11 +129360,48 @@ var SSH_COMMAND_TIMEOUT_MS = 6e4;
|
|
|
129277
129360
|
var SSH_DETACH_TIMEOUT_MS = 12e4;
|
|
129278
129361
|
var SSH_EXEC_TIMEOUT_MS = 30 * 6e4;
|
|
129279
129362
|
var FORWARD_STDERR_KEEP = 16 * 1024;
|
|
129363
|
+
var CLIXML_MARK = /<\/?(?:Objs|Obj|S|MS|PR|TN|TNRef|Props|I32|I64|B|AV)[\s>/]|_x00[0-9A-F]{2}_/;
|
|
129364
|
+
var ANSI = /\x1b\[[0-?]*[ -/]*[@-~]|\x1b[@-_]?/g;
|
|
129365
|
+
function powershellErrorLine(line) {
|
|
129366
|
+
const l = line.trim();
|
|
129367
|
+
if (l === "+" || l.startsWith("+ ")) return null;
|
|
129368
|
+
if (/^\S+ \S+:\d+ \S+:\d+$/.test(l) || /^(?:At|위치) .+:\d+ \S+:\d+$/.test(l)) return null;
|
|
129369
|
+
if (/^Line \|$/.test(l) || /^\d+ \|/.test(l) || /^\|\s*~*$/.test(l)) return null;
|
|
129370
|
+
const gutter = /^\| ?(.*)$/.exec(l);
|
|
129371
|
+
return gutter ? gutter[1] : line;
|
|
129372
|
+
}
|
|
129373
|
+
function clixmlErrorText(xml) {
|
|
129374
|
+
return [...xml.matchAll(/<S S="Error">([\s\S]*?)<\/S>/g)].map(
|
|
129375
|
+
(m) => m[1].replace(/_x([0-9A-Fa-f]{4})_/g, (_, hex3) => String.fromCharCode(parseInt(hex3, 16))).replace(/&(lt|gt|quot|apos|amp);/g, (_, e) => ({ lt: "<", gt: ">", quot: '"', apos: "'", amp: "&" })[e])
|
|
129376
|
+
).join("").replace(ANSI, "").split(/\r?\n/).flatMap((l) => {
|
|
129377
|
+
const kept = powershellErrorLine(l);
|
|
129378
|
+
return kept === null ? [] : [kept];
|
|
129379
|
+
}).join("\n");
|
|
129380
|
+
}
|
|
129381
|
+
function plainPart(text2) {
|
|
129382
|
+
const mark = text2.search(CLIXML_MARK);
|
|
129383
|
+
return mark < 0 ? text2 : text2.slice(0, text2.lastIndexOf("\n", mark) + 1);
|
|
129384
|
+
}
|
|
129280
129385
|
function withoutClixml(s) {
|
|
129281
|
-
let text2 = s.replace(
|
|
129282
|
-
const
|
|
129283
|
-
|
|
129284
|
-
|
|
129386
|
+
let text2 = s.replace(/^#< CLIXML\r?$/gm, "");
|
|
129387
|
+
const parts = [];
|
|
129388
|
+
const firstEnd = text2.indexOf("</Objs>");
|
|
129389
|
+
const firstOpen = text2.search(/<Objs[\s>]/);
|
|
129390
|
+
if (firstEnd >= 0 && (firstOpen < 0 || firstEnd < firstOpen)) {
|
|
129391
|
+
const cut = plainPart(text2.slice(0, firstEnd));
|
|
129392
|
+
parts.push(cut, "\n", clixmlErrorText(text2.slice(cut.length, firstEnd)), "\n");
|
|
129393
|
+
text2 = text2.slice(firstEnd + "</Objs>".length);
|
|
129394
|
+
}
|
|
129395
|
+
for (; ; ) {
|
|
129396
|
+
const open6 = text2.search(/<Objs[\s>]/);
|
|
129397
|
+
if (open6 < 0) break;
|
|
129398
|
+
parts.push(plainPart(text2.slice(0, open6)), "\n");
|
|
129399
|
+
const end = text2.indexOf("</Objs>", open6);
|
|
129400
|
+
parts.push(clixmlErrorText(end < 0 ? text2.slice(open6) : text2.slice(open6, end)), "\n");
|
|
129401
|
+
text2 = end < 0 ? "" : text2.slice(end + "</Objs>".length);
|
|
129402
|
+
}
|
|
129403
|
+
parts.push(plainPart(text2));
|
|
129404
|
+
return parts.join("").replace(ANSI, "").split(/\r?\n/);
|
|
129285
129405
|
}
|
|
129286
129406
|
function lastLine(s, ansi = ansiText) {
|
|
129287
129407
|
const lines = withoutClixml(s).map((l) => l.trim()).filter((l) => l && !l.startsWith("**") && !/^Node\.js v\d/.test(l) && !/^at /.test(l));
|
|
@@ -129461,7 +129581,13 @@ try {
|
|
|
129461
129581
|
if ($LASTEXITCODE -ne 0) { throw 'node_runs' }
|
|
129462
129582
|
New-Item -ItemType Directory -Force (Join-Path $r 'node') | Out-Null
|
|
129463
129583
|
if (Test-Path $n) { Remove-Item -Recurse -Force $n }
|
|
129464
|
-
|
|
129584
|
+
# Windows refuses to rename a folder while something holds a file in it, and an on-access scanner holds the node.exe
|
|
129585
|
+
# just run for a moment ("Access to the path is denied", #368): the rename is tried again for up to 15 s. A rename
|
|
129586
|
+
# and nothing else: Move-Item, refused, went on to move the folder's files one by one and left half of it at $n.
|
|
129587
|
+
# A test's stand-in for the scanner says it holds the file by creating CENTRALU_TEST_NODE_PLACE_GATE; unset, nothing waits.
|
|
129588
|
+
$g = $env:CENTRALU_TEST_NODE_PLACE_GATE
|
|
129589
|
+
if ($g) { $end = (Get-Date).AddSeconds(60); while (-not (Test-Path -LiteralPath $g) -and (Get-Date) -lt $end) { Start-Sleep -Milliseconds 20 } }
|
|
129590
|
+
for ($i = 1; ; $i++) { try { [IO.Directory]::Move($k, $n); break } catch { if ($i -ge 60) { throw }; Start-Sleep -Milliseconds 250 } }
|
|
129465
129591
|
Say 'node ok'
|
|
129466
129592
|
} catch {
|
|
129467
129593
|
$m = if ($_.Exception.Message) { $_.Exception.Message } else { "$_" }
|
|
@@ -132401,6 +132527,7 @@ var Router = class {
|
|
|
132401
132527
|
const failed3 = Array.isArray(out.failed) ? out.failed : [];
|
|
132402
132528
|
out = { ...out, failed: [...failed3, ...missed.map((m) => ({ sessionId: m.id, name: m.name, error: "this machine could not be reached, so its trash was not emptied" }))] };
|
|
132403
132529
|
}
|
|
132530
|
+
if (method === "trash.list" && missed.length && isObj(out)) out = { ...out, unreached: missed.map((m) => ({ machineId: m.id, name: m.name })) };
|
|
132404
132531
|
return out;
|
|
132405
132532
|
}
|
|
132406
132533
|
};
|
|
@@ -132737,7 +132864,7 @@ var handedToken = launch.tokenOnStdin ? await readHandedToken(process.stdin).cat
|
|
|
132737
132864
|
console.error(`[agent-host] the launcher did not hand over the token: ${e.message}`);
|
|
132738
132865
|
process.exit(1);
|
|
132739
132866
|
}) : launch.token;
|
|
132740
|
-
var BUILD = true ? "
|
|
132867
|
+
var BUILD = true ? "c807879" : "dev";
|
|
132741
132868
|
var { values } = parseArgs({
|
|
132742
132869
|
options: {
|
|
132743
132870
|
port: { type: "string", default: "5175" },
|