@alan-ai-hq/agent-manager-linux-arm64 0.1.137 → 0.1.139
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/alan-agent.cjs +2220 -334
- package/alan-holder.cjs +206 -61
- package/package.json +1 -1
package/alan-agent.cjs
CHANGED
|
@@ -20782,7 +20782,11 @@ var init_github_proxy = __esm({
|
|
|
20782
20782
|
];
|
|
20783
20783
|
gitHubProxyUpstreamSchema = external_exports.enum(GITHUB_PROXY_UPSTREAMS);
|
|
20784
20784
|
GITHUB_PROXY_PLACEHOLDER_TOKEN = "proxy-injected";
|
|
20785
|
-
GITHUB_PROXY_REFUSAL_CODES = [
|
|
20785
|
+
GITHUB_PROXY_REFUSAL_CODES = [
|
|
20786
|
+
"host_not_proxied",
|
|
20787
|
+
"machine_not_allowed",
|
|
20788
|
+
"github_not_connected"
|
|
20789
|
+
];
|
|
20786
20790
|
gitHubProxyErrorSchema = external_exports.object({
|
|
20787
20791
|
message: external_exports.string().min(1),
|
|
20788
20792
|
documentation_url: external_exports.string(),
|
|
@@ -21762,6 +21766,9 @@ For any UI or design work, read and follow the \`uiux\` skill in \`.agents/skill
|
|
|
21762
21766
|
});
|
|
21763
21767
|
|
|
21764
21768
|
// ../shared/dist/agent/attachment-mention.js
|
|
21769
|
+
function attachmentMentionPattern() {
|
|
21770
|
+
return /@\[attachment:([^:\]\s]+):(.*?)\](?=[.,;:!?)]*(?:\s|$))/gi;
|
|
21771
|
+
}
|
|
21765
21772
|
var init_attachment_mention = __esm({
|
|
21766
21773
|
"../shared/dist/agent/attachment-mention.js"() {
|
|
21767
21774
|
"use strict";
|
|
@@ -22238,6 +22245,22 @@ var init_agent = __esm({
|
|
|
22238
22245
|
}
|
|
22239
22246
|
});
|
|
22240
22247
|
|
|
22248
|
+
// ../shared/dist/agent/transcript/preview.js
|
|
22249
|
+
function toPreviewText(value2, limit) {
|
|
22250
|
+
const text2 = value2.replace(/```[\s\S]*?```/g, (block) => block.replace(/```\w*\n?|```/g, " ")).replace(/!\[[^\]]*\]\([^)]*\)/g, "").replace(/\[([^\]]+)\]\([^)]*\)/g, "$1").replace(/`([^`]+)`/g, "$1").replace(/^\s{0,3}#{1,6}\s+/gm, "").replace(/^\s{0,3}>\s?/gm, "").replace(/^\s{0,3}(?:[-*+]|\d+\.)\s+/gm, "").replace(/^\s{0,3}(?:[-*_]\s*){3,}$/gm, "").replace(/\*\*([^*]+)\*\*/g, "$1").replace(/__([^_]+)__/g, "$1").replace(/\*([^*\n]+)\*/g, "$1").replace(/~~([^~]+)~~/g, "$1").replace(/\s+/g, " ").trim();
|
|
22251
|
+
if (text2.length <= limit)
|
|
22252
|
+
return text2;
|
|
22253
|
+
const clipped = text2.slice(0, limit - 1);
|
|
22254
|
+
const lastSpace = clipped.lastIndexOf(" ");
|
|
22255
|
+
const body = lastSpace > limit * 0.6 ? clipped.slice(0, lastSpace) : clipped;
|
|
22256
|
+
return `${body.trimEnd()}\u2026`;
|
|
22257
|
+
}
|
|
22258
|
+
var init_preview = __esm({
|
|
22259
|
+
"../shared/dist/agent/transcript/preview.js"() {
|
|
22260
|
+
"use strict";
|
|
22261
|
+
}
|
|
22262
|
+
});
|
|
22263
|
+
|
|
22241
22264
|
// ../shared/dist/agent/transcript/index.js
|
|
22242
22265
|
var init_transcript = __esm({
|
|
22243
22266
|
"../shared/dist/agent/transcript/index.js"() {
|
|
@@ -22344,23 +22367,31 @@ var init_chunk_YXWJW7I5 = __esm({
|
|
|
22344
22367
|
}
|
|
22345
22368
|
});
|
|
22346
22369
|
|
|
22347
|
-
// ../agent-core/dist/chunk-
|
|
22370
|
+
// ../agent-core/dist/chunk-M6YHY2EZ.js
|
|
22348
22371
|
function windowsEnvValue(env, name) {
|
|
22349
22372
|
const wanted = name.toLowerCase();
|
|
22350
|
-
for (const [key, value2] of Object.entries(env)) {
|
|
22373
|
+
for (const [key, value2] of Object.entries(env).reverse()) {
|
|
22351
22374
|
if (key.toLowerCase() === wanted) return value2;
|
|
22352
22375
|
}
|
|
22353
22376
|
return void 0;
|
|
22354
22377
|
}
|
|
22378
|
+
function canonicalWindowsEnvironment(env) {
|
|
22379
|
+
const unique2 = /* @__PURE__ */ new Map();
|
|
22380
|
+
for (const [name, value2] of Object.entries(env)) {
|
|
22381
|
+
unique2.set(name.toLowerCase(), [name.toLowerCase() === "path" ? "PATH" : name, value2]);
|
|
22382
|
+
}
|
|
22383
|
+
return Object.fromEntries(unique2.values());
|
|
22384
|
+
}
|
|
22355
22385
|
function hasExtension(name, extensions) {
|
|
22356
22386
|
const ext = import_path.win32.extname(name).toLowerCase();
|
|
22357
22387
|
return ext.length > 0 && extensions.includes(ext);
|
|
22358
22388
|
}
|
|
22359
22389
|
function candidates(base, extensions) {
|
|
22360
|
-
|
|
22390
|
+
const extension = import_path.win32.extname(base).toLowerCase();
|
|
22391
|
+
return extension === ".exe" || extension === ".com" || hasExtension(base, extensions) ? [base] : extensions.map((ext) => `${base}${ext}`);
|
|
22361
22392
|
}
|
|
22362
22393
|
function resolveWindowsCommand(command, env, files) {
|
|
22363
|
-
const extensions = (windowsEnvValue(env, "PATHEXT") ?? DEFAULT_PATHEXT).split(";").map((ext) => ext.trim().toLowerCase()).filter((ext) =>
|
|
22394
|
+
const extensions = (windowsEnvValue(env, "PATHEXT") ?? DEFAULT_PATHEXT).split(";").map((ext) => ext.trim().toLowerCase()).filter((ext) => LAUNCHABLE_EXTENSIONS.has(ext));
|
|
22364
22395
|
if (/[\\/]/.test(command)) {
|
|
22365
22396
|
return candidates(command, extensions).find((path4) => files.isFile(path4));
|
|
22366
22397
|
}
|
|
@@ -22373,6 +22404,18 @@ function resolveWindowsCommand(command, env, files) {
|
|
|
22373
22404
|
}
|
|
22374
22405
|
return void 0;
|
|
22375
22406
|
}
|
|
22407
|
+
function unwrapNativeShim(shim, args, files) {
|
|
22408
|
+
const lines2 = files.readShim(shim)?.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
|
|
22409
|
+
if (lines2?.length !== NATIVE_SHIM_LINES.length + 1) return void 0;
|
|
22410
|
+
if (!NATIVE_SHIM_LINES.every((pattern, index) => pattern.test(lines2[index] ?? ""))) {
|
|
22411
|
+
return void 0;
|
|
22412
|
+
}
|
|
22413
|
+
const target = NATIVE_SHIM_ENTRY.exec(lines2.at(-1) ?? "")?.[1];
|
|
22414
|
+
if (target === void 0) return void 0;
|
|
22415
|
+
const directory = import_path.win32.dirname(shim);
|
|
22416
|
+
const file2 = import_path.win32.resolve(directory, target.replace(/^%dp0%\\/i, ""));
|
|
22417
|
+
return files.isFile(file2) ? { kind: "native", file: file2, args } : void 0;
|
|
22418
|
+
}
|
|
22376
22419
|
function isSimpleNodeShim(text2) {
|
|
22377
22420
|
return text2.split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0).every((line) => /^@?echo off$/i.test(line) || NODE_SHIM_ENTRY.test(line));
|
|
22378
22421
|
}
|
|
@@ -22398,7 +22441,7 @@ function planWindowsLaunch(command, args, env, files) {
|
|
|
22398
22441
|
const file2 = resolveWindowsCommand(command, env, files);
|
|
22399
22442
|
if (file2 === void 0) return void 0;
|
|
22400
22443
|
if (!/\.(cmd|bat)$/i.test(file2)) return { kind: "native", file: file2, args };
|
|
22401
|
-
return unwrapNodeShim(file2, args, env, files) ?? { kind: "batch", file: file2, args };
|
|
22444
|
+
return unwrapNativeShim(file2, args, files) ?? unwrapNodeShim(file2, args, env, files) ?? { kind: "batch", file: file2, args };
|
|
22402
22445
|
}
|
|
22403
22446
|
function quoteWindowsArgument(value2) {
|
|
22404
22447
|
if (value2.length === 0) return '""';
|
|
@@ -22900,11 +22943,12 @@ function onCliSpawned(listener) {
|
|
|
22900
22943
|
}
|
|
22901
22944
|
function spawnCli(options) {
|
|
22902
22945
|
const platform3 = options.platform ?? process.platform;
|
|
22903
|
-
const
|
|
22904
|
-
|
|
22946
|
+
const env = platform3 === "win32" ? canonicalWindowsEnvironment(options.env) : options.env;
|
|
22947
|
+
const plan2 = planSpawn({ ...options, env, platform: platform3 });
|
|
22948
|
+
if (plan2.commandLine !== null) return spawnInWindowsJob(plan2, { ...options, env });
|
|
22905
22949
|
const child = (0, import_child_process5.spawn)(plan2.file, [...plan2.args], {
|
|
22906
22950
|
cwd: options.cwd,
|
|
22907
|
-
env: { ...
|
|
22951
|
+
env: { ...env },
|
|
22908
22952
|
stdio: ["pipe", "pipe", "pipe"],
|
|
22909
22953
|
shell: false,
|
|
22910
22954
|
detached: true
|
|
@@ -22931,9 +22975,9 @@ function waitForSpawn(child, command) {
|
|
|
22931
22975
|
child.once("error", onError);
|
|
22932
22976
|
});
|
|
22933
22977
|
}
|
|
22934
|
-
var import_child_process, import_fs, import_path, import_child_process2, import_promises9, import_child_process3, import_child_process4, import_child_process5, import_child_process6, import_crypto, import_fs2, import_promises10, import_os, import_path2, SHIM_MAX_BYTES, CMD_MAX_COMMAND_LINE, MAX_COMMAND_LINE, DEFAULT_PATHEXT, nodeWindowsFiles, NODE_SHIM_ENTRY, CMD_META, NEVER_STARTED, HIDDEN_FLAG_PROBE_VALUE, NEWLINE, CARRIAGE_RETURN, EMPTY, MAX_LINE_BYTES, LineSplitter, PS_LINE, POLL_MS, DEFAULT_GRACE_MS, DEFAULT_KILL_WAIT_MS, DEFAULT_TASKKILL_TIMEOUT_MS, statuses, START_TIMEOUT_MS, spawnListeners;
|
|
22935
|
-
var
|
|
22936
|
-
"../agent-core/dist/chunk-
|
|
22978
|
+
var import_child_process, import_fs, import_path, import_child_process2, import_promises9, import_child_process3, import_child_process4, import_child_process5, import_child_process6, import_crypto, import_fs2, import_promises10, import_os, import_path2, SHIM_MAX_BYTES, CMD_MAX_COMMAND_LINE, MAX_COMMAND_LINE, DEFAULT_PATHEXT, LAUNCHABLE_EXTENSIONS, nodeWindowsFiles, NODE_SHIM_ENTRY, NATIVE_SHIM_LINES, NATIVE_SHIM_ENTRY, CMD_META, NEVER_STARTED, HIDDEN_FLAG_PROBE_VALUE, NEWLINE, CARRIAGE_RETURN, EMPTY, MAX_LINE_BYTES, LineSplitter, PS_LINE, POLL_MS, DEFAULT_GRACE_MS, DEFAULT_KILL_WAIT_MS, DEFAULT_TASKKILL_TIMEOUT_MS, statuses, START_TIMEOUT_MS, spawnListeners;
|
|
22979
|
+
var init_chunk_M6YHY2EZ = __esm({
|
|
22980
|
+
"../agent-core/dist/chunk-M6YHY2EZ.js"() {
|
|
22937
22981
|
"use strict";
|
|
22938
22982
|
init_chunk_YXWJW7I5();
|
|
22939
22983
|
import_child_process = require("child_process");
|
|
@@ -22954,6 +22998,7 @@ var init_chunk_J4T6L5LX = __esm({
|
|
|
22954
22998
|
CMD_MAX_COMMAND_LINE = 8191;
|
|
22955
22999
|
MAX_COMMAND_LINE = 32766;
|
|
22956
23000
|
DEFAULT_PATHEXT = ".COM;.EXE;.BAT;.CMD";
|
|
23001
|
+
LAUNCHABLE_EXTENSIONS = /* @__PURE__ */ new Set([".com", ".exe", ".bat", ".cmd"]);
|
|
22957
23002
|
nodeWindowsFiles = {
|
|
22958
23003
|
isFile: (path4) => {
|
|
22959
23004
|
try {
|
|
@@ -22972,6 +23017,17 @@ var init_chunk_J4T6L5LX = __esm({
|
|
|
22972
23017
|
}
|
|
22973
23018
|
};
|
|
22974
23019
|
NODE_SHIM_ENTRY = /"(%_prog%|[^"\r\n]*node(?:\.exe)?)"\s+"([^"\r\n]+\.(?:c?js|mjs))"\s+%\*/i;
|
|
23020
|
+
NATIVE_SHIM_LINES = [
|
|
23021
|
+
/^@echo off$/i,
|
|
23022
|
+
/^goto start$/i,
|
|
23023
|
+
/^:find_dp0$/i,
|
|
23024
|
+
/^set dp0=%~dp0$/i,
|
|
23025
|
+
/^exit \/b$/i,
|
|
23026
|
+
/^:start$/i,
|
|
23027
|
+
/^setlocal$/i,
|
|
23028
|
+
/^call :find_dp0$/i
|
|
23029
|
+
];
|
|
23030
|
+
NATIVE_SHIM_ENTRY = /^"(%dp0%\\(?:\.\.\\)?(?:node_modules\\)?[\w@.-]+(?:\\[\w@.-]+)*\.exe)"\s+%\*$/i;
|
|
22975
23031
|
CMD_META = /([()\][%!^"`<>&|;, *?])/g;
|
|
22976
23032
|
NEVER_STARTED = { stdout: "", stderr: "", exitCode: void 0 };
|
|
22977
23033
|
HIDDEN_FLAG_PROBE_VALUE = "__alan_probe__";
|
|
@@ -23729,29 +23785,209 @@ var init_constants = __esm({
|
|
|
23729
23785
|
});
|
|
23730
23786
|
|
|
23731
23787
|
// ../shared/dist/agent/acp/transcript-http.js
|
|
23788
|
+
var TRANSCRIPT_TOOL_RESPONSE_ID_META, TRANSCRIPT_TURN_ID_META;
|
|
23732
23789
|
var init_transcript_http = __esm({
|
|
23733
23790
|
"../shared/dist/agent/acp/transcript-http.js"() {
|
|
23734
23791
|
"use strict";
|
|
23792
|
+
TRANSCRIPT_TOOL_RESPONSE_ID_META = "alan.dev/transcriptToolResponseId";
|
|
23793
|
+
TRANSCRIPT_TURN_ID_META = "alan.dev/transcriptTurnId";
|
|
23735
23794
|
}
|
|
23736
23795
|
});
|
|
23737
23796
|
|
|
23738
23797
|
// ../shared/dist/agent/acp/ask.js
|
|
23798
|
+
function asRecord2(value2) {
|
|
23799
|
+
return value2 && typeof value2 === "object" && !Array.isArray(value2) ? value2 : void 0;
|
|
23800
|
+
}
|
|
23801
|
+
function readOptions(value2) {
|
|
23802
|
+
if (!Array.isArray(value2))
|
|
23803
|
+
return [];
|
|
23804
|
+
const options = [];
|
|
23805
|
+
for (const raw of value2) {
|
|
23806
|
+
const option2 = asRecord2(raw);
|
|
23807
|
+
const label = typeof option2?.label === "string" ? option2.label : void 0;
|
|
23808
|
+
if (!label)
|
|
23809
|
+
continue;
|
|
23810
|
+
options.push({
|
|
23811
|
+
label,
|
|
23812
|
+
description: typeof option2?.description === "string" ? option2.description : void 0
|
|
23813
|
+
});
|
|
23814
|
+
}
|
|
23815
|
+
return options;
|
|
23816
|
+
}
|
|
23817
|
+
function readQuestions(input2) {
|
|
23818
|
+
const record2 = asRecord2(input2);
|
|
23819
|
+
const raw = record2?.questions;
|
|
23820
|
+
if (!Array.isArray(raw))
|
|
23821
|
+
return [];
|
|
23822
|
+
const questions = [];
|
|
23823
|
+
for (const item of raw) {
|
|
23824
|
+
const entry = asRecord2(item);
|
|
23825
|
+
const question = typeof entry?.question === "string" ? entry.question : void 0;
|
|
23826
|
+
if (!question)
|
|
23827
|
+
continue;
|
|
23828
|
+
questions.push({
|
|
23829
|
+
question,
|
|
23830
|
+
header: typeof entry?.header === "string" ? entry.header : void 0,
|
|
23831
|
+
options: readOptions(entry?.options),
|
|
23832
|
+
multiSelect: entry?.multiSelect === true
|
|
23833
|
+
});
|
|
23834
|
+
}
|
|
23835
|
+
return questions;
|
|
23836
|
+
}
|
|
23837
|
+
function isAskToolCall(entry) {
|
|
23838
|
+
const name = entry.title || entry.toolKind;
|
|
23839
|
+
return isAskUserQuestionTool(name, entry.rawInput);
|
|
23840
|
+
}
|
|
23841
|
+
function findPendingAsk(entries, answeredIds = /* @__PURE__ */ new Set()) {
|
|
23842
|
+
for (let index = entries.length - 1; index >= 0; index -= 1) {
|
|
23843
|
+
const entry = entries[index];
|
|
23844
|
+
if (!entry || entry.kind !== "tool_call")
|
|
23845
|
+
continue;
|
|
23846
|
+
if (entry.status === "completed" || entry.status === "failed" || entry.status === "cancelled") {
|
|
23847
|
+
continue;
|
|
23848
|
+
}
|
|
23849
|
+
if (answeredIds.has(entry.id))
|
|
23850
|
+
continue;
|
|
23851
|
+
if (!isAskToolCall(entry))
|
|
23852
|
+
continue;
|
|
23853
|
+
const questions = readQuestions(entry.rawInput);
|
|
23854
|
+
if (questions.length === 0)
|
|
23855
|
+
continue;
|
|
23856
|
+
return { toolCallId: entry.id, questions, rawInput: asRecord2(entry.rawInput) ?? {} };
|
|
23857
|
+
}
|
|
23858
|
+
return null;
|
|
23859
|
+
}
|
|
23739
23860
|
var init_ask = __esm({
|
|
23740
23861
|
"../shared/dist/agent/acp/ask.js"() {
|
|
23741
23862
|
"use strict";
|
|
23863
|
+
init_agent();
|
|
23742
23864
|
}
|
|
23743
23865
|
});
|
|
23744
23866
|
|
|
23745
23867
|
// ../shared/dist/agent/acp/background-task.js
|
|
23746
|
-
|
|
23868
|
+
function oneOf(values, value2) {
|
|
23869
|
+
return typeof value2 === "string" && values.some((candidate) => candidate === value2);
|
|
23870
|
+
}
|
|
23871
|
+
function isRecord6(value2) {
|
|
23872
|
+
return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
|
|
23873
|
+
}
|
|
23874
|
+
function optionalString(value2) {
|
|
23875
|
+
return typeof value2 === "string" && value2.length > 0 ? value2 : void 0;
|
|
23876
|
+
}
|
|
23877
|
+
function readBackgroundTaskMeta(meta3) {
|
|
23878
|
+
if (!isRecord6(meta3))
|
|
23879
|
+
return null;
|
|
23880
|
+
const raw = meta3[BACKGROUND_TASK_META_KEY];
|
|
23881
|
+
if (!isRecord6(raw))
|
|
23882
|
+
return null;
|
|
23883
|
+
const taskId = optionalString(raw.taskId);
|
|
23884
|
+
if (!taskId)
|
|
23885
|
+
return null;
|
|
23886
|
+
const kind = oneOf(KINDS, raw.kind) ? raw.kind : void 0;
|
|
23887
|
+
const stop = oneOf(STRATEGIES, raw.stop) ? raw.stop : void 0;
|
|
23888
|
+
const status = oneOf(STATUSES, raw.status) ? raw.status : void 0;
|
|
23889
|
+
const label = optionalString(raw.label);
|
|
23890
|
+
const subagentType = optionalString(raw.subagentType);
|
|
23891
|
+
const taskType = optionalString(raw.taskType);
|
|
23892
|
+
return {
|
|
23893
|
+
taskId,
|
|
23894
|
+
backgrounded: raw.backgrounded === true,
|
|
23895
|
+
...kind ? { kind } : {},
|
|
23896
|
+
...label ? { label } : {},
|
|
23897
|
+
...typeof raw.startedAt === "number" ? { startedAt: raw.startedAt } : {},
|
|
23898
|
+
...stop ? { stop } : {},
|
|
23899
|
+
...status ? { status } : {},
|
|
23900
|
+
...raw.stoppedByUser === true ? { stoppedByUser: true } : {},
|
|
23901
|
+
...subagentType ? { subagentType } : {},
|
|
23902
|
+
...taskType ? { taskType } : {},
|
|
23903
|
+
...typeof raw.spawnDepth === "number" ? { spawnDepth: raw.spawnDepth } : {},
|
|
23904
|
+
...raw.ownedBySubagent === true ? { ownedBySubagent: true } : {}
|
|
23905
|
+
};
|
|
23906
|
+
}
|
|
23907
|
+
var BACKGROUND_TASK_META_KEY, KINDS, STRATEGIES, STATUSES;
|
|
23747
23908
|
var init_background_task = __esm({
|
|
23748
23909
|
"../shared/dist/agent/acp/background-task.js"() {
|
|
23749
23910
|
"use strict";
|
|
23750
23911
|
BACKGROUND_TASK_META_KEY = "alan.dev/backgroundTask";
|
|
23912
|
+
KINDS = ["shell", "agent"];
|
|
23913
|
+
STRATEGIES = [
|
|
23914
|
+
"native",
|
|
23915
|
+
"pid",
|
|
23916
|
+
"none"
|
|
23917
|
+
];
|
|
23918
|
+
STATUSES = [
|
|
23919
|
+
"running",
|
|
23920
|
+
"stopping",
|
|
23921
|
+
"stopped",
|
|
23922
|
+
"completed",
|
|
23923
|
+
"failed"
|
|
23924
|
+
];
|
|
23751
23925
|
}
|
|
23752
23926
|
});
|
|
23753
23927
|
|
|
23754
23928
|
// ../shared/dist/agent/acp/presentation/terminal-events.js
|
|
23929
|
+
function isRecord7(value2) {
|
|
23930
|
+
return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
|
|
23931
|
+
}
|
|
23932
|
+
function foldPreview(events) {
|
|
23933
|
+
const output2 = [];
|
|
23934
|
+
const slots = /* @__PURE__ */ new Map();
|
|
23935
|
+
for (const event of events) {
|
|
23936
|
+
const update = event.update;
|
|
23937
|
+
const kind = canonicalKind(update.sessionUpdate);
|
|
23938
|
+
const identity = update.messageId ?? update.toolCallId ?? update.terminalId ?? update.planId;
|
|
23939
|
+
const singleton = [
|
|
23940
|
+
"state_update",
|
|
23941
|
+
"usage_update",
|
|
23942
|
+
"session_info_update",
|
|
23943
|
+
"available_commands_update",
|
|
23944
|
+
"config_option_update",
|
|
23945
|
+
"_alan/thinking_tokens"
|
|
23946
|
+
].includes(kind);
|
|
23947
|
+
const key = identity !== void 0 || singleton ? JSON.stringify([event.sessionId ?? "", kind, identity ?? "session"]) : void 0;
|
|
23948
|
+
const slot = key ? slots.get(key) : void 0;
|
|
23949
|
+
const previous = slot === void 0 ? void 0 : output2[slot];
|
|
23950
|
+
const merged = {
|
|
23951
|
+
...previous?.update,
|
|
23952
|
+
...update,
|
|
23953
|
+
sessionUpdate: kind
|
|
23954
|
+
};
|
|
23955
|
+
if (update.sessionUpdate === "terminal_output_chunk") {
|
|
23956
|
+
const before = previous && isRecord7(previous.update.output) ? previous.update.output.data : "";
|
|
23957
|
+
merged.output = { data: String(before ?? "") + String(update.data ?? "") };
|
|
23958
|
+
} else if (update.sessionUpdate.endsWith("_chunk")) {
|
|
23959
|
+
const before = previous && Array.isArray(previous.update.content) ? previous.update.content : [];
|
|
23960
|
+
merged.content = [
|
|
23961
|
+
...before,
|
|
23962
|
+
...Array.isArray(update.content) ? update.content : update.content ? [update.content] : []
|
|
23963
|
+
];
|
|
23964
|
+
}
|
|
23965
|
+
if (isRecord7(update._meta))
|
|
23966
|
+
merged._meta = {
|
|
23967
|
+
...isRecord7(previous?.update._meta) ? previous.update._meta : {},
|
|
23968
|
+
...update._meta
|
|
23969
|
+
};
|
|
23970
|
+
if (kind === "state_update")
|
|
23971
|
+
merged.stopReason = update.state === "idle" ? update.stopReason : void 0;
|
|
23972
|
+
if (kind === "tool_call_update" && ["completed", "failed", "cancelled"].includes(String(previous?.update.status)))
|
|
23973
|
+
merged.status = previous?.update.status;
|
|
23974
|
+
const next = { ...event, line: previous?.line ?? event.line, update: merged };
|
|
23975
|
+
if (slot === void 0) {
|
|
23976
|
+
if (key)
|
|
23977
|
+
slots.set(key, output2.length);
|
|
23978
|
+
output2.push(next);
|
|
23979
|
+
} else
|
|
23980
|
+
output2[slot] = next;
|
|
23981
|
+
}
|
|
23982
|
+
return output2;
|
|
23983
|
+
}
|
|
23984
|
+
function canonicalKind(kind) {
|
|
23985
|
+
if (kind === "tool_call_content_chunk")
|
|
23986
|
+
return "tool_call_update";
|
|
23987
|
+
if (kind === "terminal_output_chunk")
|
|
23988
|
+
return "terminal_update";
|
|
23989
|
+
return kind.replace(/_chunk$/, "");
|
|
23990
|
+
}
|
|
23755
23991
|
var init_terminal_events = __esm({
|
|
23756
23992
|
"../shared/dist/agent/acp/presentation/terminal-events.js"() {
|
|
23757
23993
|
"use strict";
|
|
@@ -23759,23 +23995,357 @@ var init_terminal_events = __esm({
|
|
|
23759
23995
|
});
|
|
23760
23996
|
|
|
23761
23997
|
// ../shared/dist/agent/acp/presentation/file-edits.js
|
|
23998
|
+
function diffRows(patch) {
|
|
23999
|
+
let oldLine = 0;
|
|
24000
|
+
let newLine = 0;
|
|
24001
|
+
let oldRemaining = 0;
|
|
24002
|
+
let newRemaining = 0;
|
|
24003
|
+
const lines2 = patch.split("\n");
|
|
24004
|
+
if (lines2.at(-1) === "")
|
|
24005
|
+
lines2.pop();
|
|
24006
|
+
return lines2.map((line) => {
|
|
24007
|
+
const hunk = /^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/.exec(line);
|
|
24008
|
+
if (hunk) {
|
|
24009
|
+
oldLine = Number(hunk[1]);
|
|
24010
|
+
newLine = Number(hunk[3]);
|
|
24011
|
+
oldRemaining = Number(hunk[2] ?? 1);
|
|
24012
|
+
newRemaining = Number(hunk[4] ?? 1);
|
|
24013
|
+
return { kind: "hunk", text: line };
|
|
24014
|
+
}
|
|
24015
|
+
if (newRemaining > 0 && line.startsWith("+")) {
|
|
24016
|
+
newRemaining--;
|
|
24017
|
+
return { kind: "add", text: line.slice(1), newLine: newLine++ };
|
|
24018
|
+
}
|
|
24019
|
+
if (oldRemaining > 0 && line.startsWith("-")) {
|
|
24020
|
+
oldRemaining--;
|
|
24021
|
+
return { kind: "remove", text: line.slice(1), oldLine: oldLine++ };
|
|
24022
|
+
}
|
|
24023
|
+
if (oldRemaining > 0 && newRemaining > 0 && line.startsWith(" ")) {
|
|
24024
|
+
oldRemaining--;
|
|
24025
|
+
newRemaining--;
|
|
24026
|
+
return { kind: "context", text: line.slice(1), oldLine: oldLine++, newLine: newLine++ };
|
|
24027
|
+
}
|
|
24028
|
+
return { kind: "meta", text: line };
|
|
24029
|
+
});
|
|
24030
|
+
}
|
|
24031
|
+
function patchForPath(text2, path4, count) {
|
|
24032
|
+
if (count === 1)
|
|
24033
|
+
return text2;
|
|
24034
|
+
const normalized2 = path4.replace(/^\/+/, "");
|
|
24035
|
+
return text2.split(/(?=^diff --git )/m).find((part) => {
|
|
24036
|
+
const names = [...part.matchAll(/^(?:---|\+\+\+) (?:[ab]\/)?([^\t\n]+)/gm)];
|
|
24037
|
+
return names.some((match) => match[1].replace(/^\/+/, "") === normalized2);
|
|
24038
|
+
});
|
|
24039
|
+
}
|
|
24040
|
+
function readDiff(value2, id) {
|
|
24041
|
+
if (!isRecord7(value2) || !Array.isArray(value2.changes))
|
|
24042
|
+
return [];
|
|
24043
|
+
const patch = isRecord7(value2.patch) && typeof value2.patch.text === "string" ? value2.patch : void 0;
|
|
24044
|
+
const changes = value2.changes;
|
|
24045
|
+
return changes.flatMap((change, index) => {
|
|
24046
|
+
if (!isRecord7(change) || typeof change.path !== "string" || typeof change.operation !== "string")
|
|
24047
|
+
return [];
|
|
24048
|
+
const text2 = patch ? patchForPath(String(patch.text), change.path, changes.length) : void 0;
|
|
24049
|
+
const rows = text2 && patch?.format !== "text" ? diffRows(text2) : [];
|
|
24050
|
+
const counted = rows.some((row) => row.kind === "hunk");
|
|
24051
|
+
return [
|
|
24052
|
+
{
|
|
24053
|
+
id: `${id}:${index}`,
|
|
24054
|
+
path: change.path,
|
|
24055
|
+
operation: change.operation,
|
|
24056
|
+
...typeof change.oldPath === "string" ? { oldPath: change.oldPath } : {},
|
|
24057
|
+
patch: text2,
|
|
24058
|
+
rows,
|
|
24059
|
+
...counted ? {
|
|
24060
|
+
additions: rows.filter((row) => row.kind === "add").length,
|
|
24061
|
+
deletions: rows.filter((row) => row.kind === "remove").length
|
|
24062
|
+
} : {}
|
|
24063
|
+
}
|
|
24064
|
+
];
|
|
24065
|
+
});
|
|
24066
|
+
}
|
|
24067
|
+
function toolEdits(node2) {
|
|
24068
|
+
const content = node2.event.update.content;
|
|
24069
|
+
if (!Array.isArray(content))
|
|
24070
|
+
return [];
|
|
24071
|
+
return content.flatMap((block, index) => isRecord7(block) && block.type === "diff" ? readDiff(block.diff, `${node2.key}:${index}`) : []);
|
|
24072
|
+
}
|
|
24073
|
+
function collectEditedFiles(nodes) {
|
|
24074
|
+
const files = /* @__PURE__ */ new Map();
|
|
24075
|
+
const seen = /* @__PURE__ */ new Set();
|
|
24076
|
+
function visit2(node2) {
|
|
24077
|
+
if (seen.has(node2.key))
|
|
24078
|
+
return;
|
|
24079
|
+
seen.add(node2.key);
|
|
24080
|
+
if (node2.event.update.sessionUpdate === "tool_call_update" && node2.event.update.status === "completed") {
|
|
24081
|
+
for (const edit of toolEdits(node2)) {
|
|
24082
|
+
const previous = files.get(edit.path);
|
|
24083
|
+
const edits = [...previous?.edits ?? [], edit];
|
|
24084
|
+
const counted = edits.every((item) => item.additions !== void 0 && item.deletions !== void 0);
|
|
24085
|
+
files.set(edit.path, {
|
|
24086
|
+
path: edit.path,
|
|
24087
|
+
edits,
|
|
24088
|
+
...counted ? {
|
|
24089
|
+
additions: edits.reduce((sum, item) => sum + (item.additions ?? 0), 0),
|
|
24090
|
+
deletions: edits.reduce((sum, item) => sum + (item.deletions ?? 0), 0)
|
|
24091
|
+
} : {}
|
|
24092
|
+
});
|
|
24093
|
+
}
|
|
24094
|
+
}
|
|
24095
|
+
node2.children.forEach(visit2);
|
|
24096
|
+
}
|
|
24097
|
+
nodes.forEach(visit2);
|
|
24098
|
+
return [...files.values()];
|
|
24099
|
+
}
|
|
23762
24100
|
var init_file_edits = __esm({
|
|
23763
24101
|
"../shared/dist/agent/acp/presentation/file-edits.js"() {
|
|
23764
24102
|
"use strict";
|
|
24103
|
+
init_terminal_events();
|
|
23765
24104
|
}
|
|
23766
24105
|
});
|
|
23767
24106
|
|
|
23768
24107
|
// ../shared/dist/agent/acp/presentation/notice-visibility.js
|
|
24108
|
+
function isConversationNotice({ message: message2, kind, meta: meta3 }) {
|
|
24109
|
+
const category = kind ?? (isRecord7(meta3) ? meta3["alan.dev/noticeKind"] : void 0);
|
|
24110
|
+
return !(category === "turn_summary" || category === "task_summary" || typeof category === "string" && category.startsWith("turn_summary/") || message2.startsWith("Under-development features enabled:") || /^clamping \S+ hook timeout to /.test(message2) || message2.startsWith("Skill descriptions were shortened to fit") || /^Rate limited \(allowed(?:_warning)?\):/.test(message2));
|
|
24111
|
+
}
|
|
24112
|
+
function uniqueNotices(notices) {
|
|
24113
|
+
const seen = /* @__PURE__ */ new Set();
|
|
24114
|
+
return notices.filter((notice2) => {
|
|
24115
|
+
const key = `${notice2.message}`;
|
|
24116
|
+
if (seen.has(key))
|
|
24117
|
+
return false;
|
|
24118
|
+
seen.add(key);
|
|
24119
|
+
return true;
|
|
24120
|
+
});
|
|
24121
|
+
}
|
|
23769
24122
|
var init_notice_visibility = __esm({
|
|
23770
24123
|
"../shared/dist/agent/acp/presentation/notice-visibility.js"() {
|
|
23771
24124
|
"use strict";
|
|
24125
|
+
init_terminal_events();
|
|
23772
24126
|
}
|
|
23773
24127
|
});
|
|
23774
24128
|
|
|
23775
24129
|
// ../shared/dist/agent/acp/presentation/prepare-conversation-turns.js
|
|
24130
|
+
function entryNode(entry, index) {
|
|
24131
|
+
const prepared = preparedEntries.get(entry);
|
|
24132
|
+
if (prepared?.index === index && prepared.lastUpdateIndex === entry.lastUpdateIndex) {
|
|
24133
|
+
return { key: prepared.key, event: prepared.event, children: [] };
|
|
24134
|
+
}
|
|
24135
|
+
const update = entry.kind === "message" ? {
|
|
24136
|
+
sessionUpdate: entry.role === "user" ? "user_message" : entry.role === "thought" ? "agent_thought" : "agent_message",
|
|
24137
|
+
messageId: entry.id,
|
|
24138
|
+
content: Array.isArray(entry.content) ? entry.content : [],
|
|
24139
|
+
_meta: entry._meta
|
|
24140
|
+
} : {
|
|
24141
|
+
sessionUpdate: "tool_call_update",
|
|
24142
|
+
toolCallId: entry.id,
|
|
24143
|
+
name: entry.name ?? entry.title,
|
|
24144
|
+
title: entry.title,
|
|
24145
|
+
kind: entry.toolKind,
|
|
24146
|
+
status: entry.status,
|
|
24147
|
+
content: entry.content,
|
|
24148
|
+
locations: entry.locations,
|
|
24149
|
+
rawInput: entry.rawInput,
|
|
24150
|
+
rawOutput: entry.rawOutput,
|
|
24151
|
+
_meta: entry._meta
|
|
24152
|
+
};
|
|
24153
|
+
const clientId = entry._meta?.["alan.dev/clientMessageId"];
|
|
24154
|
+
const identity = entry.kind === "message" && entry.role === "user" && typeof clientId === "string" ? clientId : entry.id;
|
|
24155
|
+
const key = entry.kind === "message" ? `message:${entry.role}:${identity}` : `tool:${entry.id}`;
|
|
24156
|
+
const event = { id: key, line: index, seq: entry.lastUpdateIndex, update };
|
|
24157
|
+
preparedEntries.set(entry, { index, lastUpdateIndex: entry.lastUpdateIndex, key, event });
|
|
24158
|
+
return { key, event, children: [] };
|
|
24159
|
+
}
|
|
24160
|
+
function attachChildren(nodes) {
|
|
24161
|
+
const tools = /* @__PURE__ */ new Map();
|
|
24162
|
+
const terminals = /* @__PURE__ */ new Map();
|
|
24163
|
+
for (const node2 of nodes) {
|
|
24164
|
+
const u = node2.event.update;
|
|
24165
|
+
if (typeof u.toolCallId === "string")
|
|
24166
|
+
tools.set(u.toolCallId, node2);
|
|
24167
|
+
for (const block of Array.isArray(u.content) ? u.content : []) {
|
|
24168
|
+
if (isRecord7(block) && block.type === "terminal" && typeof block.terminalId === "string")
|
|
24169
|
+
terminals.set(block.terminalId, node2);
|
|
24170
|
+
}
|
|
24171
|
+
}
|
|
24172
|
+
const parents = /* @__PURE__ */ new Map();
|
|
24173
|
+
for (const node2 of nodes) {
|
|
24174
|
+
const u = node2.event.update;
|
|
24175
|
+
const parentId = isRecord7(u._meta) ? u._meta["alan.dev/parentToolCallId"] : void 0;
|
|
24176
|
+
const parent = typeof parentId === "string" ? tools.get(parentId) : typeof u.terminalId === "string" ? terminals.get(u.terminalId) : void 0;
|
|
24177
|
+
if (parent)
|
|
24178
|
+
parents.set(node2, parent);
|
|
24179
|
+
else if (typeof parentId === "string")
|
|
24180
|
+
node2.issue = `Waiting for parent tool ${parentId}`;
|
|
24181
|
+
}
|
|
24182
|
+
return nodes.filter((node2) => {
|
|
24183
|
+
let ancestor = parents.get(node2);
|
|
24184
|
+
const seen = /* @__PURE__ */ new Set([node2]);
|
|
24185
|
+
while (ancestor) {
|
|
24186
|
+
if (seen.has(ancestor)) {
|
|
24187
|
+
node2.issue = "Cyclic parent reference; shown at root";
|
|
24188
|
+
return true;
|
|
24189
|
+
}
|
|
24190
|
+
seen.add(ancestor);
|
|
24191
|
+
ancestor = parents.get(ancestor);
|
|
24192
|
+
}
|
|
24193
|
+
const parent = parents.get(node2);
|
|
24194
|
+
if (!parent)
|
|
24195
|
+
return true;
|
|
24196
|
+
parent.children.push(node2);
|
|
24197
|
+
return false;
|
|
24198
|
+
});
|
|
24199
|
+
}
|
|
24200
|
+
function turnStart(turn) {
|
|
24201
|
+
if (turn.users[0])
|
|
24202
|
+
return turn.users[0].event.line;
|
|
24203
|
+
return turn.working[0]?.event.line;
|
|
24204
|
+
}
|
|
24205
|
+
function hasAnswerContent(node2) {
|
|
24206
|
+
const content = node2.event.update.content;
|
|
24207
|
+
return Array.isArray(content) && content.some((block) => isRecord7(block) && (block.type !== "text" || typeof block.text === "string" && block.text.trim().length > 0));
|
|
24208
|
+
}
|
|
24209
|
+
function messageText(node2) {
|
|
24210
|
+
const content = node2.event.update.content;
|
|
24211
|
+
return Array.isArray(content) ? content.flatMap((block) => isRecord7(block) && block.type === "text" && typeof block.text === "string" ? [block.text] : []).join("") : "";
|
|
24212
|
+
}
|
|
24213
|
+
function prepareConversationTurns(transcript, streaming, previousTurns = []) {
|
|
24214
|
+
const entries = Array.isArray(transcript.entries) ? transcript.entries : [];
|
|
24215
|
+
const nodes = entries.map(entryNode);
|
|
24216
|
+
const terminals = transcript.unknown.flatMap((update, index) => ["terminal_update", "terminal_output_chunk"].includes(update.sessionUpdate) || isRecord7(update._meta) && typeof update._meta["alan.dev/parentToolCallId"] === "string" ? [{ id: `terminal:${index}`, line: entries.length + index, update: { ...update } }] : []);
|
|
24217
|
+
for (const event of foldPreview(terminals))
|
|
24218
|
+
nodes.push({ key: event.id, event, children: [] });
|
|
24219
|
+
const nestedThoughtIds = new Set(nodes.flatMap((node2) => node2.event.update.sessionUpdate === "agent_thought" && typeof node2.event.update.messageId === "string" && isRecord7(node2.event.update._meta) && typeof node2.event.update._meta["alan.dev/parentToolCallId"] === "string" ? [node2.event.update.messageId] : []));
|
|
24220
|
+
const visible = nodes.filter((node2) => !isThought(node2));
|
|
24221
|
+
const roots = attachChildren(visible).filter((node2, index, all) => {
|
|
24222
|
+
const previous = all[index - 1];
|
|
24223
|
+
if (previous?.event.update.sessionUpdate !== "agent_message" || node2.event.update.sessionUpdate !== "agent_message" || !nestedThoughtIds.has(String(node2.event.update.messageId)))
|
|
24224
|
+
return true;
|
|
24225
|
+
const previousText = messageText(previous);
|
|
24226
|
+
return !(previousText.length > 0 && previousText === messageText(node2));
|
|
24227
|
+
});
|
|
24228
|
+
const turns = [];
|
|
24229
|
+
for (const node2 of roots) {
|
|
24230
|
+
const user = node2.event.update.sessionUpdate === "user_message";
|
|
24231
|
+
let turn = turns.at(-1);
|
|
24232
|
+
if (!turn || user) {
|
|
24233
|
+
turn = { key: node2.key, users: [], working: [], activity: { key: node2.key, state: "idle" } };
|
|
24234
|
+
turns.push(turn);
|
|
24235
|
+
}
|
|
24236
|
+
if (user)
|
|
24237
|
+
turn.users.push(node2);
|
|
24238
|
+
else
|
|
24239
|
+
turn.working.push(node2);
|
|
24240
|
+
}
|
|
24241
|
+
const activities = [...transcript.activities ?? []].sort((left, right) => left.firstEntryIndex - right.firstEntryIndex);
|
|
24242
|
+
for (const [turnIndex, turn] of turns.entries()) {
|
|
24243
|
+
const last = turn === turns.at(-1);
|
|
24244
|
+
const firstEntryIndex = turnStart(turn);
|
|
24245
|
+
const next = turns[turnIndex + 1];
|
|
24246
|
+
const nextStart = (next && turnStart(next)) ?? Number.POSITIVE_INFINITY;
|
|
24247
|
+
const runs = firstEntryIndex === void 0 ? [] : activities.filter((activity) => activity.firstEntryIndex >= firstEntryIndex && activity.firstEntryIndex < nextStart);
|
|
24248
|
+
const recorded = runs.at(-1);
|
|
24249
|
+
turn.activity.state = last && transcript.state === "requires_action" ? "requires_action" : last && streaming ? "running" : (
|
|
24250
|
+
// Bytes cut off mid-run are history once the thread is not live; they are not still working.
|
|
24251
|
+
recorded?.state === "running" ? "idle" : recorded?.state ?? "idle"
|
|
24252
|
+
);
|
|
24253
|
+
turn.activity.stopReason = turn.activity.state === "running" ? void 0 : recorded?.stopReason ?? (last ? transcript.stopReason : void 0);
|
|
24254
|
+
const captured = runs.reduce((total, run2) => {
|
|
24255
|
+
const duration3 = run2.startedAt !== void 0 ? Math.max(0, (run2.endedAt ?? run2.updatedAt) - run2.startedAt) : run2.durationMs;
|
|
24256
|
+
return duration3 === void 0 ? total : (total ?? 0) + duration3;
|
|
24257
|
+
}, void 0);
|
|
24258
|
+
if (captured !== void 0)
|
|
24259
|
+
turn.activity.capturedMs = captured;
|
|
24260
|
+
const startedAt = runs.find((run2) => run2.startedAt !== void 0)?.startedAt;
|
|
24261
|
+
if (startedAt !== void 0)
|
|
24262
|
+
turn.activity.startedAt = startedAt;
|
|
24263
|
+
if (turn.activity.state !== "running" && recorded?.endedAt !== void 0)
|
|
24264
|
+
turn.activity.endedAt = recorded.endedAt;
|
|
24265
|
+
turn.activity.neverStarted = recorded?.state === "idle" && recorded.stopReason === "cancelled" && captured === void 0;
|
|
24266
|
+
if (last && streaming && turn.activity.state === "running") {
|
|
24267
|
+
const anchor2 = Math.max(recorded?.startedAt ?? 0, transcript.userMessageAt ?? 0);
|
|
24268
|
+
if (anchor2 > 0)
|
|
24269
|
+
turn.activity.liveStartedAt = anchor2;
|
|
24270
|
+
}
|
|
24271
|
+
const tail = turn.working.reduce((latest, node2) => !latest || (node2.event.seq ?? node2.event.line) > (latest.event.seq ?? latest.event.line) ? node2 : latest, void 0);
|
|
24272
|
+
turn.working = turn.working.filter((node2) => !isThought(node2));
|
|
24273
|
+
const final = turn.activity.state === "idle" && (!turn.activity.stopReason || turn.activity.stopReason === "end_turn" || turn.activity.stopReason === "cancelled") && tail?.event.update.sessionUpdate === "agent_message" && hasAnswerContent(tail) ? tail : void 0;
|
|
24274
|
+
if (final)
|
|
24275
|
+
turn.final = final;
|
|
24276
|
+
}
|
|
24277
|
+
const noticesByEntry = /* @__PURE__ */ new Map();
|
|
24278
|
+
for (const notice2 of uniqueNotices(transcript.notices)) {
|
|
24279
|
+
if (notice2.firstEntryIndex === void 0 || !isConversationNotice(notice2))
|
|
24280
|
+
continue;
|
|
24281
|
+
const group = noticesByEntry.get(notice2.firstEntryIndex);
|
|
24282
|
+
if (group)
|
|
24283
|
+
group.push(notice2);
|
|
24284
|
+
else
|
|
24285
|
+
noticesByEntry.set(notice2.firstEntryIndex, [notice2]);
|
|
24286
|
+
}
|
|
24287
|
+
for (const turn of turns) {
|
|
24288
|
+
const firstEntryIndex = turnStart(turn);
|
|
24289
|
+
const notices = firstEntryIndex === void 0 ? void 0 : noticesByEntry.get(firstEntryIndex);
|
|
24290
|
+
if (notices)
|
|
24291
|
+
turn.notices = notices;
|
|
24292
|
+
}
|
|
24293
|
+
const startedTurn = turns[0];
|
|
24294
|
+
if (transcript.cloudStart && startedTurn?.users.length) {
|
|
24295
|
+
startedTurn.cloudStart = transcript.cloudStart;
|
|
24296
|
+
}
|
|
24297
|
+
const previousByKey = new Map(previousTurns.map((turn) => [turn.key, turn]));
|
|
24298
|
+
return turns.map((turn) => retainTurn(turn, previousByKey.get(turn.key)));
|
|
24299
|
+
}
|
|
24300
|
+
function sameNotices(left, right) {
|
|
24301
|
+
if (left === right)
|
|
24302
|
+
return true;
|
|
24303
|
+
if (!left || !right || left.length !== right.length)
|
|
24304
|
+
return false;
|
|
24305
|
+
return left.every((notice2, index) => notice2.kind === right[index].kind && notice2.level === right[index].level && notice2.message === right[index].message);
|
|
24306
|
+
}
|
|
24307
|
+
function sameFields(left, right) {
|
|
24308
|
+
const keys = Object.keys(left);
|
|
24309
|
+
return keys.length === Object.keys(right).length && keys.every((key) => Reflect.get(left, key) === Reflect.get(right, key));
|
|
24310
|
+
}
|
|
24311
|
+
function retainNodes(nodes, previous) {
|
|
24312
|
+
const byKey = new Map(previous.map((node2) => [node2.key, node2]));
|
|
24313
|
+
const retained = nodes.map((node2) => {
|
|
24314
|
+
const before = byKey.get(node2.key);
|
|
24315
|
+
if (!before)
|
|
24316
|
+
return node2;
|
|
24317
|
+
node2.children = retainNodes(node2.children, before.children);
|
|
24318
|
+
return node2.children === before.children && node2.issue === before.issue && (node2.event === before.event || node2.event.id === before.event.id && sameFields(node2.event.update, before.event.update)) ? before : node2;
|
|
24319
|
+
});
|
|
24320
|
+
return retained.length === previous.length && retained.every((node2, index) => node2 === previous[index]) ? previous : retained;
|
|
24321
|
+
}
|
|
24322
|
+
function retainTurn(turn, previous) {
|
|
24323
|
+
if (previous) {
|
|
24324
|
+
turn.users = retainNodes(turn.users, previous.users);
|
|
24325
|
+
turn.working = retainNodes(turn.working, previous.working);
|
|
24326
|
+
if (turn.final && previous.final)
|
|
24327
|
+
turn.final = retainNodes([turn.final], [previous.final])[0];
|
|
24328
|
+
if (sameFields(turn.activity, previous.activity))
|
|
24329
|
+
turn.activity = previous.activity;
|
|
24330
|
+
if (sameNotices(turn.notices, previous.notices))
|
|
24331
|
+
turn.notices = previous.notices;
|
|
24332
|
+
if (turn.cloudStart && previous.cloudStart && sameFields(turn.cloudStart, previous.cloudStart))
|
|
24333
|
+
turn.cloudStart = previous.cloudStart;
|
|
24334
|
+
}
|
|
24335
|
+
turn.editedFiles = previous && turn.working === previous.working && turn.activity === previous.activity ? previous.editedFiles : turn.activity.state === "idle" ? collectEditedFiles(turn.working) : [];
|
|
24336
|
+
return previous && turn.users === previous.users && turn.working === previous.working && turn.final === previous.final && turn.activity === previous.activity && turn.editedFiles === previous.editedFiles && turn.notices === previous.notices && turn.cloudStart === previous.cloudStart ? previous : turn;
|
|
24337
|
+
}
|
|
24338
|
+
function isThought(node2) {
|
|
24339
|
+
return ["agent_thought", "agent_thought_chunk"].includes(node2.event.update.sessionUpdate);
|
|
24340
|
+
}
|
|
24341
|
+
var preparedEntries;
|
|
23776
24342
|
var init_prepare_conversation_turns = __esm({
|
|
23777
24343
|
"../shared/dist/agent/acp/presentation/prepare-conversation-turns.js"() {
|
|
23778
24344
|
"use strict";
|
|
24345
|
+
init_file_edits();
|
|
24346
|
+
init_notice_visibility();
|
|
24347
|
+
init_terminal_events();
|
|
24348
|
+
preparedEntries = /* @__PURE__ */ new WeakMap();
|
|
23779
24349
|
}
|
|
23780
24350
|
});
|
|
23781
24351
|
|
|
@@ -23790,23 +24360,510 @@ var init_event = __esm({
|
|
|
23790
24360
|
function isUpdate(update, kind) {
|
|
23791
24361
|
return update.sessionUpdate === kind;
|
|
23792
24362
|
}
|
|
24363
|
+
function isContentUpdate(update) {
|
|
24364
|
+
return update.sessionUpdate === "user_message" || update.sessionUpdate === "user_message_chunk" || update.sessionUpdate === "agent_message" || update.sessionUpdate === "agent_message_chunk" || update.sessionUpdate === "agent_thought" || update.sessionUpdate === "agent_thought_chunk";
|
|
24365
|
+
}
|
|
24366
|
+
function isToolUpdate(update) {
|
|
24367
|
+
return update.sessionUpdate === "tool_call_update" || update.sessionUpdate === "tool_call_content_chunk";
|
|
24368
|
+
}
|
|
24369
|
+
var MEDIA_SESSION_UPDATE_KINDS;
|
|
23793
24370
|
var init_types2 = __esm({
|
|
23794
24371
|
"../shared/dist/agent/acp/types.js"() {
|
|
23795
24372
|
"use strict";
|
|
24373
|
+
MEDIA_SESSION_UPDATE_KINDS = /* @__PURE__ */ new Set([
|
|
24374
|
+
"_alan/generated_image",
|
|
24375
|
+
"_alan/session_media"
|
|
24376
|
+
]);
|
|
23796
24377
|
}
|
|
23797
24378
|
});
|
|
23798
24379
|
|
|
23799
24380
|
// ../shared/dist/agent/acp/reduce.js
|
|
24381
|
+
function emptyTranscript() {
|
|
24382
|
+
return { entries: [], state: "idle", notices: [], unknown: [] };
|
|
24383
|
+
}
|
|
24384
|
+
function applySessionEvent(state, event) {
|
|
24385
|
+
applyUpdate(state, event.update);
|
|
24386
|
+
const update = event.update;
|
|
24387
|
+
if (update._meta && typeof update._meta === "object" && "alan.dev/parentToolCallId" in update._meta && typeof update._meta["alan.dev/parentToolCallId"] === "string")
|
|
24388
|
+
return state;
|
|
24389
|
+
if ((update.sessionUpdate === "user_message" || update.sessionUpdate === "user_message_chunk") && Number.isFinite(event.at))
|
|
24390
|
+
state.userMessageAt = event.at;
|
|
24391
|
+
const lifecycle = isUpdate(update, "state_update");
|
|
24392
|
+
const activities = state.activities ?? [];
|
|
24393
|
+
let activity = activities.at(-1);
|
|
24394
|
+
if (lifecycle) {
|
|
24395
|
+
let userIndex = -1;
|
|
24396
|
+
for (let index = state.entries.length - 1; index >= 0; index -= 1) {
|
|
24397
|
+
const entry = state.entries[index];
|
|
24398
|
+
if (entry.kind === "message" && entry.role === "user") {
|
|
24399
|
+
userIndex = index;
|
|
24400
|
+
break;
|
|
24401
|
+
}
|
|
24402
|
+
}
|
|
24403
|
+
if (!activity || activity.endedAt !== void 0 && (update.state === "running" || userIndex > activity.firstEntryIndex)) {
|
|
24404
|
+
const firstEntryIndex = userIndex >= 0 && (!activity || userIndex > activity.firstEntryIndex) ? userIndex : activity ? state.entries.length : 0;
|
|
24405
|
+
activity = { firstEntryIndex, state: update.state, updatedAt: event.at };
|
|
24406
|
+
activities.push(activity);
|
|
24407
|
+
state.activities = activities;
|
|
24408
|
+
}
|
|
24409
|
+
}
|
|
24410
|
+
if (!activity)
|
|
24411
|
+
return state;
|
|
24412
|
+
const usage = isUpdate(update, "usage_update") ? update._meta?.["alan.dev/usage"] : void 0;
|
|
24413
|
+
if (typeof usage === "object" && usage !== null && "durationMs" in usage && typeof usage.durationMs === "number" && Number.isFinite(usage.durationMs))
|
|
24414
|
+
activity.durationMs = Math.max(0, usage.durationMs);
|
|
24415
|
+
if (activity.endedAt === void 0)
|
|
24416
|
+
activity.updatedAt = event.at;
|
|
24417
|
+
if (lifecycle) {
|
|
24418
|
+
activity.state = update.state;
|
|
24419
|
+
activity.stopReason = update.state === "idle" ? update.stopReason ?? void 0 : void 0;
|
|
24420
|
+
if (update.state === "running" && activity.startedAt === void 0)
|
|
24421
|
+
activity.startedAt = event.at;
|
|
24422
|
+
if (update.state === "idle" && activity.endedAt === void 0)
|
|
24423
|
+
activity.endedAt = event.at;
|
|
24424
|
+
}
|
|
24425
|
+
return state;
|
|
24426
|
+
}
|
|
24427
|
+
function entryIndex(state) {
|
|
24428
|
+
const cached2 = entryIndexes.get(state);
|
|
24429
|
+
if (cached2 && cached2.entries === state.entries && cached2.size === state.entries.length && cached2.last === state.entries.at(-1))
|
|
24430
|
+
return cached2;
|
|
24431
|
+
const byKey = /* @__PURE__ */ new Map();
|
|
24432
|
+
for (const entry of state.entries)
|
|
24433
|
+
byKey.set(entryKey(entry), entry);
|
|
24434
|
+
const index = {
|
|
24435
|
+
entries: state.entries,
|
|
24436
|
+
size: state.entries.length,
|
|
24437
|
+
last: state.entries.at(-1),
|
|
24438
|
+
byKey
|
|
24439
|
+
};
|
|
24440
|
+
entryIndexes.set(state, index);
|
|
24441
|
+
return index;
|
|
24442
|
+
}
|
|
24443
|
+
function applyUpdate(state, update) {
|
|
24444
|
+
const index = entryIndex(state);
|
|
24445
|
+
applyOne(state, index.byKey, update);
|
|
24446
|
+
index.size = state.entries.length;
|
|
24447
|
+
index.last = state.entries.at(-1);
|
|
24448
|
+
return state;
|
|
24449
|
+
}
|
|
24450
|
+
function awaitingToolCallIds(meta3) {
|
|
24451
|
+
const ids = meta3?.[AWAITING_TOOL_CALLS_META];
|
|
24452
|
+
return Array.isArray(ids) ? ids.filter((id) => typeof id === "string") : [];
|
|
24453
|
+
}
|
|
24454
|
+
function entryKey(entry) {
|
|
24455
|
+
return entry.kind === "message" ? `m:${entry.role}:${entry.id}` : `t:${entry.id}`;
|
|
24456
|
+
}
|
|
24457
|
+
function applyOne(state, index, update) {
|
|
24458
|
+
state.updateCount = (state.updateCount ?? 0) + 1;
|
|
24459
|
+
if (isContentUpdate(update)) {
|
|
24460
|
+
applyContent(state, index, update);
|
|
24461
|
+
return;
|
|
24462
|
+
}
|
|
24463
|
+
if (isToolUpdate(update)) {
|
|
24464
|
+
applyTool(state, index, update);
|
|
24465
|
+
return;
|
|
24466
|
+
}
|
|
24467
|
+
if (update.sessionUpdate === "_alan/log" || update.sessionUpdate === "_alan/unhandled")
|
|
24468
|
+
return;
|
|
24469
|
+
if (update._meta && typeof update._meta === "object" && "alan.dev/parentToolCallId" in update._meta && typeof update._meta["alan.dev/parentToolCallId"] === "string") {
|
|
24470
|
+
state.unknown.push(update);
|
|
24471
|
+
return;
|
|
24472
|
+
}
|
|
24473
|
+
switch (update.sessionUpdate) {
|
|
24474
|
+
case "state_update": {
|
|
24475
|
+
if (!isUpdate(update, "state_update"))
|
|
24476
|
+
return;
|
|
24477
|
+
if (update.state === "running" && state.state === "idle")
|
|
24478
|
+
delete state.thinkingTokens;
|
|
24479
|
+
state.state = update.state;
|
|
24480
|
+
if (update.state !== "idle")
|
|
24481
|
+
state.stopReason = void 0;
|
|
24482
|
+
else if (update.stopReason)
|
|
24483
|
+
state.stopReason = update.stopReason;
|
|
24484
|
+
if (update.state === "requires_action")
|
|
24485
|
+
state.awaitingToolCallIds = awaitingToolCallIds(update._meta);
|
|
24486
|
+
else
|
|
24487
|
+
delete state.awaitingToolCallIds;
|
|
24488
|
+
if (update.state === "idle")
|
|
24489
|
+
settleOpenToolCalls(state);
|
|
24490
|
+
return;
|
|
24491
|
+
}
|
|
24492
|
+
case "plan_update": {
|
|
24493
|
+
if (!isUpdate(update, "plan_update"))
|
|
24494
|
+
return;
|
|
24495
|
+
state.plan = { planId: update.planId, entries: update.entries };
|
|
24496
|
+
return;
|
|
24497
|
+
}
|
|
24498
|
+
case "usage_update": {
|
|
24499
|
+
if (!isUpdate(update, "usage_update"))
|
|
24500
|
+
return;
|
|
24501
|
+
state.usage = {
|
|
24502
|
+
used: update.used,
|
|
24503
|
+
size: update.size,
|
|
24504
|
+
...update.cost ? { cost: update.cost } : {}
|
|
24505
|
+
};
|
|
24506
|
+
delete state.thinkingTokens;
|
|
24507
|
+
return;
|
|
24508
|
+
}
|
|
24509
|
+
case "session_info_update": {
|
|
24510
|
+
if (!isUpdate(update, "session_info_update"))
|
|
24511
|
+
return;
|
|
24512
|
+
if (update.title !== void 0)
|
|
24513
|
+
state.title = update.title ?? void 0;
|
|
24514
|
+
return;
|
|
24515
|
+
}
|
|
24516
|
+
case "notice": {
|
|
24517
|
+
if (!isUpdate(update, "notice"))
|
|
24518
|
+
return;
|
|
24519
|
+
const notice2 = {
|
|
24520
|
+
level: update.severity,
|
|
24521
|
+
kind: noticeKind(update.severity, update._meta),
|
|
24522
|
+
message: update.description ? `${update.title}
|
|
24523
|
+
${update.description}` : update.title,
|
|
24524
|
+
...update._meta ? { _meta: update._meta } : {}
|
|
24525
|
+
};
|
|
24526
|
+
const seen = state.notices.some((existing) => existing.level === notice2.level && existing.message === notice2.message);
|
|
24527
|
+
if (!seen)
|
|
24528
|
+
state.notices.push(notice2);
|
|
24529
|
+
return;
|
|
24530
|
+
}
|
|
24531
|
+
case "_alan/thinking_tokens": {
|
|
24532
|
+
if (!isUpdate(update, "_alan/thinking_tokens"))
|
|
24533
|
+
return;
|
|
24534
|
+
state.thinkingTokens = update.estimated;
|
|
24535
|
+
return;
|
|
24536
|
+
}
|
|
24537
|
+
// Owned by the tool call that references it, but kept so a terminal-aware
|
|
24538
|
+
// renderer can still consume the raw update.
|
|
24539
|
+
case "terminal_update":
|
|
24540
|
+
case "terminal_output_chunk":
|
|
24541
|
+
state.unknown.push(update);
|
|
24542
|
+
return;
|
|
24543
|
+
// ACP: preserve a variant this build does not know rather than dropping it.
|
|
24544
|
+
default:
|
|
24545
|
+
state.unknown.push(update);
|
|
24546
|
+
}
|
|
24547
|
+
}
|
|
24548
|
+
function noticeKind(severity, meta3) {
|
|
24549
|
+
const kind = meta3?.["alan.dev/noticeKind"];
|
|
24550
|
+
return typeof kind === "string" ? kind : severity;
|
|
24551
|
+
}
|
|
24552
|
+
function applyContent(state, index, update) {
|
|
24553
|
+
const role = ROLE_BY_KIND[update.sessionUpdate];
|
|
24554
|
+
if (!role)
|
|
24555
|
+
return;
|
|
24556
|
+
const key = `m:${role}:${update.messageId}`;
|
|
24557
|
+
let entry = index.get(key);
|
|
24558
|
+
if (!entry) {
|
|
24559
|
+
entry = { kind: "message", id: update.messageId, role, content: [] };
|
|
24560
|
+
index.set(key, entry);
|
|
24561
|
+
state.entries.push(entry);
|
|
24562
|
+
}
|
|
24563
|
+
entry.lastUpdateIndex = state.updateCount;
|
|
24564
|
+
if (update.sessionUpdate.endsWith("_chunk")) {
|
|
24565
|
+
const block = update.content;
|
|
24566
|
+
if (block)
|
|
24567
|
+
entry.content.push(block);
|
|
24568
|
+
} else {
|
|
24569
|
+
const content = update.content;
|
|
24570
|
+
if (content !== void 0) {
|
|
24571
|
+
entry.content = content === null ? [] : Array.isArray(content) ? content : [content];
|
|
24572
|
+
}
|
|
24573
|
+
}
|
|
24574
|
+
if (update._meta !== void 0) {
|
|
24575
|
+
entry._meta = update._meta === null ? void 0 : { ...entry._meta, ...update._meta };
|
|
24576
|
+
}
|
|
24577
|
+
}
|
|
24578
|
+
function isSettled(status) {
|
|
24579
|
+
return SETTLED.has(status);
|
|
24580
|
+
}
|
|
24581
|
+
function outlivesTheTurn(entry) {
|
|
24582
|
+
if (readBackgroundTaskMeta(entry._meta))
|
|
24583
|
+
return true;
|
|
24584
|
+
const input2 = entry.rawInput;
|
|
24585
|
+
return entry.name?.toLowerCase() === "bash" && typeof input2 === "object" && input2 !== null && input2.run_in_background === true;
|
|
24586
|
+
}
|
|
24587
|
+
function settleOpenToolCalls(state) {
|
|
24588
|
+
for (const entry of state.entries) {
|
|
24589
|
+
if (entry.kind !== "tool_call" || isSettled(entry.status))
|
|
24590
|
+
continue;
|
|
24591
|
+
if (outlivesTheTurn(entry))
|
|
24592
|
+
continue;
|
|
24593
|
+
entry.status = "cancelled";
|
|
24594
|
+
}
|
|
24595
|
+
}
|
|
24596
|
+
function applyTool(state, index, update) {
|
|
24597
|
+
const key = `t:${update.toolCallId}`;
|
|
24598
|
+
let entry = index.get(key);
|
|
24599
|
+
if (!entry) {
|
|
24600
|
+
entry = {
|
|
24601
|
+
kind: "tool_call",
|
|
24602
|
+
id: update.toolCallId,
|
|
24603
|
+
toolKind: "other",
|
|
24604
|
+
status: "pending",
|
|
24605
|
+
content: [],
|
|
24606
|
+
locations: []
|
|
24607
|
+
};
|
|
24608
|
+
index.set(key, entry);
|
|
24609
|
+
state.entries.push(entry);
|
|
24610
|
+
}
|
|
24611
|
+
entry.lastUpdateIndex = state.updateCount;
|
|
24612
|
+
if (update.sessionUpdate === "tool_call_content_chunk") {
|
|
24613
|
+
const block = update.content;
|
|
24614
|
+
if (block)
|
|
24615
|
+
entry.content.push(block);
|
|
24616
|
+
return;
|
|
24617
|
+
}
|
|
24618
|
+
const u = update;
|
|
24619
|
+
if (u.name !== void 0)
|
|
24620
|
+
entry.name = u.name ?? void 0;
|
|
24621
|
+
if (u.title !== void 0)
|
|
24622
|
+
entry.title = u.title ?? void 0;
|
|
24623
|
+
if (!entry.title && typeof u.name === "string" && u.name.length > 0)
|
|
24624
|
+
entry.title = u.name;
|
|
24625
|
+
if (u.kind !== void 0)
|
|
24626
|
+
entry.toolKind = u.kind ?? "other";
|
|
24627
|
+
if (u.status !== void 0 && !isSettled(entry.status))
|
|
24628
|
+
entry.status = u.status ?? "pending";
|
|
24629
|
+
if (u.content !== void 0)
|
|
24630
|
+
entry.content = u.content ?? [];
|
|
24631
|
+
if (u.locations !== void 0)
|
|
24632
|
+
entry.locations = u.locations ?? [];
|
|
24633
|
+
if (u.rawInput !== void 0)
|
|
24634
|
+
entry.rawInput = u.rawInput;
|
|
24635
|
+
if (u.rawOutput !== void 0)
|
|
24636
|
+
entry.rawOutput = u.rawOutput;
|
|
24637
|
+
if (u._meta !== void 0) {
|
|
24638
|
+
entry._meta = u._meta === null ? void 0 : { ...entry._meta, ...u._meta };
|
|
24639
|
+
}
|
|
24640
|
+
}
|
|
24641
|
+
function messageText2(entry) {
|
|
24642
|
+
return entry.content.filter((b) => b.type === "text").map((b) => b.text).join("");
|
|
24643
|
+
}
|
|
24644
|
+
var ROLE_BY_KIND, entryIndexes, AWAITING_TOOL_CALLS_META, SETTLED;
|
|
23800
24645
|
var init_reduce = __esm({
|
|
23801
24646
|
"../shared/dist/agent/acp/reduce.js"() {
|
|
23802
24647
|
"use strict";
|
|
24648
|
+
init_background_task();
|
|
24649
|
+
init_types2();
|
|
24650
|
+
ROLE_BY_KIND = {
|
|
24651
|
+
user_message: "user",
|
|
24652
|
+
user_message_chunk: "user",
|
|
24653
|
+
agent_message: "agent",
|
|
24654
|
+
agent_message_chunk: "agent",
|
|
24655
|
+
agent_thought: "thought",
|
|
24656
|
+
agent_thought_chunk: "thought"
|
|
24657
|
+
};
|
|
24658
|
+
entryIndexes = /* @__PURE__ */ new WeakMap();
|
|
24659
|
+
AWAITING_TOOL_CALLS_META = "alan.dev/awaitingToolCallIds";
|
|
24660
|
+
SETTLED = /* @__PURE__ */ new Set(["completed", "failed", "cancelled"]);
|
|
23803
24661
|
}
|
|
23804
24662
|
});
|
|
23805
24663
|
|
|
23806
24664
|
// ../shared/dist/agent/acp/conversation-messages.js
|
|
24665
|
+
function compactConversationMessageTurns(turns, keepNewestEntries) {
|
|
24666
|
+
return turns.map((turn, index) => ({
|
|
24667
|
+
...turn,
|
|
24668
|
+
display: turn.display.map((displayTurn) => {
|
|
24669
|
+
if (!displayTurn.final)
|
|
24670
|
+
return displayTurn;
|
|
24671
|
+
return {
|
|
24672
|
+
...displayTurn,
|
|
24673
|
+
working: displayTurn.working.map((node2) => node2.key === displayTurn.final?.key ? {
|
|
24674
|
+
...node2,
|
|
24675
|
+
children: [],
|
|
24676
|
+
event: {
|
|
24677
|
+
...node2.event,
|
|
24678
|
+
update: { ...node2.event.update, content: [] }
|
|
24679
|
+
}
|
|
24680
|
+
} : node2)
|
|
24681
|
+
};
|
|
24682
|
+
}),
|
|
24683
|
+
state: {
|
|
24684
|
+
...turn.state,
|
|
24685
|
+
entries: index === 0 && keepNewestEntries ? turn.state.entries.map((entry) => {
|
|
24686
|
+
if (entry.kind === "message")
|
|
24687
|
+
return entry.role === "user" ? entry : { ...entry, content: [] };
|
|
24688
|
+
const ask = isAskUserQuestionTool(entry.title || entry.toolKind, entry.rawInput);
|
|
24689
|
+
return {
|
|
24690
|
+
...entry,
|
|
24691
|
+
content: [],
|
|
24692
|
+
locations: [],
|
|
24693
|
+
rawInput: ask ? entry.rawInput : void 0,
|
|
24694
|
+
rawOutput: void 0
|
|
24695
|
+
};
|
|
24696
|
+
}) : []
|
|
24697
|
+
}
|
|
24698
|
+
}));
|
|
24699
|
+
}
|
|
24700
|
+
function prepareConversationTurnRead(state) {
|
|
24701
|
+
const prompts = [];
|
|
24702
|
+
const navigation = [];
|
|
24703
|
+
const interactiveTools = [];
|
|
24704
|
+
let modeChange = null;
|
|
24705
|
+
let latestAgentMessageId = null;
|
|
24706
|
+
for (const entry of state.entries) {
|
|
24707
|
+
if (entry.kind === "message" && entry.role === "user") {
|
|
24708
|
+
const meta3 = entry._meta ?? {};
|
|
24709
|
+
if (typeof meta3["alan.dev/parentToolCallId"] !== "string") {
|
|
24710
|
+
const clientMessageId = meta3["alan.dev/clientMessageId"];
|
|
24711
|
+
prompts.push({
|
|
24712
|
+
entryId: entry.id,
|
|
24713
|
+
...typeof clientMessageId === "string" ? { clientMessageId } : {},
|
|
24714
|
+
content: messageText2(entry),
|
|
24715
|
+
agentMode: typeof meta3["alan.dev/agentMode"] === "string" ? meta3["alan.dev/agentMode"] : null,
|
|
24716
|
+
attachmentIds: Array.isArray(meta3["alan.dev/attachmentIds"]) ? meta3["alan.dev/attachmentIds"] : void 0,
|
|
24717
|
+
references: Array.isArray(meta3["alan.dev/references"]) ? meta3["alan.dev/references"] : void 0
|
|
24718
|
+
});
|
|
24719
|
+
}
|
|
24720
|
+
const title = toPreviewText(messageText2(entry).slice(0, 960).replace(attachmentMentionPattern(), ""), 240);
|
|
24721
|
+
navigation.push({ id: entry.id, title: title || "Message with attachments" });
|
|
24722
|
+
continue;
|
|
24723
|
+
}
|
|
24724
|
+
if (entry.kind === "message" && entry.role === "agent" && navigation.length > 0) {
|
|
24725
|
+
latestAgentMessageId = entry.id;
|
|
24726
|
+
if (typeof entry._meta?.["alan.dev/parentToolCallId"] === "string")
|
|
24727
|
+
continue;
|
|
24728
|
+
const content = messageText2(entry);
|
|
24729
|
+
if (!/\S/.test(content))
|
|
24730
|
+
continue;
|
|
24731
|
+
const preview = toPreviewText(content.slice(0, 960).replace(attachmentMentionPattern(), ""), 240);
|
|
24732
|
+
if (preview)
|
|
24733
|
+
navigation[navigation.length - 1].preview = preview;
|
|
24734
|
+
continue;
|
|
24735
|
+
}
|
|
24736
|
+
if (entry.kind === "message" && entry.role === "agent") {
|
|
24737
|
+
latestAgentMessageId = entry.id;
|
|
24738
|
+
continue;
|
|
24739
|
+
}
|
|
24740
|
+
if (entry.kind !== "tool_call")
|
|
24741
|
+
continue;
|
|
24742
|
+
const name = entry.name || entry.title || entry.toolKind;
|
|
24743
|
+
const responseToolId = entry._meta?.[TRANSCRIPT_TOOL_RESPONSE_ID_META];
|
|
24744
|
+
interactiveTools.push({
|
|
24745
|
+
id: entry.id,
|
|
24746
|
+
name,
|
|
24747
|
+
...(entry.status === "pending" || entry.status === "in_progress") && {
|
|
24748
|
+
input: entry.rawInput
|
|
24749
|
+
},
|
|
24750
|
+
...typeof responseToolId === "string" ? { responseToolId } : {}
|
|
24751
|
+
});
|
|
24752
|
+
const toolName2 = (entry.name || entry.title)?.trim().toLowerCase();
|
|
24753
|
+
if (toolName2 === "enterplanmode") {
|
|
24754
|
+
modeChange = "plan";
|
|
24755
|
+
continue;
|
|
24756
|
+
}
|
|
24757
|
+
if (toolName2 !== "exitplanmode")
|
|
24758
|
+
continue;
|
|
24759
|
+
if (entry.status !== "completed" && entry.status !== "failed")
|
|
24760
|
+
continue;
|
|
24761
|
+
const output2 = typeof entry.rawOutput === "string" ? entry.rawOutput : entry.content.flatMap((item) => item.type === "content" && item.content.type === "text" ? [item.content.text] : []).join("\n");
|
|
24762
|
+
const response = output2.trim().toLowerCase();
|
|
24763
|
+
if (response === "accepted" && entry.status === "completed")
|
|
24764
|
+
modeChange = "agent";
|
|
24765
|
+
else if (response === "rejected")
|
|
24766
|
+
modeChange = "plan";
|
|
24767
|
+
}
|
|
24768
|
+
return {
|
|
24769
|
+
entryCount: state.entries.length,
|
|
24770
|
+
latestAgentMessageId,
|
|
24771
|
+
prompts,
|
|
24772
|
+
navigation,
|
|
24773
|
+
modeChange,
|
|
24774
|
+
pendingAsk: findPendingAsk(state.entries),
|
|
24775
|
+
interactiveTools
|
|
24776
|
+
};
|
|
24777
|
+
}
|
|
24778
|
+
function conversationTurnView(ordinal, state, previousDisplay = []) {
|
|
24779
|
+
return {
|
|
24780
|
+
ordinal,
|
|
24781
|
+
state,
|
|
24782
|
+
display: prepareConversationTurns(state, state.state === "running", previousDisplay),
|
|
24783
|
+
read: prepareConversationTurnRead(state)
|
|
24784
|
+
};
|
|
24785
|
+
}
|
|
24786
|
+
function diffArray(previous, next) {
|
|
24787
|
+
const changes = [];
|
|
24788
|
+
for (const [index, value2] of next.entries()) {
|
|
24789
|
+
if (previous[index] !== value2)
|
|
24790
|
+
changes.push({ index, value: value2 });
|
|
24791
|
+
}
|
|
24792
|
+
return { length: next.length, changes };
|
|
24793
|
+
}
|
|
24794
|
+
function stateFields(state) {
|
|
24795
|
+
const { entries: _entries, unknown: _unknown2, presentation: _presentation, ...fields } = state;
|
|
24796
|
+
return fields;
|
|
24797
|
+
}
|
|
24798
|
+
function diffTranscriptState(previous, next) {
|
|
24799
|
+
return {
|
|
24800
|
+
entries: diffArray(previous.entries, next.entries),
|
|
24801
|
+
unknown: diffArray(previous.unknown, next.unknown),
|
|
24802
|
+
fields: stateFields(next)
|
|
24803
|
+
};
|
|
24804
|
+
}
|
|
24805
|
+
function createLiveTurnFrameEncoder() {
|
|
24806
|
+
const sent = /* @__PURE__ */ new Map();
|
|
24807
|
+
return (ordinal, state) => {
|
|
24808
|
+
const previous = sent.get(ordinal);
|
|
24809
|
+
sent.delete(ordinal);
|
|
24810
|
+
sent.set(ordinal, state);
|
|
24811
|
+
for (const oldest of sent.keys()) {
|
|
24812
|
+
if (sent.size <= SENT_LIVE_TURNS)
|
|
24813
|
+
break;
|
|
24814
|
+
sent.delete(oldest);
|
|
24815
|
+
}
|
|
24816
|
+
return previous ? { kind: "patch", ordinal, patch: diffTranscriptState(previous, state) } : { kind: "snapshot", ordinal, state };
|
|
24817
|
+
};
|
|
24818
|
+
}
|
|
24819
|
+
function isRecord8(value2) {
|
|
24820
|
+
return value2 !== null && typeof value2 === "object" && !Array.isArray(value2);
|
|
24821
|
+
}
|
|
24822
|
+
function isTranscriptState(value2) {
|
|
24823
|
+
return isRecord8(value2) && typeof value2.state === "string" && Array.isArray(value2.entries) && Array.isArray(value2.notices) && Array.isArray(value2.unknown);
|
|
24824
|
+
}
|
|
24825
|
+
function isArrayPatch(value2) {
|
|
24826
|
+
return isRecord8(value2) && Number.isSafeInteger(value2.length) && Array.isArray(value2.changes) && value2.changes.every((change) => isRecord8(change) && Number.isSafeInteger(change.index) && "value" in change);
|
|
24827
|
+
}
|
|
24828
|
+
function isTranscriptStatePatch(value2) {
|
|
24829
|
+
return isRecord8(value2) && isArrayPatch(value2.entries) && isArrayPatch(value2.unknown) && isRecord8(value2.fields) && typeof value2.fields.state === "string" && Array.isArray(value2.fields.notices);
|
|
24830
|
+
}
|
|
24831
|
+
function isLiveTurnFrame(value2) {
|
|
24832
|
+
if (!isRecord8(value2) || !Number.isSafeInteger(value2.ordinal))
|
|
24833
|
+
return false;
|
|
24834
|
+
if (value2.kind === "snapshot")
|
|
24835
|
+
return isTranscriptState(value2.state);
|
|
24836
|
+
return value2.kind === "patch" && isTranscriptStatePatch(value2.patch);
|
|
24837
|
+
}
|
|
24838
|
+
function isPendingAsk(value2) {
|
|
24839
|
+
return value2 === null || isRecord8(value2) && typeof value2.toolCallId === "string" && isRecord8(value2.rawInput) && Array.isArray(value2.questions) && value2.questions.every((question) => isRecord8(question) && typeof question.question === "string" && (question.header === void 0 || typeof question.header === "string") && typeof question.multiSelect === "boolean" && Array.isArray(question.options) && question.options.every((option2) => isRecord8(option2) && typeof option2.label === "string" && (option2.description === void 0 || typeof option2.description === "string")));
|
|
24840
|
+
}
|
|
24841
|
+
function isInteractiveTool(value2) {
|
|
24842
|
+
return isRecord8(value2) && typeof value2.id === "string" && typeof value2.name === "string" && (value2.responseToolId === void 0 || typeof value2.responseToolId === "string");
|
|
24843
|
+
}
|
|
24844
|
+
function isConversationTurnRead(value2) {
|
|
24845
|
+
return isRecord8(value2) && Number.isSafeInteger(value2.entryCount) && (value2.latestAgentMessageId === null || typeof value2.latestAgentMessageId === "string") && Array.isArray(value2.prompts) && value2.prompts.every((prompt) => isRecord8(prompt) && (prompt.entryId === void 0 || typeof prompt.entryId === "string") && (prompt.clientMessageId === void 0 || typeof prompt.clientMessageId === "string") && typeof prompt.content === "string" && (prompt.agentMode === null || typeof prompt.agentMode === "string")) && Array.isArray(value2.navigation) && value2.navigation.every((item) => isRecord8(item) && typeof item.id === "string" && typeof item.title === "string" && (item.preview === void 0 || typeof item.preview === "string")) && (value2.modeChange === null || value2.modeChange === "plan" || value2.modeChange === "agent") && isPendingAsk(value2.pendingAsk) && Array.isArray(value2.interactiveTools) && value2.interactiveTools.every(isInteractiveTool);
|
|
24846
|
+
}
|
|
24847
|
+
function isConversationMessageTurn(value2) {
|
|
24848
|
+
return isRecord8(value2) && Number.isSafeInteger(value2.ordinal) && typeof value2.markdown === "string" && isTranscriptState(value2.state) && Array.isArray(value2.display) && isConversationTurnRead(value2.read) && value2.display.every((turn) => isRecord8(turn) && typeof turn.key === "string" && Array.isArray(turn.users) && Array.isArray(turn.working) && isRecord8(turn.activity));
|
|
24849
|
+
}
|
|
24850
|
+
function isConversationMessagesPage(value2) {
|
|
24851
|
+
return isRecord8(value2) && typeof value2.revision === "string" && typeof value2.streamCursor === "string" && (value2.before === null || typeof value2.before === "string") && Array.isArray(value2.turns) && value2.turns.every(isConversationMessageTurn);
|
|
24852
|
+
}
|
|
24853
|
+
var LIVE_TURN_FRAMES, LIVE_TURN_EVENT, SENT_LIVE_TURNS;
|
|
23807
24854
|
var init_conversation_messages = __esm({
|
|
23808
24855
|
"../shared/dist/agent/acp/conversation-messages.js"() {
|
|
23809
24856
|
"use strict";
|
|
24857
|
+
init_agent();
|
|
24858
|
+
init_attachment_mention();
|
|
24859
|
+
init_preview();
|
|
24860
|
+
init_ask();
|
|
24861
|
+
init_prepare_conversation_turns();
|
|
24862
|
+
init_reduce();
|
|
24863
|
+
init_transcript_http();
|
|
24864
|
+
LIVE_TURN_FRAMES = "patch";
|
|
24865
|
+
LIVE_TURN_EVENT = "live_turn";
|
|
24866
|
+
SENT_LIVE_TURNS = 8;
|
|
23810
24867
|
}
|
|
23811
24868
|
});
|
|
23812
24869
|
|
|
@@ -23832,9 +24889,172 @@ var init_transcript_byte_decoder = __esm({
|
|
|
23832
24889
|
});
|
|
23833
24890
|
|
|
23834
24891
|
// ../shared/dist/agent/acp/transcript-fold.js
|
|
24892
|
+
function isRecord9(value2) {
|
|
24893
|
+
return value2 !== null && typeof value2 === "object" && !Array.isArray(value2);
|
|
24894
|
+
}
|
|
24895
|
+
function scopedContent(value2, turnId) {
|
|
24896
|
+
if (!Array.isArray(value2))
|
|
24897
|
+
return value2;
|
|
24898
|
+
return value2.map((block) => isRecord9(block) && block.type === "terminal" && typeof block.terminalId === "string" ? { ...block, terminalId: `${turnId}:${block.terminalId}` } : block);
|
|
24899
|
+
}
|
|
24900
|
+
function scopeTranscriptEvent(value2) {
|
|
24901
|
+
if (!isRecord9(value2) || !Number.isSafeInteger(value2.seq) || !Number.isFinite(value2.at))
|
|
24902
|
+
return null;
|
|
24903
|
+
if (!isRecord9(value2.update) || typeof value2.update.sessionUpdate !== "string")
|
|
24904
|
+
return null;
|
|
24905
|
+
const update = value2.update;
|
|
24906
|
+
const turnId = typeof value2.turnId === "string" ? value2.turnId : void 0;
|
|
24907
|
+
const event = {
|
|
24908
|
+
seq: Number(value2.seq),
|
|
24909
|
+
at: Number(value2.at),
|
|
24910
|
+
...typeof value2.sessionId === "string" ? { sessionId: value2.sessionId } : {},
|
|
24911
|
+
update
|
|
24912
|
+
};
|
|
24913
|
+
if (!turnId)
|
|
24914
|
+
return event;
|
|
24915
|
+
const meta3 = isRecord9(update._meta) ? { ...update._meta } : {};
|
|
24916
|
+
const parent = meta3["alan.dev/parentToolCallId"];
|
|
24917
|
+
if (typeof parent === "string")
|
|
24918
|
+
meta3["alan.dev/parentToolCallId"] = `${turnId}:${parent}`;
|
|
24919
|
+
if (typeof update.toolCallId === "string")
|
|
24920
|
+
meta3[TRANSCRIPT_TOOL_RESPONSE_ID_META] = update.toolCallId;
|
|
24921
|
+
if (typeof update.sessionUpdate === "string" && MEDIA_SESSION_UPDATE_KINDS.has(update.sessionUpdate))
|
|
24922
|
+
meta3[TRANSCRIPT_TURN_ID_META] = turnId;
|
|
24923
|
+
const scoped = { ...update, _meta: meta3 };
|
|
24924
|
+
for (const key of ["messageId", "toolCallId", "terminalId", "planId"]) {
|
|
24925
|
+
if (typeof update[key] === "string")
|
|
24926
|
+
scoped[key] = `${turnId}:${update[key]}`;
|
|
24927
|
+
}
|
|
24928
|
+
if ("content" in update)
|
|
24929
|
+
scoped.content = scopedContent(update.content, turnId);
|
|
24930
|
+
return { ...event, update: scoped };
|
|
24931
|
+
}
|
|
24932
|
+
function placeMessage(cache2, message2, updateOffset, entryOffset, startsWithPrompt) {
|
|
24933
|
+
const cached2 = cache2.get(message2.messageId);
|
|
24934
|
+
const source = message2.state;
|
|
24935
|
+
const sameSource = cached2?.source === source;
|
|
24936
|
+
if (sameSource && cached2.updateCount === source.updateCount && cached2.updateOffset === updateOffset && cached2.entryOffset === entryOffset && cached2.startsWithPrompt === startsWithPrompt)
|
|
24937
|
+
return cached2.state;
|
|
24938
|
+
const replacedEntries = cached2 && !sameSource ? cached2.source.entries : void 0;
|
|
24939
|
+
const entries = source.entries.map((entry, index) => {
|
|
24940
|
+
const previous = cached2?.state.entries[index];
|
|
24941
|
+
const lastUpdateIndex = entry.lastUpdateIndex === void 0 ? void 0 : entry.lastUpdateIndex + updateOffset;
|
|
24942
|
+
if (previous && cached2.updateOffset === updateOffset && previous.id === entry.id && previous.kind === entry.kind && (sameSource ? entry.lastUpdateIndex !== void 0 && previous.lastUpdateIndex === lastUpdateIndex : replacedEntries?.[index] === entry))
|
|
24943
|
+
return previous;
|
|
24944
|
+
return entry.kind === "message" ? { ...entry, lastUpdateIndex, content: [...entry.content] } : {
|
|
24945
|
+
...entry,
|
|
24946
|
+
lastUpdateIndex,
|
|
24947
|
+
content: [...entry.content],
|
|
24948
|
+
locations: [...entry.locations]
|
|
24949
|
+
};
|
|
24950
|
+
});
|
|
24951
|
+
const state = {
|
|
24952
|
+
...source,
|
|
24953
|
+
entries,
|
|
24954
|
+
notices: [...source.notices],
|
|
24955
|
+
unknown: [...source.unknown],
|
|
24956
|
+
...source.activities ? {
|
|
24957
|
+
activities: source.activities.map((activity) => ({
|
|
24958
|
+
...activity,
|
|
24959
|
+
firstEntryIndex: entryOffset + activity.firstEntryIndex - (startsWithPrompt && activity.firstEntryIndex === 0 ? 1 : 0)
|
|
24960
|
+
}))
|
|
24961
|
+
} : {}
|
|
24962
|
+
};
|
|
24963
|
+
cache2.set(message2.messageId, {
|
|
24964
|
+
source,
|
|
24965
|
+
updateCount: source.updateCount,
|
|
24966
|
+
updateOffset,
|
|
24967
|
+
entryOffset,
|
|
24968
|
+
startsWithPrompt,
|
|
24969
|
+
state
|
|
24970
|
+
});
|
|
24971
|
+
return state;
|
|
24972
|
+
}
|
|
24973
|
+
function anchoredUpdateOffset(ordered, cache2) {
|
|
24974
|
+
let natural = 0;
|
|
24975
|
+
for (const message2 of ordered) {
|
|
24976
|
+
const placed = cache2.get(message2.messageId);
|
|
24977
|
+
if (placed)
|
|
24978
|
+
return natural - placed.updateOffset;
|
|
24979
|
+
natural += message2.state.updateCount ?? 0;
|
|
24980
|
+
}
|
|
24981
|
+
return 0;
|
|
24982
|
+
}
|
|
24983
|
+
function mergeTranscriptMessages(messages, cache2) {
|
|
24984
|
+
const merged = emptyTranscript();
|
|
24985
|
+
const ordered = [...messages].sort((left, right) => (left.turnOrdinal ?? 0) - (right.turnOrdinal ?? 0) || left.messageId.localeCompare(right.messageId));
|
|
24986
|
+
let updateOffset = -anchoredUpdateOffset(ordered, cache2);
|
|
24987
|
+
const seenToolIds = /* @__PURE__ */ new Set();
|
|
24988
|
+
const seenNotices = /* @__PURE__ */ new Set();
|
|
24989
|
+
for (const message2 of ordered) {
|
|
24990
|
+
const entryOffset = merged.entries.length;
|
|
24991
|
+
const previous = merged.entries.at(-1);
|
|
24992
|
+
const startsWithPrompt = message2.role !== "user" && previous?.kind === "message" && previous.role === "user";
|
|
24993
|
+
const state = placeMessage(cache2, message2, updateOffset, entryOffset, startsWithPrompt);
|
|
24994
|
+
const removedBefore = [0];
|
|
24995
|
+
const duplicateToolIds = /* @__PURE__ */ new Set();
|
|
24996
|
+
for (const entry of state.entries) {
|
|
24997
|
+
const parentId = entry._meta?.["alan.dev/parentToolCallId"];
|
|
24998
|
+
const rawId = entry._meta?.[TRANSCRIPT_TOOL_RESPONSE_ID_META];
|
|
24999
|
+
const providerEvent = entry._meta?.["alan.dev/providerEvent"];
|
|
25000
|
+
const providerEventId = providerEvent && typeof providerEvent === "object" && "id" in providerEvent ? providerEvent.id : void 0;
|
|
25001
|
+
const toolId = entry.kind === "tool_call" && typeof rawId === "string" && typeof providerEventId === "string" ? `${rawId}:${providerEventId}` : void 0;
|
|
25002
|
+
const duplicate = toolId !== void 0 && seenToolIds.has(toolId) || typeof parentId === "string" && duplicateToolIds.has(parentId);
|
|
25003
|
+
if (!duplicate) {
|
|
25004
|
+
merged.entries.push(entry);
|
|
25005
|
+
if (toolId)
|
|
25006
|
+
seenToolIds.add(toolId);
|
|
25007
|
+
}
|
|
25008
|
+
if (duplicate && toolId)
|
|
25009
|
+
duplicateToolIds.add(entry.id);
|
|
25010
|
+
removedBefore.push((removedBefore.at(-1) ?? 0) + Number(duplicate));
|
|
25011
|
+
}
|
|
25012
|
+
if (state.activities?.length) {
|
|
25013
|
+
merged.activities ??= [];
|
|
25014
|
+
merged.activities.push(...state.activities.map((activity, index) => ({
|
|
25015
|
+
...activity,
|
|
25016
|
+
firstEntryIndex: activity.firstEntryIndex - (removedBefore[message2.state.activities?.[index]?.firstEntryIndex ?? 0] ?? 0)
|
|
25017
|
+
})));
|
|
25018
|
+
}
|
|
25019
|
+
for (const notice2 of state.notices) {
|
|
25020
|
+
const key = JSON.stringify([notice2.level, notice2.message]);
|
|
25021
|
+
if (seenNotices.has(key))
|
|
25022
|
+
continue;
|
|
25023
|
+
seenNotices.add(key);
|
|
25024
|
+
merged.notices.push({
|
|
25025
|
+
...notice2,
|
|
25026
|
+
firstEntryIndex: startsWithPrompt ? entryOffset - 1 : entryOffset
|
|
25027
|
+
});
|
|
25028
|
+
}
|
|
25029
|
+
merged.unknown.push(...state.unknown);
|
|
25030
|
+
if (state.userMessageAt !== void 0)
|
|
25031
|
+
merged.userMessageAt = Math.max(merged.userMessageAt ?? state.userMessageAt, state.userMessageAt);
|
|
25032
|
+
if (message2.role !== "user") {
|
|
25033
|
+
merged.state = state.state;
|
|
25034
|
+
merged.stopReason = state.stopReason;
|
|
25035
|
+
merged.thinkingTokens = state.thinkingTokens;
|
|
25036
|
+
if (state.awaitingToolCallIds)
|
|
25037
|
+
merged.awaitingToolCallIds = state.awaitingToolCallIds;
|
|
25038
|
+
else
|
|
25039
|
+
delete merged.awaitingToolCallIds;
|
|
25040
|
+
}
|
|
25041
|
+
if (state.plan)
|
|
25042
|
+
merged.plan = state.plan;
|
|
25043
|
+
if (state.usage)
|
|
25044
|
+
merged.usage = state.usage;
|
|
25045
|
+
if (state.title)
|
|
25046
|
+
merged.title = state.title;
|
|
25047
|
+
updateOffset += state.updateCount ?? 0;
|
|
25048
|
+
}
|
|
25049
|
+
merged.updateCount = updateOffset;
|
|
25050
|
+
return merged;
|
|
25051
|
+
}
|
|
23835
25052
|
var init_transcript_fold = __esm({
|
|
23836
25053
|
"../shared/dist/agent/acp/transcript-fold.js"() {
|
|
23837
25054
|
"use strict";
|
|
25055
|
+
init_reduce();
|
|
25056
|
+
init_transcript_http();
|
|
25057
|
+
init_types2();
|
|
23838
25058
|
}
|
|
23839
25059
|
});
|
|
23840
25060
|
|
|
@@ -24101,7 +25321,7 @@ function withoutInlineMedia(update) {
|
|
|
24101
25321
|
...nextRawOutput === rawOutput ? {} : { rawOutput: nextRawOutput }
|
|
24102
25322
|
};
|
|
24103
25323
|
}
|
|
24104
|
-
var PROVIDER_PAYLOAD_META, TOOL_RESULT_ONLY_META, PARENT_TOOL_CALL_META, SUBAGENT_LAUNCHER_META, SUBAGENT_TASK_ID_META, SUBAGENT_OUTPUT_FILE_META, USAGE_META, TODOS_META, NOTICE_KIND_META, ASK_USER_QUESTIONS_META, USER_ANSWER_META,
|
|
25324
|
+
var PROVIDER_PAYLOAD_META, TOOL_RESULT_ONLY_META, PARENT_TOOL_CALL_META, SUBAGENT_LAUNCHER_META, SUBAGENT_TASK_ID_META, SUBAGENT_OUTPUT_FILE_META, USAGE_META, TODOS_META, NOTICE_KIND_META, ASK_USER_QUESTIONS_META, USER_ANSWER_META, AWAITING_TOOL_CALLS_META2, EXIT_PLAN_MODE_INPUT_META, BACKGROUND_TASK_META, TASK_PROGRESS_META, RATE_LIMIT_META, MODEL_META, TOOLS_META, SLASH_COMMANDS_META, TOOL_KIND_RULES, ANSWER_PREFIX, ACCEPT_WORDS, MIN_INLINE_MEDIA_CHARS, DATA_URL_PREFIX, BASE64_BODY;
|
|
24105
25325
|
var init_chunk_UGRKZTAD = __esm({
|
|
24106
25326
|
"../agent-core/dist/chunk-UGRKZTAD.js"() {
|
|
24107
25327
|
"use strict";
|
|
@@ -24119,7 +25339,7 @@ var init_chunk_UGRKZTAD = __esm({
|
|
|
24119
25339
|
NOTICE_KIND_META = "alan.dev/noticeKind";
|
|
24120
25340
|
ASK_USER_QUESTIONS_META = "alan.dev/askUserQuestions";
|
|
24121
25341
|
USER_ANSWER_META = "alan.dev/userAnswer";
|
|
24122
|
-
|
|
25342
|
+
AWAITING_TOOL_CALLS_META2 = "alan.dev/awaitingToolCallIds";
|
|
24123
25343
|
EXIT_PLAN_MODE_INPUT_META = "alan.dev/exitPlanModeInput";
|
|
24124
25344
|
BACKGROUND_TASK_META = BACKGROUND_TASK_META_KEY;
|
|
24125
25345
|
TASK_PROGRESS_META = "alan.dev/taskProgress";
|
|
@@ -24893,7 +26113,7 @@ var init_chunk_54ZRJOQP = __esm({
|
|
|
24893
26113
|
}
|
|
24894
26114
|
});
|
|
24895
26115
|
|
|
24896
|
-
// ../agent-core/dist/chunk-
|
|
26116
|
+
// ../agent-core/dist/chunk-KHYYC5IN.js
|
|
24897
26117
|
function collectStrings(value2, out) {
|
|
24898
26118
|
if (typeof value2 === "string") out.push(value2);
|
|
24899
26119
|
else if (Array.isArray(value2)) for (const item of value2) collectStrings(item, out);
|
|
@@ -25263,12 +26483,12 @@ function silentStartError(name, timeoutMs) {
|
|
|
25263
26483
|
};
|
|
25264
26484
|
}
|
|
25265
26485
|
var import_crypto3, import_fs4, import_path3, IMAGE_MIME_BY_EXT, VIDEO_MIME_BY_EXT, IMAGE_EXTENSIONS, VIDEO_EXTENSIONS, MAX_IMAGE_BYTES, MAX_VIDEO_BYTES, AGENT_BROWSER_MENTION, LocalMediaReader, SessionOpenRefusal, JsonRpcError, ACP_PROTOCOL_VERSION, ACP_ERROR, STDERR_TAIL_LINES, RESULT_EXIT_GRACE_MS, PerTurnSession;
|
|
25266
|
-
var
|
|
25267
|
-
"../agent-core/dist/chunk-
|
|
26486
|
+
var init_chunk_KHYYC5IN = __esm({
|
|
26487
|
+
"../agent-core/dist/chunk-KHYYC5IN.js"() {
|
|
25268
26488
|
"use strict";
|
|
25269
26489
|
init_chunk_UGRKZTAD();
|
|
25270
26490
|
init_chunk_54ZRJOQP();
|
|
25271
|
-
|
|
26491
|
+
init_chunk_M6YHY2EZ();
|
|
25272
26492
|
init_chunk_YXWJW7I5();
|
|
25273
26493
|
import_crypto3 = require("crypto");
|
|
25274
26494
|
import_fs4 = require("fs");
|
|
@@ -26759,7 +27979,7 @@ function launcherLabel(update) {
|
|
|
26759
27979
|
const description = asRecord(update.rawInput)?.description;
|
|
26760
27980
|
return nonEmpty(description) ?? nonEmpty(update.title);
|
|
26761
27981
|
}
|
|
26762
|
-
function
|
|
27982
|
+
function isSettled2(update) {
|
|
26763
27983
|
return update.status === "completed" || update.status === "failed" || update.status === "cancelled";
|
|
26764
27984
|
}
|
|
26765
27985
|
function isRunningTask(record2) {
|
|
@@ -26931,7 +28151,10 @@ function classifyResultError(event, context) {
|
|
|
26931
28151
|
if (classified.errorKind !== "unknown_cli_error" || !isApiError) return classified;
|
|
26932
28152
|
return { ...specForErrorKind("provider_error"), message: classified.message };
|
|
26933
28153
|
}
|
|
26934
|
-
function
|
|
28154
|
+
function isIdleUpdate(update) {
|
|
28155
|
+
return isUpdate(update, "state_update") && update.state === "idle";
|
|
28156
|
+
}
|
|
28157
|
+
function isSettled22(update) {
|
|
26935
28158
|
return update.status === "completed" || update.status === "failed" || update.status === "cancelled";
|
|
26936
28159
|
}
|
|
26937
28160
|
function parentToolUseId(event) {
|
|
@@ -27359,11 +28582,11 @@ var init_claude = __esm({
|
|
|
27359
28582
|
"../agent-core/dist/providers/claude.js"() {
|
|
27360
28583
|
"use strict";
|
|
27361
28584
|
init_chunk_DALFHI4B();
|
|
27362
|
-
|
|
28585
|
+
init_chunk_KHYYC5IN();
|
|
27363
28586
|
init_chunk_UGRKZTAD();
|
|
27364
28587
|
init_chunk_54ZRJOQP();
|
|
27365
28588
|
init_chunk_J2KTV5FP();
|
|
27366
|
-
|
|
28589
|
+
init_chunk_M6YHY2EZ();
|
|
27367
28590
|
init_chunk_ITTV3UIM();
|
|
27368
28591
|
init_chunk_YXWJW7I5();
|
|
27369
28592
|
init_effort();
|
|
@@ -27520,7 +28743,7 @@ var init_claude = __esm({
|
|
|
27520
28743
|
if (!record2) return update;
|
|
27521
28744
|
const remembered = record2.meta.label ?? this.#labels.get(update.toolCallId);
|
|
27522
28745
|
if (!record2.meta.label && remembered) record2.meta = { ...record2.meta, label: remembered };
|
|
27523
|
-
if (
|
|
28746
|
+
if (isSettled2(update) && record2.meta.kind === "agent" && isRunningTask(record2)) {
|
|
27524
28747
|
this.settle(record2, update.status ?? void 0, update.status !== "completed");
|
|
27525
28748
|
}
|
|
27526
28749
|
return { ...update, _meta: { ...update._meta, [BACKGROUND_TASK_META_KEY]: record2.meta } };
|
|
@@ -27667,6 +28890,7 @@ var init_claude = __esm({
|
|
|
27667
28890
|
#failure;
|
|
27668
28891
|
#authFailure;
|
|
27669
28892
|
#resultSeen = false;
|
|
28893
|
+
#heldIdle;
|
|
27670
28894
|
constructor(options = {}) {
|
|
27671
28895
|
this.#options = options;
|
|
27672
28896
|
this.taskRecords = options.taskRecords ?? new TaskRecords(options.now ?? (() => systemClock2.now()));
|
|
@@ -27714,7 +28938,17 @@ var init_claude = __esm({
|
|
|
27714
28938
|
readEvent(event) {
|
|
27715
28939
|
const parsed = this.#revise(parseClaudeEvent(event, this.grammar), event);
|
|
27716
28940
|
parsed.push(...this.#handle(event));
|
|
27717
|
-
const
|
|
28941
|
+
const kept = parsed.filter((update) => {
|
|
28942
|
+
if (!isIdleUpdate(update)) return true;
|
|
28943
|
+
if (this.#finalized) return true;
|
|
28944
|
+
this.#heldIdle = update;
|
|
28945
|
+
return false;
|
|
28946
|
+
});
|
|
28947
|
+
if (this.#finalized && this.#heldIdle !== void 0) {
|
|
28948
|
+
if (!kept.some(isIdleUpdate)) kept.push(this.#heldIdle);
|
|
28949
|
+
this.#heldIdle = void 0;
|
|
28950
|
+
}
|
|
28951
|
+
const updates = kept.map((update) => this.taskRecords.stamp(update));
|
|
27718
28952
|
for (const update of updates) this.#applyRunState(update);
|
|
27719
28953
|
return updates;
|
|
27720
28954
|
}
|
|
@@ -27941,7 +29175,7 @@ var init_claude = __esm({
|
|
|
27941
29175
|
this.#announced.add(id);
|
|
27942
29176
|
if (isLauncher) this.#registerLauncher(update, meta3);
|
|
27943
29177
|
}
|
|
27944
|
-
if (isLauncher &&
|
|
29178
|
+
if (isLauncher && isSettled22(update)) this.tasks.clear([id]);
|
|
27945
29179
|
}
|
|
27946
29180
|
#registerLauncher(update, meta3) {
|
|
27947
29181
|
this.tasks.registerLauncher(update.toolCallId);
|
|
@@ -30136,11 +31370,11 @@ var init_codex = __esm({
|
|
|
30136
31370
|
"../agent-core/dist/providers/codex.js"() {
|
|
30137
31371
|
"use strict";
|
|
30138
31372
|
init_chunk_DALFHI4B();
|
|
30139
|
-
|
|
31373
|
+
init_chunk_KHYYC5IN();
|
|
30140
31374
|
init_chunk_UGRKZTAD();
|
|
30141
31375
|
init_chunk_54ZRJOQP();
|
|
30142
31376
|
init_chunk_J2KTV5FP();
|
|
30143
|
-
|
|
31377
|
+
init_chunk_M6YHY2EZ();
|
|
30144
31378
|
init_chunk_ITTV3UIM();
|
|
30145
31379
|
init_chunk_YXWJW7I5();
|
|
30146
31380
|
import_fs6 = require("fs");
|
|
@@ -41406,10 +42640,10 @@ var require_tar_stream = __commonJS({
|
|
|
41406
42640
|
var init_dist = __esm({
|
|
41407
42641
|
"../agent-core/dist/index.js"() {
|
|
41408
42642
|
"use strict";
|
|
41409
|
-
|
|
42643
|
+
init_chunk_KHYYC5IN();
|
|
41410
42644
|
init_chunk_UGRKZTAD();
|
|
41411
42645
|
init_chunk_54ZRJOQP();
|
|
41412
|
-
|
|
42646
|
+
init_chunk_M6YHY2EZ();
|
|
41413
42647
|
init_chunk_YXWJW7I5();
|
|
41414
42648
|
}
|
|
41415
42649
|
});
|
|
@@ -41645,7 +42879,7 @@ function isRunning(task) {
|
|
|
41645
42879
|
return task.meta.status === "running" || task.meta.status === "stopping";
|
|
41646
42880
|
}
|
|
41647
42881
|
function isPlanStatus(value2) {
|
|
41648
|
-
return
|
|
42882
|
+
return STATUSES2.has(value2);
|
|
41649
42883
|
}
|
|
41650
42884
|
function todoEntries2(todos) {
|
|
41651
42885
|
return asArray(todos).flatMap((raw) => {
|
|
@@ -42149,15 +43383,15 @@ async function acpTurnInput(run2, context) {
|
|
|
42149
43383
|
...encoded.length ? { images: encoded, imagePaths: images.map((image) => image.path) } : {}
|
|
42150
43384
|
};
|
|
42151
43385
|
}
|
|
42152
|
-
var import_promises48, import_path9, import_crypto12, import_promises49, CURSOR_ASK_QUESTION, copilotAcpProfile, cursorAcpProfile, MODEL_REJECTED, MAX_READ_BYTES, FsDenied, ENV_REFERENCE, AcpBackgroundTasks, CURSOR_CREATE_PLAN,
|
|
43386
|
+
var import_promises48, import_path9, import_crypto12, import_promises49, CURSOR_ASK_QUESTION, copilotAcpProfile, cursorAcpProfile, MODEL_REJECTED, MAX_READ_BYTES, FsDenied, ENV_REFERENCE, AcpBackgroundTasks, CURSOR_CREATE_PLAN, STATUSES2, READ_KINDS, ALLOW_KINDS, REJECT_KINDS, CANCELLED_PERMISSION, STOP_REASONS, CHUNKS, ECHOES, AcpTurn, STDERR_TAIL_LINES4, MAX_BETWEEN_UPDATES2, AcpSession, DEFAULTS3, CLIENT_INFO2, TASK_BACKGROUNDED, TASK_COMPLETED, SESSION_NOTIFICATION, KILLED_STATUSES, SUCCESS_STATUSES, SUBAGENT_ID, grokTaskDialect, grokAcpProfile, kimiAcpProfile, ACP_PROFILES, ACP_MODES;
|
|
42153
43387
|
var init_acp3 = __esm({
|
|
42154
43388
|
"../agent-core/dist/providers/acp.js"() {
|
|
42155
43389
|
"use strict";
|
|
42156
|
-
|
|
43390
|
+
init_chunk_KHYYC5IN();
|
|
42157
43391
|
init_chunk_UGRKZTAD();
|
|
42158
43392
|
init_chunk_54ZRJOQP();
|
|
42159
43393
|
init_chunk_J2KTV5FP();
|
|
42160
|
-
|
|
43394
|
+
init_chunk_M6YHY2EZ();
|
|
42161
43395
|
init_chunk_ITTV3UIM();
|
|
42162
43396
|
init_chunk_YXWJW7I5();
|
|
42163
43397
|
import_promises48 = require("fs/promises");
|
|
@@ -42364,7 +43598,7 @@ var init_acp3 = __esm({
|
|
|
42364
43598
|
}
|
|
42365
43599
|
};
|
|
42366
43600
|
CURSOR_CREATE_PLAN = "cursor/create_plan";
|
|
42367
|
-
|
|
43601
|
+
STATUSES2 = /* @__PURE__ */ new Set(["pending", "in_progress", "completed", "cancelled"]);
|
|
42368
43602
|
READ_KINDS = /* @__PURE__ */ new Set(["read", "search", "think", "fetch"]);
|
|
42369
43603
|
ALLOW_KINDS = ["allow_once", "allow", "allow_always"];
|
|
42370
43604
|
REJECT_KINDS = ["reject_once", "reject", "deny", "reject_always"];
|
|
@@ -43038,15 +44272,16 @@ function createPersistentDriver(provider4, options) {
|
|
|
43038
44272
|
return void 0;
|
|
43039
44273
|
};
|
|
43040
44274
|
const resumeNotice = (spec, session, sink) => {
|
|
44275
|
+
if (spec.resumeFallbackContext) {
|
|
44276
|
+
log.info("holder.session_resume_fallback", { harness: provider4.harness, runId: spec.runId });
|
|
44277
|
+
return { session, contextPrefix: spec.resumeFallbackContext };
|
|
44278
|
+
}
|
|
43041
44279
|
sink.onEvent({
|
|
43042
44280
|
seq: 0,
|
|
43043
44281
|
at: clock.now(),
|
|
43044
44282
|
update: noticeUpdate("warning", "session_resume_failed", RESUME_UNAVAILABLE)
|
|
43045
44283
|
});
|
|
43046
|
-
return {
|
|
43047
|
-
session,
|
|
43048
|
-
...spec.resumeFallbackContext ? { contextPrefix: spec.resumeFallbackContext } : {}
|
|
43049
|
-
};
|
|
44284
|
+
return { session };
|
|
43050
44285
|
};
|
|
43051
44286
|
const managedMcpAccess = async (signal) => {
|
|
43052
44287
|
const managed = options.managedMcp;
|
|
@@ -43121,6 +44356,7 @@ function createPersistentDriver(provider4, options) {
|
|
|
43121
44356
|
};
|
|
43122
44357
|
const _events = __using(_stack, session.onEvent(forward));
|
|
43123
44358
|
live.turn = turn;
|
|
44359
|
+
record2({ sessionUpdate: "state_update", state: "running" });
|
|
43124
44360
|
if (session.pid !== void 0) sink.onSpawned(session.pid);
|
|
43125
44361
|
const onAbort = () => {
|
|
43126
44362
|
void session.cancel();
|
|
@@ -43231,7 +44467,7 @@ function awaitingUpdate(waiting) {
|
|
|
43231
44467
|
return {
|
|
43232
44468
|
sessionUpdate: "state_update",
|
|
43233
44469
|
state: "requires_action",
|
|
43234
|
-
_meta: { [
|
|
44470
|
+
_meta: { [AWAITING_TOOL_CALLS_META2]: [...waiting] }
|
|
43235
44471
|
};
|
|
43236
44472
|
}
|
|
43237
44473
|
var RESUME_UNAVAILABLE;
|
|
@@ -43857,11 +45093,11 @@ var import_http10, import_crypto13, import_promises50, import_path10, import_pat
|
|
|
43857
45093
|
var init_opencode = __esm({
|
|
43858
45094
|
"../agent-core/dist/providers/opencode.js"() {
|
|
43859
45095
|
"use strict";
|
|
43860
|
-
|
|
45096
|
+
init_chunk_KHYYC5IN();
|
|
43861
45097
|
init_chunk_UGRKZTAD();
|
|
43862
45098
|
init_chunk_54ZRJOQP();
|
|
43863
45099
|
init_chunk_J2KTV5FP();
|
|
43864
|
-
|
|
45100
|
+
init_chunk_M6YHY2EZ();
|
|
43865
45101
|
init_chunk_ITTV3UIM();
|
|
43866
45102
|
init_chunk_YXWJW7I5();
|
|
43867
45103
|
import_http10 = require("http");
|
|
@@ -45052,7 +46288,7 @@ function createAlanCodeHolderDriver(options) {
|
|
|
45052
46288
|
open: open6,
|
|
45053
46289
|
turnInput: async (spec, inputs, contextPrefix) => openCodeTurnInput(spec, {
|
|
45054
46290
|
attachments: inputs.attachments,
|
|
45055
|
-
skills:
|
|
46291
|
+
skills: inputs.skills,
|
|
45056
46292
|
...contextPrefix === void 0 ? {} : { contextPrefix }
|
|
45057
46293
|
})
|
|
45058
46294
|
},
|
|
@@ -45134,7 +46370,7 @@ __export(codex_exports, {
|
|
|
45134
46370
|
createCodexHolderDriver: () => createCodexHolderDriver
|
|
45135
46371
|
});
|
|
45136
46372
|
function sha2563(value2) {
|
|
45137
|
-
return (0,
|
|
46373
|
+
return (0, import_node_crypto26.createHash)("sha256").update(value2).digest("hex");
|
|
45138
46374
|
}
|
|
45139
46375
|
function createCodexLogin(broker) {
|
|
45140
46376
|
const state = {};
|
|
@@ -45209,11 +46445,11 @@ function createCodexHolderDriver(options) {
|
|
|
45209
46445
|
}
|
|
45210
46446
|
);
|
|
45211
46447
|
}
|
|
45212
|
-
var
|
|
46448
|
+
var import_node_crypto26;
|
|
45213
46449
|
var init_codex2 = __esm({
|
|
45214
46450
|
"src/holder/drivers/codex.ts"() {
|
|
45215
46451
|
"use strict";
|
|
45216
|
-
|
|
46452
|
+
import_node_crypto26 = require("crypto");
|
|
45217
46453
|
init_dist();
|
|
45218
46454
|
init_codex();
|
|
45219
46455
|
init_persistent();
|
|
@@ -45665,11 +46901,11 @@ var import_crypto15, import_promises51, FACTORY_API_VERSION, FACTORY_PROTOCOL_VE
|
|
|
45665
46901
|
var init_droid = __esm({
|
|
45666
46902
|
"../agent-core/dist/providers/droid.js"() {
|
|
45667
46903
|
"use strict";
|
|
45668
|
-
|
|
46904
|
+
init_chunk_KHYYC5IN();
|
|
45669
46905
|
init_chunk_UGRKZTAD();
|
|
45670
46906
|
init_chunk_54ZRJOQP();
|
|
45671
46907
|
init_chunk_J2KTV5FP();
|
|
45672
|
-
|
|
46908
|
+
init_chunk_M6YHY2EZ();
|
|
45673
46909
|
init_chunk_ITTV3UIM();
|
|
45674
46910
|
init_chunk_YXWJW7I5();
|
|
45675
46911
|
init_runtime_v2();
|
|
@@ -46068,7 +47304,7 @@ function createDroidHolderDriver(options) {
|
|
|
46068
47304
|
},
|
|
46069
47305
|
turnInput: (spec, inputs, contextPrefix) => droidTurnInput(spec, {
|
|
46070
47306
|
attachments: inputs.attachments,
|
|
46071
|
-
skills:
|
|
47307
|
+
skills: inputs.skills,
|
|
46072
47308
|
...contextPrefix === void 0 ? {} : { contextPrefix }
|
|
46073
47309
|
})
|
|
46074
47310
|
},
|
|
@@ -46116,7 +47352,7 @@ function createOpenCodeHolderDriver(options) {
|
|
|
46116
47352
|
},
|
|
46117
47353
|
turnInput: async (spec, inputs, contextPrefix) => openCodeTurnInput(spec, {
|
|
46118
47354
|
attachments: inputs.attachments,
|
|
46119
|
-
skills:
|
|
47355
|
+
skills: inputs.skills,
|
|
46120
47356
|
...contextPrefix === void 0 ? {} : { contextPrefix }
|
|
46121
47357
|
})
|
|
46122
47358
|
},
|
|
@@ -46768,10 +48004,10 @@ var init_antigravity = __esm({
|
|
|
46768
48004
|
"../agent-core/dist/providers/antigravity.js"() {
|
|
46769
48005
|
"use strict";
|
|
46770
48006
|
init_chunk_DALFHI4B();
|
|
46771
|
-
|
|
48007
|
+
init_chunk_KHYYC5IN();
|
|
46772
48008
|
init_chunk_UGRKZTAD();
|
|
46773
48009
|
init_chunk_54ZRJOQP();
|
|
46774
|
-
|
|
48010
|
+
init_chunk_M6YHY2EZ();
|
|
46775
48011
|
init_chunk_ITTV3UIM();
|
|
46776
48012
|
init_chunk_YXWJW7I5();
|
|
46777
48013
|
import_promises52 = require("fs/promises");
|
|
@@ -47472,11 +48708,11 @@ var import_promises53, import_path15, import_crypto17, COMMAND_CODE_GRAMMAR_NAME
|
|
|
47472
48708
|
var init_command_code = __esm({
|
|
47473
48709
|
"../agent-core/dist/providers/command-code.js"() {
|
|
47474
48710
|
"use strict";
|
|
47475
|
-
|
|
48711
|
+
init_chunk_KHYYC5IN();
|
|
47476
48712
|
init_chunk_UGRKZTAD();
|
|
47477
48713
|
init_chunk_54ZRJOQP();
|
|
47478
48714
|
init_chunk_J2KTV5FP();
|
|
47479
|
-
|
|
48715
|
+
init_chunk_M6YHY2EZ();
|
|
47480
48716
|
init_chunk_ITTV3UIM();
|
|
47481
48717
|
init_chunk_YXWJW7I5();
|
|
47482
48718
|
import_promises53 = require("fs/promises");
|
|
@@ -48098,7 +49334,7 @@ var require_XMLHttpRequest = __commonJS({
|
|
|
48098
49334
|
"use strict";
|
|
48099
49335
|
var fs = require("fs");
|
|
48100
49336
|
var Url = require("url");
|
|
48101
|
-
var
|
|
49337
|
+
var spawn10 = require("child_process").spawn;
|
|
48102
49338
|
module2.exports = XMLHttpRequest3;
|
|
48103
49339
|
XMLHttpRequest3.XMLHttpRequest = XMLHttpRequest3;
|
|
48104
49340
|
function XMLHttpRequest3(opts) {
|
|
@@ -48394,7 +49630,7 @@ var require_XMLHttpRequest = __commonJS({
|
|
|
48394
49630
|
var syncFile = ".node-xmlhttprequest-sync-" + process.pid;
|
|
48395
49631
|
fs.writeFileSync(syncFile, "", "utf8");
|
|
48396
49632
|
var execString = "var http = require('http'), https = require('https'), fs = require('fs');var doRequest = http" + (ssl ? "s" : "") + ".request;var options = " + JSON.stringify(options) + ";var responseText = '';var responseData = Buffer.alloc(0);var req = doRequest(options, function(response) {response.on('data', function(chunk) { var data = Buffer.from(chunk); responseText += data.toString('utf8'); responseData = Buffer.concat([responseData, data]);});response.on('end', function() {fs.writeFileSync('" + contentFile + "', JSON.stringify({err: null, data: {statusCode: response.statusCode, headers: response.headers, text: responseText, data: responseData.toString('base64')}}), 'utf8');fs.unlinkSync('" + syncFile + "');});response.on('error', function(error) {fs.writeFileSync('" + contentFile + "', 'NODE-XMLHTTPREQUEST-ERROR:' + JSON.stringify(error), 'utf8');fs.unlinkSync('" + syncFile + "');});}).on('error', function(error) {fs.writeFileSync('" + contentFile + "', 'NODE-XMLHTTPREQUEST-ERROR:' + JSON.stringify(error), 'utf8');fs.unlinkSync('" + syncFile + "');});" + (data ? "req.write('" + JSON.stringify(data).slice(1, -1).replace(/'/g, "\\'") + "');" : "") + "req.end();";
|
|
48397
|
-
var syncProc =
|
|
49633
|
+
var syncProc = spawn10(process.argv[0], ["-e", execString]);
|
|
48398
49634
|
var statusText;
|
|
48399
49635
|
while (fs.existsSync(syncFile)) {
|
|
48400
49636
|
}
|
|
@@ -52875,7 +54111,7 @@ var require_websocket_server = __commonJS({
|
|
|
52875
54111
|
// package.json
|
|
52876
54112
|
var package_default = {
|
|
52877
54113
|
name: "@alan-ai-hq/agent-manager",
|
|
52878
|
-
version: "0.1.
|
|
54114
|
+
version: "0.1.139",
|
|
52879
54115
|
private: true,
|
|
52880
54116
|
type: "module",
|
|
52881
54117
|
description: "Alan machine runtime (alan-agent): identity, link, reconciler, session holders, run log, uploader, local API",
|
|
@@ -52924,8 +54160,8 @@ var package_default = {
|
|
|
52924
54160
|
};
|
|
52925
54161
|
|
|
52926
54162
|
// src/cli/commands/compat.ts
|
|
52927
|
-
var
|
|
52928
|
-
var
|
|
54163
|
+
var import_node_crypto31 = require("crypto");
|
|
54164
|
+
var import_promises66 = require("fs/promises");
|
|
52929
54165
|
init_runtime_v2();
|
|
52930
54166
|
init_zod();
|
|
52931
54167
|
|
|
@@ -53769,7 +55005,8 @@ var openTurnResponseSchema = external_exports.object({
|
|
|
53769
55005
|
runId: external_exports.string().min(1),
|
|
53770
55006
|
userMessageId: external_exports.string().min(1),
|
|
53771
55007
|
assistantMessageId: external_exports.string().min(1),
|
|
53772
|
-
created: external_exports.boolean()
|
|
55008
|
+
created: external_exports.boolean(),
|
|
55009
|
+
turnOrdinals: external_exports.object({ user: external_exports.number().int().nonnegative(), assistant: external_exports.number().int().nonnegative() }).optional()
|
|
53773
55010
|
});
|
|
53774
55011
|
var errorBodySchema2 = external_exports.object({ code: external_exports.string() });
|
|
53775
55012
|
function createNativeSessionsClient({
|
|
@@ -54961,7 +56198,7 @@ async function push(context, request2) {
|
|
|
54961
56198
|
var import_node_child_process = require("child_process");
|
|
54962
56199
|
|
|
54963
56200
|
// ../agent-core/dist/process.js
|
|
54964
|
-
|
|
56201
|
+
init_chunk_M6YHY2EZ();
|
|
54965
56202
|
init_chunk_YXWJW7I5();
|
|
54966
56203
|
|
|
54967
56204
|
// src/capabilities/git/run-git.ts
|
|
@@ -55969,6 +57206,7 @@ function markVersionInUse(bundlePath) {
|
|
|
55969
57206
|
}
|
|
55970
57207
|
|
|
55971
57208
|
// src/platform/instance-lock.ts
|
|
57209
|
+
var import_node_crypto7 = require("crypto");
|
|
55972
57210
|
var import_node_fs5 = require("fs");
|
|
55973
57211
|
var import_promises15 = require("fs/promises");
|
|
55974
57212
|
var import_node_path10 = require("path");
|
|
@@ -55997,17 +57235,22 @@ function inodeOf(path4) {
|
|
|
55997
57235
|
}
|
|
55998
57236
|
}
|
|
55999
57237
|
function tryCreate(path4, self) {
|
|
57238
|
+
const staged = `${path4}.${(0, import_node_crypto7.randomUUID)()}.candidate`;
|
|
56000
57239
|
try {
|
|
56001
|
-
const fd = (0, import_node_fs5.openSync)(
|
|
57240
|
+
const fd = (0, import_node_fs5.openSync)(staged, "wx", 384);
|
|
56002
57241
|
try {
|
|
56003
57242
|
(0, import_node_fs5.writeSync)(fd, JSON.stringify(self));
|
|
56004
57243
|
} finally {
|
|
56005
57244
|
(0, import_node_fs5.closeSync)(fd);
|
|
56006
57245
|
}
|
|
56007
|
-
|
|
57246
|
+
const inode = (0, import_node_fs5.statSync)(staged).ino;
|
|
57247
|
+
(0, import_node_fs5.linkSync)(staged, path4);
|
|
57248
|
+
return inode;
|
|
56008
57249
|
} catch (error61) {
|
|
56009
|
-
if (errnoCode(error61) === "EEXIST") return
|
|
57250
|
+
if (errnoCode(error61) === "EEXIST") return null;
|
|
56010
57251
|
throw error61;
|
|
57252
|
+
} finally {
|
|
57253
|
+
(0, import_node_fs5.rmSync)(staged, { force: true });
|
|
56011
57254
|
}
|
|
56012
57255
|
}
|
|
56013
57256
|
function removeStale(path4, inode) {
|
|
@@ -56019,21 +57262,26 @@ function removeStale(path4, inode) {
|
|
|
56019
57262
|
}
|
|
56020
57263
|
}
|
|
56021
57264
|
async function attempt(path4, self, probe) {
|
|
56022
|
-
|
|
57265
|
+
const created = tryCreate(path4, self);
|
|
57266
|
+
if (created !== null) return { kind: "acquired", inode: created };
|
|
56023
57267
|
const inode = inodeOf(path4);
|
|
56024
57268
|
const owner = readOwner(path4);
|
|
56025
57269
|
if (owner !== null && await mayBeSameProcess(owner, probe)) return { kind: "held", owner };
|
|
56026
57270
|
if (inode !== null) removeStale(path4, inode);
|
|
56027
|
-
return
|
|
57271
|
+
return attempt(path4, self, probe);
|
|
56028
57272
|
}
|
|
56029
57273
|
async function acquireInstanceLock(path4, { clock, waitMs, signal, probe = systemProcessProbe }) {
|
|
56030
57274
|
await (0, import_promises15.mkdir)((0, import_node_path10.dirname)(path4), { recursive: true, mode: 448 });
|
|
56031
57275
|
const self = await readProcessIdentity(process.pid);
|
|
56032
57276
|
if (self === null) throw new RuntimeFault("internal", "Cannot read this process's identity");
|
|
56033
57277
|
const deadline = clock.monotonic() + waitMs;
|
|
57278
|
+
let heldInode = null;
|
|
56034
57279
|
for (; ; ) {
|
|
56035
57280
|
const result = await attempt(path4, self, probe);
|
|
56036
|
-
if (result.kind === "acquired")
|
|
57281
|
+
if (result.kind === "acquired") {
|
|
57282
|
+
heldInode = result.inode;
|
|
57283
|
+
break;
|
|
57284
|
+
}
|
|
56037
57285
|
if (clock.monotonic() >= deadline) {
|
|
56038
57286
|
throw new RuntimeFault(
|
|
56039
57287
|
"already_running",
|
|
@@ -56046,13 +57294,15 @@ async function acquireInstanceLock(path4, { clock, waitMs, signal, probe = syste
|
|
|
56046
57294
|
owner: self,
|
|
56047
57295
|
[Symbol.dispose]: () => {
|
|
56048
57296
|
const owner = readOwner(path4);
|
|
56049
|
-
if (owner?.pid === self.pid && owner.startedAt === self.startedAt)
|
|
57297
|
+
if (inodeOf(path4) === heldInode && owner?.pid === self.pid && owner.startedAt === self.startedAt) {
|
|
57298
|
+
(0, import_node_fs5.unlinkSync)(path4);
|
|
57299
|
+
}
|
|
56050
57300
|
}
|
|
56051
57301
|
};
|
|
56052
57302
|
}
|
|
56053
57303
|
|
|
56054
57304
|
// src/platform/ipc-endpoint.ts
|
|
56055
|
-
var
|
|
57305
|
+
var import_node_crypto8 = require("crypto");
|
|
56056
57306
|
var import_node_fs6 = require("fs");
|
|
56057
57307
|
var import_node_os = require("os");
|
|
56058
57308
|
var import_node_path11 = require("path");
|
|
@@ -56061,7 +57311,7 @@ function windowsPipeName(socketsDir, id) {
|
|
|
56061
57311
|
return `\\\\.\\pipe\\alan-${socketsScope(socketsDir)}-${id}`;
|
|
56062
57312
|
}
|
|
56063
57313
|
function socketsScope(socketsDir) {
|
|
56064
|
-
return (0,
|
|
57314
|
+
return (0, import_node_crypto8.createHash)("sha256").update(socketsDir.toLowerCase()).digest("hex").slice(0, 12);
|
|
56065
57315
|
}
|
|
56066
57316
|
function ipcEndpoint(socketsDir, id, platform3 = process.platform) {
|
|
56067
57317
|
if (platform3 === "win32") return windowsPipeName(socketsDir, id);
|
|
@@ -56084,11 +57334,12 @@ var HOLDER_JITLESS_FLAG = "--jitless";
|
|
|
56084
57334
|
var HOLDER_NODE_FLAGS = [
|
|
56085
57335
|
"--max-semi-space-size=1",
|
|
56086
57336
|
"--max-old-space-size=1024",
|
|
57337
|
+
"--use-system-ca",
|
|
56087
57338
|
HOLDER_JITLESS_FLAG
|
|
56088
57339
|
];
|
|
56089
57340
|
|
|
56090
57341
|
// src/platform/npm-release.ts
|
|
56091
|
-
var
|
|
57342
|
+
var import_node_crypto9 = require("crypto");
|
|
56092
57343
|
init_zod();
|
|
56093
57344
|
var RELEASE_TARGETS = [
|
|
56094
57345
|
"darwin-arm64",
|
|
@@ -56156,11 +57407,11 @@ function verifyNpmIntegrity(bytes, dist) {
|
|
|
56156
57407
|
if (expected.length === 0) {
|
|
56157
57408
|
return { ok: false, reason: "the registry's integrity has no sha512 digest" };
|
|
56158
57409
|
}
|
|
56159
|
-
const actual = (0,
|
|
57410
|
+
const actual = (0, import_node_crypto9.createHash)("sha512").update(bytes).digest("base64");
|
|
56160
57411
|
return expected.includes(actual) ? { ok: true, algorithm: "sha512" } : { ok: false, reason: "the tarball does not match the registry's sha512 integrity" };
|
|
56161
57412
|
}
|
|
56162
57413
|
if (dist.shasum !== void 0) {
|
|
56163
|
-
return (0,
|
|
57414
|
+
return (0, import_node_crypto9.createHash)("sha1").update(bytes).digest("hex") === dist.shasum ? { ok: true, algorithm: "sha1" } : { ok: false, reason: "the tarball does not match the registry's shasum" };
|
|
56164
57415
|
}
|
|
56165
57416
|
return { ok: false, reason: "the registry lists no integrity for the tarball" };
|
|
56166
57417
|
}
|
|
@@ -56234,7 +57485,7 @@ function readMemoryPressure() {
|
|
|
56234
57485
|
}
|
|
56235
57486
|
|
|
56236
57487
|
// src/platform/release.ts
|
|
56237
|
-
var
|
|
57488
|
+
var import_node_crypto10 = require("crypto");
|
|
56238
57489
|
var REJECTED_VERSION_RETRY_MS = 24 * 60 * 60 * 1e3;
|
|
56239
57490
|
function parseVersion(version2) {
|
|
56240
57491
|
if (!releaseVersionSchema.safeParse(version2).success) return null;
|
|
@@ -56277,7 +57528,7 @@ function compareVersions(a, b) {
|
|
|
56277
57528
|
return comparePrerelease(left.prerelease, right.prerelease);
|
|
56278
57529
|
}
|
|
56279
57530
|
function rolloutBucket(machineId, version2) {
|
|
56280
|
-
return (0,
|
|
57531
|
+
return (0, import_node_crypto10.createHash)("sha256").update(`${machineId}
|
|
56281
57532
|
${version2}`).digest().readUInt32BE(0) % 100;
|
|
56282
57533
|
}
|
|
56283
57534
|
function hostReleaseTarget(platform3 = process.platform, arch2 = process.arch) {
|
|
@@ -56307,7 +57558,7 @@ function planUpdate(input2) {
|
|
|
56307
57558
|
|
|
56308
57559
|
// src/platform/release-apply.ts
|
|
56309
57560
|
var import_node_child_process5 = require("child_process");
|
|
56310
|
-
var
|
|
57561
|
+
var import_node_crypto11 = require("crypto");
|
|
56311
57562
|
var import_promises17 = require("fs/promises");
|
|
56312
57563
|
var import_node_path13 = require("path");
|
|
56313
57564
|
var import_node_util4 = require("util");
|
|
@@ -56344,7 +57595,7 @@ async function stageNpmTarball({
|
|
|
56344
57595
|
}) {
|
|
56345
57596
|
const integrity = verifyNpmIntegrity(tarball, release2.dist);
|
|
56346
57597
|
if (!integrity.ok) throw new RuntimeFault("invalid_file", integrity.reason);
|
|
56347
|
-
const scratch = (0, import_node_path13.join)(tmpDir, (0,
|
|
57598
|
+
const scratch = (0, import_node_path13.join)(tmpDir, (0, import_node_crypto11.randomUUID)());
|
|
56348
57599
|
await (0, import_promises17.mkdir)(scratch, { recursive: true, mode: 448 });
|
|
56349
57600
|
try {
|
|
56350
57601
|
const tarballPath = (0, import_node_path13.join)(scratch, "package.tgz");
|
|
@@ -57452,19 +58703,21 @@ function createServiceManager(host, profile) {
|
|
|
57452
58703
|
// src/platform/sleep.ts
|
|
57453
58704
|
var import_node_child_process7 = require("child_process");
|
|
57454
58705
|
var WAKE_THRESHOLD_MS = 3e4;
|
|
57455
|
-
function createWakeDetector(clock, thresholdMs = WAKE_THRESHOLD_MS) {
|
|
57456
|
-
const last = { drift: clock.now() - clock.monotonic() };
|
|
58706
|
+
function createWakeDetector(clock, thresholdMs = WAKE_THRESHOLD_MS, platform3 = process.platform) {
|
|
58707
|
+
const last = { wall: clock.now(), drift: clock.now() - clock.monotonic() };
|
|
57457
58708
|
return {
|
|
57458
58709
|
check: () => {
|
|
57459
|
-
const
|
|
57460
|
-
const
|
|
58710
|
+
const wall = clock.now();
|
|
58711
|
+
const drift = wall - clock.monotonic();
|
|
58712
|
+
const slept = platform3 === "win32" ? wall - last.wall : drift - last.drift;
|
|
58713
|
+
last.wall = wall;
|
|
57461
58714
|
last.drift = drift;
|
|
57462
58715
|
return slept >= thresholdMs ? slept : 0;
|
|
57463
58716
|
}
|
|
57464
58717
|
};
|
|
57465
58718
|
}
|
|
57466
|
-
function wakeJob(clock, onWake, thresholdMs = WAKE_THRESHOLD_MS) {
|
|
57467
|
-
const detector = createWakeDetector(clock, thresholdMs);
|
|
58719
|
+
function wakeJob(clock, onWake, thresholdMs = WAKE_THRESHOLD_MS, platform3 = process.platform) {
|
|
58720
|
+
const detector = createWakeDetector(clock, thresholdMs, platform3);
|
|
57468
58721
|
return {
|
|
57469
58722
|
name: "wake.detect",
|
|
57470
58723
|
run: () => {
|
|
@@ -57554,7 +58807,7 @@ function systemAssertionSpawner(log) {
|
|
|
57554
58807
|
|
|
57555
58808
|
// src/platform/spawn-detached.ts
|
|
57556
58809
|
var import_node_child_process8 = require("child_process");
|
|
57557
|
-
var
|
|
58810
|
+
var import_node_crypto12 = require("crypto");
|
|
57558
58811
|
var import_node_fs8 = require("fs");
|
|
57559
58812
|
var import_node_path21 = require("path");
|
|
57560
58813
|
var WINDOWS_UNSAFE_ENV = "NODE_PENDING_PIPE_INSTANCES";
|
|
@@ -57591,7 +58844,7 @@ async function probeHolderIsolation(platform3, exec, env) {
|
|
|
57591
58844
|
}
|
|
57592
58845
|
const probe = await exec({
|
|
57593
58846
|
command: SYSTEMD_RUN,
|
|
57594
|
-
args: [...scopeArguments(`${SCOPE_PREFIX}-probe-${(0,
|
|
58847
|
+
args: [...scopeArguments(`${SCOPE_PREFIX}-probe-${(0, import_node_crypto12.randomBytes)(4).toString("hex")}`), "true"],
|
|
57595
58848
|
timeoutMs: SCOPE_PROBE_TIMEOUT_MS
|
|
57596
58849
|
});
|
|
57597
58850
|
if (probe.status === 0) return { kind: "systemd-scope" };
|
|
@@ -57603,7 +58856,7 @@ async function probeHolderIsolation(platform3, exec, env) {
|
|
|
57603
58856
|
}
|
|
57604
58857
|
function isolatedCommand(request2, isolation) {
|
|
57605
58858
|
if (isolation.kind === "detached") return { command: request2.command, args: [...request2.args] };
|
|
57606
|
-
const unit = `${SCOPE_PREFIX}-${(0,
|
|
58859
|
+
const unit = `${SCOPE_PREFIX}-${(0, import_node_crypto12.randomBytes)(6).toString("hex")}`;
|
|
57607
58860
|
return {
|
|
57608
58861
|
command: SYSTEMD_RUN,
|
|
57609
58862
|
args: [...scopeArguments(unit), request2.command, ...request2.args]
|
|
@@ -57881,7 +59134,7 @@ function createGit(options) {
|
|
|
57881
59134
|
|
|
57882
59135
|
// src/capabilities/github-proxy/certificates.ts
|
|
57883
59136
|
var import_node_child_process9 = require("child_process");
|
|
57884
|
-
var
|
|
59137
|
+
var import_node_crypto13 = require("crypto");
|
|
57885
59138
|
var import_promises24 = require("fs/promises");
|
|
57886
59139
|
var import_node_path22 = require("path");
|
|
57887
59140
|
var OPENSSL_TIMEOUT_MS = 1e4;
|
|
@@ -57946,7 +59199,7 @@ async function createGitHubProxyCertificates(stateDir) {
|
|
|
57946
59199
|
work
|
|
57947
59200
|
);
|
|
57948
59201
|
await openssl(
|
|
57949
|
-
["x509", "-req", "-in", "leaf.csr", "-CA", "ca.pem", "-CAkey", "ca.key", "-sha256"].concat(["-set_serial", `0x${(0,
|
|
59202
|
+
["x509", "-req", "-in", "leaf.csr", "-CA", "ca.pem", "-CAkey", "ca.key", "-sha256"].concat(["-set_serial", `0x${(0, import_node_crypto13.randomBytes)(16).toString("hex")}`, "-days", VALIDITY_DAYS]).concat(["-extfile", "leaf.cnf", "-extensions", "leaf", "-out", "leaf.pem"]),
|
|
57950
59203
|
work
|
|
57951
59204
|
);
|
|
57952
59205
|
const caPath = (0, import_node_path22.join)(stateDir, "github-ca.pem");
|
|
@@ -58172,7 +59425,7 @@ async function startGitHubProxy(options) {
|
|
|
58172
59425
|
}
|
|
58173
59426
|
|
|
58174
59427
|
// src/capabilities/mcp-config/mcp-config.ts
|
|
58175
|
-
var
|
|
59428
|
+
var import_node_crypto14 = require("crypto");
|
|
58176
59429
|
var import_promises27 = require("fs/promises");
|
|
58177
59430
|
var import_node_path24 = require("path");
|
|
58178
59431
|
|
|
@@ -59156,7 +60409,7 @@ async function readConfig(cli, home) {
|
|
|
59156
60409
|
}
|
|
59157
60410
|
}
|
|
59158
60411
|
async function writeConfig(path4, text2) {
|
|
59159
|
-
const temporary = `${path4}.alan-${(0,
|
|
60412
|
+
const temporary = `${path4}.alan-${(0, import_node_crypto14.randomUUID)()}.tmp`;
|
|
59160
60413
|
try {
|
|
59161
60414
|
await (0, import_promises27.writeFile)(temporary, text2, { encoding: "utf8", mode: 384, flag: "wx" });
|
|
59162
60415
|
await (0, import_promises27.rename)(temporary, path4);
|
|
@@ -60264,7 +61517,7 @@ function reconcileTranscriptIdentity(entry, transcriptPath, identity, size) {
|
|
|
60264
61517
|
}
|
|
60265
61518
|
|
|
60266
61519
|
// src/capabilities/native-ingest/transcript-window.ts
|
|
60267
|
-
var
|
|
61520
|
+
var import_node_crypto15 = require("crypto");
|
|
60268
61521
|
var import_promises32 = require("fs/promises");
|
|
60269
61522
|
init_acp2();
|
|
60270
61523
|
init_claude();
|
|
@@ -60414,7 +61667,7 @@ function lastMatchingTurnIndex(turns, target) {
|
|
|
60414
61667
|
function signalDigest(target) {
|
|
60415
61668
|
const fingerprint = target.assistantFingerprint;
|
|
60416
61669
|
const basis = target.providerTurnId ?? (fingerprint ? `${fingerprint.length}\0${fingerprint.head}\0${fingerprint.tail}` : null);
|
|
60417
|
-
return basis ? (0,
|
|
61670
|
+
return basis ? (0, import_node_crypto15.createHash)("sha256").update(basis).digest("hex") : null;
|
|
60418
61671
|
}
|
|
60419
61672
|
function lastForegroundStop(updates) {
|
|
60420
61673
|
for (let index = updates.length - 1; index >= 0; index -= 1) {
|
|
@@ -60529,9 +61782,23 @@ async function ingestTurn(ctx, worker, entry, turn) {
|
|
|
60529
61782
|
},
|
|
60530
61783
|
ctx.shutdown
|
|
60531
61784
|
);
|
|
61785
|
+
const ordinals = opened.turnOrdinals;
|
|
60532
61786
|
await ctx.publisher.publish({
|
|
60533
61787
|
runId: opened.runId,
|
|
60534
61788
|
conversationId: entry.conversationId,
|
|
61789
|
+
...ordinals ? {
|
|
61790
|
+
userMessage: {
|
|
61791
|
+
id: opened.userMessageId,
|
|
61792
|
+
content: userMessage,
|
|
61793
|
+
turnOrdinal: ordinals.user,
|
|
61794
|
+
createdAt: startedAt
|
|
61795
|
+
},
|
|
61796
|
+
assistantMessage: {
|
|
61797
|
+
id: opened.assistantMessageId,
|
|
61798
|
+
turnOrdinal: ordinals.assistant,
|
|
61799
|
+
createdAt: startedAt
|
|
61800
|
+
}
|
|
61801
|
+
} : {},
|
|
60535
61802
|
records: nativeTurnRecords({
|
|
60536
61803
|
updates: withTerminalIdle(turn.updates, startedAt),
|
|
60537
61804
|
startedAt,
|
|
@@ -61156,7 +62423,9 @@ function providerCommandFor(backendKind) {
|
|
|
61156
62423
|
return BY_BACKEND.get(backendKind)?.command;
|
|
61157
62424
|
}
|
|
61158
62425
|
function envValue(env, name) {
|
|
61159
|
-
const key = Object.keys(env).
|
|
62426
|
+
const key = Object.keys(env).findLast(
|
|
62427
|
+
(candidate) => candidate.toUpperCase() === name.toUpperCase()
|
|
62428
|
+
);
|
|
61160
62429
|
return key === void 0 ? "" : env[key] ?? "";
|
|
61161
62430
|
}
|
|
61162
62431
|
function pathDelimiter(platform3) {
|
|
@@ -61172,12 +62441,18 @@ async function isRunnable(path4, platform3) {
|
|
|
61172
62441
|
}
|
|
61173
62442
|
}
|
|
61174
62443
|
function windowsExtensions(command, env) {
|
|
61175
|
-
const extensions = (envValue(env, "PATHEXT") || ".COM;.EXE;.BAT;.CMD").split(";").
|
|
62444
|
+
const extensions = (envValue(env, "PATHEXT") || ".COM;.EXE;.BAT;.CMD").split(";").map((extension) => extension.trim()).filter((extension) => [".COM", ".EXE", ".BAT", ".CMD"].includes(extension.toUpperCase()));
|
|
61176
62445
|
const named = command.toLowerCase();
|
|
61177
|
-
return extensions.
|
|
62446
|
+
return [".com", ".exe", ...extensions.map((extension) => extension.toLowerCase())].some(
|
|
62447
|
+
(extension) => named.endsWith(extension)
|
|
62448
|
+
) ? [""] : extensions;
|
|
61178
62449
|
}
|
|
61179
62450
|
async function resolveCommandOnPath(command, env, platform3) {
|
|
61180
|
-
const directories = envValue(env, "PATH").split(pathDelimiter(platform3)).
|
|
62451
|
+
const directories = envValue(env, "PATH").split(pathDelimiter(platform3)).map(
|
|
62452
|
+
(directory) => platform3 === "win32" ? directory.trim().replace(/^"(.*)"$/, "$1") : directory
|
|
62453
|
+
).filter(
|
|
62454
|
+
(directory) => platform3 === "win32" ? import_node_path32.win32.isAbsolute(directory) : directory.length > 0
|
|
62455
|
+
);
|
|
61181
62456
|
const extensions = platform3 === "win32" ? windowsExtensions(command, env) : [""];
|
|
61182
62457
|
for (const directory of directories) {
|
|
61183
62458
|
for (const extension of extensions) {
|
|
@@ -61224,8 +62499,21 @@ function alanCodeProviderModels() {
|
|
|
61224
62499
|
var import_node_child_process10 = require("child_process");
|
|
61225
62500
|
var DEFAULT_TIMEOUT_MS2 = 5e3;
|
|
61226
62501
|
var DEFAULT_MAX_BYTES = 1024 * 1024;
|
|
62502
|
+
function withWindowsHelper(env) {
|
|
62503
|
+
const helper = windowsHelperPath();
|
|
62504
|
+
return helper === null ? env : { ...env, ALAN_WINHELPER_PATH: helper };
|
|
62505
|
+
}
|
|
61227
62506
|
function directLaunch(command, args, options) {
|
|
61228
62507
|
try {
|
|
62508
|
+
if ((options.platform ?? process.platform) === "win32") {
|
|
62509
|
+
const plan2 = planSpawn({
|
|
62510
|
+
command,
|
|
62511
|
+
args,
|
|
62512
|
+
env: canonicalWindowsEnvironment(options.env),
|
|
62513
|
+
platform: "win32"
|
|
62514
|
+
});
|
|
62515
|
+
return { file: plan2.file, args: plan2.args, windowsVerbatimArguments: false };
|
|
62516
|
+
}
|
|
61229
62517
|
return planDirectLaunch({
|
|
61230
62518
|
command,
|
|
61231
62519
|
args,
|
|
@@ -61237,42 +62525,88 @@ function directLaunch(command, args, options) {
|
|
|
61237
62525
|
}
|
|
61238
62526
|
}
|
|
61239
62527
|
function captureProbe(command, args, options) {
|
|
62528
|
+
const platform3 = options.platform ?? process.platform;
|
|
61240
62529
|
const launch = directLaunch(command, args, options);
|
|
61241
62530
|
if (launch === void 0) return Promise.resolve({ stdout: "", stderr: "", exitCode: void 0 });
|
|
62531
|
+
const env = platform3 === "win32" ? withWindowsHelper(canonicalWindowsEnvironment(options.env)) : options.env;
|
|
61242
62532
|
return new Promise((resolve12) => {
|
|
61243
62533
|
const limit = options.maxBufferBytes ?? DEFAULT_MAX_BYTES;
|
|
61244
62534
|
const stdout = [];
|
|
61245
62535
|
const stderr = [];
|
|
61246
62536
|
let bytes = 0;
|
|
61247
62537
|
let overflowed = false;
|
|
61248
|
-
const
|
|
61249
|
-
|
|
62538
|
+
const windowsChild = platform3 === "win32" ? spawnInWindowsJob(planSpawn({ command, args, env, platform: platform3 }), {
|
|
62539
|
+
cwd: process.cwd(),
|
|
62540
|
+
env
|
|
62541
|
+
}) : void 0;
|
|
62542
|
+
const child = windowsChild ?? (0, import_node_child_process10.spawn)(launch.file, [...launch.args], {
|
|
62543
|
+
env: { ...env },
|
|
61250
62544
|
stdio: ["ignore", "pipe", "pipe"],
|
|
61251
|
-
|
|
62545
|
+
detached: true,
|
|
61252
62546
|
windowsHide: true,
|
|
61253
62547
|
windowsVerbatimArguments: launch.windowsVerbatimArguments
|
|
61254
62548
|
});
|
|
62549
|
+
child.stdin?.end();
|
|
62550
|
+
const terminate = () => {
|
|
62551
|
+
if (platform3 !== "win32" && child.pid !== void 0) {
|
|
62552
|
+
try {
|
|
62553
|
+
process.kill(-child.pid, "SIGKILL");
|
|
62554
|
+
return;
|
|
62555
|
+
} catch {
|
|
62556
|
+
}
|
|
62557
|
+
}
|
|
62558
|
+
child.kill("SIGKILL");
|
|
62559
|
+
};
|
|
62560
|
+
let settled2 = false;
|
|
62561
|
+
const deadlineController = new AbortController();
|
|
62562
|
+
const finish = (exitCode) => {
|
|
62563
|
+
if (settled2) return;
|
|
62564
|
+
settled2 = true;
|
|
62565
|
+
deadlineController.abort();
|
|
62566
|
+
options.signal?.removeEventListener("abort", abort);
|
|
62567
|
+
resolve12({
|
|
62568
|
+
stdout: Buffer.concat(stdout).toString("utf8"),
|
|
62569
|
+
stderr: Buffer.concat(stderr).toString("utf8"),
|
|
62570
|
+
exitCode
|
|
62571
|
+
});
|
|
62572
|
+
};
|
|
62573
|
+
void systemClock.sleep(options.timeoutMs ?? DEFAULT_TIMEOUT_MS2, deadlineController.signal).then(
|
|
62574
|
+
() => {
|
|
62575
|
+
terminate();
|
|
62576
|
+
child.stdout.destroy();
|
|
62577
|
+
child.stderr.destroy();
|
|
62578
|
+
finish(void 0);
|
|
62579
|
+
},
|
|
62580
|
+
() => void 0
|
|
62581
|
+
);
|
|
62582
|
+
const abort = () => {
|
|
62583
|
+
terminate();
|
|
62584
|
+
child.stdout.destroy();
|
|
62585
|
+
child.stderr.destroy();
|
|
62586
|
+
finish(void 0);
|
|
62587
|
+
};
|
|
62588
|
+
options.signal?.addEventListener("abort", abort, { once: true });
|
|
62589
|
+
if (options.signal?.aborted) abort();
|
|
61255
62590
|
const collect = (into) => (chunk) => {
|
|
61256
62591
|
bytes += chunk.length;
|
|
61257
62592
|
if (bytes > limit) {
|
|
61258
62593
|
overflowed = true;
|
|
61259
|
-
|
|
62594
|
+
terminate();
|
|
62595
|
+
finish(void 0);
|
|
61260
62596
|
return;
|
|
61261
62597
|
}
|
|
61262
62598
|
into.push(chunk);
|
|
61263
62599
|
};
|
|
61264
62600
|
child.stdout.on("data", collect(stdout));
|
|
61265
62601
|
child.stderr.on("data", collect(stderr));
|
|
61266
|
-
const finish = (exitCode) => resolve12({
|
|
61267
|
-
stdout: Buffer.concat(stdout).toString("utf8"),
|
|
61268
|
-
stderr: Buffer.concat(stderr).toString("utf8"),
|
|
61269
|
-
exitCode
|
|
61270
|
-
});
|
|
61271
62602
|
child.once("error", () => finish(void 0));
|
|
61272
62603
|
child.once(
|
|
61273
62604
|
"close",
|
|
61274
62605
|
(code, signal) => finish(overflowed || signal !== null || code === null ? void 0 : code)
|
|
61275
62606
|
);
|
|
62607
|
+
if (windowsChild !== void 0) {
|
|
62608
|
+
void waitForWindowsJob(windowsChild, command).catch(() => finish(void 0));
|
|
62609
|
+
}
|
|
61276
62610
|
});
|
|
61277
62611
|
}
|
|
61278
62612
|
|
|
@@ -61719,7 +63053,7 @@ var import_node_path37 = require("path");
|
|
|
61719
63053
|
|
|
61720
63054
|
// ../shared/dist/node/shell-environment.js
|
|
61721
63055
|
var import_node_child_process12 = require("child_process");
|
|
61722
|
-
var
|
|
63056
|
+
var import_node_crypto16 = require("crypto");
|
|
61723
63057
|
var import_node_fs15 = require("fs");
|
|
61724
63058
|
var import_node_os5 = require("os");
|
|
61725
63059
|
var import_node_path36 = require("path");
|
|
@@ -61863,6 +63197,15 @@ function installerDirectories(home, platform3) {
|
|
|
61863
63197
|
const system = platform3 === "darwin" ? ["/opt/homebrew/bin", "/usr/local/bin"] : ["/usr/local/bin"];
|
|
61864
63198
|
return [...user, ...system];
|
|
61865
63199
|
}
|
|
63200
|
+
function windowsInstallerDirectories(env) {
|
|
63201
|
+
const home = envValue(env, "USERPROFILE") || envValue(env, "HOME");
|
|
63202
|
+
const hasHome = import_node_path37.win32.isAbsolute(home);
|
|
63203
|
+
const appData = envValue(env, "APPDATA") || (hasHome ? import_node_path37.win32.join(home, "AppData", "Roaming") : "");
|
|
63204
|
+
return [
|
|
63205
|
+
...hasHome ? [import_node_path37.win32.join(home, ".local", "bin")] : [],
|
|
63206
|
+
...import_node_path37.win32.isAbsolute(appData) ? [import_node_path37.win32.join(appData, "npm")] : []
|
|
63207
|
+
];
|
|
63208
|
+
}
|
|
61866
63209
|
function printPathCommand() {
|
|
61867
63210
|
return `printf '${MARKER}%s${MARKER}' "$PATH"`;
|
|
61868
63211
|
}
|
|
@@ -61915,7 +63258,14 @@ async function rememberLastKnownGood(file2, path4) {
|
|
|
61915
63258
|
}
|
|
61916
63259
|
async function resolveCliEnvironmentDetailed(options) {
|
|
61917
63260
|
const { env, platform: platform3 } = options;
|
|
61918
|
-
if (platform3 === "win32")
|
|
63261
|
+
if (platform3 === "win32") {
|
|
63262
|
+
const path4 = appendPathDirectories(
|
|
63263
|
+
envValue(env, "PATH"),
|
|
63264
|
+
windowsInstallerDirectories(env),
|
|
63265
|
+
";"
|
|
63266
|
+
);
|
|
63267
|
+
return { env: canonicalWindowsEnvironment({ ...env, PATH: path4 }), source: "none" };
|
|
63268
|
+
}
|
|
61919
63269
|
const loginPath = await readLoginShellPath(env, options.capture ?? captureProbe);
|
|
61920
63270
|
if (loginPath !== null) await rememberLastKnownGood(options.lastKnownGoodFile, loginPath);
|
|
61921
63271
|
const lastKnownGood = loginPath === null ? await readLastKnownGood(options.lastKnownGoodFile) : null;
|
|
@@ -61962,8 +63312,7 @@ async function openCliEnvironment(options) {
|
|
|
61962
63312
|
}
|
|
61963
63313
|
|
|
61964
63314
|
// src/capabilities/providers/managed.ts
|
|
61965
|
-
var
|
|
61966
|
-
var import_node_crypto16 = require("crypto");
|
|
63315
|
+
var import_node_crypto17 = require("crypto");
|
|
61967
63316
|
var import_promises36 = require("fs/promises");
|
|
61968
63317
|
var import_node_path38 = require("path");
|
|
61969
63318
|
init_zod();
|
|
@@ -61992,9 +63341,10 @@ function withManagedProviderPaths(manager, env, nodeDirectory, platform3 = proce
|
|
|
61992
63341
|
const path4 = [
|
|
61993
63342
|
...manager.selections().map((item) => item.binDir),
|
|
61994
63343
|
...nodeDirectory === void 0 ? [] : [nodeDirectory],
|
|
61995
|
-
env
|
|
63344
|
+
envValue(env, "PATH")
|
|
61996
63345
|
].filter(Boolean);
|
|
61997
|
-
|
|
63346
|
+
const merged = { ...env, PATH: path4.join(pathDelimiter(platform3)) };
|
|
63347
|
+
return platform3 === "win32" ? canonicalWindowsEnvironment(merged) : merged;
|
|
61998
63348
|
}
|
|
61999
63349
|
function packageFor(backendKind) {
|
|
62000
63350
|
const provider4 = PACKAGES[backendKind];
|
|
@@ -62091,7 +63441,7 @@ function createManagedProviderClis(options) {
|
|
|
62091
63441
|
};
|
|
62092
63442
|
const persist = async () => {
|
|
62093
63443
|
await (0, import_promises36.mkdir)(options.root, { recursive: true, mode: 448 });
|
|
62094
|
-
const staged = `${file2}.${(0,
|
|
63444
|
+
const staged = `${file2}.${(0, import_node_crypto17.randomUUID)()}`;
|
|
62095
63445
|
try {
|
|
62096
63446
|
await (0, import_promises36.writeFile)(staged, JSON.stringify(state), { mode: 384 });
|
|
62097
63447
|
await (0, import_promises36.rename)(staged, file2);
|
|
@@ -62126,7 +63476,7 @@ function createManagedProviderClis(options) {
|
|
|
62126
63476
|
try {
|
|
62127
63477
|
parsed = selectedSchema.parse(JSON.parse(raw));
|
|
62128
63478
|
} catch {
|
|
62129
|
-
await (0, import_promises36.rename)(file2, `${file2}.invalid.${(0,
|
|
63479
|
+
await (0, import_promises36.rename)(file2, `${file2}.invalid.${(0, import_node_crypto17.randomUUID)()}`).catch(() => void 0);
|
|
62130
63480
|
return;
|
|
62131
63481
|
}
|
|
62132
63482
|
for (const [backendKind, version2] of Object.entries(parsed)) {
|
|
@@ -62184,7 +63534,7 @@ function createManagedProviderClis(options) {
|
|
|
62184
63534
|
const existing = selection(options.root, backendKind, exact);
|
|
62185
63535
|
if (!await runnable(existing.executable) || !await options.probe(existing.executable, backendKind)) {
|
|
62186
63536
|
await (0, import_promises36.mkdir)((0, import_node_path38.dirname)(target), { recursive: true, mode: 448 });
|
|
62187
|
-
const staged = `${target}.${(0,
|
|
63537
|
+
const staged = `${target}.${(0, import_node_crypto17.randomUUID)()}`;
|
|
62188
63538
|
try {
|
|
62189
63539
|
await options.installPackage(provider4.name, exact, staged, provider4.command, signal);
|
|
62190
63540
|
const built = (0, import_node_path38.join)(staged, "node_modules", ".bin", provider4.command);
|
|
@@ -62214,9 +63564,18 @@ function createManagedProviderClis(options) {
|
|
|
62214
63564
|
})
|
|
62215
63565
|
};
|
|
62216
63566
|
}
|
|
63567
|
+
function withInstallerPath(options) {
|
|
63568
|
+
const platform3 = options.platform ?? process.platform;
|
|
63569
|
+
const path4 = [
|
|
63570
|
+
platform3 === "win32" ? import_node_path38.win32.dirname(options.command) : (0, import_node_path38.dirname)(options.command),
|
|
63571
|
+
envValue(options.env, "PATH")
|
|
63572
|
+
].filter(Boolean).join(pathDelimiter(platform3));
|
|
63573
|
+
const env = { ...options.env, PATH: path4 };
|
|
63574
|
+
return platform3 === "win32" ? canonicalWindowsEnvironment(env) : env;
|
|
63575
|
+
}
|
|
62217
63576
|
function createNpmPackageInstaller(options) {
|
|
62218
|
-
return (packageName, version2, destination, _command, signal) =>
|
|
62219
|
-
const
|
|
63577
|
+
return async (packageName, version2, destination, _command, signal) => {
|
|
63578
|
+
const result = await captureProbe(
|
|
62220
63579
|
options.command,
|
|
62221
63580
|
[
|
|
62222
63581
|
...options.argsBeforeNpm ?? [],
|
|
@@ -62228,53 +63587,35 @@ function createNpmPackageInstaller(options) {
|
|
|
62228
63587
|
`${packageName}@${version2}`
|
|
62229
63588
|
],
|
|
62230
63589
|
{
|
|
62231
|
-
env:
|
|
63590
|
+
env: withInstallerPath(options),
|
|
62232
63591
|
signal,
|
|
62233
|
-
|
|
63592
|
+
timeoutMs: 10 * 6e4,
|
|
63593
|
+
maxBufferBytes: 1024 * 1024
|
|
62234
63594
|
}
|
|
62235
63595
|
);
|
|
62236
|
-
|
|
62237
|
-
|
|
62238
|
-
|
|
62239
|
-
|
|
62240
|
-
|
|
63596
|
+
if (result.exitCode !== 0) {
|
|
63597
|
+
const output2 = `${result.stdout}
|
|
63598
|
+
${result.stderr}`.trim().slice(-8e3);
|
|
63599
|
+
throw new Error(
|
|
63600
|
+
`npm install failed (${result.exitCode ?? "timeout, cancellation or launch"}): ${output2}`
|
|
63601
|
+
);
|
|
62241
63602
|
}
|
|
62242
|
-
|
|
62243
|
-
child.on("close", (code) => {
|
|
62244
|
-
if (code === 0) resolve12();
|
|
62245
|
-
else reject(new Error(`npm install failed (${code ?? "signal"}): ${output2.trim()}`));
|
|
62246
|
-
});
|
|
62247
|
-
});
|
|
63603
|
+
};
|
|
62248
63604
|
}
|
|
62249
63605
|
function createNpmVersionResolver(options) {
|
|
62250
|
-
return (packageName, signal) =>
|
|
62251
|
-
const
|
|
63606
|
+
return async (packageName, signal) => {
|
|
63607
|
+
const result = await captureProbe(
|
|
62252
63608
|
options.command,
|
|
62253
63609
|
[...options.argsBeforeNpm ?? [], "view", packageName, "version", "--json"],
|
|
62254
|
-
{
|
|
62255
|
-
env: { ...options.env },
|
|
62256
|
-
signal: AbortSignal.any([
|
|
62257
|
-
signal ?? new AbortController().signal,
|
|
62258
|
-
AbortSignal.timeout(3e4)
|
|
62259
|
-
]),
|
|
62260
|
-
stdio: ["ignore", "pipe", "pipe"]
|
|
62261
|
-
}
|
|
63610
|
+
{ env: withInstallerPath(options), signal, timeoutMs: 3e4, maxBufferBytes: 1e5 }
|
|
62262
63611
|
);
|
|
62263
|
-
|
|
62264
|
-
|
|
62265
|
-
|
|
62266
|
-
|
|
62267
|
-
}
|
|
62268
|
-
|
|
62269
|
-
|
|
62270
|
-
if (code !== 0) return reject(new Error(`Cannot look up ${packageName} version`));
|
|
62271
|
-
try {
|
|
62272
|
-
resolve12(parseNpmVersion(output2, packageName));
|
|
62273
|
-
} catch (error61) {
|
|
62274
|
-
reject(error61);
|
|
62275
|
-
}
|
|
62276
|
-
});
|
|
62277
|
-
});
|
|
63612
|
+
if (result.exitCode !== 0) {
|
|
63613
|
+
throw new Error(
|
|
63614
|
+
`Cannot look up ${packageName} version: ${result.stderr.trim().slice(-2e3)}`
|
|
63615
|
+
);
|
|
63616
|
+
}
|
|
63617
|
+
return parseNpmVersion(result.stdout, packageName);
|
|
63618
|
+
};
|
|
62278
63619
|
}
|
|
62279
63620
|
function parseNpmVersion(output2, packageName) {
|
|
62280
63621
|
const versions = external_exports.union([external_exports.string(), external_exports.array(external_exports.string())]).parse(JSON.parse(output2));
|
|
@@ -62311,7 +63652,7 @@ var import_node_path43 = __toESM(require("path"));
|
|
|
62311
63652
|
|
|
62312
63653
|
// ../shared/dist/node/skill-package.js
|
|
62313
63654
|
var import_node_buffer = require("buffer");
|
|
62314
|
-
var
|
|
63655
|
+
var import_node_crypto18 = require("crypto");
|
|
62315
63656
|
var import_promises37 = require("fs/promises");
|
|
62316
63657
|
var import_node_path39 = require("path");
|
|
62317
63658
|
var import_yaml = __toESM(require_dist(), 1);
|
|
@@ -62711,7 +64052,7 @@ function comparePackageFiles(left, right) {
|
|
|
62711
64052
|
return import_node_buffer.Buffer.compare(import_node_buffer.Buffer.from(left.manifest.path, "utf8"), import_node_buffer.Buffer.from(right.manifest.path, "utf8"));
|
|
62712
64053
|
}
|
|
62713
64054
|
function hashPackageTree(files) {
|
|
62714
|
-
const hash2 = (0,
|
|
64055
|
+
const hash2 = (0, import_node_crypto18.createHash)("sha256");
|
|
62715
64056
|
hash2.update(TREE_HASH_PREFIX);
|
|
62716
64057
|
for (const file2 of files) {
|
|
62717
64058
|
const path4 = import_node_buffer.Buffer.from(file2.path, "utf8");
|
|
@@ -62724,7 +64065,7 @@ function hashPackageTree(files) {
|
|
|
62724
64065
|
return `sha256:${hash2.digest("hex")}`;
|
|
62725
64066
|
}
|
|
62726
64067
|
function sha256(bytes) {
|
|
62727
|
-
return `sha256:${(0,
|
|
64068
|
+
return `sha256:${(0, import_node_crypto18.createHash)("sha256").update(bytes).digest("hex")}`;
|
|
62728
64069
|
}
|
|
62729
64070
|
function uint322(value2) {
|
|
62730
64071
|
const buffer = import_node_buffer.Buffer.allocUnsafe(4);
|
|
@@ -62738,13 +64079,13 @@ function uint642(value2) {
|
|
|
62738
64079
|
}
|
|
62739
64080
|
|
|
62740
64081
|
// src/capabilities/skills/local-sources.ts
|
|
62741
|
-
var
|
|
64082
|
+
var import_node_crypto20 = require("crypto");
|
|
62742
64083
|
var import_promises39 = require("fs/promises");
|
|
62743
64084
|
var import_node_path41 = __toESM(require("path"));
|
|
62744
64085
|
init_type_guards();
|
|
62745
64086
|
|
|
62746
64087
|
// src/capabilities/skills/local-scan.ts
|
|
62747
|
-
var
|
|
64088
|
+
var import_node_crypto19 = require("crypto");
|
|
62748
64089
|
var import_promises38 = require("fs/promises");
|
|
62749
64090
|
var import_node_path40 = __toESM(require("path"));
|
|
62750
64091
|
var MAX_CANDIDATES = 2e3;
|
|
@@ -62753,7 +64094,7 @@ function createLocalSkillScanCache() {
|
|
|
62753
64094
|
return { inspections: /* @__PURE__ */ new Map(), lastCompleteRevision: null };
|
|
62754
64095
|
}
|
|
62755
64096
|
async function scanSkillRoots(input2, cache2) {
|
|
62756
|
-
const attemptId = (0,
|
|
64097
|
+
const attemptId = (0, import_node_crypto19.randomUUID)();
|
|
62757
64098
|
const ignoredPaths = input2.ignoredPaths ?? [];
|
|
62758
64099
|
const resolvedRoots = resolveScanRoots(input2.roots, input2.enabledProviderKinds ?? []);
|
|
62759
64100
|
const pass = {
|
|
@@ -62818,7 +64159,7 @@ function failedLocalSkillScan(cache2, code, message2) {
|
|
|
62818
64159
|
return {
|
|
62819
64160
|
outcome: {
|
|
62820
64161
|
status: "failed",
|
|
62821
|
-
attemptId: (0,
|
|
64162
|
+
attemptId: (0, import_node_crypto19.randomUUID)(),
|
|
62822
64163
|
retainedInventoryRevision: cache2.lastCompleteRevision,
|
|
62823
64164
|
diagnostics: [{ code, message: message2.slice(0, 2048) }]
|
|
62824
64165
|
},
|
|
@@ -62982,11 +64323,11 @@ function candidateOrigin(root) {
|
|
|
62982
64323
|
}
|
|
62983
64324
|
function createLocalKey(root, skillName) {
|
|
62984
64325
|
const rootIdentity = root.kind === "configured" ? `configured:${root.declarationId}` : root.kind === "repository" ? `repository:${root.repositoryId}` : "drafts";
|
|
62985
|
-
const digest = (0,
|
|
64326
|
+
const digest = (0, import_node_crypto19.createHash)("sha256").update("alan-local-skill-v1\0").update(rootIdentity).update("\0").update(skillName.normalize("NFC")).digest("hex");
|
|
62986
64327
|
return `local:${digest}`;
|
|
62987
64328
|
}
|
|
62988
64329
|
function hashInventory(candidates2) {
|
|
62989
|
-
const hash2 = (0,
|
|
64330
|
+
const hash2 = (0, import_node_crypto19.createHash)("sha256").update("alan-skill-inventory-v1\0");
|
|
62990
64331
|
for (const candidate of candidates2) {
|
|
62991
64332
|
hash2.update(candidate.localKey).update("\0");
|
|
62992
64333
|
hash2.update(candidate.contentHash).update("\0");
|
|
@@ -63006,7 +64347,7 @@ function deduplicateByContent(candidates2) {
|
|
|
63006
64347
|
return candidates2.filter((located) => winners.has(located));
|
|
63007
64348
|
}
|
|
63008
64349
|
async function fingerprintPackage(root) {
|
|
63009
|
-
const hash2 = (0,
|
|
64350
|
+
const hash2 = (0, import_node_crypto19.createHash)("sha256").update("alan-skill-stat-fingerprint-v1\0");
|
|
63010
64351
|
const visit2 = async (directory, relativeDirectory) => {
|
|
63011
64352
|
const entries = await (0, import_promises38.readdir)(directory, { withFileTypes: true });
|
|
63012
64353
|
entries.sort((left, right) => Buffer.compare(Buffer.from(left.name), Buffer.from(right.name)));
|
|
@@ -63209,7 +64550,7 @@ function staleCodexDeclaration(relativeDirectory, label, providerKinds) {
|
|
|
63209
64550
|
return ownedByCursor || label === "Legacy Cursor-compatible skills";
|
|
63210
64551
|
}
|
|
63211
64552
|
function stableSourceDeclarationId(sourcePath) {
|
|
63212
|
-
const digest = (0,
|
|
64553
|
+
const digest = (0, import_node_crypto20.createHash)("sha256").update("alan-skill-source-v1\0").update(sourcePath.normalize("NFC")).digest("hex").slice(0, 24);
|
|
63213
64554
|
return `source-${digest}`;
|
|
63214
64555
|
}
|
|
63215
64556
|
function requiredSourceId(value2, field3) {
|
|
@@ -63256,10 +64597,10 @@ var import_promises40 = require("fs/promises");
|
|
|
63256
64597
|
var import_node_path42 = require("path");
|
|
63257
64598
|
|
|
63258
64599
|
// ../shared/dist/node/alan-skill-identity.js
|
|
63259
|
-
var
|
|
64600
|
+
var import_node_crypto21 = require("crypto");
|
|
63260
64601
|
var ALAN_SKILL_NAMESPACE = "ec71d99b-d207-4ca2-a9eb-3a7bed4a73fd";
|
|
63261
64602
|
function uuidV5(name, namespace) {
|
|
63262
|
-
const bytes = (0,
|
|
64603
|
+
const bytes = (0, import_node_crypto21.createHash)("sha1").update(Buffer.from(namespace.replaceAll("-", ""), "hex")).update(name, "utf8").digest().subarray(0, 16);
|
|
63263
64604
|
bytes[6] = bytes[6] & 15 | 80;
|
|
63264
64605
|
bytes[8] = bytes[8] & 63 | 128;
|
|
63265
64606
|
const hex3 = bytes.toString("hex");
|
|
@@ -63526,7 +64867,7 @@ var import_promises43 = require("fs/promises");
|
|
|
63526
64867
|
|
|
63527
64868
|
// ../shared/dist/node/skill-bundle.js
|
|
63528
64869
|
var import_node_buffer2 = require("buffer");
|
|
63529
|
-
var
|
|
64870
|
+
var import_node_crypto22 = require("crypto");
|
|
63530
64871
|
var import_promises42 = require("fs/promises");
|
|
63531
64872
|
var import_node_path44 = require("path");
|
|
63532
64873
|
var import_node_stream = require("stream");
|
|
@@ -63665,7 +65006,7 @@ function requireSafeArchivePath(value2) {
|
|
|
63665
65006
|
return normalized2;
|
|
63666
65007
|
}
|
|
63667
65008
|
function sha2562(bytes) {
|
|
63668
|
-
return `sha256:${(0,
|
|
65009
|
+
return `sha256:${(0, import_node_crypto22.createHash)("sha256").update(bytes).digest("hex")}`;
|
|
63669
65010
|
}
|
|
63670
65011
|
|
|
63671
65012
|
// src/capabilities/skills/local-upload.ts
|
|
@@ -63709,14 +65050,14 @@ async function publishLocalSkill(options) {
|
|
|
63709
65050
|
}
|
|
63710
65051
|
|
|
63711
65052
|
// src/capabilities/skills/sync.ts
|
|
63712
|
-
var
|
|
65053
|
+
var import_node_crypto23 = require("crypto");
|
|
63713
65054
|
var import_promises44 = require("fs/promises");
|
|
63714
65055
|
var import_node_path45 = require("path");
|
|
63715
65056
|
var SKILL_PREPARE_WAIT_MS = 15e3;
|
|
63716
65057
|
async function install(layout, source, skill, download, signal) {
|
|
63717
65058
|
const bytes = await source.download(download.url, signal);
|
|
63718
65059
|
await (0, import_promises44.mkdir)(layout.tmpDir, { recursive: true, mode: 448 });
|
|
63719
|
-
const staging = (0, import_node_path45.join)(layout.tmpDir, (0,
|
|
65060
|
+
const staging = (0, import_node_path45.join)(layout.tmpDir, (0, import_node_crypto23.randomUUID)());
|
|
63720
65061
|
await extractSkillBundle(Buffer.from(bytes), staging, {
|
|
63721
65062
|
expectedArchiveHash: download.archiveHash,
|
|
63722
65063
|
expectedContentHash: skill.contentHash
|
|
@@ -64129,7 +65470,7 @@ async function openApprovedPaths(options) {
|
|
|
64129
65470
|
}
|
|
64130
65471
|
|
|
64131
65472
|
// src/capabilities/workspace/locks.ts
|
|
64132
|
-
var
|
|
65473
|
+
var import_node_crypto24 = require("crypto");
|
|
64133
65474
|
var import_promises46 = require("fs/promises");
|
|
64134
65475
|
var import_node_path47 = require("path");
|
|
64135
65476
|
init_zod();
|
|
@@ -64146,7 +65487,7 @@ var ownerSchema = external_exports.object({
|
|
|
64146
65487
|
since: external_exports.number().int().nonnegative()
|
|
64147
65488
|
});
|
|
64148
65489
|
function repositoryLockKey(commonDir, platform3) {
|
|
64149
|
-
return (0,
|
|
65490
|
+
return (0, import_node_crypto24.createHash)("sha256").update(comparablePath(commonDir, platform3)).digest("hex").slice(0, 32);
|
|
64150
65491
|
}
|
|
64151
65492
|
async function readOwner2(path4) {
|
|
64152
65493
|
let text2;
|
|
@@ -64259,7 +65600,7 @@ function openRepositoryLocks(options) {
|
|
|
64259
65600
|
},
|
|
64260
65601
|
tryShared: async (commonDir, runId) => {
|
|
64261
65602
|
const { key, dir } = await folder(commonDir);
|
|
64262
|
-
const file2 = `${RUN_FILE_PREFIX}${(0,
|
|
65603
|
+
const file2 = `${RUN_FILE_PREFIX}${(0, import_node_crypto24.createHash)("sha256").update(runId).digest("hex").slice(0, 32)}.json`;
|
|
64263
65604
|
const path4 = (0, import_node_path47.join)(dir, file2);
|
|
64264
65605
|
const owner = await self(runId);
|
|
64265
65606
|
await writeJsonFileAtomic(path4, owner);
|
|
@@ -64495,7 +65836,7 @@ async function openWorkspaces(options) {
|
|
|
64495
65836
|
|
|
64496
65837
|
// src/cli/config.ts
|
|
64497
65838
|
var import_node_os11 = require("os");
|
|
64498
|
-
var
|
|
65839
|
+
var import_node_path65 = require("path");
|
|
64499
65840
|
init_zod();
|
|
64500
65841
|
|
|
64501
65842
|
// src/client/contract.ts
|
|
@@ -64780,6 +66121,7 @@ var mcpConfigResultSchema = external_exports.object({
|
|
|
64780
66121
|
|
|
64781
66122
|
// src/client/runtime-client.ts
|
|
64782
66123
|
var import_promises47 = require("fs/promises");
|
|
66124
|
+
init_acp();
|
|
64783
66125
|
init_runtime_v2();
|
|
64784
66126
|
|
|
64785
66127
|
// src/client/sse.ts
|
|
@@ -64797,14 +66139,18 @@ function applyField(pending, line) {
|
|
|
64797
66139
|
}
|
|
64798
66140
|
async function* readServerSentEvents(body) {
|
|
64799
66141
|
const decoder3 = new TextDecoder();
|
|
64800
|
-
let
|
|
66142
|
+
let partial2 = [];
|
|
64801
66143
|
let pending = emptyEvent();
|
|
64802
66144
|
for await (const chunk of body) {
|
|
64803
|
-
|
|
64804
|
-
let
|
|
66145
|
+
const text2 = decoder3.decode(chunk, { stream: true });
|
|
66146
|
+
let start = 0;
|
|
66147
|
+
let newline = text2.indexOf("\n");
|
|
64805
66148
|
while (newline !== -1) {
|
|
64806
|
-
|
|
64807
|
-
|
|
66149
|
+
partial2.push(text2.slice(start, newline));
|
|
66150
|
+
const line = partial2.join("").replace(/\r$/, "");
|
|
66151
|
+
partial2 = [];
|
|
66152
|
+
start = newline + 1;
|
|
66153
|
+
newline = text2.indexOf("\n", start);
|
|
64808
66154
|
if (line.length === 0) {
|
|
64809
66155
|
if (pending.data.length > 0) {
|
|
64810
66156
|
yield { event: pending.event, id: pending.id, data: pending.data.join("\n") };
|
|
@@ -64813,8 +66159,8 @@ async function* readServerSentEvents(body) {
|
|
|
64813
66159
|
} else if (!line.startsWith(":")) {
|
|
64814
66160
|
applyField(pending, line);
|
|
64815
66161
|
}
|
|
64816
|
-
newline = buffer.indexOf("\n");
|
|
64817
66162
|
}
|
|
66163
|
+
if (start < text2.length) partial2.push(text2.slice(start));
|
|
64818
66164
|
}
|
|
64819
66165
|
}
|
|
64820
66166
|
|
|
@@ -64851,6 +66197,23 @@ async function readDiscovery(path4) {
|
|
|
64851
66197
|
}
|
|
64852
66198
|
return parsed.data;
|
|
64853
66199
|
}
|
|
66200
|
+
function conversationQuery(query) {
|
|
66201
|
+
return {
|
|
66202
|
+
limit: String(query.limit),
|
|
66203
|
+
...query.before ? { before: query.before } : {},
|
|
66204
|
+
...query.runtimeId ? { runtimeId: query.runtimeId } : {}
|
|
66205
|
+
};
|
|
66206
|
+
}
|
|
66207
|
+
function conversationUpdate(event) {
|
|
66208
|
+
const value2 = JSON.parse(event.data);
|
|
66209
|
+
if (event.event === "snapshot" && isConversationMessagesPage(value2))
|
|
66210
|
+
return { kind: "snapshot", page: value2 };
|
|
66211
|
+
if (event.event === "turn" && isConversationMessageTurn(value2))
|
|
66212
|
+
return { kind: "turn", turn: value2 };
|
|
66213
|
+
if (event.event === LIVE_TURN_EVENT && isLiveTurnFrame(value2))
|
|
66214
|
+
return { kind: "live_turn", frame: value2 };
|
|
66215
|
+
throw new RuntimeClientError("protocol", "Invalid local conversation update");
|
|
66216
|
+
}
|
|
64854
66217
|
function parseWith(schema, raw, what) {
|
|
64855
66218
|
const parsed = schema.safeParse(raw);
|
|
64856
66219
|
if (!parsed.success) {
|
|
@@ -64996,11 +66359,44 @@ function createRuntimeClient(options) {
|
|
|
64996
66359
|
throw new RuntimeClientError("unavailable", "The run log stream closed before the run ended");
|
|
64997
66360
|
}
|
|
64998
66361
|
const runs = async (signal) => (await json2({ path: LOCAL_API_ROUTES.runs }, runsResponseSchema, signal)).runs;
|
|
66362
|
+
async function* followConversationMessages(query, signal) {
|
|
66363
|
+
const stopped = new AbortController();
|
|
66364
|
+
try {
|
|
66365
|
+
const body = await openStream(
|
|
66366
|
+
{
|
|
66367
|
+
path: `/v2/conversations/${encodeURIComponent(query.conversationId)}/messages/sse`,
|
|
66368
|
+
query: { ...conversationQuery(query), frames: LIVE_TURN_FRAMES }
|
|
66369
|
+
},
|
|
66370
|
+
AbortSignal.any([signal, stopped.signal])
|
|
66371
|
+
);
|
|
66372
|
+
for await (const event of readServerSentEvents(body)) yield conversationUpdate(event);
|
|
66373
|
+
if (!signal.aborted)
|
|
66374
|
+
throw new RuntimeClientError("unavailable", "The local conversation stream closed");
|
|
66375
|
+
} finally {
|
|
66376
|
+
stopped.abort();
|
|
66377
|
+
}
|
|
66378
|
+
}
|
|
64999
66379
|
return {
|
|
65000
66380
|
status: (signal) => json2({ path: LOCAL_API_ROUTES.status }, runtimeStatusSchema, signal),
|
|
65001
66381
|
watchStatus,
|
|
66382
|
+
followConversationMessages,
|
|
65002
66383
|
runs,
|
|
65003
66384
|
conversationRuns: async (conversationId, signal) => (await runs(signal)).filter((run2) => run2.conversationId === conversationId),
|
|
66385
|
+
readConversationMessages: async (query, signal) => {
|
|
66386
|
+
const response = await send2(
|
|
66387
|
+
{
|
|
66388
|
+
path: `/v2/conversations/${encodeURIComponent(query.conversationId)}/messages`,
|
|
66389
|
+
query: conversationQuery(query)
|
|
66390
|
+
},
|
|
66391
|
+
signal
|
|
66392
|
+
);
|
|
66393
|
+
if (response.status === 404) return null;
|
|
66394
|
+
if (!response.ok) throw await rejection(response);
|
|
66395
|
+
const page = await response.json();
|
|
66396
|
+
if (!isConversationMessagesPage(page))
|
|
66397
|
+
throw new RuntimeClientError("protocol", "Invalid local conversation page");
|
|
66398
|
+
return page;
|
|
66399
|
+
},
|
|
65004
66400
|
readRunLog: async (runId, query, signal) => {
|
|
65005
66401
|
const response = await send2(
|
|
65006
66402
|
{
|
|
@@ -65166,14 +66562,14 @@ async function sendNativeHookSignal(discoveryPath, hookSignal, signal) {
|
|
|
65166
66562
|
}
|
|
65167
66563
|
|
|
65168
66564
|
// src/sessions/index.ts
|
|
65169
|
-
var
|
|
65170
|
-
var
|
|
66565
|
+
var import_node_crypto30 = require("crypto");
|
|
66566
|
+
var import_promises64 = require("fs/promises");
|
|
65171
66567
|
var import_node_os10 = require("os");
|
|
65172
|
-
var
|
|
66568
|
+
var import_node_path64 = require("path");
|
|
65173
66569
|
init_runtime_v2();
|
|
65174
66570
|
|
|
65175
66571
|
// src/holder/control-client.ts
|
|
65176
|
-
var
|
|
66572
|
+
var import_node_crypto25 = require("crypto");
|
|
65177
66573
|
var import_node_net2 = require("net");
|
|
65178
66574
|
init_runtime_v2();
|
|
65179
66575
|
|
|
@@ -65243,7 +66639,7 @@ async function connectHolder(endpoint, token, onEvent) {
|
|
|
65243
66639
|
});
|
|
65244
66640
|
const pid = await ready;
|
|
65245
66641
|
const request2 = (body) => {
|
|
65246
|
-
const id = (0,
|
|
66642
|
+
const id = (0, import_node_crypto25.randomUUID)();
|
|
65247
66643
|
return new Promise((resolve12, reject) => {
|
|
65248
66644
|
const timer = AbortSignal.timeout(REQUEST_TIMEOUT_MS7);
|
|
65249
66645
|
timer.addEventListener("abort", () => {
|
|
@@ -65582,10 +66978,10 @@ async function prepareRunInputs(spec, { source, tmpDir, signal, skills = [] }) {
|
|
|
65582
66978
|
}
|
|
65583
66979
|
|
|
65584
66980
|
// src/holder/serve.ts
|
|
65585
|
-
var
|
|
66981
|
+
var import_node_crypto29 = require("crypto");
|
|
65586
66982
|
var import_node_fs21 = require("fs");
|
|
65587
66983
|
var import_node_net3 = require("net");
|
|
65588
|
-
var
|
|
66984
|
+
var import_node_path63 = require("path");
|
|
65589
66985
|
init_runtime_v2();
|
|
65590
66986
|
|
|
65591
66987
|
// src/holder/admission.ts
|
|
@@ -65676,7 +67072,7 @@ async function discoverRelocatedWorkspace(search) {
|
|
|
65676
67072
|
}
|
|
65677
67073
|
|
|
65678
67074
|
// src/holder/checkout-refresh.ts
|
|
65679
|
-
var
|
|
67075
|
+
var import_node_crypto27 = require("crypto");
|
|
65680
67076
|
var import_promises57 = require("fs/promises");
|
|
65681
67077
|
var import_node_path56 = require("path");
|
|
65682
67078
|
function short(sha) {
|
|
@@ -65723,7 +67119,7 @@ async function fastForward(freshness, operationId, deps, signal) {
|
|
|
65723
67119
|
async function atFirstLease(freshness, spec, deps, signal) {
|
|
65724
67120
|
const first = await claimOnce(
|
|
65725
67121
|
(0, import_node_path56.join)(deps.dir, "leased"),
|
|
65726
|
-
(0,
|
|
67122
|
+
(0, import_node_crypto27.createHash)("sha256").update(freshness.path).digest("hex")
|
|
65727
67123
|
);
|
|
65728
67124
|
switch (freshness.state) {
|
|
65729
67125
|
case "current":
|
|
@@ -66340,7 +67736,7 @@ function createSessionFacts(options) {
|
|
|
66340
67736
|
init_acp2();
|
|
66341
67737
|
|
|
66342
67738
|
// src/run-log/complete.ts
|
|
66343
|
-
var
|
|
67739
|
+
var import_node_crypto28 = require("crypto");
|
|
66344
67740
|
var import_node_fs19 = require("fs");
|
|
66345
67741
|
var import_node_path60 = require("path");
|
|
66346
67742
|
|
|
@@ -66349,7 +67745,24 @@ var import_promises61 = require("fs/promises");
|
|
|
66349
67745
|
var import_node_path59 = require("path");
|
|
66350
67746
|
init_runtime_v2();
|
|
66351
67747
|
init_zod();
|
|
66352
|
-
var runMetaSchema = external_exports.object({
|
|
67748
|
+
var runMetaSchema = external_exports.object({
|
|
67749
|
+
runId: runIdSchema,
|
|
67750
|
+
conversationId: conversationIdSchema,
|
|
67751
|
+
agentMode: external_exports.string().optional(),
|
|
67752
|
+
userMessage: external_exports.object({
|
|
67753
|
+
id: external_exports.string(),
|
|
67754
|
+
content: external_exports.string(),
|
|
67755
|
+
turnOrdinal: external_exports.number().int().nullable(),
|
|
67756
|
+
createdAt: external_exports.string(),
|
|
67757
|
+
clientMessageId: external_exports.string().optional(),
|
|
67758
|
+
attachmentIds: external_exports.array(external_exports.string()).optional()
|
|
67759
|
+
}).optional(),
|
|
67760
|
+
assistantMessage: external_exports.object({
|
|
67761
|
+
id: external_exports.string(),
|
|
67762
|
+
turnOrdinal: external_exports.number().int().nullable(),
|
|
67763
|
+
createdAt: external_exports.string()
|
|
67764
|
+
}).optional()
|
|
67765
|
+
});
|
|
66353
67766
|
async function readRunMeta(path4) {
|
|
66354
67767
|
const read = await readJsonFile(path4, runMetaSchema);
|
|
66355
67768
|
return read.kind === "ok" ? read.value : null;
|
|
@@ -66374,7 +67787,7 @@ async function isRunClaimed(runsDir, runId) {
|
|
|
66374
67787
|
|
|
66375
67788
|
// src/run-log/complete.ts
|
|
66376
67789
|
function writeLogFile(path4, dir, text2) {
|
|
66377
|
-
const temp = (0, import_node_path60.join)(dir, `.log.${(0,
|
|
67790
|
+
const temp = (0, import_node_path60.join)(dir, `.log.${(0, import_node_crypto28.randomUUID)()}.tmp`);
|
|
66378
67791
|
const fd = (0, import_node_fs19.openSync)(temp, "wx", 384);
|
|
66379
67792
|
try {
|
|
66380
67793
|
(0, import_node_fs19.writeSync)(fd, text2);
|
|
@@ -66402,8 +67815,86 @@ async function writeCompleteRunLog(runsDir, meta3, records) {
|
|
|
66402
67815
|
if (await readRunMeta(paths.meta) === null) await writeJsonFileAtomic(paths.meta, meta3);
|
|
66403
67816
|
}
|
|
66404
67817
|
|
|
66405
|
-
// src/run-log/
|
|
67818
|
+
// src/run-log/conversation-index.ts
|
|
66406
67819
|
var import_promises62 = require("fs/promises");
|
|
67820
|
+
var import_node_path61 = require("path");
|
|
67821
|
+
init_runtime_v2();
|
|
67822
|
+
init_zod();
|
|
67823
|
+
var ORDINALS_PER_SHARD = 1e3;
|
|
67824
|
+
var indexRecordSchema = external_exports.object({
|
|
67825
|
+
ordinal: external_exports.number().int().nonnegative(),
|
|
67826
|
+
nextOrdinal: external_exports.number().int().positive(),
|
|
67827
|
+
runId: runIdSchema
|
|
67828
|
+
});
|
|
67829
|
+
var coverageSchema = external_exports.object({
|
|
67830
|
+
// Files written before ranges could start mid-conversation always started at turn 0.
|
|
67831
|
+
lowestOrdinal: external_exports.number().int().nonnegative().default(0),
|
|
67832
|
+
highestOrdinal: external_exports.number().int().nonnegative(),
|
|
67833
|
+
nextExpectedOrdinal: external_exports.number().int().positive()
|
|
67834
|
+
});
|
|
67835
|
+
function indexDirectory(runsDir, conversationId) {
|
|
67836
|
+
return (0, import_node_path61.join)((0, import_node_path61.dirname)(runsDir), "sessions", conversationId, "turn-index");
|
|
67837
|
+
}
|
|
67838
|
+
function shardPath(runsDir, conversationId, ordinal) {
|
|
67839
|
+
return (0, import_node_path61.join)(
|
|
67840
|
+
indexDirectory(runsDir, conversationId),
|
|
67841
|
+
`${Math.floor(ordinal / ORDINALS_PER_SHARD)}.jsonl`
|
|
67842
|
+
);
|
|
67843
|
+
}
|
|
67844
|
+
async function indexConversationRun(runsDir, conversationId, ordinal, assistantOrdinal, runId) {
|
|
67845
|
+
const nextOrdinal = assistantOrdinal + 1;
|
|
67846
|
+
if (nextOrdinal <= ordinal) throw new Error("Assistant order must follow the prompt");
|
|
67847
|
+
const path4 = shardPath(runsDir, conversationId, ordinal);
|
|
67848
|
+
await (0, import_promises62.mkdir)((0, import_node_path61.dirname)(path4), { recursive: true, mode: 448 });
|
|
67849
|
+
await (0, import_promises62.appendFile)(path4, `${JSON.stringify({ ordinal, nextOrdinal, runId })}
|
|
67850
|
+
`, { mode: 384 });
|
|
67851
|
+
const coveragePath = (0, import_node_path61.join)((0, import_node_path61.dirname)((0, import_node_path61.dirname)(path4)), "coverage.json");
|
|
67852
|
+
const coverage = await readJsonFile(coveragePath, coverageSchema);
|
|
67853
|
+
const current = coverage.kind === "ok" ? coverage.value : null;
|
|
67854
|
+
const next = nextCoverage(current, ordinal, nextOrdinal);
|
|
67855
|
+
if (next) await writeJsonFileAtomic(coveragePath, next);
|
|
67856
|
+
}
|
|
67857
|
+
function nextCoverage(current, ordinal, nextOrdinal) {
|
|
67858
|
+
if (current === null || ordinal > current.nextExpectedOrdinal)
|
|
67859
|
+
return { lowestOrdinal: ordinal, highestOrdinal: ordinal, nextExpectedOrdinal: nextOrdinal };
|
|
67860
|
+
if (ordinal === current.nextExpectedOrdinal)
|
|
67861
|
+
return { ...current, highestOrdinal: ordinal, nextExpectedOrdinal: nextOrdinal };
|
|
67862
|
+
if (ordinal === current.highestOrdinal) return { ...current, nextExpectedOrdinal: nextOrdinal };
|
|
67863
|
+
return null;
|
|
67864
|
+
}
|
|
67865
|
+
async function readConversationIndexCoverage(runsDir, conversationId) {
|
|
67866
|
+
const path4 = (0, import_node_path61.join)((0, import_node_path61.dirname)(indexDirectory(runsDir, conversationId)), "coverage.json");
|
|
67867
|
+
const result = await readJsonFile(path4, coverageSchema);
|
|
67868
|
+
return result.kind === "ok" ? result.value : null;
|
|
67869
|
+
}
|
|
67870
|
+
async function readConversationRunIndex(runsDir, conversationId, before, limit) {
|
|
67871
|
+
const directory = indexDirectory(runsDir, conversationId);
|
|
67872
|
+
const names = await (0, import_promises62.readdir)(directory).catch((error61) => {
|
|
67873
|
+
if (error61.code === "ENOENT") return [];
|
|
67874
|
+
throw error61;
|
|
67875
|
+
});
|
|
67876
|
+
const shards = names.map((name) => /^\d+\.jsonl$/.test(name) ? Number(name.slice(0, -6)) : NaN).filter((shard) => Number.isSafeInteger(shard)).filter(
|
|
67877
|
+
(shard) => before === void 0 || shard <= Math.floor((before - 1) / ORDINALS_PER_SHARD)
|
|
67878
|
+
).sort((left, right) => right - left);
|
|
67879
|
+
const selected = [];
|
|
67880
|
+
for (const shard of shards) {
|
|
67881
|
+
const text2 = await (0, import_promises62.readFile)((0, import_node_path61.join)(directory, `${shard}.jsonl`), "utf8");
|
|
67882
|
+
const records = text2.split("\n").flatMap((line) => {
|
|
67883
|
+
if (!line) return [];
|
|
67884
|
+
const parsed = indexRecordSchema.parse(JSON.parse(line));
|
|
67885
|
+
return [parsed];
|
|
67886
|
+
}).filter((record2) => before === void 0 || record2.ordinal < before).reverse().sort((left, right) => right.ordinal - left.ordinal);
|
|
67887
|
+
for (const record2 of records) {
|
|
67888
|
+
if (selected.some((entry) => entry.ordinal === record2.ordinal)) continue;
|
|
67889
|
+
selected.push(record2);
|
|
67890
|
+
if (selected.length >= limit) return selected;
|
|
67891
|
+
}
|
|
67892
|
+
}
|
|
67893
|
+
return selected;
|
|
67894
|
+
}
|
|
67895
|
+
|
|
67896
|
+
// src/run-log/reader.ts
|
|
67897
|
+
var import_promises63 = require("fs/promises");
|
|
66407
67898
|
init_runtime_v2();
|
|
66408
67899
|
|
|
66409
67900
|
// src/run-log/tail.ts
|
|
@@ -66426,7 +67917,7 @@ function firstRecordLength(bytes) {
|
|
|
66426
67917
|
return bytes.indexOf(RUN_LOG_RECORD_SEPARATOR) + 1;
|
|
66427
67918
|
}
|
|
66428
67919
|
async function openRunLogReader(path4) {
|
|
66429
|
-
const handle = await (0,
|
|
67920
|
+
const handle = await (0, import_promises63.open)(path4, "r");
|
|
66430
67921
|
const readAt = async (position, length) => {
|
|
66431
67922
|
const buffer = Buffer.alloc(length);
|
|
66432
67923
|
const { bytesRead } = await handle.read(buffer, 0, length, position);
|
|
@@ -66460,7 +67951,7 @@ async function openRunLogReader(path4) {
|
|
|
66460
67951
|
};
|
|
66461
67952
|
}
|
|
66462
67953
|
async function readLastRecord(path4) {
|
|
66463
|
-
const handle = await (0,
|
|
67954
|
+
const handle = await (0, import_promises63.open)(path4, "r").catch(() => null);
|
|
66464
67955
|
if (handle === null) return null;
|
|
66465
67956
|
try {
|
|
66466
67957
|
const { size } = await handle.stat();
|
|
@@ -66494,7 +67985,7 @@ var decoder = new TextDecoder();
|
|
|
66494
67985
|
|
|
66495
67986
|
// src/run-log/writer.ts
|
|
66496
67987
|
var import_node_fs20 = require("fs");
|
|
66497
|
-
var
|
|
67988
|
+
var import_node_path62 = require("path");
|
|
66498
67989
|
init_runtime_v2();
|
|
66499
67990
|
function lastSeq(fd, size) {
|
|
66500
67991
|
for (const length of tailWindows(size)) {
|
|
@@ -66510,7 +68001,7 @@ function lastSeq(fd, size) {
|
|
|
66510
68001
|
throw new RuntimeFault("record_too_large", "Run log tail record is larger than any record");
|
|
66511
68002
|
}
|
|
66512
68003
|
function openRunLog(path4, clock) {
|
|
66513
|
-
(0, import_node_fs20.mkdirSync)((0,
|
|
68004
|
+
(0, import_node_fs20.mkdirSync)((0, import_node_path62.dirname)(path4), { recursive: true, mode: 448 });
|
|
66514
68005
|
const fd = (0, import_node_fs20.openSync)(path4, "a+", 384);
|
|
66515
68006
|
let size = (0, import_node_fs20.fstatSync)(fd).size;
|
|
66516
68007
|
let seq = lastSeq(fd, size);
|
|
@@ -66742,10 +68233,30 @@ async function admitAndRun(spec, context, append, sink, signal) {
|
|
|
66742
68233
|
async function claimRun(spec, context) {
|
|
66743
68234
|
if (await isRunClaimed(context.runsDir, spec.runId)) return null;
|
|
66744
68235
|
const paths = runDirectory(context.runsDir, spec.runId);
|
|
66745
|
-
await writeJsonFileAtomic(paths.meta, {
|
|
68236
|
+
await writeJsonFileAtomic(paths.meta, {
|
|
68237
|
+
runId: spec.runId,
|
|
68238
|
+
conversationId: spec.conversationId,
|
|
68239
|
+
...spec.mode ? { agentMode: spec.mode } : {},
|
|
68240
|
+
...spec.userMessage ? { userMessage: spec.userMessage } : {},
|
|
68241
|
+
...spec.assistantMessage ? { assistantMessage: spec.assistantMessage } : {}
|
|
68242
|
+
});
|
|
66746
68243
|
const log = openRunLog(paths.log, context.clock);
|
|
66747
68244
|
const offset = log.append(runAccepted(context.machineId, context.clock.now()));
|
|
66748
68245
|
context.onAppended(spec.runId, offset);
|
|
68246
|
+
if (spec.userMessage?.turnOrdinal !== null && spec.userMessage?.turnOrdinal !== void 0 && spec.assistantMessage?.turnOrdinal !== null && spec.assistantMessage?.turnOrdinal !== void 0) {
|
|
68247
|
+
try {
|
|
68248
|
+
await indexConversationRun(
|
|
68249
|
+
context.runsDir,
|
|
68250
|
+
spec.conversationId,
|
|
68251
|
+
spec.userMessage.turnOrdinal,
|
|
68252
|
+
spec.assistantMessage.turnOrdinal,
|
|
68253
|
+
spec.runId
|
|
68254
|
+
);
|
|
68255
|
+
context.onAppended(spec.runId, offset);
|
|
68256
|
+
} catch (error61) {
|
|
68257
|
+
context.log.warn("holder.conversation_index_failed", { runId: spec.runId, error: error61 });
|
|
68258
|
+
}
|
|
68259
|
+
}
|
|
66749
68260
|
return log;
|
|
66750
68261
|
}
|
|
66751
68262
|
async function runClaimedTurn(spec, claimed, context, signal) {
|
|
@@ -66807,12 +68318,12 @@ var TASK_UNSUPPORTED = {
|
|
|
66807
68318
|
message: "This agent cannot stop one background task."
|
|
66808
68319
|
};
|
|
66809
68320
|
function sha2564(value2) {
|
|
66810
|
-
return (0,
|
|
68321
|
+
return (0, import_node_crypto29.createHash)("sha256").update(value2).digest("hex");
|
|
66811
68322
|
}
|
|
66812
68323
|
function tokenMatches(expected, presented) {
|
|
66813
68324
|
const a = Buffer.from(sha2564(expected), "hex");
|
|
66814
68325
|
const b = Buffer.from(sha2564(presented), "hex");
|
|
66815
|
-
return (0,
|
|
68326
|
+
return (0, import_node_crypto29.timingSafeEqual)(a, b);
|
|
66816
68327
|
}
|
|
66817
68328
|
async function runHolder({
|
|
66818
68329
|
launch,
|
|
@@ -66826,7 +68337,7 @@ async function runHolder({
|
|
|
66826
68337
|
try {
|
|
66827
68338
|
const identity = await readProcessIdentity(process.pid);
|
|
66828
68339
|
if (identity === null) throw new RuntimeFault("internal", "Cannot read own process identity");
|
|
66829
|
-
const _engines = __using(_stack, recordSpawnedEngines(engineRecordsPath((0,
|
|
68340
|
+
const _engines = __using(_stack, recordSpawnedEngines(engineRecordsPath((0, import_node_path63.dirname)(launch.statusPath)), clock, log));
|
|
66830
68341
|
const holder = {
|
|
66831
68342
|
state: "idle",
|
|
66832
68343
|
runId: null,
|
|
@@ -67120,7 +68631,7 @@ var DEFAULT_MAX_ACTIVE_RUNS = 32;
|
|
|
67120
68631
|
var HOLDER_BUSY = "busy";
|
|
67121
68632
|
async function listIds(dir, schema) {
|
|
67122
68633
|
const ids = [];
|
|
67123
|
-
for (const name of await (0,
|
|
68634
|
+
for (const name of await (0, import_promises64.readdir)(dir).catch(() => [])) {
|
|
67124
68635
|
const parsed = schema.safeParse(name);
|
|
67125
68636
|
if (parsed.success) ids.push(parsed.data);
|
|
67126
68637
|
}
|
|
@@ -67134,8 +68645,8 @@ function holderIdentity(status) {
|
|
|
67134
68645
|
return command === void 0 ? { pid, startedAt } : { pid, startedAt, command };
|
|
67135
68646
|
}
|
|
67136
68647
|
function sessionFiles(paths, conversationId) {
|
|
67137
|
-
const dir = (0,
|
|
67138
|
-
return { dir, launch: (0,
|
|
68648
|
+
const dir = (0, import_node_path64.join)(paths.sessions, conversationId);
|
|
68649
|
+
return { dir, launch: (0, import_node_path64.join)(dir, "launch.json"), status: (0, import_node_path64.join)(dir, "holder.json") };
|
|
67139
68650
|
}
|
|
67140
68651
|
async function openSessions(deps) {
|
|
67141
68652
|
const { paths, clock, log } = deps;
|
|
@@ -67176,7 +68687,7 @@ async function openSessions(deps) {
|
|
|
67176
68687
|
await reapLeftoverEngines(engineRecordsPath(dir), { clock, log, conversationId }).catch(
|
|
67177
68688
|
(error61) => log.warn("sessions.engine_reap_failed", { conversationId, error: error61 })
|
|
67178
68689
|
);
|
|
67179
|
-
await (0,
|
|
68690
|
+
await (0, import_promises64.rm)(dir, { recursive: true, force: true });
|
|
67180
68691
|
};
|
|
67181
68692
|
const retireIfGone = async (conversationId) => {
|
|
67182
68693
|
const files = sessionFiles(paths, conversationId);
|
|
@@ -67264,7 +68775,7 @@ async function openSessions(deps) {
|
|
|
67264
68775
|
log.info("sessions.reattached", { conversationId });
|
|
67265
68776
|
return;
|
|
67266
68777
|
}
|
|
67267
|
-
if (alive) await (0,
|
|
68778
|
+
if (alive) await (0, import_promises64.rm)(files.dir, { recursive: true, force: true });
|
|
67268
68779
|
else await discardSession(conversationId);
|
|
67269
68780
|
};
|
|
67270
68781
|
const busyRunIds = async () => {
|
|
@@ -67289,14 +68800,14 @@ async function openSessions(deps) {
|
|
|
67289
68800
|
if (!busy.has(runId)) await markInterrupted(runId);
|
|
67290
68801
|
}
|
|
67291
68802
|
};
|
|
67292
|
-
const
|
|
68803
|
+
const spawn10 = async (conversationId) => {
|
|
67293
68804
|
const files = sessionFiles(paths, conversationId);
|
|
67294
68805
|
const launch = {
|
|
67295
68806
|
protocol: HOLDER_PROTOCOL,
|
|
67296
68807
|
conversationId,
|
|
67297
68808
|
machineId: deps.machineId,
|
|
67298
|
-
endpoint: ipcEndpoint(paths.sockets, (0,
|
|
67299
|
-
token: (0,
|
|
68809
|
+
endpoint: ipcEndpoint(paths.sockets, (0, import_node_crypto30.randomUUID)().slice(0, 8)),
|
|
68810
|
+
token: (0, import_node_crypto30.randomBytes)(32).toString("hex"),
|
|
67300
68811
|
runsDir: paths.runs,
|
|
67301
68812
|
statusPath: files.status
|
|
67302
68813
|
};
|
|
@@ -67322,7 +68833,7 @@ async function openSessions(deps) {
|
|
|
67322
68833
|
const meta3 = await readRunMeta(dir.meta);
|
|
67323
68834
|
const last = await readLastRecord(dir.log);
|
|
67324
68835
|
if (meta3 === null || last === null) return null;
|
|
67325
|
-
const logged = await (0,
|
|
68836
|
+
const logged = await (0, import_promises64.stat)(dir.log).catch((error61) => {
|
|
67326
68837
|
if (errnoCode(error61) === "ENOENT") return null;
|
|
67327
68838
|
throw error61;
|
|
67328
68839
|
});
|
|
@@ -67433,7 +68944,7 @@ async function openSessions(deps) {
|
|
|
67433
68944
|
return "started";
|
|
67434
68945
|
}
|
|
67435
68946
|
if (await activeRunsOtherThan(run2.runId) >= maxActiveRuns) return "waiting";
|
|
67436
|
-
if (!connections.has(run2.conversationId)) await
|
|
68947
|
+
if (!connections.has(run2.conversationId)) await spawn10(run2.conversationId);
|
|
67437
68948
|
const connection = connections.get(run2.conversationId);
|
|
67438
68949
|
if (connection === void 0) {
|
|
67439
68950
|
throw new RuntimeFault("internal", "Holder connection missing");
|
|
@@ -67632,7 +69143,7 @@ function loadRuntimeConfig(env = process.env, totalMemoryBytes = (0, import_node
|
|
|
67632
69143
|
providerProbes: ALAN_RUNTIME_PROVIDER_PROBES === "on",
|
|
67633
69144
|
providerToolchain: ALAN_RUNTIME_PROVIDER_NODE !== void 0 && ALAN_RUNTIME_PROVIDER_NPM_CLI !== void 0 ? { node: ALAN_RUNTIME_PROVIDER_NODE, npmCli: ALAN_RUNTIME_PROVIDER_NPM_CLI } : null,
|
|
67634
69145
|
home,
|
|
67635
|
-
configHome: XDG_CONFIG_HOME ?? (0,
|
|
69146
|
+
configHome: XDG_CONFIG_HOME ?? (0, import_node_path65.join)(home, ".config"),
|
|
67636
69147
|
...githubProxyConfig({ ALAN_RUNTIME_GITHUB_PROXY, XDG_CONFIG_HOME, GH_CONFIG_DIR }, home),
|
|
67637
69148
|
gitGatewayUrl: ALAN_RUNTIME_GIT_GATEWAY_URL ?? null,
|
|
67638
69149
|
workspaceRoot: ALAN_RUNTIME_WORKSPACE_ROOT ?? null,
|
|
@@ -67641,10 +69152,10 @@ function loadRuntimeConfig(env = process.env, totalMemoryBytes = (0, import_node
|
|
|
67641
69152
|
};
|
|
67642
69153
|
}
|
|
67643
69154
|
function githubProxyConfig(env, home) {
|
|
67644
|
-
const configHome = env.XDG_CONFIG_HOME ?? (0,
|
|
69155
|
+
const configHome = env.XDG_CONFIG_HOME ?? (0, import_node_path65.join)(home, ".config");
|
|
67645
69156
|
return {
|
|
67646
69157
|
githubProxy: env.ALAN_RUNTIME_GITHUB_PROXY === "on",
|
|
67647
|
-
ghConfigDir: env.GH_CONFIG_DIR ?? (0,
|
|
69158
|
+
ghConfigDir: env.GH_CONFIG_DIR ?? (0, import_node_path65.join)(configHome, "gh")
|
|
67648
69159
|
};
|
|
67649
69160
|
}
|
|
67650
69161
|
function serviceEnvironment2(env, profile) {
|
|
@@ -67702,9 +69213,9 @@ function takeEnrollmentCodeFromEnv(env = process.env) {
|
|
|
67702
69213
|
}
|
|
67703
69214
|
|
|
67704
69215
|
// src/cli/context.ts
|
|
67705
|
-
var
|
|
69216
|
+
var import_promises65 = require("fs/promises");
|
|
67706
69217
|
var import_node_os12 = require("os");
|
|
67707
|
-
var
|
|
69218
|
+
var import_node_path66 = require("path");
|
|
67708
69219
|
var DESKTOP_BUNDLE_IDS = {
|
|
67709
69220
|
production: ["com.alan-ai.desktop"],
|
|
67710
69221
|
staging: ["com.alan-ai.desktop.staging"],
|
|
@@ -67744,7 +69255,7 @@ function serviceSpec({ config: config2, paths, self }) {
|
|
|
67744
69255
|
profile: config2.profile,
|
|
67745
69256
|
program: serviceCommand(config2.host, self, launcher),
|
|
67746
69257
|
environment: config2.serviceEnvironment,
|
|
67747
|
-
logPath: (0,
|
|
69258
|
+
logPath: (0, import_node_path66.join)(paths.logs, "service.log"),
|
|
67748
69259
|
associatedBundleIds: DESKTOP_BUNDLE_IDS[config2.profile]
|
|
67749
69260
|
};
|
|
67750
69261
|
}
|
|
@@ -67752,7 +69263,7 @@ async function installedServiceSpec(ctx) {
|
|
|
67752
69263
|
const spec = serviceSpec(ctx);
|
|
67753
69264
|
if (ctx.config.host === "app") return spec;
|
|
67754
69265
|
const layout = installLayout(ctx.config.installDir, ctx.config.profile);
|
|
67755
|
-
const installed = await (0,
|
|
69266
|
+
const installed = await (0, import_promises65.access)(layout.launcher).then(
|
|
67756
69267
|
() => true,
|
|
67757
69268
|
() => false
|
|
67758
69269
|
);
|
|
@@ -67880,7 +69391,7 @@ var manifestRevisionSchema = external_exports.object({ revision: external_export
|
|
|
67880
69391
|
async function manifestRevision(path4) {
|
|
67881
69392
|
let raw;
|
|
67882
69393
|
try {
|
|
67883
|
-
raw = JSON.parse(await (0,
|
|
69394
|
+
raw = JSON.parse(await (0, import_promises66.readFile)(path4, "utf8"));
|
|
67884
69395
|
} catch (error61) {
|
|
67885
69396
|
throw new RuntimeFault("invalid_file", `Cannot read the skill manifest at ${path4}`, {
|
|
67886
69397
|
cause: error61
|
|
@@ -67898,7 +69409,7 @@ async function runSkills(argv) {
|
|
|
67898
69409
|
case "scan":
|
|
67899
69410
|
writeJson({
|
|
67900
69411
|
status: "failed",
|
|
67901
|
-
attemptId: (0,
|
|
69412
|
+
attemptId: (0, import_node_crypto31.randomUUID)(),
|
|
67902
69413
|
retainedInventoryRevision: null,
|
|
67903
69414
|
diagnostics: [
|
|
67904
69415
|
{ code: "RUNTIME_SKILL_SCAN_UNSUPPORTED", message: SKILLS_SYNCED_BY_RUNTIME }
|
|
@@ -67914,7 +69425,7 @@ async function runSkills(argv) {
|
|
|
67914
69425
|
);
|
|
67915
69426
|
}
|
|
67916
69427
|
writeJson({
|
|
67917
|
-
attemptId: (0,
|
|
69428
|
+
attemptId: (0, import_node_crypto31.randomUUID)(),
|
|
67918
69429
|
desiredRevision: await manifestRevision(manifest),
|
|
67919
69430
|
skills: []
|
|
67920
69431
|
});
|
|
@@ -67934,8 +69445,8 @@ async function runSkills(argv) {
|
|
|
67934
69445
|
}
|
|
67935
69446
|
|
|
67936
69447
|
// src/cli/commands/doctor.ts
|
|
67937
|
-
var
|
|
67938
|
-
var
|
|
69448
|
+
var import_promises69 = require("fs/promises");
|
|
69449
|
+
var import_node_path70 = require("path");
|
|
67939
69450
|
init_runtime_v2();
|
|
67940
69451
|
|
|
67941
69452
|
// src/identity/credential.ts
|
|
@@ -68112,24 +69623,24 @@ async function authorizeDevice(input2) {
|
|
|
68112
69623
|
}
|
|
68113
69624
|
|
|
68114
69625
|
// src/identity/enroll.ts
|
|
68115
|
-
var
|
|
69626
|
+
var import_promises67 = require("fs/promises");
|
|
68116
69627
|
init_runtime_v2();
|
|
68117
69628
|
|
|
68118
69629
|
// src/identity/installation.ts
|
|
68119
|
-
var
|
|
68120
|
-
var
|
|
69630
|
+
var import_node_crypto32 = require("crypto");
|
|
69631
|
+
var import_node_path67 = require("path");
|
|
68121
69632
|
init_zod();
|
|
68122
69633
|
var installationFileSchema = external_exports.object({
|
|
68123
69634
|
installationId: external_exports.uuid()
|
|
68124
69635
|
});
|
|
68125
69636
|
function installationPath(paths) {
|
|
68126
|
-
return (0,
|
|
69637
|
+
return (0, import_node_path67.join)(paths.stateDir, "installation.json");
|
|
68127
69638
|
}
|
|
68128
69639
|
async function ensureInstallationId(paths) {
|
|
68129
69640
|
const path4 = installationPath(paths);
|
|
68130
69641
|
const existing = await readJsonFile(path4, installationFileSchema);
|
|
68131
69642
|
if (existing.kind === "ok") return existing.value.installationId;
|
|
68132
|
-
const created = { installationId: (0,
|
|
69643
|
+
const created = { installationId: (0, import_node_crypto32.randomUUID)() };
|
|
68133
69644
|
await writeJsonFileAtomic(path4, created);
|
|
68134
69645
|
return created.installationId;
|
|
68135
69646
|
}
|
|
@@ -68216,13 +69727,13 @@ async function enrollFromGrantFile(input2) {
|
|
|
68216
69727
|
clock: input2.clock,
|
|
68217
69728
|
access: input2.access
|
|
68218
69729
|
});
|
|
68219
|
-
await (0,
|
|
69730
|
+
await (0, import_promises67.rm)(input2.grantPath, { force: true });
|
|
68220
69731
|
return machine;
|
|
68221
69732
|
}
|
|
68222
69733
|
|
|
68223
69734
|
// src/identity/migrate-v1.ts
|
|
68224
|
-
var
|
|
68225
|
-
var
|
|
69735
|
+
var import_promises68 = require("fs/promises");
|
|
69736
|
+
var import_node_path68 = require("path");
|
|
68226
69737
|
init_runtime_v2();
|
|
68227
69738
|
init_zod();
|
|
68228
69739
|
var EXIT_POLL_MS = 200;
|
|
@@ -68243,11 +69754,11 @@ var ownerLeaseSchema = external_exports.looseObject({ pid: external_exports.numb
|
|
|
68243
69754
|
function legacyConfigPath(home, profile) {
|
|
68244
69755
|
switch (profile) {
|
|
68245
69756
|
case "production":
|
|
68246
|
-
return (0,
|
|
69757
|
+
return (0, import_node_path68.join)(home, ".alan", "agent", "config.json");
|
|
68247
69758
|
case "staging":
|
|
68248
|
-
return (0,
|
|
69759
|
+
return (0, import_node_path68.join)(home, ".alan-staging", "agent", "config.json");
|
|
68249
69760
|
default:
|
|
68250
|
-
return (0,
|
|
69761
|
+
return (0, import_node_path68.join)(home, ".alan-dev", "agent", "config.json");
|
|
68251
69762
|
}
|
|
68252
69763
|
}
|
|
68253
69764
|
async function findLegacyInstall(home, profile) {
|
|
@@ -68272,8 +69783,8 @@ async function scrubLegacyInstall(install2) {
|
|
|
68272
69783
|
const scrubbed = { ...install2.config, migratedToRuntimeV2: true };
|
|
68273
69784
|
for (const key of SCRUBBED_KEYS) delete scrubbed[key];
|
|
68274
69785
|
await writeJsonFileAtomic(`${install2.configPath}.migrated-v1`, scrubbed);
|
|
68275
|
-
await (0,
|
|
68276
|
-
await (0,
|
|
69786
|
+
await (0, import_promises68.rm)(install2.configPath, { force: true });
|
|
69787
|
+
await (0, import_promises68.rm)(install2.ownerLeasePath, { force: true });
|
|
68277
69788
|
}
|
|
68278
69789
|
async function exchangeCredential(deps) {
|
|
68279
69790
|
const { config: config2 } = deps.install;
|
|
@@ -68382,7 +69893,7 @@ async function loadIdentity(paths, options = {}) {
|
|
|
68382
69893
|
}
|
|
68383
69894
|
|
|
68384
69895
|
// src/cli/commands/status.ts
|
|
68385
|
-
var
|
|
69896
|
+
var import_node_path69 = require("path");
|
|
68386
69897
|
async function serviceStatus(ctx) {
|
|
68387
69898
|
try {
|
|
68388
69899
|
return await createServiceManager(ctx.host, ctx.config.profile).status();
|
|
@@ -68409,7 +69920,7 @@ async function runtimeState(ctx) {
|
|
|
68409
69920
|
const running = await readRunningRuntime(ctx.paths.lock);
|
|
68410
69921
|
if (running === null) return { state: "offline", pid: null, localApi: null };
|
|
68411
69922
|
const discovery = await readJsonFile(
|
|
68412
|
-
(0,
|
|
69923
|
+
(0, import_node_path69.join)(ctx.paths.stateDir, LOCAL_API_DISCOVERY_FILE),
|
|
68413
69924
|
localApiDiscoverySchema
|
|
68414
69925
|
);
|
|
68415
69926
|
const localApi = discovery.kind === "ok" && discovery.value.pid === running.pid ? {
|
|
@@ -68630,7 +70141,7 @@ async function runtimeCheck(ctx, status) {
|
|
|
68630
70141
|
return check2("runtime", "warn", "No runtime is running for this profile");
|
|
68631
70142
|
}
|
|
68632
70143
|
const client = createRuntimeClient({
|
|
68633
|
-
discoveryPath: (0,
|
|
70144
|
+
discoveryPath: (0, import_node_path70.join)(ctx.paths.stateDir, LOCAL_API_DISCOVERY_FILE)
|
|
68634
70145
|
});
|
|
68635
70146
|
try {
|
|
68636
70147
|
const live = await client.status(AbortSignal.timeout(LOCAL_TIMEOUT_MS));
|
|
@@ -68657,7 +70168,7 @@ async function runtimeCheck(ctx, status) {
|
|
|
68657
70168
|
}
|
|
68658
70169
|
}
|
|
68659
70170
|
async function probeHolder(dir, conversationId) {
|
|
68660
|
-
const launch = await readJsonFile((0,
|
|
70171
|
+
const launch = await readJsonFile((0, import_node_path70.join)(dir, "launch.json"), holderLaunchSchema);
|
|
68661
70172
|
if (launch.kind !== "ok") return null;
|
|
68662
70173
|
try {
|
|
68663
70174
|
const reply2 = await withTimeout(
|
|
@@ -68682,8 +70193,8 @@ async function probeHolder(dir, conversationId) {
|
|
|
68682
70193
|
}
|
|
68683
70194
|
}
|
|
68684
70195
|
async function holdersCheck(ctx) {
|
|
68685
|
-
const names = await (0,
|
|
68686
|
-
const holders = (await Promise.all(names.map((name) => probeHolder((0,
|
|
70196
|
+
const names = await (0, import_promises69.readdir)(ctx.paths.sessions).catch(() => []);
|
|
70197
|
+
const holders = (await Promise.all(names.map((name) => probeHolder((0, import_node_path70.join)(ctx.paths.sessions, name), name)))).filter((facts) => facts !== null);
|
|
68687
70198
|
const dead = holders.filter((holder) => !holder.alive).length;
|
|
68688
70199
|
return check2(
|
|
68689
70200
|
"holders",
|
|
@@ -68694,10 +70205,10 @@ async function holdersCheck(ctx) {
|
|
|
68694
70205
|
}
|
|
68695
70206
|
async function freeBytesAt(path4) {
|
|
68696
70207
|
try {
|
|
68697
|
-
const stats = await (0,
|
|
70208
|
+
const stats = await (0, import_promises69.statfs)(path4);
|
|
68698
70209
|
return { path: path4, freeBytes: stats.bavail * stats.bsize };
|
|
68699
70210
|
} catch (error61) {
|
|
68700
|
-
const parent = (0,
|
|
70211
|
+
const parent = (0, import_node_path70.dirname)(path4);
|
|
68701
70212
|
if (parent === path4) throw error61;
|
|
68702
70213
|
return freeBytesAt(parent);
|
|
68703
70214
|
}
|
|
@@ -68833,7 +70344,7 @@ async function runDoctor(argv, context = cliContext) {
|
|
|
68833
70344
|
}
|
|
68834
70345
|
|
|
68835
70346
|
// src/cli/commands/git-credential.ts
|
|
68836
|
-
var
|
|
70347
|
+
var import_promises70 = require("fs/promises");
|
|
68837
70348
|
var import_node_net4 = require("net");
|
|
68838
70349
|
var MAX_RESPONSE_BYTES = 64 * 1024;
|
|
68839
70350
|
async function readAll(stream) {
|
|
@@ -68943,7 +70454,7 @@ async function configure(argv) {
|
|
|
68943
70454
|
}
|
|
68944
70455
|
async function configureGitGateway(config2, gatewayUrl, signal) {
|
|
68945
70456
|
const { launcher } = installLayout(config2.installDir, config2.profile);
|
|
68946
|
-
const installed = await (0,
|
|
70457
|
+
const installed = await (0, import_promises70.access)(launcher).then(
|
|
68947
70458
|
() => true,
|
|
68948
70459
|
() => false
|
|
68949
70460
|
);
|
|
@@ -68970,7 +70481,7 @@ async function runGitCredential(argv) {
|
|
|
68970
70481
|
}
|
|
68971
70482
|
|
|
68972
70483
|
// src/cli/commands/hold.ts
|
|
68973
|
-
var
|
|
70484
|
+
var import_node_path71 = require("path");
|
|
68974
70485
|
init_agent2();
|
|
68975
70486
|
init_runtime_v2();
|
|
68976
70487
|
async function machineAccess(paths, log, conversationId, transport) {
|
|
@@ -69028,7 +70539,7 @@ async function runHold(argv) {
|
|
|
69028
70539
|
const config2 = loadRuntimeConfig();
|
|
69029
70540
|
const paths = runtimePaths(config2.stateDir);
|
|
69030
70541
|
const log = __using(_stack, openFileLog(
|
|
69031
|
-
(0,
|
|
70542
|
+
(0, import_node_path71.join)(paths.logs, `holder-${launch.value.conversationId}.jsonl`),
|
|
69032
70543
|
config2.logLevel,
|
|
69033
70544
|
systemClock
|
|
69034
70545
|
));
|
|
@@ -69039,7 +70550,7 @@ async function runHold(argv) {
|
|
|
69039
70550
|
);
|
|
69040
70551
|
const transport = __using(_stack, createHttpTransport());
|
|
69041
70552
|
const access7 = await machineAccess(paths, log, launch.value.conversationId, transport);
|
|
69042
|
-
const credentialPath = (0,
|
|
70553
|
+
const credentialPath = (0, import_node_path71.join)(paths.tmp, "mcp", `${launch.value.conversationId}.json`);
|
|
69043
70554
|
const managedMcp = __using(_stack, access7.managedMcp === void 0 ? void 0 : createHelperMcpAccess({
|
|
69044
70555
|
managedMcp: access7.managedMcp,
|
|
69045
70556
|
conversationId: launch.value.conversationId,
|
|
@@ -69079,7 +70590,7 @@ async function runHold(argv) {
|
|
|
69079
70590
|
}
|
|
69080
70591
|
|
|
69081
70592
|
// src/cli/commands/hook.ts
|
|
69082
|
-
var
|
|
70593
|
+
var import_node_path72 = require("path");
|
|
69083
70594
|
var RUNTIME_ANSWER_MS = 2e3;
|
|
69084
70595
|
var DEBUG_VARIABLE = "ALAN_HOOK_DEBUG";
|
|
69085
70596
|
function flag(argv, name) {
|
|
@@ -69111,7 +70622,7 @@ async function forwardHook(argv, io) {
|
|
|
69111
70622
|
return "transcript outside provider root";
|
|
69112
70623
|
}
|
|
69113
70624
|
const verdict = await io.send(
|
|
69114
|
-
(0,
|
|
70625
|
+
(0, import_node_path72.join)(io.stateDir, LOCAL_API_DISCOVERY_FILE),
|
|
69115
70626
|
hookSignal,
|
|
69116
70627
|
AbortSignal.timeout(RUNTIME_ANSWER_MS)
|
|
69117
70628
|
);
|
|
@@ -69147,7 +70658,7 @@ async function runHook(argv, overrides = {}) {
|
|
|
69147
70658
|
}
|
|
69148
70659
|
|
|
69149
70660
|
// src/cli/commands/ingestion-hooks.ts
|
|
69150
|
-
var
|
|
70661
|
+
var import_promises71 = require("fs/promises");
|
|
69151
70662
|
var CODEX_TRUST_NOTE = "Codex runs new hooks only after you review them: open /hooks in Codex.";
|
|
69152
70663
|
function isAction(value2) {
|
|
69153
70664
|
return value2 === "enable" || value2 === "disable" || value2 === "status";
|
|
@@ -69170,7 +70681,7 @@ function errorMessage2(error61) {
|
|
|
69170
70681
|
return error61 instanceof Error ? error61.message : String(error61);
|
|
69171
70682
|
}
|
|
69172
70683
|
async function exists5(path4) {
|
|
69173
|
-
return (0,
|
|
70684
|
+
return (0, import_promises71.access)(path4).then(
|
|
69174
70685
|
() => true,
|
|
69175
70686
|
() => false
|
|
69176
70687
|
);
|
|
@@ -69273,10 +70784,10 @@ async function runIntegrationsCommand(argv) {
|
|
|
69273
70784
|
}
|
|
69274
70785
|
|
|
69275
70786
|
// src/cli/commands/legacy.ts
|
|
69276
|
-
var
|
|
70787
|
+
var import_node_path74 = require("path");
|
|
69277
70788
|
|
|
69278
70789
|
// src/cli/commands/setup.ts
|
|
69279
|
-
var
|
|
70790
|
+
var import_node_path73 = require("path");
|
|
69280
70791
|
init_zod();
|
|
69281
70792
|
|
|
69282
70793
|
// src/cli/legacy.ts
|
|
@@ -69358,7 +70869,7 @@ async function grantFileCredential(argv, grantPath, ctx, deps) {
|
|
|
69358
70869
|
return enrollFromGrantFile({
|
|
69359
70870
|
paths: ctx.paths,
|
|
69360
70871
|
storeKind: credentialStoreFlag(argv) ?? ctx.config.credentialStore,
|
|
69361
|
-
grantPath: (0,
|
|
70872
|
+
grantPath: (0, import_node_path73.resolve)(grantPath),
|
|
69362
70873
|
clock: deps.clock,
|
|
69363
70874
|
access: ctx.access
|
|
69364
70875
|
});
|
|
@@ -69434,7 +70945,7 @@ async function runSetup(argv, signal) {
|
|
|
69434
70945
|
var _stack = [];
|
|
69435
70946
|
try {
|
|
69436
70947
|
const ctx = cliContext();
|
|
69437
|
-
const log = __using(_stack, openFileLog((0,
|
|
70948
|
+
const log = __using(_stack, openFileLog((0, import_node_path73.join)(ctx.paths.logs, "cli.jsonl"), ctx.config.logLevel, systemClock));
|
|
69438
70949
|
const result = await setupMachine(argv, ctx, {
|
|
69439
70950
|
enrollment: (apiUrl) => createEnrollmentClient({ apiUrl }),
|
|
69440
70951
|
isProcessAlive,
|
|
@@ -69517,7 +71028,7 @@ async function runToken(argv, signal) {
|
|
|
69517
71028
|
);
|
|
69518
71029
|
}
|
|
69519
71030
|
const ctx = cliContext();
|
|
69520
|
-
const log = __using(_stack, openFileLog((0,
|
|
71031
|
+
const log = __using(_stack, openFileLog((0, import_node_path74.join)(ctx.paths.logs, "cli.jsonl"), ctx.config.logLevel, systemClock));
|
|
69521
71032
|
const result = await rotateMachineCredential(ctx, { clock: systemClock, log, signal });
|
|
69522
71033
|
process.stdout.write(`${rotationMessage(result)}
|
|
69523
71034
|
`);
|
|
@@ -69529,8 +71040,8 @@ async function runToken(argv, signal) {
|
|
|
69529
71040
|
}
|
|
69530
71041
|
|
|
69531
71042
|
// src/cli/commands/logout.ts
|
|
69532
|
-
var
|
|
69533
|
-
var
|
|
71043
|
+
var import_promises72 = require("fs/promises");
|
|
71044
|
+
var import_node_path75 = require("path");
|
|
69534
71045
|
init_runtime_v2();
|
|
69535
71046
|
var RUNTIME_EXIT_WAIT_MS = 35e3;
|
|
69536
71047
|
var TURN_END_WAIT_MS = 3e4;
|
|
@@ -69589,9 +71100,9 @@ async function stopHolder(launch, deps, outcome2) {
|
|
|
69589
71100
|
}
|
|
69590
71101
|
async function stopHeldRuns(ctx, deps, outcome2 = "aborted") {
|
|
69591
71102
|
const stopped = [];
|
|
69592
|
-
for (const name of await (0,
|
|
71103
|
+
for (const name of await (0, import_promises72.readdir)(ctx.paths.sessions).catch(() => [])) {
|
|
69593
71104
|
const launch = await readJsonFile(
|
|
69594
|
-
(0,
|
|
71105
|
+
(0, import_node_path75.join)(ctx.paths.sessions, name, "launch.json"),
|
|
69595
71106
|
holderLaunchSchema
|
|
69596
71107
|
);
|
|
69597
71108
|
if (launch.kind !== "ok") continue;
|
|
@@ -69628,13 +71139,13 @@ async function forgetMachineLocally(ctx) {
|
|
|
69628
71139
|
const machine = await readMachineFile(ctx.paths);
|
|
69629
71140
|
if (machine === null) return;
|
|
69630
71141
|
await credentialStoreFor(ctx.paths, machine.credentialStore, ctx.access).clear();
|
|
69631
|
-
await (0,
|
|
71142
|
+
await (0, import_promises72.rm)(ctx.paths.machine, { force: true });
|
|
69632
71143
|
}
|
|
69633
71144
|
async function runLogout(argv, signal) {
|
|
69634
71145
|
var _stack = [];
|
|
69635
71146
|
try {
|
|
69636
71147
|
const ctx = cliContext();
|
|
69637
|
-
const log = __using(_stack, openFileLog((0,
|
|
71148
|
+
const log = __using(_stack, openFileLog((0, import_node_path75.join)(ctx.paths.logs, "cli.jsonl"), ctx.config.logLevel, systemClock));
|
|
69638
71149
|
const result = await logoutMachine(argv, ctx, {
|
|
69639
71150
|
api: (apiUrl, accessToken) => createApiClient({ apiUrl, accessToken }),
|
|
69640
71151
|
stopHeldRuns,
|
|
@@ -69651,7 +71162,8 @@ async function runLogout(argv, signal) {
|
|
|
69651
71162
|
}
|
|
69652
71163
|
|
|
69653
71164
|
// src/cli/commands/run.ts
|
|
69654
|
-
var
|
|
71165
|
+
var import_node_fs23 = require("fs");
|
|
71166
|
+
var import_node_path79 = require("path");
|
|
69655
71167
|
|
|
69656
71168
|
// src/local-api/app-attachments.ts
|
|
69657
71169
|
function createAppAttachments(clock) {
|
|
@@ -69685,7 +71197,9 @@ function createAppAttachments(clock) {
|
|
|
69685
71197
|
// src/local-api/run-appends.ts
|
|
69686
71198
|
function createRunAppends() {
|
|
69687
71199
|
const waiters = /* @__PURE__ */ new Map();
|
|
71200
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
69688
71201
|
const wake = (runId) => {
|
|
71202
|
+
for (const listener of listeners) listener(runId);
|
|
69689
71203
|
const pending = waiters.get(runId);
|
|
69690
71204
|
if (pending === void 0) return;
|
|
69691
71205
|
waiters.delete(runId);
|
|
@@ -69693,8 +71207,17 @@ function createRunAppends() {
|
|
|
69693
71207
|
};
|
|
69694
71208
|
return {
|
|
69695
71209
|
notify: wake,
|
|
71210
|
+
subscribe: (listener) => {
|
|
71211
|
+
listeners.add(listener);
|
|
71212
|
+
return {
|
|
71213
|
+
[Symbol.dispose]: () => {
|
|
71214
|
+
listeners.delete(listener);
|
|
71215
|
+
}
|
|
71216
|
+
};
|
|
71217
|
+
},
|
|
69696
71218
|
notifyAll: () => {
|
|
69697
71219
|
for (const runId of [...waiters.keys()]) wake(runId);
|
|
71220
|
+
for (const listener of listeners) listener(null);
|
|
69698
71221
|
},
|
|
69699
71222
|
nextAppend: (runId, signal) => {
|
|
69700
71223
|
if (signal.aborted) return Promise.resolve();
|
|
@@ -69716,18 +71239,18 @@ function createRunAppends() {
|
|
|
69716
71239
|
}
|
|
69717
71240
|
|
|
69718
71241
|
// src/local-api/server.ts
|
|
69719
|
-
var
|
|
69720
|
-
var
|
|
71242
|
+
var import_node_crypto34 = require("crypto");
|
|
71243
|
+
var import_promises73 = require("fs/promises");
|
|
69721
71244
|
var import_node_http4 = require("http");
|
|
69722
|
-
var
|
|
71245
|
+
var import_node_path76 = require("path");
|
|
69723
71246
|
|
|
69724
71247
|
// src/local-api/guard.ts
|
|
69725
|
-
var
|
|
71248
|
+
var import_node_crypto33 = require("crypto");
|
|
69726
71249
|
var ALLOWED = { kind: "allowed" };
|
|
69727
71250
|
function tokenMatches2(expected, header) {
|
|
69728
71251
|
if (header === void 0 || !header.startsWith("Bearer ")) return false;
|
|
69729
71252
|
const presented = Buffer.from(header.slice("Bearer ".length));
|
|
69730
|
-
return presented.length === expected.length && (0,
|
|
71253
|
+
return presented.length === expected.length && (0, import_node_crypto33.timingSafeEqual)(presented, expected);
|
|
69731
71254
|
}
|
|
69732
71255
|
function isBrowserReachable(req, allowedHosts) {
|
|
69733
71256
|
if (req.headers.origin !== void 0 || req.headers.referer !== void 0) return true;
|
|
@@ -69835,6 +71358,283 @@ function requestSignal(res) {
|
|
|
69835
71358
|
init_runtime_v2();
|
|
69836
71359
|
init_zod();
|
|
69837
71360
|
|
|
71361
|
+
// src/local-api/conversation-messages.ts
|
|
71362
|
+
init_acp();
|
|
71363
|
+
init_runtime_v2();
|
|
71364
|
+
function applyLogLine(line, assistantMessageId, state) {
|
|
71365
|
+
const raw = JSON.parse(line);
|
|
71366
|
+
const record2 = runLogRecordSchema.safeParse(raw);
|
|
71367
|
+
if (!record2.success) return null;
|
|
71368
|
+
const kind = record2.data.update.sessionUpdate;
|
|
71369
|
+
if (isRunLifecycleKind(kind)) {
|
|
71370
|
+
const lifecycle = runLifecycleUpdateSchema.parse(record2.data.update);
|
|
71371
|
+
if (lifecycle.sessionUpdate === "_alan/run.accepted") {
|
|
71372
|
+
state.state = "running";
|
|
71373
|
+
return false;
|
|
71374
|
+
}
|
|
71375
|
+
const ended = lifecycle.sessionUpdate === "_alan/run.ended";
|
|
71376
|
+
applySessionEvent(state, {
|
|
71377
|
+
seq: record2.data.seq,
|
|
71378
|
+
at: record2.data.at,
|
|
71379
|
+
update: {
|
|
71380
|
+
sessionUpdate: "state_update",
|
|
71381
|
+
state: ended ? "idle" : "running",
|
|
71382
|
+
...ended && {
|
|
71383
|
+
stopReason: lifecycle.outcome === "aborted" || lifecycle.outcome === "interrupted" ? "cancelled" : "end_turn"
|
|
71384
|
+
}
|
|
71385
|
+
}
|
|
71386
|
+
});
|
|
71387
|
+
return ended;
|
|
71388
|
+
}
|
|
71389
|
+
const event = scopeTranscriptEvent({ ...record2.data, turnId: assistantMessageId });
|
|
71390
|
+
if (!event) return null;
|
|
71391
|
+
applySessionEvent(state, event);
|
|
71392
|
+
return false;
|
|
71393
|
+
}
|
|
71394
|
+
function applyLogChunk(text2, assistantMessageId, state) {
|
|
71395
|
+
let ended = false;
|
|
71396
|
+
for (const line of text2.trimEnd().split("\n")) {
|
|
71397
|
+
const applied = applyLogLine(line, assistantMessageId, state);
|
|
71398
|
+
if (applied === null) throw new Error("Invalid local transcript record");
|
|
71399
|
+
if (applied) ended = true;
|
|
71400
|
+
}
|
|
71401
|
+
return ended;
|
|
71402
|
+
}
|
|
71403
|
+
async function openLocalTurnProjection(runsDir, runId, conversationId, ordinal) {
|
|
71404
|
+
const paths = runDirectory(runsDir, runId);
|
|
71405
|
+
const meta3 = await readRunMeta(paths.meta);
|
|
71406
|
+
if (!meta3?.userMessage || !meta3.assistantMessage || meta3.conversationId !== conversationId || meta3.userMessage.turnOrdinal !== ordinal)
|
|
71407
|
+
return null;
|
|
71408
|
+
const assistantMessageId = meta3.assistantMessage.id;
|
|
71409
|
+
const state = emptyTranscript();
|
|
71410
|
+
const promptAt = Date.parse(meta3.userMessage.createdAt);
|
|
71411
|
+
applySessionEvent(state, {
|
|
71412
|
+
seq: 0,
|
|
71413
|
+
at: Number.isFinite(promptAt) ? promptAt : 0,
|
|
71414
|
+
update: {
|
|
71415
|
+
sessionUpdate: "user_message",
|
|
71416
|
+
messageId: meta3.userMessage.id,
|
|
71417
|
+
content: [{ type: "text", text: meta3.userMessage.content }],
|
|
71418
|
+
_meta: {
|
|
71419
|
+
...meta3.userMessage.clientMessageId ? { "alan.dev/clientMessageId": meta3.userMessage.clientMessageId } : {},
|
|
71420
|
+
...meta3.agentMode ? { "alan.dev/agentMode": meta3.agentMode } : {},
|
|
71421
|
+
...meta3.userMessage.attachmentIds?.length ? { "alan.dev/attachmentIds": meta3.userMessage.attachmentIds } : {}
|
|
71422
|
+
}
|
|
71423
|
+
}
|
|
71424
|
+
});
|
|
71425
|
+
const reader = await openRunLogReader(paths.log).catch((error61) => {
|
|
71426
|
+
if (error61.code === "ENOENT") return null;
|
|
71427
|
+
throw error61;
|
|
71428
|
+
});
|
|
71429
|
+
if (!reader) return null;
|
|
71430
|
+
let offset = toByteOffset(0);
|
|
71431
|
+
let ended = false;
|
|
71432
|
+
let snapshot2;
|
|
71433
|
+
let prepared;
|
|
71434
|
+
const merge2 = /* @__PURE__ */ new Map();
|
|
71435
|
+
const decoder3 = new TextDecoder();
|
|
71436
|
+
const readState = async () => {
|
|
71437
|
+
const priorOffset = offset;
|
|
71438
|
+
for (; ; ) {
|
|
71439
|
+
const chunk = await reader.readFrom(offset, DEFAULT_RUN_LOG_LIMIT);
|
|
71440
|
+
if (chunk.bytes.length === 0) break;
|
|
71441
|
+
if (applyLogChunk(decoder3.decode(chunk.bytes), assistantMessageId, state)) ended = true;
|
|
71442
|
+
offset = chunk.to;
|
|
71443
|
+
}
|
|
71444
|
+
if (offset === priorOffset && snapshot2) return snapshot2;
|
|
71445
|
+
if (ended) state.state = "idle";
|
|
71446
|
+
snapshot2 = mergeTranscriptMessages(
|
|
71447
|
+
[{ messageId: assistantMessageId, turnOrdinal: ordinal, role: "assistant", state }],
|
|
71448
|
+
merge2
|
|
71449
|
+
);
|
|
71450
|
+
return snapshot2;
|
|
71451
|
+
};
|
|
71452
|
+
return {
|
|
71453
|
+
runId,
|
|
71454
|
+
ordinal,
|
|
71455
|
+
readState,
|
|
71456
|
+
read: async () => {
|
|
71457
|
+
const current = await readState();
|
|
71458
|
+
if (prepared?.state !== current)
|
|
71459
|
+
prepared = { ...conversationTurnView(ordinal, current, prepared?.display), markdown: "" };
|
|
71460
|
+
return prepared;
|
|
71461
|
+
},
|
|
71462
|
+
[Symbol.asyncDispose]: async () => {
|
|
71463
|
+
await reader[Symbol.asyncDispose]();
|
|
71464
|
+
}
|
|
71465
|
+
};
|
|
71466
|
+
}
|
|
71467
|
+
async function projectLocalRun(runsDir, runId, conversationId, ordinal) {
|
|
71468
|
+
var _stack = [];
|
|
71469
|
+
try {
|
|
71470
|
+
const projection = __using(_stack, await openLocalTurnProjection(runsDir, runId, conversationId, ordinal), true);
|
|
71471
|
+
return projection ? await projection.read() : null;
|
|
71472
|
+
} catch (_) {
|
|
71473
|
+
var _error = _, _hasError = true;
|
|
71474
|
+
} finally {
|
|
71475
|
+
var _promise2 = __callDispose(_stack, _error, _hasError);
|
|
71476
|
+
_promise2 && await _promise2;
|
|
71477
|
+
}
|
|
71478
|
+
}
|
|
71479
|
+
async function readLocalConversationMessages(runsDir, conversationId, limit, before, projection) {
|
|
71480
|
+
const coverage = await readConversationIndexCoverage(runsDir, conversationId);
|
|
71481
|
+
if (coverage === null || before !== void 0 && before <= coverage.lowestOrdinal) return null;
|
|
71482
|
+
const indexed = (await readConversationRunIndex(runsDir, conversationId, before, limit + 1)).filter((entry) => entry.ordinal >= coverage.lowestOrdinal);
|
|
71483
|
+
if (before === void 0 && indexed[0]?.ordinal !== coverage.highestOrdinal) return null;
|
|
71484
|
+
if (before !== void 0 && indexed[0]?.nextOrdinal !== before) return null;
|
|
71485
|
+
if (indexed.some((entry, index) => index > 0 && entry.nextOrdinal !== indexed[index - 1].ordinal))
|
|
71486
|
+
return null;
|
|
71487
|
+
if (indexed.length < limit && indexed.at(-1)?.ordinal !== coverage.lowestOrdinal) return null;
|
|
71488
|
+
const selected = indexed.slice(0, limit);
|
|
71489
|
+
if (selected.length === 0) return null;
|
|
71490
|
+
const turns = await Promise.all(
|
|
71491
|
+
selected.map(
|
|
71492
|
+
(entry) => entry.runId === projection?.runId ? projection.read() : projectLocalRun(runsDir, entry.runId, conversationId, entry.ordinal)
|
|
71493
|
+
)
|
|
71494
|
+
);
|
|
71495
|
+
if (turns.some((turn) => turn === null)) return null;
|
|
71496
|
+
const completeTurns = turns.filter((turn) => turn !== null);
|
|
71497
|
+
return {
|
|
71498
|
+
turns: compactConversationMessageTurns(completeTurns, before === void 0),
|
|
71499
|
+
before: selected.at(-1)?.ordinal === 0 ? null : String(selected.at(-1)?.ordinal),
|
|
71500
|
+
revision: `local-${selected[0].runId}`,
|
|
71501
|
+
streamCursor: ""
|
|
71502
|
+
};
|
|
71503
|
+
}
|
|
71504
|
+
|
|
71505
|
+
// src/local-api/conversation-messages-stream.ts
|
|
71506
|
+
init_acp();
|
|
71507
|
+
async function readChangedTurn(deps, conversationId, runId, slot) {
|
|
71508
|
+
const meta3 = await readRunMeta(runDirectory(deps.runsDir, runId).meta);
|
|
71509
|
+
if (meta3?.conversationId !== conversationId || meta3.userMessage?.turnOrdinal == null) return null;
|
|
71510
|
+
if (slot.current?.ordinal === meta3.userMessage.turnOrdinal && slot.current.runId !== runId) {
|
|
71511
|
+
const [latest] = await readConversationRunIndex(
|
|
71512
|
+
deps.runsDir,
|
|
71513
|
+
conversationId,
|
|
71514
|
+
meta3.userMessage.turnOrdinal + 1,
|
|
71515
|
+
1
|
|
71516
|
+
);
|
|
71517
|
+
if (latest?.runId !== runId) return null;
|
|
71518
|
+
}
|
|
71519
|
+
if (slot.current && meta3.userMessage.turnOrdinal < slot.current.ordinal) {
|
|
71520
|
+
const previous = await openLocalTurnProjection(
|
|
71521
|
+
deps.runsDir,
|
|
71522
|
+
runId,
|
|
71523
|
+
conversationId,
|
|
71524
|
+
meta3.userMessage.turnOrdinal
|
|
71525
|
+
);
|
|
71526
|
+
if (!previous) return null;
|
|
71527
|
+
return {
|
|
71528
|
+
projection: previous,
|
|
71529
|
+
changed: { ordinal: previous.ordinal, state: await previous.readState() }
|
|
71530
|
+
};
|
|
71531
|
+
}
|
|
71532
|
+
if (slot.current?.runId !== runId) {
|
|
71533
|
+
const next = await openLocalTurnProjection(
|
|
71534
|
+
deps.runsDir,
|
|
71535
|
+
runId,
|
|
71536
|
+
conversationId,
|
|
71537
|
+
meta3.userMessage.turnOrdinal
|
|
71538
|
+
);
|
|
71539
|
+
await slot.current?.[Symbol.asyncDispose]();
|
|
71540
|
+
slot.current = next;
|
|
71541
|
+
}
|
|
71542
|
+
if (!slot.current) throw new Error("Local transcript metadata is incomplete");
|
|
71543
|
+
return {
|
|
71544
|
+
projection: slot.current,
|
|
71545
|
+
changed: { ordinal: slot.current.ordinal, state: await slot.current.readState() }
|
|
71546
|
+
};
|
|
71547
|
+
}
|
|
71548
|
+
async function nextChangedRuns(bell, signal) {
|
|
71549
|
+
if (bell.pending.size === 0) {
|
|
71550
|
+
await new Promise((resolve12) => {
|
|
71551
|
+
bell.wake = resolve12;
|
|
71552
|
+
if (signal.aborted || bell.pending.size > 0) resolve12();
|
|
71553
|
+
});
|
|
71554
|
+
bell.wake = void 0;
|
|
71555
|
+
}
|
|
71556
|
+
if (signal.aborted) return [];
|
|
71557
|
+
await systemClock.sleep(50, signal);
|
|
71558
|
+
const changed = [...bell.pending];
|
|
71559
|
+
bell.pending.clear();
|
|
71560
|
+
return changed;
|
|
71561
|
+
}
|
|
71562
|
+
async function writeChangedTurn(writer, runId, read) {
|
|
71563
|
+
const { ordinal, state } = read.changed;
|
|
71564
|
+
if (state === writer.lastState) return;
|
|
71565
|
+
writer.lastState = state;
|
|
71566
|
+
const patch = writer.frames === "patch";
|
|
71567
|
+
const data = patch ? JSON.stringify(writer.encode(ordinal, state)) : JSON.stringify(await read.projection.read());
|
|
71568
|
+
await writeEvent(writer.res, {
|
|
71569
|
+
name: patch ? LIVE_TURN_EVENT : "turn",
|
|
71570
|
+
id: `${runId}`,
|
|
71571
|
+
dataLines: [data]
|
|
71572
|
+
});
|
|
71573
|
+
}
|
|
71574
|
+
async function streamLocalConversationMessages(deps, conversationId, limit, frames, res, signal) {
|
|
71575
|
+
var _stack = [];
|
|
71576
|
+
try {
|
|
71577
|
+
const bell = { pending: /* @__PURE__ */ new Set(), wake: void 0 };
|
|
71578
|
+
const slot = { current: null };
|
|
71579
|
+
const _subscription = __using(_stack, deps.appends.subscribe((runId) => {
|
|
71580
|
+
const changed = runId ?? slot.current?.runId;
|
|
71581
|
+
if (changed) bell.pending.add(changed);
|
|
71582
|
+
bell.wake?.();
|
|
71583
|
+
}));
|
|
71584
|
+
signal.addEventListener("abort", () => bell.wake?.(), { once: true });
|
|
71585
|
+
try {
|
|
71586
|
+
const [newest] = await readConversationRunIndex(deps.runsDir, conversationId, void 0, 1);
|
|
71587
|
+
if (newest)
|
|
71588
|
+
slot.current = await openLocalTurnProjection(
|
|
71589
|
+
deps.runsDir,
|
|
71590
|
+
newest.runId,
|
|
71591
|
+
conversationId,
|
|
71592
|
+
newest.ordinal
|
|
71593
|
+
);
|
|
71594
|
+
const writer = {
|
|
71595
|
+
frames,
|
|
71596
|
+
encode: createLiveTurnFrameEncoder(),
|
|
71597
|
+
res,
|
|
71598
|
+
lastState: await slot.current?.readState()
|
|
71599
|
+
};
|
|
71600
|
+
const page = await readLocalConversationMessages(
|
|
71601
|
+
deps.runsDir,
|
|
71602
|
+
conversationId,
|
|
71603
|
+
limit,
|
|
71604
|
+
void 0,
|
|
71605
|
+
slot.current ?? void 0
|
|
71606
|
+
);
|
|
71607
|
+
if (!page) {
|
|
71608
|
+
sendError(res, 404, "not_found", "This computer has no complete local page");
|
|
71609
|
+
return;
|
|
71610
|
+
}
|
|
71611
|
+
startEventStream(res);
|
|
71612
|
+
await writeEvent(res, {
|
|
71613
|
+
name: "snapshot",
|
|
71614
|
+
id: page.revision,
|
|
71615
|
+
dataLines: [JSON.stringify(page)]
|
|
71616
|
+
});
|
|
71617
|
+
while (!signal.aborted) {
|
|
71618
|
+
for (const runId of await nextChangedRuns(bell, signal)) {
|
|
71619
|
+
const read = await readChangedTurn(deps, conversationId, runId, slot);
|
|
71620
|
+
if (!read) continue;
|
|
71621
|
+
try {
|
|
71622
|
+
await writeChangedTurn(writer, runId, read);
|
|
71623
|
+
} finally {
|
|
71624
|
+
if (read.projection !== slot.current) await read.projection[Symbol.asyncDispose]();
|
|
71625
|
+
}
|
|
71626
|
+
}
|
|
71627
|
+
}
|
|
71628
|
+
} finally {
|
|
71629
|
+
await slot.current?.[Symbol.asyncDispose]();
|
|
71630
|
+
}
|
|
71631
|
+
} catch (_) {
|
|
71632
|
+
var _error = _, _hasError = true;
|
|
71633
|
+
} finally {
|
|
71634
|
+
__callDispose(_stack, _error, _hasError);
|
|
71635
|
+
}
|
|
71636
|
+
}
|
|
71637
|
+
|
|
69838
71638
|
// src/local-api/request.ts
|
|
69839
71639
|
async function readBody3(request2, schema) {
|
|
69840
71640
|
const body = await readJsonBody(request2.req);
|
|
@@ -70033,6 +71833,13 @@ async function followRunLogRoute(deps, runId, url3, res, signal) {
|
|
|
70033
71833
|
|
|
70034
71834
|
// src/local-api/routes.ts
|
|
70035
71835
|
var RUN_PATH = /^\/v2\/runs\/([^/]+)\/(log|log\/stream|abort)$/;
|
|
71836
|
+
var CONVERSATION_MESSAGES_PATH = /^\/v2\/conversations\/([^/]+)\/messages(\/sse)?$/;
|
|
71837
|
+
var conversationMessagesQuerySchema = external_exports.object({
|
|
71838
|
+
limit: external_exports.coerce.number().int().min(1).max(100).default(10),
|
|
71839
|
+
before: external_exports.coerce.number().int().nonnegative().optional(),
|
|
71840
|
+
runtimeId: external_exports.string().uuid().optional(),
|
|
71841
|
+
frames: external_exports.enum(["turn", "patch"]).default("turn")
|
|
71842
|
+
});
|
|
70036
71843
|
var emptyBodySchema = external_exports.object({});
|
|
70037
71844
|
function activeRunIds(runs) {
|
|
70038
71845
|
return runs.filter((run2) => run2.state !== "ended").map((run2) => run2.runId);
|
|
@@ -70252,6 +72059,44 @@ var FIXED_ROUTES = new Map([
|
|
|
70252
72059
|
[LOCAL_API_ROUTES.providerExternal, { method: "POST", handle: providerExternal }],
|
|
70253
72060
|
...machineFeatureRoutes
|
|
70254
72061
|
]);
|
|
72062
|
+
async function routeConversationMessages(deps, request2, conversationMatch) {
|
|
72063
|
+
if (request2.req.method !== "GET") {
|
|
72064
|
+
sendError(request2.res, 405, "method_not_allowed", "Use GET");
|
|
72065
|
+
return;
|
|
72066
|
+
}
|
|
72067
|
+
const conversationId = conversationIdSchema.safeParse(conversationMatch[1]);
|
|
72068
|
+
const query = conversationMessagesQuerySchema.safeParse(
|
|
72069
|
+
Object.fromEntries(request2.url.searchParams)
|
|
72070
|
+
);
|
|
72071
|
+
if (!conversationId.success || !query.success) {
|
|
72072
|
+
sendError(request2.res, 400, "invalid_request", "Invalid conversation messages request");
|
|
72073
|
+
return;
|
|
72074
|
+
}
|
|
72075
|
+
if (query.data.runtimeId && query.data.runtimeId !== deps.readFacts().machineId) {
|
|
72076
|
+
sendError(request2.res, 404, "not_found", "This conversation runs on another computer");
|
|
72077
|
+
return;
|
|
72078
|
+
}
|
|
72079
|
+
if (conversationMatch[2])
|
|
72080
|
+
return streamLocalConversationMessages(
|
|
72081
|
+
deps,
|
|
72082
|
+
conversationId.data,
|
|
72083
|
+
query.data.limit,
|
|
72084
|
+
query.data.frames,
|
|
72085
|
+
request2.res,
|
|
72086
|
+
request2.signal
|
|
72087
|
+
);
|
|
72088
|
+
const page = await readLocalConversationMessages(
|
|
72089
|
+
deps.runsDir,
|
|
72090
|
+
conversationId.data,
|
|
72091
|
+
query.data.limit,
|
|
72092
|
+
query.data.before
|
|
72093
|
+
);
|
|
72094
|
+
if (page === null) {
|
|
72095
|
+
sendError(request2.res, 404, "not_found", "This computer has no complete local page");
|
|
72096
|
+
return;
|
|
72097
|
+
}
|
|
72098
|
+
sendJson(request2.res, 200, page);
|
|
72099
|
+
}
|
|
70255
72100
|
async function routeRun(deps, request2, match) {
|
|
70256
72101
|
const runId = runIdSchema.safeParse(match[1]);
|
|
70257
72102
|
const action = match[2];
|
|
@@ -70279,6 +72124,9 @@ async function route(deps, request2) {
|
|
|
70279
72124
|
}
|
|
70280
72125
|
const match = RUN_PATH.exec(request2.url.pathname);
|
|
70281
72126
|
if (match !== null) return routeRun(deps, request2, match);
|
|
72127
|
+
const conversationMatch = CONVERSATION_MESSAGES_PATH.exec(request2.url.pathname);
|
|
72128
|
+
if (conversationMatch !== null)
|
|
72129
|
+
return routeConversationMessages(deps, request2, conversationMatch);
|
|
70282
72130
|
sendError(request2.res, 404, "not_found", "Not found");
|
|
70283
72131
|
}
|
|
70284
72132
|
|
|
@@ -70328,6 +72176,15 @@ var REQUEST_TIMEOUT_MS8 = 1e4;
|
|
|
70328
72176
|
var KEEP_ALIVE_TIMEOUT_MS = 2e3;
|
|
70329
72177
|
var ACTION_TIMEOUT_MS = 3e4;
|
|
70330
72178
|
var PROVIDER_INSTALL_TIMEOUT_MS = 10 * 6e4;
|
|
72179
|
+
function localRequestSignal(path4, closed) {
|
|
72180
|
+
if (path4.endsWith("/stream") || path4.endsWith("/sse")) return closed;
|
|
72181
|
+
return AbortSignal.any([
|
|
72182
|
+
closed,
|
|
72183
|
+
AbortSignal.timeout(
|
|
72184
|
+
path4 === LOCAL_API_ROUTES.providerInstall ? PROVIDER_INSTALL_TIMEOUT_MS : ACTION_TIMEOUT_MS
|
|
72185
|
+
)
|
|
72186
|
+
]);
|
|
72187
|
+
}
|
|
70331
72188
|
async function listenOnLoopback(server) {
|
|
70332
72189
|
await new Promise((resolve12, reject) => {
|
|
70333
72190
|
server.once("error", reject);
|
|
@@ -70372,11 +72229,12 @@ async function serveLocalApi(deps) {
|
|
|
70372
72229
|
server.keepAliveTimeout = KEEP_ALIVE_TIMEOUT_MS;
|
|
70373
72230
|
server.maxConnections = HARD_MAX_CONNECTIONS;
|
|
70374
72231
|
const port = await listenOnLoopback(server);
|
|
70375
|
-
const token = (0,
|
|
72232
|
+
const token = (0, import_node_crypto34.randomBytes)(32).toString("base64url");
|
|
70376
72233
|
const guard = createRequestGuard({ token, port, rateLimit: limits.rateLimit, clock });
|
|
70377
72234
|
const appAttachments = createAppAttachments(clock);
|
|
70378
72235
|
const routeDeps = {
|
|
70379
72236
|
feed,
|
|
72237
|
+
readFacts: deps.readFacts,
|
|
70380
72238
|
appAttachments,
|
|
70381
72239
|
actions: deps.actions,
|
|
70382
72240
|
runsDir: deps.runsDir,
|
|
@@ -70398,15 +72256,11 @@ async function serveLocalApi(deps) {
|
|
|
70398
72256
|
inFlight += 1;
|
|
70399
72257
|
const url3 = new URL(req.url ?? "/", `http://127.0.0.1:${port}`);
|
|
70400
72258
|
const closed = requestSignal(res);
|
|
70401
|
-
const signal = url3.pathname
|
|
70402
|
-
closed,
|
|
70403
|
-
AbortSignal.timeout(
|
|
70404
|
-
url3.pathname === LOCAL_API_ROUTES.providerInstall ? PROVIDER_INSTALL_TIMEOUT_MS : ACTION_TIMEOUT_MS
|
|
70405
|
-
)
|
|
70406
|
-
]);
|
|
72259
|
+
const signal = localRequestSignal(url3.pathname, closed);
|
|
70407
72260
|
try {
|
|
70408
72261
|
await route(routeDeps, { req, res, url: url3, signal });
|
|
70409
72262
|
} catch (error61) {
|
|
72263
|
+
if (closed.aborted) return;
|
|
70410
72264
|
log.warn("local_api.request_failed", { path: url3.pathname, error: error61 });
|
|
70411
72265
|
sendError(res, 500, "internal", "The runtime could not complete the request");
|
|
70412
72266
|
} finally {
|
|
@@ -70422,7 +72276,7 @@ async function serveLocalApi(deps) {
|
|
|
70422
72276
|
startedAtMs,
|
|
70423
72277
|
runtimeVersion: deps.runtimeVersion
|
|
70424
72278
|
};
|
|
70425
|
-
const discoveryPath = (0,
|
|
72279
|
+
const discoveryPath = (0, import_node_path76.join)(deps.stateDir, LOCAL_API_DISCOVERY_FILE);
|
|
70426
72280
|
await writeJsonFileAtomic(discoveryPath, discovery);
|
|
70427
72281
|
const followers = startMaintenance({
|
|
70428
72282
|
everyMs: limits.refreshEveryMs,
|
|
@@ -70456,7 +72310,7 @@ async function serveLocalApi(deps) {
|
|
|
70456
72310
|
await watchedStatus[Symbol.asyncDispose]();
|
|
70457
72311
|
const current = await readJsonFile(discoveryPath, localApiDiscoverySchema);
|
|
70458
72312
|
if (current.kind === "ok" && current.value.token === token) {
|
|
70459
|
-
await (0,
|
|
72313
|
+
await (0, import_promises73.rm)(discoveryPath, { force: true });
|
|
70460
72314
|
}
|
|
70461
72315
|
await closeServer(server);
|
|
70462
72316
|
log.info("local_api.closed", {});
|
|
@@ -70541,7 +72395,7 @@ function machineFeatureActions(deps) {
|
|
|
70541
72395
|
}
|
|
70542
72396
|
|
|
70543
72397
|
// src/cli/commands/machine-plane.ts
|
|
70544
|
-
var
|
|
72398
|
+
var import_node_path78 = require("path");
|
|
70545
72399
|
|
|
70546
72400
|
// src/link/index.ts
|
|
70547
72401
|
init_runtime_v2();
|
|
@@ -74209,7 +76063,7 @@ function refusalFailure(refusal2) {
|
|
|
74209
76063
|
}
|
|
74210
76064
|
|
|
74211
76065
|
// src/link/probe.ts
|
|
74212
|
-
var
|
|
76066
|
+
var import_promises74 = require("dns/promises");
|
|
74213
76067
|
var import_node_net5 = require("net");
|
|
74214
76068
|
var import_node_tls2 = require("tls");
|
|
74215
76069
|
var PROBE_TIMEOUT_MS4 = 5e3;
|
|
@@ -74245,7 +76099,7 @@ async function connectOnce(url3, clock) {
|
|
|
74245
76099
|
}
|
|
74246
76100
|
async function probeEndpoint(url3, clock) {
|
|
74247
76101
|
try {
|
|
74248
|
-
await (0,
|
|
76102
|
+
await (0, import_promises74.lookup)(url3.hostname);
|
|
74249
76103
|
} catch (error61) {
|
|
74250
76104
|
const reason = classifyTransportFailure(error61);
|
|
74251
76105
|
return reason === "other" ? "dns" : reason;
|
|
@@ -74368,8 +76222,12 @@ function connectLink(options) {
|
|
|
74368
76222
|
const hello = await options.hello(connectEpoch);
|
|
74369
76223
|
const ack = await socket.timeout(HELLO_TIMEOUT_MS).emitWithAck("hello", hello);
|
|
74370
76224
|
await ready;
|
|
74371
|
-
if (connectEpoch !== epoch) return;
|
|
76225
|
+
if (connectEpoch !== epoch || !socket.connected) return;
|
|
74372
76226
|
options.onHelloAck(helloAckSchema.parse(ack), connectEpoch);
|
|
76227
|
+
retry.attempt = 0;
|
|
76228
|
+
retry.credentialFailures = 0;
|
|
76229
|
+
setState({ kind: "connected", epoch: connectEpoch });
|
|
76230
|
+
log.info("link.connected", { epoch: connectEpoch });
|
|
74373
76231
|
};
|
|
74374
76232
|
const setState = (next) => {
|
|
74375
76233
|
current = next;
|
|
@@ -74439,12 +76297,16 @@ function connectLink(options) {
|
|
|
74439
76297
|
};
|
|
74440
76298
|
socket.on("connect", () => {
|
|
74441
76299
|
epoch += 1;
|
|
74442
|
-
|
|
74443
|
-
retry.credentialFailures = 0;
|
|
76300
|
+
const connectEpoch = epoch;
|
|
74444
76301
|
cancelRedial();
|
|
74445
|
-
setState({ kind: "
|
|
74446
|
-
|
|
74447
|
-
|
|
76302
|
+
setState({ kind: "connecting", lastFailure: null });
|
|
76303
|
+
greet(connectEpoch).catch((error61) => {
|
|
76304
|
+
if (connectEpoch !== epoch || current.kind === "stopped" || !socket.connected) return;
|
|
76305
|
+
log.warn("link.hello_failed", { epoch: connectEpoch, error: error61 });
|
|
76306
|
+
recordTransportFailure("other", "The backend did not acknowledge this runtime");
|
|
76307
|
+
socket.disconnect();
|
|
76308
|
+
redialAfter(redialDelayMs(retry.attempt++));
|
|
76309
|
+
});
|
|
74448
76310
|
});
|
|
74449
76311
|
socket.on("disconnect", (reason) => {
|
|
74450
76312
|
log.info("link.disconnected", { reason });
|
|
@@ -74498,7 +76360,7 @@ function connectLink(options) {
|
|
|
74498
76360
|
void ready.then(() => answerModelsScan(raw, options.scanModels, log)).then((result) => ack(result));
|
|
74499
76361
|
});
|
|
74500
76362
|
const pushCapabilities = async (capabilities) => {
|
|
74501
|
-
if (!socket.connected) return false;
|
|
76363
|
+
if (current.kind !== "connected" || !socket.connected) return false;
|
|
74502
76364
|
try {
|
|
74503
76365
|
const ack = await socket.timeout(CAPABILITIES_ACK_TIMEOUT_MS).emitWithAck("capabilities", capabilities);
|
|
74504
76366
|
const parsed = capabilitiesAckSchema.safeParse(ack);
|
|
@@ -74547,9 +76409,9 @@ function planReconcile(desired, held) {
|
|
|
74547
76409
|
}
|
|
74548
76410
|
|
|
74549
76411
|
// src/reconciler/desired-sync.ts
|
|
74550
|
-
var
|
|
76412
|
+
var import_node_crypto35 = require("crypto");
|
|
74551
76413
|
function fingerprintOf(desired) {
|
|
74552
|
-
return (0,
|
|
76414
|
+
return (0, import_node_crypto35.createHash)("sha256").update(JSON.stringify(desired)).digest("hex");
|
|
74553
76415
|
}
|
|
74554
76416
|
var FAILED_READ_RETRY_MS = 3e4;
|
|
74555
76417
|
function createDesiredSync(deps) {
|
|
@@ -74686,7 +76548,7 @@ function createReconciler(host, lifecycle, log, signal) {
|
|
|
74686
76548
|
}
|
|
74687
76549
|
|
|
74688
76550
|
// src/uploader/index.ts
|
|
74689
|
-
var
|
|
76551
|
+
var import_promises75 = require("fs/promises");
|
|
74690
76552
|
init_runtime_v2();
|
|
74691
76553
|
init_zod();
|
|
74692
76554
|
var RETRY_DELAYS_MS = [250, 500, 1e3, 2e3, 5e3, 1e4, 3e4];
|
|
@@ -74717,12 +76579,15 @@ function startUploader({ api, runsDir, clock, log }) {
|
|
|
74717
76579
|
if (stored.kind === "ok") return stored.value;
|
|
74718
76580
|
const receipt = await api.readReceipt(target, controller.signal);
|
|
74719
76581
|
switch (receipt.kind) {
|
|
74720
|
-
case "read":
|
|
76582
|
+
case "read": {
|
|
74721
76583
|
log.debug("upload.resumed", {
|
|
74722
76584
|
runId,
|
|
74723
76585
|
admittedOffset: receipt.receipt?.admittedOffset ?? 0
|
|
74724
76586
|
});
|
|
74725
|
-
|
|
76587
|
+
const progress = progressFromReceipt(receipt.receipt);
|
|
76588
|
+
if (progress.sealed) await writeJsonFileAtomic(path4, progress);
|
|
76589
|
+
return progress;
|
|
76590
|
+
}
|
|
74726
76591
|
case "rejected":
|
|
74727
76592
|
await reject(runId, path4, progressFromReceipt(null), receipt);
|
|
74728
76593
|
return null;
|
|
@@ -74827,7 +76692,7 @@ function startUploader({ api, runsDir, clock, log }) {
|
|
|
74827
76692
|
active.set(runId, task);
|
|
74828
76693
|
};
|
|
74829
76694
|
const sweep2 = async () => {
|
|
74830
|
-
for (const name of await (0,
|
|
76695
|
+
for (const name of await (0, import_promises75.readdir)(runsDir).catch(() => [])) {
|
|
74831
76696
|
const runId = runIdSchema.safeParse(name);
|
|
74832
76697
|
if (runId.success) run2(runId.data);
|
|
74833
76698
|
}
|
|
@@ -74837,18 +76702,18 @@ function startUploader({ api, runsDir, clock, log }) {
|
|
|
74837
76702
|
const dir = runDirectory(runsDir, runId);
|
|
74838
76703
|
const progress = await readJsonFile(dir.upload, uploadProgressSchema);
|
|
74839
76704
|
if (progress.kind !== "ok" || !progress.value.sealed) return false;
|
|
74840
|
-
const sealedAt = (await (0,
|
|
76705
|
+
const sealedAt = (await (0, import_promises75.stat)(dir.upload)).mtimeMs;
|
|
74841
76706
|
if (clock.now() - sealedAt < options.sealedForMs) return false;
|
|
74842
76707
|
return (await readLastRecord(dir.log))?.update.sessionUpdate === "_alan/run.ended";
|
|
74843
76708
|
};
|
|
74844
76709
|
const prune = async (options) => {
|
|
74845
76710
|
let removed = 0;
|
|
74846
|
-
for (const name of await (0,
|
|
76711
|
+
for (const name of await (0, import_promises75.readdir)(runsDir).catch(() => [])) {
|
|
74847
76712
|
const runId = runIdSchema.safeParse(name);
|
|
74848
76713
|
if (!runId.success) continue;
|
|
74849
76714
|
try {
|
|
74850
76715
|
if (!await isPrunable(runId.data, options)) continue;
|
|
74851
|
-
await (0,
|
|
76716
|
+
await (0, import_promises75.rm)(runDirectory(runsDir, runId.data).dir, { recursive: true, force: true });
|
|
74852
76717
|
removed += 1;
|
|
74853
76718
|
} catch (error61) {
|
|
74854
76719
|
log.warn("upload.prune_failed", { runId: runId.data, error: error61 });
|
|
@@ -74972,6 +76837,28 @@ function unwrap(outcome2, what) {
|
|
|
74972
76837
|
outcome2.code
|
|
74973
76838
|
);
|
|
74974
76839
|
}
|
|
76840
|
+
async function writeNativeTurnRun(runsDir, run2, log) {
|
|
76841
|
+
const runId = runIdSchema.parse(run2.runId);
|
|
76842
|
+
const conversationId = conversationIdSchema.parse(run2.conversationId);
|
|
76843
|
+
const { userMessage, assistantMessage } = run2;
|
|
76844
|
+
await writeCompleteRunLog(
|
|
76845
|
+
runsDir,
|
|
76846
|
+
{ runId, conversationId, userMessage, assistantMessage },
|
|
76847
|
+
run2.records
|
|
76848
|
+
);
|
|
76849
|
+
if (userMessage?.turnOrdinal != null && assistantMessage?.turnOrdinal != null) {
|
|
76850
|
+
await indexConversationRun(
|
|
76851
|
+
runsDir,
|
|
76852
|
+
conversationId,
|
|
76853
|
+
userMessage.turnOrdinal,
|
|
76854
|
+
assistantMessage.turnOrdinal,
|
|
76855
|
+
runId
|
|
76856
|
+
).catch(
|
|
76857
|
+
(error61) => log.warn("native_ingest.conversation_index_failed", { runId, error: error61 })
|
|
76858
|
+
);
|
|
76859
|
+
}
|
|
76860
|
+
return runId;
|
|
76861
|
+
}
|
|
74975
76862
|
async function startMachineNativeIngest(deps) {
|
|
74976
76863
|
const client = createNativeSessionsClient({
|
|
74977
76864
|
apiUrl: deps.apiUrl,
|
|
@@ -74988,13 +76875,7 @@ async function startMachineNativeIngest(deps) {
|
|
|
74988
76875
|
api,
|
|
74989
76876
|
publisher: {
|
|
74990
76877
|
publish: async (run2) => {
|
|
74991
|
-
|
|
74992
|
-
await writeCompleteRunLog(
|
|
74993
|
-
deps.runsDir,
|
|
74994
|
-
{ runId, conversationId: conversationIdSchema.parse(run2.conversationId) },
|
|
74995
|
-
run2.records
|
|
74996
|
-
);
|
|
74997
|
-
deps.onPublished(runId);
|
|
76878
|
+
deps.onPublished(await writeNativeTurnRun(deps.runsDir, run2, deps.log));
|
|
74998
76879
|
}
|
|
74999
76880
|
},
|
|
75000
76881
|
clock: deps.clock,
|
|
@@ -75030,12 +76911,12 @@ async function startMachineNativeIngest(deps) {
|
|
|
75030
76911
|
}
|
|
75031
76912
|
|
|
75032
76913
|
// src/cli/commands/run-updates.ts
|
|
75033
|
-
var
|
|
76914
|
+
var import_node_path77 = require("path");
|
|
75034
76915
|
init_runtime_v2();
|
|
75035
76916
|
var UPDATE_CHECK_EVERY_MS = 6 * 60 * 60 * 1e3;
|
|
75036
76917
|
var DEFERRED_RETRY_MS = 5 * 60 * 1e3;
|
|
75037
76918
|
function isInstalledBundle(layout, bundlePath) {
|
|
75038
|
-
return (0,
|
|
76919
|
+
return (0, import_node_path77.resolve)((0, import_node_path77.dirname)((0, import_node_path77.dirname)(bundlePath))) === (0, import_node_path77.resolve)(layout.versions);
|
|
75039
76920
|
}
|
|
75040
76921
|
async function settleUpgradeOnStart({
|
|
75041
76922
|
layout,
|
|
@@ -75142,7 +77023,7 @@ function startRuntimeUpdates(options) {
|
|
|
75142
77023
|
layout,
|
|
75143
77024
|
release: npmRelease,
|
|
75144
77025
|
tarball: await options.downloader.download(npmRelease.dist.tarball, signal),
|
|
75145
|
-
tmpDir: (0,
|
|
77026
|
+
tmpDir: (0, import_node_path77.join)(layout.root, ".downloads")
|
|
75146
77027
|
});
|
|
75147
77028
|
await lifecycle.exclusive("upgrade", async () => {
|
|
75148
77029
|
await recordPendingUpgrade(layout, currentVersion2, version2, clock.now());
|
|
@@ -75367,7 +77248,7 @@ async function startMachinePlane(deps) {
|
|
|
75367
77248
|
[ALAN_MANAGED_SESSION_ENV]: "1"
|
|
75368
77249
|
},
|
|
75369
77250
|
cwd: paths.stateDir,
|
|
75370
|
-
outputPath: (0,
|
|
77251
|
+
outputPath: (0, import_node_path78.join)(paths.logs, "holders.log")
|
|
75371
77252
|
},
|
|
75372
77253
|
deps.holderIsolation
|
|
75373
77254
|
);
|
|
@@ -75598,7 +77479,7 @@ async function startMachinePlane(deps) {
|
|
|
75598
77479
|
git: createGitRunner({ env: cliEnvironment }),
|
|
75599
77480
|
clock,
|
|
75600
77481
|
log,
|
|
75601
|
-
dir: (0,
|
|
77482
|
+
dir: (0, import_node_path78.join)(paths.stateDir, "checkout-freshness")
|
|
75602
77483
|
},
|
|
75603
77484
|
stopped.signal
|
|
75604
77485
|
);
|
|
@@ -75892,23 +77773,28 @@ function lockWaitMs(argv) {
|
|
|
75892
77773
|
}
|
|
75893
77774
|
async function openManagedProviders(config2, paths) {
|
|
75894
77775
|
const providerEnv = readCliEnvironment();
|
|
75895
|
-
const
|
|
75896
|
-
const
|
|
77776
|
+
const bundledNpm = (0, import_node_path79.join)((0, import_node_path79.dirname)(process.execPath), "npm", "bin", "npm-cli.js");
|
|
77777
|
+
const providerToolchain = config2.providerToolchain ?? (process.platform === "win32" && (0, import_node_fs23.existsSync)(bundledNpm) ? { node: process.execPath, npmCli: bundledNpm } : null);
|
|
77778
|
+
const npmPath = providerToolchain?.node ?? await resolveCommandOnPath("npm", providerEnv, process.platform);
|
|
77779
|
+
const npmOptions = npmPath === null || process.platform === "win32" && providerToolchain === null ? null : {
|
|
75897
77780
|
command: npmPath,
|
|
75898
|
-
...
|
|
77781
|
+
...providerToolchain === null ? {} : { argsBeforeNpm: [providerToolchain.npmCli] },
|
|
75899
77782
|
env: providerEnv
|
|
75900
77783
|
};
|
|
75901
|
-
const providerNodeDir =
|
|
75902
|
-
const
|
|
77784
|
+
const providerNodeDir = providerToolchain?.node === void 0 ? void 0 : (0, import_node_path79.dirname)(providerToolchain.node);
|
|
77785
|
+
const probeEnv = providerNodeDir === void 0 ? providerEnv : {
|
|
77786
|
+
...providerEnv,
|
|
77787
|
+
PATH: `${providerNodeDir}${pathDelimiter(process.platform)}${envValue(providerEnv, "PATH")}`
|
|
77788
|
+
};
|
|
77789
|
+
const canonicalProbeEnv = process.platform === "win32" ? canonicalWindowsEnvironment(probeEnv) : probeEnv;
|
|
77790
|
+
const unavailable = async () => {
|
|
77791
|
+
throw new Error("Provider installer is unavailable on this computer");
|
|
77792
|
+
};
|
|
75903
77793
|
const managed = createManagedProviderClis({
|
|
75904
|
-
root: (0,
|
|
75905
|
-
resolveVersion: npmOptions === null ?
|
|
75906
|
-
|
|
75907
|
-
|
|
75908
|
-
installPackage: npmOptions === null ? async () => {
|
|
75909
|
-
throw new Error("Provider installer is unavailable on this computer");
|
|
75910
|
-
} : createNpmPackageInstaller(npmOptions),
|
|
75911
|
-
probe: (executable, backendKind) => probeManagedProvider(executable, backendKind, providerProbeEnv)
|
|
77794
|
+
root: (0, import_node_path79.join)(paths.stateDir, "provider-clis"),
|
|
77795
|
+
resolveVersion: npmOptions === null ? unavailable : createNpmVersionResolver(npmOptions),
|
|
77796
|
+
installPackage: npmOptions === null ? unavailable : createNpmPackageInstaller(npmOptions),
|
|
77797
|
+
probe: (executable, backendKind) => probeManagedProvider(executable, backendKind, canonicalProbeEnv)
|
|
75912
77798
|
});
|
|
75913
77799
|
await managed.load();
|
|
75914
77800
|
return { managed, providerNodeDir };
|
|
@@ -75937,7 +77823,7 @@ async function runService(argv, stop, restart = new AbortController().signal) {
|
|
|
75937
77823
|
waitMs: lockWaitMs(argv),
|
|
75938
77824
|
signal: stop
|
|
75939
77825
|
}));
|
|
75940
|
-
const log = __using(_stack, openFileLog((0,
|
|
77826
|
+
const log = __using(_stack, openFileLog((0, import_node_path79.join)(paths.logs, "runtime.jsonl"), config2.logLevel, clock));
|
|
75941
77827
|
const lifecycle = createLifecycleQueue({ clock, log });
|
|
75942
77828
|
const install2 = installLayout(config2.installDir, config2.profile);
|
|
75943
77829
|
const bundlePath = process.argv[1] ?? "";
|
|
@@ -75971,7 +77857,7 @@ async function runService(argv, stop, restart = new AbortController().signal) {
|
|
|
75971
77857
|
openCliEnvironment({
|
|
75972
77858
|
env: readCliEnvironment(),
|
|
75973
77859
|
platform: process.platform,
|
|
75974
|
-
lastKnownGoodFile: (0,
|
|
77860
|
+
lastKnownGoodFile: (0, import_node_path79.join)(paths.stateDir, "login-path.json"),
|
|
75975
77861
|
clock,
|
|
75976
77862
|
decorate: (env) => withPackagedAlanCodeEngine(env, bundlePath, process.platform)
|
|
75977
77863
|
})
|
|
@@ -76148,17 +78034,17 @@ async function runServiceCommand(argv, ctx = cliContext()) {
|
|
|
76148
78034
|
}
|
|
76149
78035
|
|
|
76150
78036
|
// src/cli/commands/upgrade.ts
|
|
76151
|
-
var
|
|
76152
|
-
var
|
|
78037
|
+
var import_promises76 = require("fs/promises");
|
|
78038
|
+
var import_node_path80 = require("path");
|
|
76153
78039
|
function isNotNewer(version2, installed) {
|
|
76154
78040
|
return installed !== null && isReleaseVersion(version2) && isReleaseVersion(installed) && compareVersions(version2, installed) <= 0;
|
|
76155
78041
|
}
|
|
76156
78042
|
async function installFromSource(source) {
|
|
76157
78043
|
const { layout, from, ifNewer } = source;
|
|
76158
|
-
const isTarball = (await (0,
|
|
76159
|
-
const downloads = (0,
|
|
76160
|
-
if (isTarball) await (0,
|
|
76161
|
-
const scratch = isTarball ? await (0,
|
|
78044
|
+
const isTarball = (await (0, import_promises76.stat)(from)).isFile();
|
|
78045
|
+
const downloads = (0, import_node_path80.join)(layout.root, ".downloads");
|
|
78046
|
+
if (isTarball) await (0, import_promises76.mkdir)(downloads, { recursive: true, mode: 448 });
|
|
78047
|
+
const scratch = isTarball ? await (0, import_promises76.mkdtemp)((0, import_node_path80.join)(downloads, "upgrade-")) : null;
|
|
76162
78048
|
try {
|
|
76163
78049
|
const sourceDir = scratch === null ? from : await extractPackageTarball(from, scratch);
|
|
76164
78050
|
const version2 = await readPackageVersion(sourceDir);
|
|
@@ -76166,7 +78052,7 @@ async function installFromSource(source) {
|
|
|
76166
78052
|
if (ifNewer && isNotNewer(version2, installed)) return { kind: "skipped", version: version2, installed };
|
|
76167
78053
|
return { kind: "installed", ...await installVersion(layout, sourceDir) };
|
|
76168
78054
|
} finally {
|
|
76169
|
-
if (scratch !== null) await (0,
|
|
78055
|
+
if (scratch !== null) await (0, import_promises76.rm)(scratch, { recursive: true, force: true });
|
|
76170
78056
|
}
|
|
76171
78057
|
}
|
|
76172
78058
|
async function runUpgrade(argv) {
|
|
@@ -76178,7 +78064,7 @@ async function runUpgrade(argv) {
|
|
|
76178
78064
|
const layout = installLayout(config2.installDir, config2.profile);
|
|
76179
78065
|
const outcome2 = await installFromSource({
|
|
76180
78066
|
layout,
|
|
76181
|
-
from: (0,
|
|
78067
|
+
from: (0, import_node_path80.resolve)(from),
|
|
76182
78068
|
ifNewer: hasFlag(argv, "--if-newer")
|
|
76183
78069
|
});
|
|
76184
78070
|
if (outcome2.kind === "skipped") {
|