@aiden-ade/sandbox-agent 0.1.53 → 0.1.55
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/dist/index.cjs +1457 -690
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -7761,7 +7761,7 @@ var require_compile = __commonJS({
|
|
|
7761
7761
|
const schOrFunc = root.refs[ref];
|
|
7762
7762
|
if (schOrFunc)
|
|
7763
7763
|
return schOrFunc;
|
|
7764
|
-
let _sch =
|
|
7764
|
+
let _sch = resolve9.call(this, root, ref);
|
|
7765
7765
|
if (_sch === void 0) {
|
|
7766
7766
|
const schema = (_a2 = root.localRefs) === null || _a2 === void 0 ? void 0 : _a2[ref];
|
|
7767
7767
|
const { schemaId } = this.opts;
|
|
@@ -7788,7 +7788,7 @@ var require_compile = __commonJS({
|
|
|
7788
7788
|
function sameSchemaEnv(s1, s2) {
|
|
7789
7789
|
return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId;
|
|
7790
7790
|
}
|
|
7791
|
-
function
|
|
7791
|
+
function resolve9(root, ref) {
|
|
7792
7792
|
let sch;
|
|
7793
7793
|
while (typeof (sch = this.refs[ref]) == "string")
|
|
7794
7794
|
ref = sch;
|
|
@@ -8419,55 +8419,55 @@ var require_fast_uri = __commonJS({
|
|
|
8419
8419
|
}
|
|
8420
8420
|
return uri;
|
|
8421
8421
|
}
|
|
8422
|
-
function
|
|
8422
|
+
function resolve9(baseURI, relativeURI, options) {
|
|
8423
8423
|
const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
|
|
8424
8424
|
const resolved = resolveComponent(parse6(baseURI, schemelessOptions), parse6(relativeURI, schemelessOptions), schemelessOptions, true);
|
|
8425
8425
|
schemelessOptions.skipEscape = true;
|
|
8426
8426
|
return serialize(resolved, schemelessOptions);
|
|
8427
8427
|
}
|
|
8428
|
-
function resolveComponent(base,
|
|
8428
|
+
function resolveComponent(base, relative4, options, skipNormalization) {
|
|
8429
8429
|
const target = {};
|
|
8430
8430
|
if (!skipNormalization) {
|
|
8431
8431
|
base = parse6(serialize(base, options), options);
|
|
8432
|
-
|
|
8432
|
+
relative4 = parse6(serialize(relative4, options), options);
|
|
8433
8433
|
}
|
|
8434
8434
|
options = options || {};
|
|
8435
|
-
if (!options.tolerant &&
|
|
8436
|
-
target.scheme =
|
|
8437
|
-
target.userinfo =
|
|
8438
|
-
target.host =
|
|
8439
|
-
target.port =
|
|
8440
|
-
target.path = removeDotSegments(
|
|
8441
|
-
target.query =
|
|
8435
|
+
if (!options.tolerant && relative4.scheme) {
|
|
8436
|
+
target.scheme = relative4.scheme;
|
|
8437
|
+
target.userinfo = relative4.userinfo;
|
|
8438
|
+
target.host = relative4.host;
|
|
8439
|
+
target.port = relative4.port;
|
|
8440
|
+
target.path = removeDotSegments(relative4.path || "");
|
|
8441
|
+
target.query = relative4.query;
|
|
8442
8442
|
} else {
|
|
8443
|
-
if (
|
|
8444
|
-
target.userinfo =
|
|
8445
|
-
target.host =
|
|
8446
|
-
target.port =
|
|
8447
|
-
target.path = removeDotSegments(
|
|
8448
|
-
target.query =
|
|
8443
|
+
if (relative4.userinfo !== void 0 || relative4.host !== void 0 || relative4.port !== void 0) {
|
|
8444
|
+
target.userinfo = relative4.userinfo;
|
|
8445
|
+
target.host = relative4.host;
|
|
8446
|
+
target.port = relative4.port;
|
|
8447
|
+
target.path = removeDotSegments(relative4.path || "");
|
|
8448
|
+
target.query = relative4.query;
|
|
8449
8449
|
} else {
|
|
8450
|
-
if (!
|
|
8450
|
+
if (!relative4.path) {
|
|
8451
8451
|
target.path = base.path;
|
|
8452
|
-
if (
|
|
8453
|
-
target.query =
|
|
8452
|
+
if (relative4.query !== void 0) {
|
|
8453
|
+
target.query = relative4.query;
|
|
8454
8454
|
} else {
|
|
8455
8455
|
target.query = base.query;
|
|
8456
8456
|
}
|
|
8457
8457
|
} else {
|
|
8458
|
-
if (
|
|
8459
|
-
target.path = removeDotSegments(
|
|
8458
|
+
if (relative4.path[0] === "/") {
|
|
8459
|
+
target.path = removeDotSegments(relative4.path);
|
|
8460
8460
|
} else {
|
|
8461
8461
|
if ((base.userinfo !== void 0 || base.host !== void 0 || base.port !== void 0) && !base.path) {
|
|
8462
|
-
target.path = "/" +
|
|
8462
|
+
target.path = "/" + relative4.path;
|
|
8463
8463
|
} else if (!base.path) {
|
|
8464
|
-
target.path =
|
|
8464
|
+
target.path = relative4.path;
|
|
8465
8465
|
} else {
|
|
8466
|
-
target.path = base.path.slice(0, base.path.lastIndexOf("/") + 1) +
|
|
8466
|
+
target.path = base.path.slice(0, base.path.lastIndexOf("/") + 1) + relative4.path;
|
|
8467
8467
|
}
|
|
8468
8468
|
target.path = removeDotSegments(target.path);
|
|
8469
8469
|
}
|
|
8470
|
-
target.query =
|
|
8470
|
+
target.query = relative4.query;
|
|
8471
8471
|
}
|
|
8472
8472
|
target.userinfo = base.userinfo;
|
|
8473
8473
|
target.host = base.host;
|
|
@@ -8475,7 +8475,7 @@ var require_fast_uri = __commonJS({
|
|
|
8475
8475
|
}
|
|
8476
8476
|
target.scheme = base.scheme;
|
|
8477
8477
|
}
|
|
8478
|
-
target.fragment =
|
|
8478
|
+
target.fragment = relative4.fragment;
|
|
8479
8479
|
return target;
|
|
8480
8480
|
}
|
|
8481
8481
|
function equal(uriA, uriB, options) {
|
|
@@ -8677,7 +8677,7 @@ var require_fast_uri = __commonJS({
|
|
|
8677
8677
|
var fastUri = {
|
|
8678
8678
|
SCHEMES,
|
|
8679
8679
|
normalize,
|
|
8680
|
-
resolve:
|
|
8680
|
+
resolve: resolve9,
|
|
8681
8681
|
resolveComponent,
|
|
8682
8682
|
equal,
|
|
8683
8683
|
serialize,
|
|
@@ -11703,9 +11703,7 @@ var PROVIDER_ALIASES = {
|
|
|
11703
11703
|
agy: "antigravity_cli",
|
|
11704
11704
|
antigravity: "antigravity_cli",
|
|
11705
11705
|
antigravity_cli: "antigravity_cli",
|
|
11706
|
-
codex: "codex_app_server"
|
|
11707
|
-
gemini: "antigravity_cli",
|
|
11708
|
-
gemini_cli: "antigravity_cli"
|
|
11706
|
+
codex: "codex_app_server"
|
|
11709
11707
|
};
|
|
11710
11708
|
var BACKEND_CLI_COMMANDS = {
|
|
11711
11709
|
claude_cli: "claude",
|
|
@@ -11716,11 +11714,10 @@ var BACKEND_CLI_COMMANDS = {
|
|
|
11716
11714
|
agy: "agy",
|
|
11717
11715
|
antigravity: "agy",
|
|
11718
11716
|
antigravity_cli: "agy",
|
|
11719
|
-
gemini_cli: "agy",
|
|
11720
|
-
gemini: "agy",
|
|
11721
11717
|
kimi_cli: "kimi-cli",
|
|
11722
11718
|
grok_cli: "grok",
|
|
11723
11719
|
opencode_cli: "opencode",
|
|
11720
|
+
opencode_serve: "opencode",
|
|
11724
11721
|
droid_cli: "droid",
|
|
11725
11722
|
supatest_cli: "supatest"
|
|
11726
11723
|
};
|
|
@@ -11812,7 +11809,7 @@ function resolveViaWhere(command, env) {
|
|
|
11812
11809
|
return null;
|
|
11813
11810
|
}
|
|
11814
11811
|
function runCliProbeAsync(executable, env, args = ["--version"], timeoutMs = 3e3, spawnOptions) {
|
|
11815
|
-
return new Promise((
|
|
11812
|
+
return new Promise((resolve9) => {
|
|
11816
11813
|
const isWin = (0, import_node_os.platform)() === "win32";
|
|
11817
11814
|
let command = executable;
|
|
11818
11815
|
let commandArgs = args;
|
|
@@ -11832,7 +11829,7 @@ function runCliProbeAsync(executable, env, args = ["--version"], timeoutMs = 3e3
|
|
|
11832
11829
|
stdio: closeStdin ? ["pipe", "pipe", "pipe"] : void 0
|
|
11833
11830
|
});
|
|
11834
11831
|
} catch (error2) {
|
|
11835
|
-
|
|
11832
|
+
resolve9({ status: null, stdout: "", stderr: "", error: error2 });
|
|
11836
11833
|
return;
|
|
11837
11834
|
}
|
|
11838
11835
|
if (closeStdin) {
|
|
@@ -11846,10 +11843,10 @@ function runCliProbeAsync(executable, env, args = ["--version"], timeoutMs = 3e3
|
|
|
11846
11843
|
child.stderr?.setEncoding("utf8").on("data", (chunk) => {
|
|
11847
11844
|
stderr += chunk;
|
|
11848
11845
|
});
|
|
11849
|
-
child.once("error", (error2) =>
|
|
11846
|
+
child.once("error", (error2) => resolve9({ status: null, stdout, stderr, error: error2 }));
|
|
11850
11847
|
child.once(
|
|
11851
11848
|
"close",
|
|
11852
|
-
(status, signal) =>
|
|
11849
|
+
(status, signal) => resolve9({ status, stdout, stderr, signal: signal ?? null })
|
|
11853
11850
|
);
|
|
11854
11851
|
});
|
|
11855
11852
|
}
|
|
@@ -12161,7 +12158,7 @@ You MUST NOT call these tools:
|
|
|
12161
12158
|
|
|
12162
12159
|
You MUST NOT call \`start_task_session\` before you have written a plan or requirements document. Delegate only after scope is defined.
|
|
12163
12160
|
|
|
12164
|
-
Read-only inspection is fine when you need to understand what exists.
|
|
12161
|
+
Read-only inspection is fine when you need to understand what exists \u2014 but check the platform first. See "Platform tools come before local tools" below.
|
|
12165
12162
|
|
|
12166
12163
|
## Platform document policy
|
|
12167
12164
|
|
|
@@ -12169,13 +12166,37 @@ Platform Documents are the default destination and source of truth for PM work.
|
|
|
12169
12166
|
|
|
12170
12167
|
Do NOT call \`create_plan\`, \`create_document_artifact\`, or another artifact-creation tool unless the user explicitly asks for an **artifact**. If \`create_document\` is unavailable or fails, report that blocker; do not silently substitute an artifact.
|
|
12171
12168
|
|
|
12172
|
-
##
|
|
12169
|
+
## Platform tools come before local tools
|
|
12173
12170
|
|
|
12174
|
-
|
|
12175
|
-
1. **Platform Documents first** \u2014 use \`list_documents\` or \`search\` to locate the relevant platform document, then \`get_document\` to read it. If a document ID is already known, call \`get_document\` directly.
|
|
12176
|
-
2. **Local repository docs only as fallback** \u2014 read \`README.md\`, \`AGENTS.md\`, \`notes/\`, or \`docs/\` only when no relevant platform document exists or the platform document tools are unavailable.
|
|
12171
|
+
You work on the Alan platform. The platform is where product truth lives: tasks, subtasks, decisions, events, sessions, artifacts, memory, and Documents. Local files and shell commands are a **last resort**, not a starting point.
|
|
12177
12172
|
|
|
12178
|
-
|
|
12173
|
+
**Before every lookup, ask: does the platform know this?** If a platform MCP tool could plausibly answer the question, you MUST call it before any \`Read\`, \`Glob\`, \`Grep\`, or \`Bash\`. Reaching for a local tool first is a mistake even when it would be faster or you already know the file path.
|
|
12174
|
+
|
|
12175
|
+
| What you want | Use this | Not this |
|
|
12176
|
+
|---|---|---|
|
|
12177
|
+
| Requirements, PRDs, specs, notes, any written knowledge | \`list_documents\`, \`search\`, \`get_document\` | reading \`docs/\`, \`notes/\`, \`README.md\` |
|
|
12178
|
+
| Scope, status, priority, or history of work | \`get_task\`, \`list_subtasks\`, \`list_tasks\` | \`git log\`, commit messages |
|
|
12179
|
+
| What was decided and why | \`list_task_decisions\`, \`list_task_events\` | code comments, in-repo ADRs |
|
|
12180
|
+
| What an agent did or is doing | \`list_sessions\`, \`get_session_context\` | \`git log\`, diffing the worktree |
|
|
12181
|
+
| Prior agent context | \`list_agent_memory\`, \`get_task_memory\` | scratch files |
|
|
12182
|
+
| Outputs of completed work | \`list_artifacts\`, \`get_artifact\` | build output, generated files |
|
|
12183
|
+
| Where code lives or how it works | \`search_code_context\` first, then \`Read\` the cited files | \`Grep\`/\`Glob\` sweeps |
|
|
12184
|
+
|
|
12185
|
+
**If you do fall back to a local tool, say so out loud** \u2014 name the platform tool you tried and what it returned (nothing, unavailable, insufficient). A silent local read is a violation of this rule. If no platform tool was tried, you have not earned the local read.
|
|
12186
|
+
|
|
12187
|
+
Code is the exception that proves the rule: understanding how something works legitimately ends in reading source. Even then, start with \`search_code_context\` and read only the files it cites.
|
|
12188
|
+
|
|
12189
|
+
**Default for written knowledge: platform Documents.** Any request to find, check, consult, review, summarize, or answer from written knowledge resolves against platform Documents \u2014 use \`list_documents\` or \`search\` to locate it, then \`get_document\` to read it. If a document ID is already known, call \`get_document\` directly.
|
|
12190
|
+
|
|
12191
|
+
This applies no matter which word the user uses. Treat all of these as the same request: docs, documentation, documents, notes, PRD, spec, requirements, design doc, plan, proposal, RFC, wiki, runbook, onboarding, guidelines, "what did we decide", "what did we write down", "what do we have on X". The noun never changes where you look.
|
|
12192
|
+
|
|
12193
|
+
**Local repository files are off-limits for knowledge lookup** unless the user unambiguously points you at the repository. Do not read \`README.md\`, \`AGENTS.md\`, \`notes/\`, \`docs/\`, or any other in-repo file as a fallback, as corroboration, because no platform document matched, or because the user's wording happens to match a directory name.
|
|
12194
|
+
|
|
12195
|
+
A bare noun is never a pointer to the repository. "Check the notes" means platform Documents, not \`notes/\`. "Check the docs" means platform Documents, not \`docs/\`. Only these count as pointing at the repository:
|
|
12196
|
+
- an explicit location \u2014 "in the repo", "in the codebase", "local files", "on disk", "in the worktree"
|
|
12197
|
+
- a concrete path or filename \u2014 \`notes/foo.md\`, \`AGENTS.md\`, "the readme"
|
|
12198
|
+
|
|
12199
|
+
When platform Documents do not cover the question, stop and say so, then offer to check the repository. Do not read local files first, and do not guess. Cite which document answered the question.
|
|
12179
12200
|
|
|
12180
12201
|
## Your primary tools
|
|
12181
12202
|
|
|
@@ -12631,7 +12652,10 @@ function toAntigravityMcpServers(src) {
|
|
|
12631
12652
|
const s = raw;
|
|
12632
12653
|
if (typeof s.type === "string" && s.type === "http" || typeof s.url === "string") {
|
|
12633
12654
|
out[name] = {
|
|
12634
|
-
|
|
12655
|
+
// Antigravity's current mcp_config.json schema uses `serverUrl`. Its
|
|
12656
|
+
// legacy settings.json integration used `httpUrl`, which the current CLI
|
|
12657
|
+
// intentionally does not read for MCP registration.
|
|
12658
|
+
serverUrl: s.url,
|
|
12635
12659
|
...s.headers && typeof s.headers === "object" && s.headers !== null && Object.keys(s.headers).length > 0 ? { headers: s.headers } : {}
|
|
12636
12660
|
};
|
|
12637
12661
|
} else if (typeof s.command === "string") {
|
|
@@ -12720,11 +12744,7 @@ function renderAlanMcpConfigFiles(mcpServers, home) {
|
|
|
12720
12744
|
content: JSON.stringify({ mcpServers: toFactoryMcpServers(mcpServers) })
|
|
12721
12745
|
},
|
|
12722
12746
|
{
|
|
12723
|
-
path: `${home}/.gemini/
|
|
12724
|
-
content: JSON.stringify({ mcpServers: toAntigravityMcpServers(mcpServers) })
|
|
12725
|
-
},
|
|
12726
|
-
{
|
|
12727
|
-
path: `${home}/.gemini/antigravity-cli/settings.json`,
|
|
12747
|
+
path: `${home}/.gemini/config/mcp_config.json`,
|
|
12728
12748
|
content: JSON.stringify({ mcpServers: toAntigravityMcpServers(mcpServers) })
|
|
12729
12749
|
},
|
|
12730
12750
|
{
|
|
@@ -12747,8 +12767,9 @@ function alanMcpConfigFilesForBackend(backendKind, mcpServers, home) {
|
|
|
12747
12767
|
case "droid_cli":
|
|
12748
12768
|
return byPathSuffix("/.factory/mcp.json");
|
|
12749
12769
|
case "antigravity_cli":
|
|
12750
|
-
return byPathSuffix("/.gemini/
|
|
12770
|
+
return byPathSuffix("/.gemini/config/mcp_config.json");
|
|
12751
12771
|
case "opencode_cli":
|
|
12772
|
+
case "opencode_serve":
|
|
12752
12773
|
return byPathSuffix("/.config/opencode/opencode.json");
|
|
12753
12774
|
default:
|
|
12754
12775
|
return all;
|
|
@@ -16926,6 +16947,7 @@ var APPLICATION_PROBLEM_CODES = [
|
|
|
16926
16947
|
"app.dispatch.runtime_offline",
|
|
16927
16948
|
"app.dispatch.delivery_failed",
|
|
16928
16949
|
"app.workspace.missing",
|
|
16950
|
+
"app.workspace.branch_changed",
|
|
16929
16951
|
"app.transport.disconnected",
|
|
16930
16952
|
"app.persistence.failed",
|
|
16931
16953
|
"app.service.unavailable",
|
|
@@ -16960,6 +16982,7 @@ var APPLICATION_PROBLEM_TITLES = {
|
|
|
16960
16982
|
"app.dispatch.runtime_offline": "Runtime unavailable",
|
|
16961
16983
|
"app.dispatch.delivery_failed": "Agent delivery failed",
|
|
16962
16984
|
"app.workspace.missing": "Workspace unavailable",
|
|
16985
|
+
"app.workspace.branch_changed": "Workspace branch changed",
|
|
16963
16986
|
"app.transport.disconnected": "Connection lost",
|
|
16964
16987
|
"app.persistence.failed": "Persistence failed",
|
|
16965
16988
|
"app.service.unavailable": "Service unavailable",
|
|
@@ -16985,6 +17008,14 @@ var APPLICATION_PROBLEM_RECOVERY = {
|
|
|
16985
17008
|
},
|
|
16986
17009
|
"app.dispatch.delivery_failed": { mode: "manual", action: "start_new_attempt", safe: false },
|
|
16987
17010
|
"app.workspace.missing": { mode: "after_user_action", action: "select_workspace", safe: true },
|
|
17011
|
+
// Distinct from `app.workspace.missing`: the folder is exactly where it was, so
|
|
17012
|
+
// telling the user to relocate it sends them looking for a problem that does not
|
|
17013
|
+
// exist. What they need to do is restore the branch the run was pinned to.
|
|
17014
|
+
"app.workspace.branch_changed": {
|
|
17015
|
+
mode: "after_user_action",
|
|
17016
|
+
action: "restore_branch",
|
|
17017
|
+
safe: true
|
|
17018
|
+
},
|
|
16988
17019
|
"app.transport.disconnected": { mode: "automatic", action: "reconnect", safe: true },
|
|
16989
17020
|
"app.persistence.failed": { mode: "automatic", action: "reconcile", safe: true },
|
|
16990
17021
|
"app.service.unavailable": { mode: "after_user_action", action: "retry", safe: true },
|
|
@@ -17310,6 +17341,55 @@ function getAlanAgentPrompt(agentId) {
|
|
|
17310
17341
|
return getAgentSystemPrompt(agentId);
|
|
17311
17342
|
}
|
|
17312
17343
|
|
|
17344
|
+
// ../shared/dist/constants/agent.js
|
|
17345
|
+
var INTERACTIVE_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
17346
|
+
"askuserquestion",
|
|
17347
|
+
"askquestion",
|
|
17348
|
+
"exitplanmode",
|
|
17349
|
+
"enterplanmode"
|
|
17350
|
+
]);
|
|
17351
|
+
var HARNESS_ASK_TOOL_NAMES = /* @__PURE__ */ new Set(["askuserquestion", "askquestion"]);
|
|
17352
|
+
function normalizeToolName2(name) {
|
|
17353
|
+
const lower = name.toLowerCase();
|
|
17354
|
+
const mcp = lower.match(/^mcp__[a-z0-9-]+__(.+)$/);
|
|
17355
|
+
const bare = mcp ? mcp[1] : lower;
|
|
17356
|
+
return bare.replace(/[_\s-]/g, "");
|
|
17357
|
+
}
|
|
17358
|
+
function toolNameFromInput(input) {
|
|
17359
|
+
if (!input || typeof input !== "object")
|
|
17360
|
+
return null;
|
|
17361
|
+
const rec = input;
|
|
17362
|
+
if (typeof rec.toolName === "string" && rec.toolName.trim())
|
|
17363
|
+
return rec.toolName;
|
|
17364
|
+
if (typeof rec.name === "string" && rec.name.trim())
|
|
17365
|
+
return rec.name;
|
|
17366
|
+
return null;
|
|
17367
|
+
}
|
|
17368
|
+
function inputLooksLikeAskUserQuestion(input) {
|
|
17369
|
+
if (!input || typeof input !== "object")
|
|
17370
|
+
return false;
|
|
17371
|
+
const rec = input;
|
|
17372
|
+
const args = typeof rec.args === "object" && rec.args !== null ? rec.args : rec;
|
|
17373
|
+
return Array.isArray(args.questions) && args.questions.length > 0;
|
|
17374
|
+
}
|
|
17375
|
+
function isAskUserQuestionTool(name, input) {
|
|
17376
|
+
if (HARNESS_ASK_TOOL_NAMES.has(normalizeToolName2(name)))
|
|
17377
|
+
return true;
|
|
17378
|
+
const nested = toolNameFromInput(input);
|
|
17379
|
+
if (nested && nested !== name && HARNESS_ASK_TOOL_NAMES.has(normalizeToolName2(nested))) {
|
|
17380
|
+
return true;
|
|
17381
|
+
}
|
|
17382
|
+
return inputLooksLikeAskUserQuestion(input);
|
|
17383
|
+
}
|
|
17384
|
+
function isInteractiveToolName(name, input) {
|
|
17385
|
+
const normalized = normalizeToolName2(name);
|
|
17386
|
+
if (INTERACTIVE_TOOL_NAMES.has(normalized))
|
|
17387
|
+
return true;
|
|
17388
|
+
return isAskUserQuestionTool(name, input);
|
|
17389
|
+
}
|
|
17390
|
+
var ALAN_AGENT_WORKOS_USER_ID_PREFIX = "alan-agent:";
|
|
17391
|
+
var ALAN_AGENT_WORKOS_USER_ID_LIKE_PATTERN = `${ALAN_AGENT_WORKOS_USER_ID_PREFIX}%`;
|
|
17392
|
+
|
|
17313
17393
|
// ../shared/dist/effort.js
|
|
17314
17394
|
var EFFORT_LEVELS = ["minimal", "low", "medium", "high", "xhigh", "max", "ultra"];
|
|
17315
17395
|
var CLAUDE_EFFORT_LEVELS = [
|
|
@@ -17736,6 +17816,9 @@ var PROVIDER_MODELS = {
|
|
|
17736
17816
|
cursor_agent_cli: CURSOR_AGENT_MODELS,
|
|
17737
17817
|
antigravity_cli: ANTIGRAVITY_CLI_SEED_MODELS,
|
|
17738
17818
|
opencode_cli: OPENCODE_ZEN_MODELS,
|
|
17819
|
+
// Server transport dispatches the same "opencode" binary/models as opencode_cli —
|
|
17820
|
+
// share the catalog reference rather than duplicating it.
|
|
17821
|
+
opencode_serve: OPENCODE_ZEN_MODELS,
|
|
17739
17822
|
droid_cli: [
|
|
17740
17823
|
{ id: "claude-opus-4-8", name: "Claude Opus 4.8" },
|
|
17741
17824
|
{ id: "claude-haiku-4-5-20251001", name: "Claude Haiku 4.5" },
|
|
@@ -17946,17 +18029,17 @@ var CODEX_APP_SERVER_PICKER_FALLBACK_MODELS = [
|
|
|
17946
18029
|
var ANTIGRAVITY_CLI_PICKER_FALLBACK_MODELS = [
|
|
17947
18030
|
{ id: "", name: "CLI default", capabilities: caps([]) },
|
|
17948
18031
|
{
|
|
17949
|
-
id: "
|
|
18032
|
+
id: "gemini-3.5-flash",
|
|
17950
18033
|
name: "Antigravity 3.5 Flash",
|
|
17951
18034
|
capabilities: caps(ANTIGRAVITY_EFFORT)
|
|
17952
18035
|
},
|
|
17953
18036
|
{
|
|
17954
|
-
id: "
|
|
18037
|
+
id: "gemini-3.1-pro",
|
|
17955
18038
|
name: "Antigravity 3.1 Pro",
|
|
17956
18039
|
capabilities: caps(ANTIGRAVITY_EFFORT)
|
|
17957
18040
|
},
|
|
17958
18041
|
{
|
|
17959
|
-
id: "
|
|
18042
|
+
id: "gemini-3-flash",
|
|
17960
18043
|
name: "Antigravity 3 Flash",
|
|
17961
18044
|
capabilities: caps(ANTIGRAVITY_EFFORT)
|
|
17962
18045
|
},
|
|
@@ -18027,14 +18110,16 @@ var DISCOVERY_SEED_PROVIDERS = /* @__PURE__ */ new Set([
|
|
|
18027
18110
|
"antigravity_cli",
|
|
18028
18111
|
"cursor_agent_cli",
|
|
18029
18112
|
"opencode_cli",
|
|
18113
|
+
"opencode_serve",
|
|
18030
18114
|
"kimi_cli",
|
|
18031
18115
|
"grok_cli",
|
|
18032
18116
|
"copilot_cli",
|
|
18033
18117
|
"droid_cli"
|
|
18034
18118
|
]);
|
|
18035
18119
|
function baseCatalogForProvider(providerKind) {
|
|
18036
|
-
const
|
|
18037
|
-
const
|
|
18120
|
+
const catalogProvider = providerKind === "opencode_serve" ? "opencode_cli" : providerKind;
|
|
18121
|
+
const fallback = getProviderPickerFallbackModels(catalogProvider);
|
|
18122
|
+
const staticCatalog = PROVIDER_MODELS[catalogProvider] ?? [];
|
|
18038
18123
|
if (staticCatalog.length === 0) {
|
|
18039
18124
|
return fallback;
|
|
18040
18125
|
}
|
|
@@ -18063,68 +18148,25 @@ var import_os2 = require("os");
|
|
|
18063
18148
|
var import_path2 = require("path");
|
|
18064
18149
|
var import_child_process = require("child_process");
|
|
18065
18150
|
var import_fs3 = require("fs");
|
|
18066
|
-
var import_os3 = require("os");
|
|
18067
18151
|
var import_path3 = require("path");
|
|
18152
|
+
var import_fs4 = require("fs");
|
|
18153
|
+
var import_os3 = require("os");
|
|
18154
|
+
var import_path4 = require("path");
|
|
18068
18155
|
var import_readline = require("readline");
|
|
18069
18156
|
var import_crypto2 = require("crypto");
|
|
18070
18157
|
var import_child_process2 = require("child_process");
|
|
18071
18158
|
var import_child_process3 = require("child_process");
|
|
18072
|
-
var
|
|
18073
|
-
var import_fs4 = require("fs");
|
|
18159
|
+
var import_fs5 = require("fs");
|
|
18074
18160
|
var import_os4 = require("os");
|
|
18075
|
-
var
|
|
18161
|
+
var import_path5 = require("path");
|
|
18162
|
+
var import_url = require("url");
|
|
18163
|
+
var import_crypto3 = require("crypto");
|
|
18164
|
+
var import_fs6 = require("fs");
|
|
18165
|
+
var import_os5 = require("os");
|
|
18166
|
+
var import_path6 = require("path");
|
|
18076
18167
|
var import_child_process4 = require("child_process");
|
|
18077
18168
|
var import_util4 = require("util");
|
|
18078
18169
|
|
|
18079
|
-
// ../shared/dist/constants/agent.js
|
|
18080
|
-
var INTERACTIVE_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
18081
|
-
"askuserquestion",
|
|
18082
|
-
"askquestion",
|
|
18083
|
-
"exitplanmode",
|
|
18084
|
-
"enterplanmode"
|
|
18085
|
-
]);
|
|
18086
|
-
var HARNESS_ASK_TOOL_NAMES = /* @__PURE__ */ new Set(["askuserquestion", "askquestion"]);
|
|
18087
|
-
function normalizeToolName2(name) {
|
|
18088
|
-
const lower = name.toLowerCase();
|
|
18089
|
-
const mcp = lower.match(/^mcp__[a-z0-9-]+__(.+)$/);
|
|
18090
|
-
const bare = mcp ? mcp[1] : lower;
|
|
18091
|
-
return bare.replace(/[_\s-]/g, "");
|
|
18092
|
-
}
|
|
18093
|
-
function toolNameFromInput(input) {
|
|
18094
|
-
if (!input || typeof input !== "object")
|
|
18095
|
-
return null;
|
|
18096
|
-
const rec = input;
|
|
18097
|
-
if (typeof rec.toolName === "string" && rec.toolName.trim())
|
|
18098
|
-
return rec.toolName;
|
|
18099
|
-
if (typeof rec.name === "string" && rec.name.trim())
|
|
18100
|
-
return rec.name;
|
|
18101
|
-
return null;
|
|
18102
|
-
}
|
|
18103
|
-
function inputLooksLikeAskUserQuestion(input) {
|
|
18104
|
-
if (!input || typeof input !== "object")
|
|
18105
|
-
return false;
|
|
18106
|
-
const rec = input;
|
|
18107
|
-
const args = typeof rec.args === "object" && rec.args !== null ? rec.args : rec;
|
|
18108
|
-
return Array.isArray(args.questions) && args.questions.length > 0;
|
|
18109
|
-
}
|
|
18110
|
-
function isAskUserQuestionTool(name, input) {
|
|
18111
|
-
if (HARNESS_ASK_TOOL_NAMES.has(normalizeToolName2(name)))
|
|
18112
|
-
return true;
|
|
18113
|
-
const nested = toolNameFromInput(input);
|
|
18114
|
-
if (nested && nested !== name && HARNESS_ASK_TOOL_NAMES.has(normalizeToolName2(nested))) {
|
|
18115
|
-
return true;
|
|
18116
|
-
}
|
|
18117
|
-
return inputLooksLikeAskUserQuestion(input);
|
|
18118
|
-
}
|
|
18119
|
-
function isInteractiveToolName(name, input) {
|
|
18120
|
-
const normalized = normalizeToolName2(name);
|
|
18121
|
-
if (INTERACTIVE_TOOL_NAMES.has(normalized))
|
|
18122
|
-
return true;
|
|
18123
|
-
return isAskUserQuestionTool(name, input);
|
|
18124
|
-
}
|
|
18125
|
-
var ALAN_AGENT_WORKOS_USER_ID_PREFIX = "alan-agent:";
|
|
18126
|
-
var ALAN_AGENT_WORKOS_USER_ID_LIKE_PATTERN = `${ALAN_AGENT_WORKOS_USER_ID_PREFIX}%`;
|
|
18127
|
-
|
|
18128
18170
|
// ../shared/dist/constants/colors.js
|
|
18129
18171
|
var CATEGORICAL_COLORS = {
|
|
18130
18172
|
slate: "#7280a0",
|
|
@@ -18368,23 +18410,23 @@ var PRIORITY_OPTIONS = [
|
|
|
18368
18410
|
];
|
|
18369
18411
|
|
|
18370
18412
|
// ../agent-core/dist/index.js
|
|
18371
|
-
var import_fs5 = require("fs");
|
|
18372
|
-
var import_os5 = require("os");
|
|
18373
|
-
var import_path5 = require("path");
|
|
18374
|
-
var import_fs6 = require("fs");
|
|
18375
|
-
var import_os6 = require("os");
|
|
18376
|
-
var import_path6 = require("path");
|
|
18377
18413
|
var import_fs7 = require("fs");
|
|
18378
|
-
var
|
|
18414
|
+
var import_os6 = require("os");
|
|
18379
18415
|
var import_path7 = require("path");
|
|
18380
|
-
var import_readline2 = require("readline");
|
|
18381
|
-
var import_url = require("url");
|
|
18382
18416
|
var import_fs8 = require("fs");
|
|
18383
|
-
var
|
|
18417
|
+
var import_os7 = require("os");
|
|
18384
18418
|
var import_path8 = require("path");
|
|
18385
|
-
var import_crypto4 = require("crypto");
|
|
18386
18419
|
var import_fs9 = require("fs");
|
|
18420
|
+
var import_os8 = require("os");
|
|
18387
18421
|
var import_path9 = require("path");
|
|
18422
|
+
var import_readline2 = require("readline");
|
|
18423
|
+
var import_url2 = require("url");
|
|
18424
|
+
var import_fs10 = require("fs");
|
|
18425
|
+
var import_os9 = require("os");
|
|
18426
|
+
var import_path10 = require("path");
|
|
18427
|
+
var import_crypto4 = require("crypto");
|
|
18428
|
+
var import_fs11 = require("fs");
|
|
18429
|
+
var import_path11 = require("path");
|
|
18388
18430
|
var MANAGED_ALAN_MCP_SERVER_NAMES = [
|
|
18389
18431
|
"alan",
|
|
18390
18432
|
"alan-prod",
|
|
@@ -18438,7 +18480,7 @@ async function acquireConfigLock(path) {
|
|
|
18438
18480
|
if (Date.now() - startedAt >= 2e3) {
|
|
18439
18481
|
throw new Error(`Alan could not safely update ${path}`);
|
|
18440
18482
|
}
|
|
18441
|
-
await new Promise((
|
|
18483
|
+
await new Promise((resolve42) => setTimeout(resolve42, 20));
|
|
18442
18484
|
}
|
|
18443
18485
|
}
|
|
18444
18486
|
}
|
|
@@ -18674,23 +18716,10 @@ function buildJsonTargets(home) {
|
|
|
18674
18716
|
server.headers = headers;
|
|
18675
18717
|
}
|
|
18676
18718
|
},
|
|
18677
|
-
{
|
|
18678
|
-
cli: "Antigravity",
|
|
18679
|
-
configPath: (0, import_path2.join)(home, ".gemini", "settings.json"),
|
|
18680
|
-
guardDir: (0, import_path2.join)(home, ".gemini"),
|
|
18681
|
-
readServers: (config2) => config2.mcpServers ?? {},
|
|
18682
|
-
writeServers: (config2, servers) => {
|
|
18683
|
-
config2.mcpServers = servers;
|
|
18684
|
-
},
|
|
18685
|
-
readHeaders: (server) => server.headers,
|
|
18686
|
-
writeHeaders: (server, headers) => {
|
|
18687
|
-
server.headers = headers;
|
|
18688
|
-
}
|
|
18689
|
-
},
|
|
18690
18719
|
{
|
|
18691
18720
|
cli: "Antigravity CLI",
|
|
18692
|
-
configPath: (0, import_path2.join)(home, ".gemini", "
|
|
18693
|
-
guardDir: (0, import_path2.join)(home, ".gemini"),
|
|
18721
|
+
configPath: (0, import_path2.join)(home, ".gemini", "config", "mcp_config.json"),
|
|
18722
|
+
guardDir: (0, import_path2.join)(home, ".gemini", "config"),
|
|
18694
18723
|
readServers: (config2) => config2.mcpServers ?? {},
|
|
18695
18724
|
writeServers: (config2, servers) => {
|
|
18696
18725
|
config2.mcpServers = servers;
|
|
@@ -18736,8 +18765,8 @@ var mcpConfigWriteGateTail = Promise.resolve();
|
|
|
18736
18765
|
function acquireMcpConfigWriteGate() {
|
|
18737
18766
|
const previous = mcpConfigWriteGateTail;
|
|
18738
18767
|
let releaseCurrent;
|
|
18739
|
-
const current = new Promise((
|
|
18740
|
-
releaseCurrent =
|
|
18768
|
+
const current = new Promise((resolve42) => {
|
|
18769
|
+
releaseCurrent = resolve42;
|
|
18741
18770
|
});
|
|
18742
18771
|
mcpConfigWriteGateTail = previous.then(() => current);
|
|
18743
18772
|
return previous.then(() => {
|
|
@@ -18749,6 +18778,64 @@ function acquireMcpConfigWriteGate() {
|
|
|
18749
18778
|
};
|
|
18750
18779
|
});
|
|
18751
18780
|
}
|
|
18781
|
+
var AGENT_INSTRUCTIONS_FILE = "AGENTS.md";
|
|
18782
|
+
var MAX_INSTRUCTION_CHARS = 48e3;
|
|
18783
|
+
function isWorkspaceRoot(dir) {
|
|
18784
|
+
return (0, import_fs3.existsSync)((0, import_path3.join)(dir, ".git"));
|
|
18785
|
+
}
|
|
18786
|
+
function findWorkspaceRoot(cwd) {
|
|
18787
|
+
let current = (0, import_path3.resolve)(cwd);
|
|
18788
|
+
while (true) {
|
|
18789
|
+
if (isWorkspaceRoot(current)) return current;
|
|
18790
|
+
const parent = (0, import_path3.dirname)(current);
|
|
18791
|
+
if (parent === current) return (0, import_path3.resolve)(cwd);
|
|
18792
|
+
current = parent;
|
|
18793
|
+
}
|
|
18794
|
+
}
|
|
18795
|
+
function instructionPaths(cwd) {
|
|
18796
|
+
const root = findWorkspaceRoot(cwd);
|
|
18797
|
+
const paths = [];
|
|
18798
|
+
let current = (0, import_path3.resolve)(cwd);
|
|
18799
|
+
while (true) {
|
|
18800
|
+
const path = (0, import_path3.join)(current, AGENT_INSTRUCTIONS_FILE);
|
|
18801
|
+
try {
|
|
18802
|
+
if ((0, import_fs3.existsSync)(path) && (0, import_fs3.statSync)(path).isFile()) paths.unshift(path);
|
|
18803
|
+
} catch {
|
|
18804
|
+
}
|
|
18805
|
+
if (current === root) return paths;
|
|
18806
|
+
const parent = (0, import_path3.dirname)(current);
|
|
18807
|
+
if (parent === current) return paths;
|
|
18808
|
+
current = parent;
|
|
18809
|
+
}
|
|
18810
|
+
}
|
|
18811
|
+
function buildAntigravityWorkspaceInstructions(cwd) {
|
|
18812
|
+
let remaining = MAX_INSTRUCTION_CHARS;
|
|
18813
|
+
const sections = [];
|
|
18814
|
+
for (const path of instructionPaths(cwd)) {
|
|
18815
|
+
if (remaining <= 0) break;
|
|
18816
|
+
let content;
|
|
18817
|
+
try {
|
|
18818
|
+
content = (0, import_fs3.readFileSync)(path, "utf8").trim();
|
|
18819
|
+
} catch {
|
|
18820
|
+
continue;
|
|
18821
|
+
}
|
|
18822
|
+
if (!content) continue;
|
|
18823
|
+
const included = content.slice(0, remaining);
|
|
18824
|
+
sections.push(
|
|
18825
|
+
[
|
|
18826
|
+
`<workspace_agent_instructions source="${path}">`,
|
|
18827
|
+
included,
|
|
18828
|
+
"</workspace_agent_instructions>"
|
|
18829
|
+
].join("\n")
|
|
18830
|
+
);
|
|
18831
|
+
remaining -= included.length;
|
|
18832
|
+
}
|
|
18833
|
+
if (sections.length === 0) return void 0;
|
|
18834
|
+
return [
|
|
18835
|
+
"Treat the following repository agent instructions as active for this session.",
|
|
18836
|
+
...sections
|
|
18837
|
+
].join("\n\n");
|
|
18838
|
+
}
|
|
18752
18839
|
function buildPromptWithSystem(config2, promptText) {
|
|
18753
18840
|
const parts2 = [
|
|
18754
18841
|
config2.systemPrompt?.trim(),
|
|
@@ -18780,16 +18867,16 @@ function imageFileExtension(mimeType) {
|
|
|
18780
18867
|
}
|
|
18781
18868
|
function createImageTempDirectory(cwd) {
|
|
18782
18869
|
const candidates = [
|
|
18783
|
-
cwd ? (0,
|
|
18784
|
-
(0,
|
|
18870
|
+
cwd ? (0, import_path4.join)(cwd, ".alan-images-") : null,
|
|
18871
|
+
(0, import_path4.join)((0, import_os3.tmpdir)(), "alan-images-")
|
|
18785
18872
|
].filter((value2) => Boolean(value2));
|
|
18786
18873
|
for (const candidate of candidates) {
|
|
18787
18874
|
try {
|
|
18788
|
-
return (0,
|
|
18875
|
+
return (0, import_fs4.mkdtempSync)(candidate);
|
|
18789
18876
|
} catch {
|
|
18790
18877
|
}
|
|
18791
18878
|
}
|
|
18792
|
-
return (0,
|
|
18879
|
+
return (0, import_fs4.mkdtempSync)((0, import_path4.join)((0, import_os3.tmpdir)(), "alan-images-"));
|
|
18793
18880
|
}
|
|
18794
18881
|
function safeFilename(filename) {
|
|
18795
18882
|
const safe = filename.replace(/[^a-zA-Z0-9._-]/g, "_").replace(/^_+/, "");
|
|
@@ -18803,8 +18890,8 @@ function writeImagesToTempFiles(images, cwd) {
|
|
|
18803
18890
|
const files = [];
|
|
18804
18891
|
for (const img of images) {
|
|
18805
18892
|
const ext = imageFileExtension(img.mimeType);
|
|
18806
|
-
const filePath = (0,
|
|
18807
|
-
(0,
|
|
18893
|
+
const filePath = (0, import_path4.join)(directory, `alan-img-${img.id}.${ext}`);
|
|
18894
|
+
(0, import_fs4.writeFileSync)(filePath, Buffer.from(img.data, "base64"));
|
|
18808
18895
|
paths.push(filePath);
|
|
18809
18896
|
files.push({
|
|
18810
18897
|
filename: img.filename,
|
|
@@ -18819,7 +18906,7 @@ function writeImagesToTempFiles(images, cwd) {
|
|
|
18819
18906
|
files,
|
|
18820
18907
|
cleanup: () => {
|
|
18821
18908
|
try {
|
|
18822
|
-
(0,
|
|
18909
|
+
(0, import_fs4.rmSync)(directory, { recursive: true, force: true });
|
|
18823
18910
|
} catch {
|
|
18824
18911
|
}
|
|
18825
18912
|
}
|
|
@@ -18845,8 +18932,8 @@ function writeFilesToTempFiles(files, cwd) {
|
|
|
18845
18932
|
}
|
|
18846
18933
|
for (const file2 of dataFiles) {
|
|
18847
18934
|
if (!directory || file2.data === void 0) continue;
|
|
18848
|
-
const filePath = (0,
|
|
18849
|
-
(0,
|
|
18935
|
+
const filePath = (0, import_path4.join)(directory, `${file2.id}-${safeFilename(file2.filename)}`);
|
|
18936
|
+
(0, import_fs4.writeFileSync)(filePath, Buffer.from(file2.data, "base64"));
|
|
18850
18937
|
paths.push(filePath);
|
|
18851
18938
|
tempFiles.push({
|
|
18852
18939
|
filename: file2.filename,
|
|
@@ -18861,7 +18948,7 @@ function writeFilesToTempFiles(files, cwd) {
|
|
|
18861
18948
|
cleanup: () => {
|
|
18862
18949
|
if (!directory) return;
|
|
18863
18950
|
try {
|
|
18864
|
-
(0,
|
|
18951
|
+
(0, import_fs4.rmSync)(directory, { recursive: true, force: true });
|
|
18865
18952
|
} catch {
|
|
18866
18953
|
}
|
|
18867
18954
|
}
|
|
@@ -19322,15 +19409,15 @@ var SPAWN_RETRY_DELAYS_BY_CODE = {
|
|
|
19322
19409
|
ETXTBSY: [250, 750, 1500, 3e3, 5e3],
|
|
19323
19410
|
ENOENT: [250, 750]
|
|
19324
19411
|
};
|
|
19325
|
-
var delay = (ms) => new Promise((
|
|
19412
|
+
var delay = (ms) => new Promise((resolve42) => setTimeout(resolve42, ms));
|
|
19326
19413
|
var SPAWN_OUTCOME_TIMEOUT_MS = 2e3;
|
|
19327
19414
|
function waitForSpawnOutcome(child, timeoutMs = SPAWN_OUTCOME_TIMEOUT_MS) {
|
|
19328
|
-
return new Promise((
|
|
19329
|
-
const timer = setTimeout(() =>
|
|
19415
|
+
return new Promise((resolve42) => {
|
|
19416
|
+
const timer = setTimeout(() => resolve42(null), timeoutMs);
|
|
19330
19417
|
timer.unref?.();
|
|
19331
19418
|
const settle = (value2) => {
|
|
19332
19419
|
clearTimeout(timer);
|
|
19333
|
-
|
|
19420
|
+
resolve42(value2);
|
|
19334
19421
|
};
|
|
19335
19422
|
child.once("spawn", () => settle(null));
|
|
19336
19423
|
child.once("error", (error2) => settle(error2));
|
|
@@ -19457,36 +19544,36 @@ function createGenericCliBackend(options) {
|
|
|
19457
19544
|
let idleTimedOut = false;
|
|
19458
19545
|
let idleTimeoutReason = null;
|
|
19459
19546
|
try {
|
|
19460
|
-
const exitPromise = new Promise((
|
|
19547
|
+
const exitPromise = new Promise((resolve42, reject) => {
|
|
19461
19548
|
child.on("error", (error2) => {
|
|
19462
19549
|
reject(formatCliSpawnError(options.command, error2));
|
|
19463
19550
|
});
|
|
19464
|
-
child.on("close", (exitCode2, signal) =>
|
|
19551
|
+
child.on("close", (exitCode2, signal) => resolve42({ exitCode: exitCode2, signal }));
|
|
19465
19552
|
const onAbort = () => {
|
|
19466
19553
|
killProcessTree(child.pid, { signal: "SIGTERM", child });
|
|
19467
19554
|
};
|
|
19468
19555
|
context.abortController.signal.addEventListener("abort", onAbort, { once: true });
|
|
19469
19556
|
});
|
|
19470
19557
|
if (options.keepStdinOpen) {
|
|
19471
|
-
const resultPromise = new Promise((
|
|
19472
|
-
state.onResultReceived = () =>
|
|
19473
|
-
if (state.resultReceived)
|
|
19558
|
+
const resultPromise = new Promise((resolve42) => {
|
|
19559
|
+
state.onResultReceived = () => resolve42("result_received");
|
|
19560
|
+
if (state.resultReceived) resolve42("result_received");
|
|
19474
19561
|
});
|
|
19475
19562
|
const IDLE_MS = options.resultIdleTimeoutMs ?? 10 * 60 * 1e3;
|
|
19476
19563
|
let idleTimer = null;
|
|
19477
|
-
const idlePromise = new Promise((
|
|
19564
|
+
const idlePromise = new Promise((resolve42) => {
|
|
19478
19565
|
const armIdleTimer = () => {
|
|
19479
19566
|
if (idleTimer) clearTimeout(idleTimer);
|
|
19480
19567
|
idleTimer = setTimeout(() => {
|
|
19481
19568
|
if (presenter.pendingAskUserToolIds?.size) {
|
|
19482
19569
|
idleTimeoutReason = "pending_user_answer";
|
|
19483
|
-
|
|
19570
|
+
resolve42("idle_timeout");
|
|
19484
19571
|
} else if (state.awaitingPostBackgroundSynthesis || state.resultDeferredOnBackgroundWork && state.activeBackgroundTaskIds?.size) {
|
|
19485
19572
|
idleTimeoutReason = state.awaitingPostBackgroundSynthesis ? "post_subagent_synthesis" : "background_task";
|
|
19486
|
-
|
|
19573
|
+
resolve42("idle_timeout");
|
|
19487
19574
|
} else if (options.postStartupSilenceTimeoutMs && sawStdoutLine && typeof state.lastRawOutputAtMs === "number" && Date.now() - state.lastRawOutputAtMs >= options.postStartupSilenceTimeoutMs) {
|
|
19488
19575
|
idleTimeoutReason = "post_startup_silence";
|
|
19489
|
-
|
|
19576
|
+
resolve42("idle_timeout");
|
|
19490
19577
|
} else {
|
|
19491
19578
|
armIdleTimer();
|
|
19492
19579
|
}
|
|
@@ -19507,14 +19594,14 @@ function createGenericCliBackend(options) {
|
|
|
19507
19594
|
processExit = await Promise.race([
|
|
19508
19595
|
exitPromise,
|
|
19509
19596
|
new Promise(
|
|
19510
|
-
(
|
|
19597
|
+
(resolve42) => setTimeout(() => resolve42({ exitCode: null, signal: "SIGKILL" }), 5e3)
|
|
19511
19598
|
)
|
|
19512
19599
|
]);
|
|
19513
19600
|
} else if (raceResult === "result_received") {
|
|
19514
19601
|
const GRACE_MS = 5e3;
|
|
19515
19602
|
const gracedExit = await Promise.race([
|
|
19516
19603
|
exitPromise,
|
|
19517
|
-
new Promise((
|
|
19604
|
+
new Promise((resolve42) => setTimeout(() => resolve42(null), GRACE_MS))
|
|
19518
19605
|
]);
|
|
19519
19606
|
if (gracedExit) processExit = gracedExit;
|
|
19520
19607
|
if (child.exitCode === null && !child.killed) {
|
|
@@ -19832,6 +19919,234 @@ function createGenericCliBackend(options) {
|
|
|
19832
19919
|
}
|
|
19833
19920
|
};
|
|
19834
19921
|
}
|
|
19922
|
+
function stringField(record2, key) {
|
|
19923
|
+
const value2 = record2[key];
|
|
19924
|
+
return typeof value2 === "string" && value2.trim().length > 0 ? value2 : void 0;
|
|
19925
|
+
}
|
|
19926
|
+
function backgroundTaskKeys(record2) {
|
|
19927
|
+
return [
|
|
19928
|
+
stringField(record2, "task_id"),
|
|
19929
|
+
stringField(record2, "taskId"),
|
|
19930
|
+
stringField(record2, "tool_use_id"),
|
|
19931
|
+
stringField(record2, "toolUseId"),
|
|
19932
|
+
stringField(record2, "id")
|
|
19933
|
+
].filter((key) => Boolean(key));
|
|
19934
|
+
}
|
|
19935
|
+
function backgroundTaskId(record2) {
|
|
19936
|
+
return stringField(record2, "task_id") ?? stringField(record2, "taskId");
|
|
19937
|
+
}
|
|
19938
|
+
function backgroundToolUseId(record2) {
|
|
19939
|
+
return stringField(record2, "tool_use_id") ?? stringField(record2, "toolUseId");
|
|
19940
|
+
}
|
|
19941
|
+
function registerBackgroundTaskIds(state, keys) {
|
|
19942
|
+
for (const key of keys) {
|
|
19943
|
+
if (!key) continue;
|
|
19944
|
+
if (!state.activeBackgroundTaskIds) state.activeBackgroundTaskIds = /* @__PURE__ */ new Set();
|
|
19945
|
+
state.activeBackgroundTaskIds.add(key);
|
|
19946
|
+
}
|
|
19947
|
+
}
|
|
19948
|
+
function registerBackgroundLauncher(state, toolUseId) {
|
|
19949
|
+
registerBackgroundTaskIds(state, [toolUseId]);
|
|
19950
|
+
if (!state.pendingLauncherToolIds) state.pendingLauncherToolIds = [];
|
|
19951
|
+
if (!state.pendingLauncherToolIds.includes(toolUseId)) {
|
|
19952
|
+
state.pendingLauncherToolIds.push(toolUseId);
|
|
19953
|
+
}
|
|
19954
|
+
}
|
|
19955
|
+
function drainNextUnlinkedBackgroundLauncher(state) {
|
|
19956
|
+
const launcherId = state.pendingLauncherToolIds?.shift();
|
|
19957
|
+
if (state.pendingLauncherToolIds?.length === 0) state.pendingLauncherToolIds = void 0;
|
|
19958
|
+
if (launcherId) clearBackgroundTaskIds(state, [launcherId]);
|
|
19959
|
+
return launcherId;
|
|
19960
|
+
}
|
|
19961
|
+
function registerBackgroundTaskRecord(state, record2, launcherToolUseId) {
|
|
19962
|
+
const taskId = backgroundTaskId(record2);
|
|
19963
|
+
let toolUseId = backgroundToolUseId(record2) ?? launcherToolUseId ?? void 0;
|
|
19964
|
+
if (!toolUseId && taskId) {
|
|
19965
|
+
const nextLauncher = state.pendingLauncherToolIds?.[0];
|
|
19966
|
+
if (nextLauncher) {
|
|
19967
|
+
toolUseId = nextLauncher;
|
|
19968
|
+
} else if (state.activeBackgroundTaskIds?.size === 1) {
|
|
19969
|
+
const [candidate] = state.activeBackgroundTaskIds;
|
|
19970
|
+
if (candidate && candidate !== taskId) toolUseId = candidate;
|
|
19971
|
+
}
|
|
19972
|
+
}
|
|
19973
|
+
registerBackgroundTaskIds(state, backgroundTaskKeys(record2));
|
|
19974
|
+
if (!taskId || !toolUseId) return;
|
|
19975
|
+
if (state.pendingLauncherToolIds) {
|
|
19976
|
+
const idx = state.pendingLauncherToolIds.indexOf(toolUseId);
|
|
19977
|
+
if (idx >= 0) state.pendingLauncherToolIds.splice(idx, 1);
|
|
19978
|
+
if (state.pendingLauncherToolIds.length === 0) state.pendingLauncherToolIds = void 0;
|
|
19979
|
+
}
|
|
19980
|
+
if (!state.backgroundToolIdByTaskId) state.backgroundToolIdByTaskId = /* @__PURE__ */ new Map();
|
|
19981
|
+
if (!state.backgroundTaskIdsByToolId) state.backgroundTaskIdsByToolId = /* @__PURE__ */ new Map();
|
|
19982
|
+
state.backgroundToolIdByTaskId.set(taskId, toolUseId);
|
|
19983
|
+
const taskIds = state.backgroundTaskIdsByToolId.get(toolUseId) ?? /* @__PURE__ */ new Set();
|
|
19984
|
+
taskIds.add(taskId);
|
|
19985
|
+
state.backgroundTaskIdsByToolId.set(toolUseId, taskIds);
|
|
19986
|
+
}
|
|
19987
|
+
function clearBackgroundTaskIds(state, keys) {
|
|
19988
|
+
const activeIds = state.activeBackgroundTaskIds;
|
|
19989
|
+
if (!activeIds) return;
|
|
19990
|
+
for (const key of keys) {
|
|
19991
|
+
if (!key) continue;
|
|
19992
|
+
activeIds.delete(key);
|
|
19993
|
+
const toolUseId = state.backgroundToolIdByTaskId?.get(key);
|
|
19994
|
+
if (toolUseId) {
|
|
19995
|
+
activeIds.delete(toolUseId);
|
|
19996
|
+
state.backgroundToolIdByTaskId?.delete(key);
|
|
19997
|
+
const taskIds2 = state.backgroundTaskIdsByToolId?.get(toolUseId);
|
|
19998
|
+
taskIds2?.delete(key);
|
|
19999
|
+
if (taskIds2?.size === 0) state.backgroundTaskIdsByToolId?.delete(toolUseId);
|
|
20000
|
+
}
|
|
20001
|
+
const taskIds = state.backgroundTaskIdsByToolId?.get(key);
|
|
20002
|
+
if (taskIds) {
|
|
20003
|
+
for (const taskId of taskIds) {
|
|
20004
|
+
activeIds.delete(taskId);
|
|
20005
|
+
state.backgroundToolIdByTaskId?.delete(taskId);
|
|
20006
|
+
}
|
|
20007
|
+
state.backgroundTaskIdsByToolId?.delete(key);
|
|
20008
|
+
}
|
|
20009
|
+
}
|
|
20010
|
+
if (state.pendingLauncherToolIds) {
|
|
20011
|
+
state.pendingLauncherToolIds = state.pendingLauncherToolIds.filter((id) => activeIds.has(id));
|
|
20012
|
+
if (state.pendingLauncherToolIds.length === 0) state.pendingLauncherToolIds = void 0;
|
|
20013
|
+
}
|
|
20014
|
+
if (activeIds.size === 0) state.activeBackgroundTaskIds = void 0;
|
|
20015
|
+
}
|
|
20016
|
+
function resolveBackgroundTaskToolUseId(state, record2) {
|
|
20017
|
+
const explicitToolUseId = backgroundToolUseId(record2);
|
|
20018
|
+
if (explicitToolUseId) return explicitToolUseId;
|
|
20019
|
+
const taskId = backgroundTaskId(record2);
|
|
20020
|
+
return taskId ? state.backgroundToolIdByTaskId?.get(taskId) : void 0;
|
|
20021
|
+
}
|
|
20022
|
+
var TERMINAL_BACKGROUND_STATUSES = /* @__PURE__ */ new Set([
|
|
20023
|
+
"complete",
|
|
20024
|
+
"completed",
|
|
20025
|
+
"done",
|
|
20026
|
+
"success",
|
|
20027
|
+
"succeeded",
|
|
20028
|
+
"failed",
|
|
20029
|
+
"failure",
|
|
20030
|
+
"error",
|
|
20031
|
+
"cancelled",
|
|
20032
|
+
"canceled",
|
|
20033
|
+
"aborted",
|
|
20034
|
+
"interrupted",
|
|
20035
|
+
"stopped"
|
|
20036
|
+
]);
|
|
20037
|
+
var NON_TERMINAL_BACKGROUND_STATUSES = /* @__PURE__ */ new Set([
|
|
20038
|
+
"running",
|
|
20039
|
+
"in_progress",
|
|
20040
|
+
"inprogress",
|
|
20041
|
+
"started",
|
|
20042
|
+
"pending",
|
|
20043
|
+
"active",
|
|
20044
|
+
"working",
|
|
20045
|
+
"queued"
|
|
20046
|
+
]);
|
|
20047
|
+
var ASYNC_LAUNCH_ACK_RE = /^(async agent launched successfully|background (?:task|agent|subagent) (?:launched|started|running)|task (?:launched|started) successfully)/i;
|
|
20048
|
+
function isTerminalBackgroundStatus(record2) {
|
|
20049
|
+
const status = stringField(record2, "status")?.toLowerCase();
|
|
20050
|
+
if (status && TERMINAL_BACKGROUND_STATUSES.has(status)) return true;
|
|
20051
|
+
if (status && NON_TERMINAL_BACKGROUND_STATUSES.has(status)) return false;
|
|
20052
|
+
return typeof record2.duration_ms === "number" || typeof record2.durationMs === "number" || typeof record2.total_tokens === "number" || typeof record2.totalTokens === "number" || typeof record2.tool_uses === "number" || typeof record2.toolUses === "number";
|
|
20053
|
+
}
|
|
20054
|
+
function isFailedBackgroundStatus(record2) {
|
|
20055
|
+
const status = stringField(record2, "status")?.toLowerCase();
|
|
20056
|
+
return status === "failed" || status === "failure" || status === "error" || status === "cancelled" || status === "canceled" || status === "aborted" || status === "interrupted";
|
|
20057
|
+
}
|
|
20058
|
+
function extractBackgroundTaskIdFromPayload(value2) {
|
|
20059
|
+
if (typeof value2 === "string") {
|
|
20060
|
+
const trimmed = value2.trim();
|
|
20061
|
+
if (!trimmed) return void 0;
|
|
20062
|
+
try {
|
|
20063
|
+
return extractBackgroundTaskIdFromPayload(JSON.parse(trimmed));
|
|
20064
|
+
} catch {
|
|
20065
|
+
const match = trimmed.match(/\btask[_-]?id["']?\s*[:=]\s*["']?([A-Za-z0-9_.-]+)/i) ?? trimmed.match(/\btasks\/([A-Za-z0-9_.-]+)/i);
|
|
20066
|
+
if (match?.[1]) return match[1];
|
|
20067
|
+
if (/^[A-Za-z0-9_-]{6,128}$/.test(trimmed) && /(?:task|bg|async|job|agent)/i.test(trimmed)) {
|
|
20068
|
+
return trimmed;
|
|
20069
|
+
}
|
|
20070
|
+
return void 0;
|
|
20071
|
+
}
|
|
20072
|
+
}
|
|
20073
|
+
if (!value2 || typeof value2 !== "object" || Array.isArray(value2)) return void 0;
|
|
20074
|
+
const record2 = value2;
|
|
20075
|
+
return stringField(record2, "task_id") ?? stringField(record2, "taskId") ?? stringField(record2, "agentId") ?? stringField(record2, "agent_id") ?? extractBackgroundTaskIdFromPayload(record2.value) ?? extractBackgroundTaskIdFromPayload(record2.result) ?? extractBackgroundTaskIdFromPayload(record2.data) ?? extractBackgroundTaskIdFromPayload(record2.content);
|
|
20076
|
+
}
|
|
20077
|
+
function looksLikeBackgroundLaunchAck(options) {
|
|
20078
|
+
const taskId = extractBackgroundTaskIdFromPayload(options.value) ?? extractBackgroundTaskIdFromPayload(options.content);
|
|
20079
|
+
const content = options.content.trim();
|
|
20080
|
+
const explicitAckText = ASYNC_LAUNCH_ACK_RE.test(content);
|
|
20081
|
+
if (!options.trackedUnlinkedLauncher) return { isAck: false, taskId };
|
|
20082
|
+
if (options.explicitBackground && taskId) return { isAck: true, taskId };
|
|
20083
|
+
if (explicitAckText) return { isAck: true, taskId };
|
|
20084
|
+
if (taskId && content.length > 0 && content.length < 400) {
|
|
20085
|
+
const record2 = options.value && typeof options.value === "object" && !Array.isArray(options.value) ? options.value : null;
|
|
20086
|
+
const looksStructured = record2 !== null || content.startsWith("{") || /^task[_-]?id\b/i.test(content) || content === taskId;
|
|
20087
|
+
if (looksStructured) return { isAck: true, taskId };
|
|
20088
|
+
}
|
|
20089
|
+
return { isAck: false, taskId };
|
|
20090
|
+
}
|
|
20091
|
+
function settleBackgroundTerminalNotification(kind, context, state, record2, options) {
|
|
20092
|
+
const toolUseId = resolveBackgroundTaskToolUseId(state, record2);
|
|
20093
|
+
const keys = backgroundTaskKeys(record2);
|
|
20094
|
+
const wasActive = !!toolUseId && state.activeBackgroundTaskIds?.has(toolUseId) === true || keys.some((key) => state.activeBackgroundTaskIds?.has(key) === true);
|
|
20095
|
+
if (toolUseId && wasActive) {
|
|
20096
|
+
options.emitToolResult(toolUseId, options.resultText, options.isError);
|
|
20097
|
+
clearBackgroundTaskIds(state, keys);
|
|
20098
|
+
maybeFinalizeDeferredResult(kind, context, state);
|
|
20099
|
+
return toolUseId;
|
|
20100
|
+
}
|
|
20101
|
+
clearBackgroundTaskIds(state, keys);
|
|
20102
|
+
const drainedLauncher = drainNextUnlinkedBackgroundLauncher(state);
|
|
20103
|
+
if (drainedLauncher) {
|
|
20104
|
+
options.emitToolResult(drainedLauncher, options.resultText, options.isError);
|
|
20105
|
+
}
|
|
20106
|
+
maybeFinalizeDeferredResult(kind, context, state);
|
|
20107
|
+
return drainedLauncher;
|
|
20108
|
+
}
|
|
20109
|
+
function finalizeStructuredResult(kind, state) {
|
|
20110
|
+
state.resultReceived = true;
|
|
20111
|
+
state.onResultReceived?.();
|
|
20112
|
+
if (state.stdin && !state.stdin.destroyed) {
|
|
20113
|
+
state.stdin.end();
|
|
20114
|
+
console.info(`[${kind}] Closed stdin after result event to signal CLI exit`);
|
|
20115
|
+
}
|
|
20116
|
+
}
|
|
20117
|
+
function deferOrFinalizeStructuredResult(kind, context, state) {
|
|
20118
|
+
const pendingAsks = context.presenter.pendingAskUserToolIds?.size ?? 0;
|
|
20119
|
+
if (pendingAsks > 0) {
|
|
20120
|
+
console.info(
|
|
20121
|
+
`[${kind}] Keeping stdin open \u2014 ${pendingAsks} interactive question(s) awaiting user response`
|
|
20122
|
+
);
|
|
20123
|
+
state.resultDeferredOnPendingAnswer = true;
|
|
20124
|
+
return "deferred_pending_answer";
|
|
20125
|
+
}
|
|
20126
|
+
const activeBackgroundTasks = state.activeBackgroundTaskIds?.size ?? 0;
|
|
20127
|
+
if (activeBackgroundTasks > 0) {
|
|
20128
|
+
console.info(
|
|
20129
|
+
`[${kind}] Keeping stdin open \u2014 ${activeBackgroundTasks} background task(s) still active`
|
|
20130
|
+
);
|
|
20131
|
+
state.resultDeferredOnBackgroundWork = true;
|
|
20132
|
+
return "deferred_background_work";
|
|
20133
|
+
}
|
|
20134
|
+
finalizeStructuredResult(kind, state);
|
|
20135
|
+
return "finalized";
|
|
20136
|
+
}
|
|
20137
|
+
function maybeFinalizeDeferredResult(kind, context, state) {
|
|
20138
|
+
if (!state.resultDeferredOnBackgroundWork && !state.resultDeferredOnPendingAnswer) return;
|
|
20139
|
+
if (context.presenter.pendingAskUserToolIds?.size || state.activeBackgroundTaskIds?.size) return;
|
|
20140
|
+
if (state.resultDeferredOnBackgroundWork) {
|
|
20141
|
+
state.awaitingPostBackgroundSynthesis = true;
|
|
20142
|
+
console.info(
|
|
20143
|
+
`[${kind}] Background work drained \u2014 awaiting post-subagent synthesis before stdin close`
|
|
20144
|
+
);
|
|
20145
|
+
return;
|
|
20146
|
+
}
|
|
20147
|
+
state.resultDeferredOnPendingAnswer = false;
|
|
20148
|
+
finalizeStructuredResult(kind, state);
|
|
20149
|
+
}
|
|
19835
20150
|
var MAX_INLINE_GENERATED_IMAGE_BYTES = 20 * 1024 * 1024;
|
|
19836
20151
|
function inferImageMimeType(buffer) {
|
|
19837
20152
|
if (buffer.length >= 8 && buffer.subarray(0, 8).equals(Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]))) {
|
|
@@ -19947,6 +20262,20 @@ function buildToolResultText(parsed) {
|
|
|
19947
20262
|
const status = typeof parsed.status === "string" ? parsed.status.trim() : "";
|
|
19948
20263
|
return status || "Tool completed";
|
|
19949
20264
|
}
|
|
20265
|
+
function buildSubagentResultText(parsed) {
|
|
20266
|
+
const output = buildToolResultText(parsed);
|
|
20267
|
+
const status = typeof parsed.status === "string" ? parsed.status.trim() : "";
|
|
20268
|
+
const details = [
|
|
20269
|
+
typeof parsed.duration_ms === "number" ? `Duration: ${parsed.duration_ms}ms.` : "",
|
|
20270
|
+
typeof parsed.durationMs === "number" ? `Duration: ${parsed.durationMs}ms.` : "",
|
|
20271
|
+
typeof parsed.tool_uses === "number" ? `Tool uses: ${parsed.tool_uses}.` : "",
|
|
20272
|
+
typeof parsed.toolUses === "number" ? `Tool uses: ${parsed.toolUses}.` : "",
|
|
20273
|
+
typeof parsed.total_tokens === "number" ? `Tokens: ${parsed.total_tokens}.` : "",
|
|
20274
|
+
typeof parsed.totalTokens === "number" ? `Tokens: ${parsed.totalTokens}.` : ""
|
|
20275
|
+
].filter(Boolean);
|
|
20276
|
+
if (output !== "Tool completed") return output;
|
|
20277
|
+
return [`Subagent ${status || "completed"}.`, ...details].join(" ");
|
|
20278
|
+
}
|
|
19950
20279
|
function extractText(parsed) {
|
|
19951
20280
|
for (const key of ["text", "delta", "content", "message", "result"]) {
|
|
19952
20281
|
const value2 = parsed[key];
|
|
@@ -19993,6 +20322,286 @@ function extractSubagentInput(parsed) {
|
|
|
19993
20322
|
workspace: parsed.workspace
|
|
19994
20323
|
};
|
|
19995
20324
|
}
|
|
20325
|
+
function antigravityTranscriptRoot(context) {
|
|
20326
|
+
const home = context.env.HOME || process.env.HOME || (0, import_os4.homedir)();
|
|
20327
|
+
return (0, import_path5.resolve)(home, ".gemini", "antigravity-cli", "brain");
|
|
20328
|
+
}
|
|
20329
|
+
function resolveAntigravityTranscriptPath(parsed, context) {
|
|
20330
|
+
const logUri = stringField2(parsed, "log_uri");
|
|
20331
|
+
const conversationId = stringField2(parsed, "task_id") ?? stringField2(parsed, "conversation_id");
|
|
20332
|
+
if (!logUri || !conversationId) return void 0;
|
|
20333
|
+
try {
|
|
20334
|
+
const url3 = new URL(logUri);
|
|
20335
|
+
if (url3.protocol !== "file:") return void 0;
|
|
20336
|
+
const root = antigravityTranscriptRoot(context);
|
|
20337
|
+
const transcriptPath = (0, import_path5.resolve)((0, import_url.fileURLToPath)(url3));
|
|
20338
|
+
const pathFromRoot = (0, import_path5.relative)(root, transcriptPath);
|
|
20339
|
+
const segments = pathFromRoot.split(import_path5.sep);
|
|
20340
|
+
if (!pathFromRoot || pathFromRoot === ".." || pathFromRoot.startsWith(`..${import_path5.sep}`) || (0, import_path5.isAbsolute)(pathFromRoot) || segments[0] !== conversationId || segments.at(-1) !== "transcript.jsonl" || segments.at(-2) !== "logs" || segments.at(-3) !== ".system_generated") {
|
|
20341
|
+
return void 0;
|
|
20342
|
+
}
|
|
20343
|
+
return transcriptPath;
|
|
20344
|
+
} catch {
|
|
20345
|
+
return void 0;
|
|
20346
|
+
}
|
|
20347
|
+
}
|
|
20348
|
+
function antigravityTranscriptToolId(parentToolUseId, lineIndex, toolIndex) {
|
|
20349
|
+
return `${parentToolUseId}-transcript-${lineIndex}-${toolIndex}`;
|
|
20350
|
+
}
|
|
20351
|
+
var ANTIGRAVITY_TOOL_RESULT_TYPES = /* @__PURE__ */ new Set([
|
|
20352
|
+
"LIST_DIRECTORY",
|
|
20353
|
+
"VIEW_FILE",
|
|
20354
|
+
"MCP_TOOL",
|
|
20355
|
+
"INVOKE_SUBAGENT",
|
|
20356
|
+
"RUN_COMMAND",
|
|
20357
|
+
"GENERIC",
|
|
20358
|
+
"GREP_SEARCH",
|
|
20359
|
+
"CODE_ACTION",
|
|
20360
|
+
"SEND_MESSAGE"
|
|
20361
|
+
]);
|
|
20362
|
+
function isAntigravityToolResultEntry(entry) {
|
|
20363
|
+
const type = stringField2(entry, "type")?.toUpperCase();
|
|
20364
|
+
if (type && ANTIGRAVITY_TOOL_RESULT_TYPES.has(type)) return true;
|
|
20365
|
+
const content = stringField2(entry, "content");
|
|
20366
|
+
return Boolean(content?.startsWith("Created At:"));
|
|
20367
|
+
}
|
|
20368
|
+
function stripAntigravityToolResultEnvelope(content) {
|
|
20369
|
+
const stripped = content.replace(/^(?:Created At:[^\n]*\n|Completed At:[^\n]*\n)+/u, "");
|
|
20370
|
+
return stripped.trim().length > 0 ? stripped : content;
|
|
20371
|
+
}
|
|
20372
|
+
function readAntigravityTranscriptLines(transcriptPath) {
|
|
20373
|
+
try {
|
|
20374
|
+
const lines = (0, import_fs5.readFileSync)(transcriptPath, "utf8").split(/\r?\n/);
|
|
20375
|
+
if (lines.at(-1) === "") lines.pop();
|
|
20376
|
+
return lines;
|
|
20377
|
+
} catch {
|
|
20378
|
+
return void 0;
|
|
20379
|
+
}
|
|
20380
|
+
}
|
|
20381
|
+
function syncAntigravitySubagentTranscript(transcriptPath, parentToolUseId, presenter, startLine = 0, pendingToolIds = []) {
|
|
20382
|
+
const lines = readAntigravityTranscriptLines(transcriptPath);
|
|
20383
|
+
if (!lines) {
|
|
20384
|
+
return { processedLineCount: startLine, emittedEventCount: 0, pendingToolIds };
|
|
20385
|
+
}
|
|
20386
|
+
let processedLineCount = startLine > lines.length ? 0 : startLine;
|
|
20387
|
+
let emittedEventCount = 0;
|
|
20388
|
+
for (let lineIndex = processedLineCount; lineIndex < lines.length; lineIndex += 1) {
|
|
20389
|
+
const line = lines[lineIndex];
|
|
20390
|
+
if (!line) {
|
|
20391
|
+
processedLineCount = lineIndex + 1;
|
|
20392
|
+
continue;
|
|
20393
|
+
}
|
|
20394
|
+
let entry;
|
|
20395
|
+
try {
|
|
20396
|
+
entry = JSON.parse(line);
|
|
20397
|
+
} catch {
|
|
20398
|
+
break;
|
|
20399
|
+
}
|
|
20400
|
+
processedLineCount = lineIndex + 1;
|
|
20401
|
+
if (stringField2(entry, "source") !== "MODEL") continue;
|
|
20402
|
+
const thinking = stringField2(entry, "thinking") ?? stringField2(entry, "thinking_delta");
|
|
20403
|
+
if (thinking) {
|
|
20404
|
+
emittedEventCount += 1;
|
|
20405
|
+
void presenter.onThinking(thinking, parentToolUseId);
|
|
20406
|
+
}
|
|
20407
|
+
const toolCalls = Array.isArray(entry.tool_calls) ? entry.tool_calls : [];
|
|
20408
|
+
toolCalls.forEach((rawToolCall, toolIndex) => {
|
|
20409
|
+
const toolCall = asRecord(rawToolCall);
|
|
20410
|
+
const toolName = toolCall && stringField2(toolCall, "name");
|
|
20411
|
+
if (!toolName) return;
|
|
20412
|
+
const toolId = antigravityTranscriptToolId(parentToolUseId, lineIndex, toolIndex);
|
|
20413
|
+
pendingToolIds.push(toolId);
|
|
20414
|
+
emittedEventCount += 1;
|
|
20415
|
+
void presenter.onToolUse(
|
|
20416
|
+
toolName,
|
|
20417
|
+
toolCall?.args ?? toolCall?.parameters ?? {},
|
|
20418
|
+
toolId,
|
|
20419
|
+
parentToolUseId
|
|
20420
|
+
);
|
|
20421
|
+
});
|
|
20422
|
+
const content = stringField2(entry, "content");
|
|
20423
|
+
if (content && isAntigravityToolResultEntry(entry)) {
|
|
20424
|
+
const toolId = pendingToolIds.shift();
|
|
20425
|
+
if (toolId) {
|
|
20426
|
+
emittedEventCount += 1;
|
|
20427
|
+
void presenter.onToolResult?.(
|
|
20428
|
+
toolId,
|
|
20429
|
+
stripAntigravityToolResultEnvelope(content),
|
|
20430
|
+
void 0,
|
|
20431
|
+
parentToolUseId
|
|
20432
|
+
);
|
|
20433
|
+
}
|
|
20434
|
+
continue;
|
|
20435
|
+
}
|
|
20436
|
+
if (!content) continue;
|
|
20437
|
+
const entryType = stringField2(entry, "type")?.toUpperCase();
|
|
20438
|
+
if (entryType === "SYSTEM_MESSAGE") continue;
|
|
20439
|
+
emittedEventCount += 1;
|
|
20440
|
+
void presenter.onAssistantText(content, parentToolUseId);
|
|
20441
|
+
}
|
|
20442
|
+
return { processedLineCount, emittedEventCount, pendingToolIds };
|
|
20443
|
+
}
|
|
20444
|
+
function resolveAntigravityParentTranscriptPath(conversationId, context) {
|
|
20445
|
+
return (0, import_path5.resolve)(
|
|
20446
|
+
antigravityTranscriptRoot(context),
|
|
20447
|
+
conversationId,
|
|
20448
|
+
".system_generated",
|
|
20449
|
+
"logs",
|
|
20450
|
+
"transcript.jsonl"
|
|
20451
|
+
);
|
|
20452
|
+
}
|
|
20453
|
+
function syncAntigravityParentThinkingFromTranscript(context, state) {
|
|
20454
|
+
const parent = state.antigravityParentTranscript;
|
|
20455
|
+
if (!parent?.transcriptPath) return 0;
|
|
20456
|
+
const lines = readAntigravityTranscriptLines(parent.transcriptPath);
|
|
20457
|
+
if (!lines) return 0;
|
|
20458
|
+
let processedLineCount = parent.replayedLineCount > lines.length ? 0 : parent.replayedLineCount;
|
|
20459
|
+
let emittedEventCount = 0;
|
|
20460
|
+
for (let lineIndex = processedLineCount; lineIndex < lines.length; lineIndex += 1) {
|
|
20461
|
+
const line = lines[lineIndex];
|
|
20462
|
+
if (!line) {
|
|
20463
|
+
processedLineCount = lineIndex + 1;
|
|
20464
|
+
continue;
|
|
20465
|
+
}
|
|
20466
|
+
let entry;
|
|
20467
|
+
try {
|
|
20468
|
+
entry = JSON.parse(line);
|
|
20469
|
+
} catch {
|
|
20470
|
+
break;
|
|
20471
|
+
}
|
|
20472
|
+
processedLineCount = lineIndex + 1;
|
|
20473
|
+
if (stringField2(entry, "source") !== "MODEL") continue;
|
|
20474
|
+
const thinking = stringField2(entry, "thinking") ?? stringField2(entry, "thinking_delta");
|
|
20475
|
+
if (!thinking) continue;
|
|
20476
|
+
emittedEventCount += 1;
|
|
20477
|
+
void context.presenter.onThinking(thinking);
|
|
20478
|
+
}
|
|
20479
|
+
parent.replayedLineCount = processedLineCount;
|
|
20480
|
+
return emittedEventCount;
|
|
20481
|
+
}
|
|
20482
|
+
function syncAntigravitySubagentEventsFromTranscripts(context, state) {
|
|
20483
|
+
let emittedEventCount = syncAntigravityParentThinkingFromTranscript(context, state);
|
|
20484
|
+
for (const [launcherId, task] of state.antigravitySubagentTranscripts ?? []) {
|
|
20485
|
+
if (!task.transcriptPath) continue;
|
|
20486
|
+
const replay = syncAntigravitySubagentTranscript(
|
|
20487
|
+
task.transcriptPath,
|
|
20488
|
+
launcherId,
|
|
20489
|
+
context.presenter,
|
|
20490
|
+
task.replayedLineCount,
|
|
20491
|
+
task.pendingToolIds ?? []
|
|
20492
|
+
);
|
|
20493
|
+
task.replayedLineCount = replay.processedLineCount;
|
|
20494
|
+
task.pendingToolIds = replay.pendingToolIds;
|
|
20495
|
+
task.emittedEventCount += replay.emittedEventCount;
|
|
20496
|
+
emittedEventCount += replay.emittedEventCount;
|
|
20497
|
+
}
|
|
20498
|
+
if (emittedEventCount > 0) state.onNewOutput?.();
|
|
20499
|
+
return emittedEventCount;
|
|
20500
|
+
}
|
|
20501
|
+
function ensureAntigravitySubagentTranscriptPolling(context, state) {
|
|
20502
|
+
if (state.providerTranscriptPollTimer) {
|
|
20503
|
+
syncAntigravitySubagentEventsFromTranscripts(context, state);
|
|
20504
|
+
return;
|
|
20505
|
+
}
|
|
20506
|
+
const poll = () => {
|
|
20507
|
+
try {
|
|
20508
|
+
syncAntigravitySubagentEventsFromTranscripts(context, state);
|
|
20509
|
+
state.providerTranscriptPollErrorLogged = false;
|
|
20510
|
+
} catch (error2) {
|
|
20511
|
+
if (!state.providerTranscriptPollErrorLogged) {
|
|
20512
|
+
console.warn("[antigravity_cli] Failed to poll child transcript:", error2);
|
|
20513
|
+
state.providerTranscriptPollErrorLogged = true;
|
|
20514
|
+
}
|
|
20515
|
+
}
|
|
20516
|
+
};
|
|
20517
|
+
poll();
|
|
20518
|
+
const timer = setInterval(poll, 750);
|
|
20519
|
+
timer.unref?.();
|
|
20520
|
+
state.providerTranscriptPollTimer = timer;
|
|
20521
|
+
}
|
|
20522
|
+
function clearAntigravityTranscriptPollingIfIdle(state) {
|
|
20523
|
+
const hasChildren = (state.antigravitySubagentTranscripts?.size ?? 0) > 0;
|
|
20524
|
+
const hasParent = Boolean(state.antigravityParentTranscript);
|
|
20525
|
+
if (hasChildren || hasParent) return;
|
|
20526
|
+
if (state.providerTranscriptPollTimer) clearInterval(state.providerTranscriptPollTimer);
|
|
20527
|
+
state.providerTranscriptPollTimer = void 0;
|
|
20528
|
+
}
|
|
20529
|
+
function registerAntigravityParentTranscript(conversationId, context, state) {
|
|
20530
|
+
if (!conversationId) return;
|
|
20531
|
+
const existing = state.antigravityParentTranscript;
|
|
20532
|
+
if (existing?.conversationId === conversationId) {
|
|
20533
|
+
ensureAntigravitySubagentTranscriptPolling(context, state);
|
|
20534
|
+
return;
|
|
20535
|
+
}
|
|
20536
|
+
state.antigravityParentTranscript = {
|
|
20537
|
+
conversationId,
|
|
20538
|
+
transcriptPath: resolveAntigravityParentTranscriptPath(conversationId, context),
|
|
20539
|
+
// Skip historical rows from prior turns on resume; only stream new thinking.
|
|
20540
|
+
replayedLineCount: readAntigravityTranscriptLines(
|
|
20541
|
+
resolveAntigravityParentTranscriptPath(conversationId, context)
|
|
20542
|
+
)?.length ?? 0
|
|
20543
|
+
};
|
|
20544
|
+
ensureAntigravitySubagentTranscriptPolling(context, state);
|
|
20545
|
+
}
|
|
20546
|
+
function registerAntigravitySubagentTranscript(parsed, toolId, context, state) {
|
|
20547
|
+
if (!state.antigravitySubagentTranscripts) state.antigravitySubagentTranscripts = /* @__PURE__ */ new Map();
|
|
20548
|
+
const task = state.antigravitySubagentTranscripts.get(toolId) ?? {
|
|
20549
|
+
replayedLineCount: 0,
|
|
20550
|
+
emittedEventCount: 0,
|
|
20551
|
+
pendingToolIds: []
|
|
20552
|
+
};
|
|
20553
|
+
const incomingConversationId = stringField2(parsed, "task_id");
|
|
20554
|
+
if (task.conversationId && incomingConversationId && incomingConversationId !== task.conversationId) {
|
|
20555
|
+
if (!state.antigravityCorrelationWarnLogged) {
|
|
20556
|
+
console.warn(
|
|
20557
|
+
`[antigravity_cli] Subagent launcher ${toolId} saw a conversation id change (${task.conversationId} -> ${incomingConversationId}); keeping the original transcript association.`
|
|
20558
|
+
);
|
|
20559
|
+
state.antigravityCorrelationWarnLogged = true;
|
|
20560
|
+
}
|
|
20561
|
+
return;
|
|
20562
|
+
}
|
|
20563
|
+
task.conversationId = incomingConversationId ?? task.conversationId;
|
|
20564
|
+
const resolvedPath = resolveAntigravityTranscriptPath(parsed, context);
|
|
20565
|
+
if (!resolvedPath && !task.transcriptPath && stringField2(parsed, "log_uri")) {
|
|
20566
|
+
if (!state.antigravityTranscriptPathWarnLogged) {
|
|
20567
|
+
console.warn(
|
|
20568
|
+
`[antigravity_cli] Subagent log_uri for ${toolId} did not match the expected Antigravity transcript path layout; its live stream will not be tailed.`
|
|
20569
|
+
);
|
|
20570
|
+
state.antigravityTranscriptPathWarnLogged = true;
|
|
20571
|
+
}
|
|
20572
|
+
}
|
|
20573
|
+
task.transcriptPath = resolvedPath ?? task.transcriptPath;
|
|
20574
|
+
state.antigravitySubagentTranscripts.set(toolId, task);
|
|
20575
|
+
if (task.transcriptPath) ensureAntigravitySubagentTranscriptPolling(context, state);
|
|
20576
|
+
}
|
|
20577
|
+
function settleAntigravitySubagentTranscripts(context, state, isError = false) {
|
|
20578
|
+
syncAntigravitySubagentEventsFromTranscripts(context, state);
|
|
20579
|
+
for (const [toolId, task] of state.antigravitySubagentTranscripts ?? []) {
|
|
20580
|
+
settleBackgroundTerminalNotification(
|
|
20581
|
+
"antigravity_cli",
|
|
20582
|
+
context,
|
|
20583
|
+
state,
|
|
20584
|
+
{
|
|
20585
|
+
tool_use_id: toolId,
|
|
20586
|
+
...task.conversationId ? { task_id: task.conversationId } : {},
|
|
20587
|
+
status: isError ? "error" : "completed"
|
|
20588
|
+
},
|
|
20589
|
+
{
|
|
20590
|
+
resultText: isError ? "Subagent ended because the parent run failed" : "Subagent completed",
|
|
20591
|
+
isError: isError || void 0,
|
|
20592
|
+
emitToolResult: (id, text, error2) => {
|
|
20593
|
+
void context.presenter.onToolResult?.(id, text, error2);
|
|
20594
|
+
}
|
|
20595
|
+
}
|
|
20596
|
+
);
|
|
20597
|
+
state.antigravitySubagentTranscripts?.delete(toolId);
|
|
20598
|
+
}
|
|
20599
|
+
if (state.antigravitySubagentTranscripts?.size === 0) {
|
|
20600
|
+
state.antigravitySubagentTranscripts = void 0;
|
|
20601
|
+
}
|
|
20602
|
+
state.antigravityParentTranscript = void 0;
|
|
20603
|
+
clearAntigravityTranscriptPollingIfIdle(state);
|
|
20604
|
+
}
|
|
19996
20605
|
function extractToolId(parsed, state) {
|
|
19997
20606
|
for (const key of ["tool_id", "toolId", "id", "call_id"]) {
|
|
19998
20607
|
const value2 = parsed[key];
|
|
@@ -20001,21 +20610,140 @@ function extractToolId(parsed, state) {
|
|
|
20001
20610
|
state.iterations += 1;
|
|
20002
20611
|
return `antigravity-tool-${state.iterations}`;
|
|
20003
20612
|
}
|
|
20004
|
-
function
|
|
20005
|
-
|
|
20006
|
-
|
|
20007
|
-
|
|
20008
|
-
|
|
20009
|
-
|
|
20010
|
-
|
|
20011
|
-
|
|
20613
|
+
function asRecord(value2) {
|
|
20614
|
+
return typeof value2 === "object" && value2 !== null && !Array.isArray(value2) ? value2 : void 0;
|
|
20615
|
+
}
|
|
20616
|
+
function stringField2(value2, key) {
|
|
20617
|
+
const field = value2[key];
|
|
20618
|
+
return typeof field === "string" && field.trim() ? field : void 0;
|
|
20619
|
+
}
|
|
20620
|
+
function liveStepId(step, subagentIndex) {
|
|
20621
|
+
const conversationId = stringField2(step, "conversation_id") ?? "unknown";
|
|
20622
|
+
const stepIndex = typeof step.step_index === "number" ? step.step_index : "unknown";
|
|
20623
|
+
const base = `antigravity-${conversationId}-step-${stepIndex}`;
|
|
20624
|
+
return typeof subagentIndex === "number" ? `${base}-subagent-${subagentIndex}` : base;
|
|
20625
|
+
}
|
|
20626
|
+
function isActiveStep(step) {
|
|
20627
|
+
return stringField2(step, "state")?.toLowerCase() === "active";
|
|
20628
|
+
}
|
|
20629
|
+
function normalizeLiveAntigravityEvent(parsed) {
|
|
20630
|
+
const event = stringField2(parsed, "event");
|
|
20631
|
+
if (!event) return void 0;
|
|
20632
|
+
const conversationId = stringField2(parsed, "conversation_id");
|
|
20633
|
+
if (event === "init") {
|
|
20634
|
+
return [
|
|
20635
|
+
{
|
|
20636
|
+
...asRecord(parsed.init) ?? {},
|
|
20637
|
+
type: "init",
|
|
20638
|
+
...conversationId ? { conversation_id: conversationId } : {}
|
|
20639
|
+
}
|
|
20640
|
+
];
|
|
20641
|
+
}
|
|
20642
|
+
if (event === "result") {
|
|
20643
|
+
const result = asRecord(parsed.result) ?? {};
|
|
20644
|
+
return [
|
|
20645
|
+
{
|
|
20646
|
+
...result,
|
|
20647
|
+
type: "complete",
|
|
20648
|
+
...conversationId && !stringField2(result, "conversation_id") ? { conversation_id: conversationId } : {},
|
|
20649
|
+
...typeof result.response === "string" && typeof result.result !== "string" ? { result: result.response } : {}
|
|
20650
|
+
}
|
|
20651
|
+
];
|
|
20652
|
+
}
|
|
20653
|
+
if (event !== "step_update") return [{ type: `antigravity_event:${event}` }];
|
|
20654
|
+
const step = asRecord(parsed.step_update);
|
|
20655
|
+
if (!step) return [{ type: "antigravity_step_update" }];
|
|
20656
|
+
const normalizedStep = {
|
|
20657
|
+
...step,
|
|
20658
|
+
...conversationId && !stringField2(step, "conversation_id") ? { conversation_id: conversationId } : {}
|
|
20659
|
+
};
|
|
20660
|
+
const stepType = stringField2(normalizedStep, "step_type")?.toLowerCase();
|
|
20661
|
+
const thinkingText = stringField2(normalizedStep, "thinking_delta") ?? stringField2(normalizedStep, "thinking");
|
|
20662
|
+
const thinkingEvents = thinkingText ? [{ type: "thinking", text: thinkingText, content: thinkingText }] : [];
|
|
20663
|
+
if (stepType === "agent_response") {
|
|
20664
|
+
return [
|
|
20665
|
+
...thinkingEvents,
|
|
20666
|
+
{
|
|
20667
|
+
...normalizedStep,
|
|
20668
|
+
type: "assistant_message",
|
|
20669
|
+
...typeof normalizedStep.text_delta === "string" ? { content: normalizedStep.text_delta } : {}
|
|
20670
|
+
}
|
|
20671
|
+
];
|
|
20012
20672
|
}
|
|
20673
|
+
if (stepType === "tool") {
|
|
20674
|
+
const toolInfo = asRecord(normalizedStep.tool_info) ?? {};
|
|
20675
|
+
const toolName = stringField2(normalizedStep, "tool_name") ?? stringField2(toolInfo, "name") ?? "Antigravity Tool";
|
|
20676
|
+
const toolId = liveStepId(normalizedStep);
|
|
20677
|
+
if (isActiveStep(normalizedStep)) {
|
|
20678
|
+
return [
|
|
20679
|
+
...thinkingEvents,
|
|
20680
|
+
{
|
|
20681
|
+
...normalizedStep,
|
|
20682
|
+
...toolInfo,
|
|
20683
|
+
type: "tool_call",
|
|
20684
|
+
tool_id: toolId,
|
|
20685
|
+
tool_name: toolName,
|
|
20686
|
+
parameters: toolInfo.parameters ?? normalizedStep.parameters ?? {}
|
|
20687
|
+
}
|
|
20688
|
+
];
|
|
20689
|
+
}
|
|
20690
|
+
const toolOutput = stringField2(toolInfo, "output") ?? stringField2(normalizedStep, "output") ?? `${toolName} completed`;
|
|
20691
|
+
return [
|
|
20692
|
+
...thinkingEvents,
|
|
20693
|
+
{
|
|
20694
|
+
...normalizedStep,
|
|
20695
|
+
type: "tool_result",
|
|
20696
|
+
tool_id: toolId,
|
|
20697
|
+
output: toolOutput
|
|
20698
|
+
}
|
|
20699
|
+
];
|
|
20700
|
+
}
|
|
20701
|
+
if (stepType === "subagent") {
|
|
20702
|
+
const subagents = asRecord(normalizedStep.subagent_info)?.subagents;
|
|
20703
|
+
const children = Array.isArray(subagents) ? subagents.map(asRecord).filter((subagent) => Boolean(subagent)) : [];
|
|
20704
|
+
const entries = children.length > 0 ? children : [void 0];
|
|
20705
|
+
return [
|
|
20706
|
+
...thinkingEvents,
|
|
20707
|
+
...entries.map((subagent, index) => {
|
|
20708
|
+
const toolId = liveStepId(normalizedStep, index);
|
|
20709
|
+
const childConversationId = subagent && stringField2(subagent, "conversation_id");
|
|
20710
|
+
return {
|
|
20711
|
+
...normalizedStep,
|
|
20712
|
+
// AGY's DONE means the invocation was accepted, not that the child has
|
|
20713
|
+
// finished. The authenticated stream emits it milliseconds after ACTIVE
|
|
20714
|
+
// while the child transcript is still growing.
|
|
20715
|
+
type: isActiveStep(normalizedStep) ? "subagent_started" : "subagent_launch_ack",
|
|
20716
|
+
antigravity_live: true,
|
|
20717
|
+
tool_id: toolId,
|
|
20718
|
+
task_id: childConversationId ?? toolId,
|
|
20719
|
+
role: subagent && stringField2(subagent, "role"),
|
|
20720
|
+
type_name: subagent && stringField2(subagent, "type_name"),
|
|
20721
|
+
prompt: subagent && (stringField2(subagent, "initial_prompt") ?? stringField2(subagent, "prompt")),
|
|
20722
|
+
workspace: subagent && stringField2(subagent, "workspace"),
|
|
20723
|
+
log_uri: subagent && stringField2(subagent, "log_uri"),
|
|
20724
|
+
status: isActiveStep(normalizedStep) ? "running" : "launched"
|
|
20725
|
+
};
|
|
20726
|
+
})
|
|
20727
|
+
];
|
|
20728
|
+
}
|
|
20729
|
+
if (thinkingEvents.length > 0) return thinkingEvents;
|
|
20730
|
+
return [{ ...normalizedStep, type: "antigravity_step_update" }];
|
|
20731
|
+
}
|
|
20732
|
+
function handleAntigravityStructuredEvent(parsed, context, state) {
|
|
20733
|
+
const normalized = normalizeLiveAntigravityEvent(parsed);
|
|
20734
|
+
if (normalized) {
|
|
20735
|
+
return normalized.every((event) => handleAntigravityStructuredEvent(event, context, state));
|
|
20736
|
+
}
|
|
20737
|
+
const presenter = context.presenter;
|
|
20013
20738
|
state.onNewOutput?.();
|
|
20014
20739
|
const type = typeof parsed.type === "string" ? parsed.type : "";
|
|
20015
|
-
if (!type) return;
|
|
20740
|
+
if (!type) return false;
|
|
20016
20741
|
if (typeof parsed.session_id === "string") state.runtimeSessionId = parsed.session_id;
|
|
20017
20742
|
if (typeof parsed.conversation_id === "string") state.runtimeSessionId = parsed.conversation_id;
|
|
20018
20743
|
if (typeof parsed.model === "string") state.activeModel = parsed.model;
|
|
20744
|
+
if (typeof state.runtimeSessionId === "string" && state.runtimeSessionId.trim()) {
|
|
20745
|
+
registerAntigravityParentTranscript(state.runtimeSessionId, context, state);
|
|
20746
|
+
}
|
|
20019
20747
|
switch (type) {
|
|
20020
20748
|
case "init":
|
|
20021
20749
|
case "session_start": {
|
|
@@ -20023,29 +20751,31 @@ function parseAntigravityStructuredLine(line, context, state) {
|
|
|
20023
20751
|
void presenter.onLog(
|
|
20024
20752
|
`[antigravity] Session initialized with ${formatAntigravityModelName(model)}`
|
|
20025
20753
|
);
|
|
20026
|
-
|
|
20754
|
+
return true;
|
|
20027
20755
|
}
|
|
20756
|
+
case "antigravity_step_update":
|
|
20757
|
+
return true;
|
|
20028
20758
|
case "thinking":
|
|
20029
20759
|
case "reasoning":
|
|
20030
20760
|
case "thought": {
|
|
20031
20761
|
const text = extractText(parsed);
|
|
20032
|
-
if (!text)
|
|
20762
|
+
if (!text) return true;
|
|
20033
20763
|
state.iterations = Math.max(state.iterations, 1);
|
|
20034
20764
|
void presenter.onThinking(text);
|
|
20035
|
-
|
|
20765
|
+
return true;
|
|
20036
20766
|
}
|
|
20037
20767
|
case "message":
|
|
20038
20768
|
case "assistant_message":
|
|
20039
20769
|
case "text":
|
|
20040
20770
|
case "content": {
|
|
20041
20771
|
const role = typeof parsed.role === "string" ? parsed.role : "assistant";
|
|
20042
|
-
if (role !== "assistant")
|
|
20772
|
+
if (role !== "assistant") return true;
|
|
20043
20773
|
const content = extractText(parsed);
|
|
20044
|
-
if (!content)
|
|
20774
|
+
if (!content) return true;
|
|
20045
20775
|
state.iterations = Math.max(state.iterations, 1);
|
|
20046
20776
|
state.summary += content;
|
|
20047
20777
|
void presenter.onAssistantText(content);
|
|
20048
|
-
|
|
20778
|
+
return true;
|
|
20049
20779
|
}
|
|
20050
20780
|
case "tool_use":
|
|
20051
20781
|
case "tool_call":
|
|
@@ -20054,7 +20784,7 @@ function parseAntigravityStructuredLine(line, context, state) {
|
|
|
20054
20784
|
const toolId = extractToolId(parsed, state);
|
|
20055
20785
|
state.iterations = Math.max(state.iterations, 1);
|
|
20056
20786
|
void presenter.onToolUse(extractToolName(parsed), extractToolInput(parsed), toolId);
|
|
20057
|
-
|
|
20787
|
+
return true;
|
|
20058
20788
|
}
|
|
20059
20789
|
case "subagent_start":
|
|
20060
20790
|
case "subagent_started":
|
|
@@ -20064,12 +20794,22 @@ function parseAntigravityStructuredLine(line, context, state) {
|
|
|
20064
20794
|
case "background_subagent_started": {
|
|
20065
20795
|
const toolId = extractToolId(parsed, state);
|
|
20066
20796
|
state.iterations = Math.max(state.iterations, 1);
|
|
20797
|
+
registerBackgroundLauncher(state, toolId);
|
|
20798
|
+
registerBackgroundTaskRecord(state, { ...parsed, tool_use_id: toolId }, toolId);
|
|
20067
20799
|
void presenter.onToolUse(
|
|
20068
20800
|
`Subagent: ${extractSubagentName(parsed)}`,
|
|
20069
20801
|
extractSubagentInput(parsed),
|
|
20070
20802
|
toolId
|
|
20071
20803
|
);
|
|
20072
|
-
|
|
20804
|
+
if (parsed.antigravity_live === true || stringField2(parsed, "log_uri")) {
|
|
20805
|
+
registerAntigravitySubagentTranscript(parsed, toolId, context, state);
|
|
20806
|
+
}
|
|
20807
|
+
return true;
|
|
20808
|
+
}
|
|
20809
|
+
case "subagent_launch_ack": {
|
|
20810
|
+
const toolId = extractToolId(parsed, state);
|
|
20811
|
+
registerAntigravitySubagentTranscript(parsed, toolId, context, state);
|
|
20812
|
+
return true;
|
|
20073
20813
|
}
|
|
20074
20814
|
case "tool_result":
|
|
20075
20815
|
case "tool_response":
|
|
@@ -20078,24 +20818,52 @@ function parseAntigravityStructuredLine(line, context, state) {
|
|
|
20078
20818
|
const toolId = extractToolId(parsed, state);
|
|
20079
20819
|
state.iterations = Math.max(state.iterations, 1);
|
|
20080
20820
|
void presenter.onToolResult?.(toolId, buildToolResultText(parsed));
|
|
20081
|
-
|
|
20821
|
+
return true;
|
|
20082
20822
|
}
|
|
20083
20823
|
case "subagent_result":
|
|
20084
20824
|
case "subagent_complete":
|
|
20085
20825
|
case "subagent_completed":
|
|
20086
20826
|
case "background_subagent_result":
|
|
20087
20827
|
case "background_subagent_completed": {
|
|
20088
|
-
const toolId = extractToolId(parsed, state);
|
|
20089
20828
|
state.iterations = Math.max(state.iterations, 1);
|
|
20090
|
-
|
|
20091
|
-
|
|
20829
|
+
const toolId = extractToolId(parsed, state);
|
|
20830
|
+
const settledToolId = settleBackgroundTerminalNotification(
|
|
20831
|
+
"antigravity_cli",
|
|
20832
|
+
context,
|
|
20833
|
+
state,
|
|
20834
|
+
{ ...parsed, tool_use_id: toolId },
|
|
20835
|
+
{
|
|
20836
|
+
resultText: buildSubagentResultText(parsed),
|
|
20837
|
+
isError: isFailedBackgroundStatus(parsed),
|
|
20838
|
+
emitToolResult: (toolId2, text, isError) => {
|
|
20839
|
+
void presenter.onToolResult?.(toolId2, text, isError);
|
|
20840
|
+
}
|
|
20841
|
+
}
|
|
20842
|
+
);
|
|
20843
|
+
if (settledToolId) state.antigravitySubagentTranscripts?.delete(settledToolId);
|
|
20844
|
+
return true;
|
|
20845
|
+
}
|
|
20846
|
+
case "subagent_status":
|
|
20847
|
+
case "background_subagent_status":
|
|
20848
|
+
case "background_task_status": {
|
|
20849
|
+
registerBackgroundTaskRecord(state, parsed);
|
|
20850
|
+
if (isTerminalBackgroundStatus(parsed)) {
|
|
20851
|
+
settleBackgroundTerminalNotification("antigravity_cli", context, state, parsed, {
|
|
20852
|
+
resultText: buildSubagentResultText(parsed),
|
|
20853
|
+
isError: isFailedBackgroundStatus(parsed),
|
|
20854
|
+
emitToolResult: (toolId, text, isError) => {
|
|
20855
|
+
void presenter.onToolResult?.(toolId, text, isError);
|
|
20856
|
+
}
|
|
20857
|
+
});
|
|
20858
|
+
}
|
|
20859
|
+
return true;
|
|
20092
20860
|
}
|
|
20093
20861
|
case "image_generation_end":
|
|
20094
20862
|
case "generated_image":
|
|
20095
20863
|
case "image": {
|
|
20096
20864
|
const image = buildGeneratedImageFromAntigravityPayload(parsed);
|
|
20097
20865
|
if (image) void presenter.onGeneratedImage?.(image);
|
|
20098
|
-
|
|
20866
|
+
return true;
|
|
20099
20867
|
}
|
|
20100
20868
|
case "error": {
|
|
20101
20869
|
const errObj = typeof parsed.error === "object" && parsed.error !== null ? parsed.error : null;
|
|
@@ -20109,20 +20877,31 @@ function parseAntigravityStructuredLine(line, context, state) {
|
|
|
20109
20877
|
void presenter.onLog(`[antigravity/${severity}] ${message}`);
|
|
20110
20878
|
}
|
|
20111
20879
|
}
|
|
20112
|
-
|
|
20880
|
+
return true;
|
|
20113
20881
|
}
|
|
20114
20882
|
case "result":
|
|
20115
20883
|
case "complete": {
|
|
20116
|
-
const stats =
|
|
20117
|
-
state.iterations = Math.max(
|
|
20884
|
+
const stats = asRecord(parsed.usage) ?? asRecord(parsed.stats) ?? parsed;
|
|
20885
|
+
state.iterations = Math.max(
|
|
20886
|
+
state.iterations,
|
|
20887
|
+
typeof parsed.num_turns === "number" ? parsed.num_turns : 1
|
|
20888
|
+
);
|
|
20889
|
+
const resultText = typeof parsed.result === "string" ? parsed.result : "";
|
|
20890
|
+
if (resultText && !state.summary.trim()) {
|
|
20891
|
+
state.summary += resultText;
|
|
20892
|
+
void presenter.onAssistantText(resultText);
|
|
20893
|
+
}
|
|
20118
20894
|
const usageModel = state.activeModel || (typeof context.config.selectedModel === "string" && context.config.selectedModel.trim() ? context.config.selectedModel : "antigravity");
|
|
20119
20895
|
state.usage = {
|
|
20120
20896
|
model: formatAntigravityModelName(usageModel),
|
|
20121
20897
|
numTurns: Math.max(state.iterations, 1),
|
|
20898
|
+
// AGY's result.duration_seconds is conversation-scoped on resumed
|
|
20899
|
+
// sessions, so it is not a trustworthy per-turn duration. Keep this at
|
|
20900
|
+
// zero until the stream provides a dedicated turn-level metric.
|
|
20122
20901
|
durationMs: typeof stats.duration_ms === "number" ? stats.duration_ms : 0,
|
|
20123
20902
|
inputTokens: typeof stats.input_tokens === "number" ? stats.input_tokens : typeof stats.input === "number" ? stats.input : 0,
|
|
20124
20903
|
outputTokens: typeof stats.output_tokens === "number" ? stats.output_tokens : 0,
|
|
20125
|
-
cacheReadTokens: typeof stats.cached === "number" ? stats.cached : 0,
|
|
20904
|
+
cacheReadTokens: typeof stats.cache_read_tokens === "number" ? stats.cache_read_tokens : typeof stats.cached_input_tokens === "number" ? stats.cached_input_tokens : typeof stats.cached === "number" ? stats.cached : 0,
|
|
20126
20905
|
cacheCreationTokens: 0,
|
|
20127
20906
|
costUsd: 0
|
|
20128
20907
|
};
|
|
@@ -20133,15 +20912,15 @@ function parseAntigravityStructuredLine(line, context, state) {
|
|
|
20133
20912
|
cacheReadTokens: state.usage.cacheReadTokens,
|
|
20134
20913
|
cacheCreationTokens: state.usage.cacheCreationTokens
|
|
20135
20914
|
});
|
|
20136
|
-
|
|
20137
|
-
|
|
20138
|
-
if (typeof parsed.status === "string" && parsed.status !== "success" && !state.error) {
|
|
20915
|
+
const status = typeof parsed.status === "string" ? parsed.status.toLowerCase() : "";
|
|
20916
|
+
if (status && !["success", "completed", "complete"].includes(status) && !state.error) {
|
|
20139
20917
|
const errObj = typeof parsed.error === "object" && parsed.error !== null ? parsed.error : null;
|
|
20140
|
-
const errMsg = typeof parsed.error === "string" && parsed.error.trim() || errObj && typeof errObj.message === "string" && errObj.message.trim() || typeof parsed.error_message === "string" && parsed.error_message.trim() || typeof parsed.message === "string" && parsed.message.trim() || typeof parsed.result === "string" && parsed.result.trim() ||
|
|
20918
|
+
const errMsg = typeof parsed.error === "string" && parsed.error.trim() || errObj && typeof errObj.message === "string" && errObj.message.trim() || typeof parsed.error_message === "string" && parsed.error_message.trim() || typeof parsed.message === "string" && parsed.message.trim() || typeof parsed.result === "string" && parsed.result.trim() || status;
|
|
20141
20919
|
state.error = errMsg;
|
|
20920
|
+
void presenter.onError(errMsg);
|
|
20142
20921
|
console.error(
|
|
20143
20922
|
"[antigravity] result status=",
|
|
20144
|
-
|
|
20923
|
+
status,
|
|
20145
20924
|
"error:",
|
|
20146
20925
|
JSON.stringify({
|
|
20147
20926
|
error: parsed.error,
|
|
@@ -20150,12 +20929,23 @@ function parseAntigravityStructuredLine(line, context, state) {
|
|
|
20150
20929
|
})
|
|
20151
20930
|
);
|
|
20152
20931
|
}
|
|
20153
|
-
|
|
20932
|
+
const completedSuccessfully = !status || ["success", "completed", "complete"].includes(status);
|
|
20933
|
+
if (type === "complete" || status) {
|
|
20934
|
+
settleAntigravitySubagentTranscripts(context, state, !completedSuccessfully);
|
|
20935
|
+
}
|
|
20936
|
+
if (type === "complete" || status === "success") {
|
|
20937
|
+
deferOrFinalizeStructuredResult("antigravity_cli", context, state);
|
|
20938
|
+
}
|
|
20939
|
+
return true;
|
|
20154
20940
|
}
|
|
20155
20941
|
default:
|
|
20156
|
-
|
|
20942
|
+
return false;
|
|
20157
20943
|
}
|
|
20158
20944
|
}
|
|
20945
|
+
var parseAntigravityStructuredLine = createStructuredLineParser(
|
|
20946
|
+
"antigravity_cli",
|
|
20947
|
+
handleAntigravityStructuredEvent
|
|
20948
|
+
);
|
|
20159
20949
|
function parseAntigravityLine(line, context, state) {
|
|
20160
20950
|
try {
|
|
20161
20951
|
JSON.parse(line);
|
|
@@ -20204,7 +20994,14 @@ function detectAntigravityCliCapabilities(command, context) {
|
|
|
20204
20994
|
version: versionOutput || void 0,
|
|
20205
20995
|
supportsStructuredPrint: hasOutputFormat && hasStructuredFormat,
|
|
20206
20996
|
supportsConversationResume: help.includes("--conversation") || help.includes("--continue"),
|
|
20207
|
-
supportsReliableNonTtyPrint: help.includes("-p") || help.includes("--print") || help.includes("--print-timeout")
|
|
20997
|
+
supportsReliableNonTtyPrint: help.includes("-p") || help.includes("--print") || help.includes("--print-timeout"),
|
|
20998
|
+
supportsAddDir: help.includes("--add-dir"),
|
|
20999
|
+
supportsAgentSelection: help.includes("--agent"),
|
|
21000
|
+
supportsExecutionMode: help.includes("--mode"),
|
|
21001
|
+
supportsSandbox: help.includes("--sandbox"),
|
|
21002
|
+
supportsProject: help.includes("--project"),
|
|
21003
|
+
supportsNewProject: help.includes("--new-project"),
|
|
21004
|
+
supportsJsonSchema: help.includes("--json-schema")
|
|
20208
21005
|
};
|
|
20209
21006
|
capabilityCache.set(cacheKey, capabilities);
|
|
20210
21007
|
return capabilities;
|
|
@@ -20229,7 +21026,33 @@ function buildAntigravityCliArgs(context, prompt, defaultArgs = [], capabilities
|
|
|
20229
21026
|
if (effort && isEffortLevel(effort)) args.push("--effort", effort);
|
|
20230
21027
|
}
|
|
20231
21028
|
if (resumeId) args.push("--conversation", resumeId);
|
|
20232
|
-
|
|
21029
|
+
const antigravity = context.config.antigravity;
|
|
21030
|
+
if (capabilities?.supportsAddDir) {
|
|
21031
|
+
const workspacePaths = Array.from(
|
|
21032
|
+
new Set(
|
|
21033
|
+
(antigravity?.additionalWorkspacePaths ?? []).map((path) => path.trim()).filter(Boolean)
|
|
21034
|
+
)
|
|
21035
|
+
);
|
|
21036
|
+
for (const path of workspacePaths) args.push("--add-dir", path);
|
|
21037
|
+
}
|
|
21038
|
+
const agent = antigravity?.agent?.trim();
|
|
21039
|
+
if (agent && capabilities?.supportsAgentSelection) args.push("--agent", agent);
|
|
21040
|
+
const project = antigravity?.project?.trim();
|
|
21041
|
+
if (project && capabilities?.supportsProject) {
|
|
21042
|
+
args.push("--project", project);
|
|
21043
|
+
} else if (antigravity?.newProject && capabilities?.supportsNewProject) {
|
|
21044
|
+
args.push("--new-project");
|
|
21045
|
+
}
|
|
21046
|
+
const jsonSchema = antigravity?.jsonSchema?.trim();
|
|
21047
|
+
if (jsonSchema && capabilities?.supportsJsonSchema) args.push("--json-schema", jsonSchema);
|
|
21048
|
+
const readOnly = shouldUseReadOnlyRuntimePermissions(context.config);
|
|
21049
|
+
if (capabilities?.supportsExecutionMode) {
|
|
21050
|
+
args.push("--mode", readOnly ? "plan" : "accept-edits");
|
|
21051
|
+
}
|
|
21052
|
+
if (readOnly && capabilities?.supportsSandbox) {
|
|
21053
|
+
args.push("--sandbox");
|
|
21054
|
+
}
|
|
21055
|
+
if (!readOnly) {
|
|
20233
21056
|
args.push("--dangerously-skip-permissions");
|
|
20234
21057
|
}
|
|
20235
21058
|
if (capabilities?.supportsStructuredPrint) {
|
|
@@ -20243,7 +21066,11 @@ function buildAntigravityAugmentedPrompt(context, images) {
|
|
|
20243
21066
|
context.config.runtimeSessionId?.trim() || context.config.providerSessionId?.trim()
|
|
20244
21067
|
);
|
|
20245
21068
|
const base = buildResumeAwarePrompt(context.config, context.promptText, { isResume });
|
|
20246
|
-
const
|
|
21069
|
+
const workspaceInstructions = isResume ? void 0 : buildAntigravityWorkspaceInstructions(context.cwd);
|
|
21070
|
+
const withWorkspaceInstructions = workspaceInstructions ? `${workspaceInstructions}
|
|
21071
|
+
|
|
21072
|
+
${base}` : base;
|
|
21073
|
+
const prompt = context.config.mode === "plan" ? buildPlanModePrefix(withWorkspaceInstructions) : withWorkspaceInstructions;
|
|
20247
21074
|
return appendImagePathReferences(prompt, images);
|
|
20248
21075
|
}
|
|
20249
21076
|
function createAntigravityCliBackend(command = "agy", defaultArgs = []) {
|
|
@@ -20278,18 +21105,18 @@ function createAntigravityCliBackend(command = "agy", defaultArgs = []) {
|
|
|
20278
21105
|
}
|
|
20279
21106
|
function resolveClaudeHome(env, variant = "claude") {
|
|
20280
21107
|
if (variant === "supatest") {
|
|
20281
|
-
return (0,
|
|
21108
|
+
return (0, import_path6.join)((0, import_os5.homedir)(), ".supatest", "claude-internal");
|
|
20282
21109
|
}
|
|
20283
|
-
return env.CLAUDE_CONFIG_DIR || process.env.CLAUDE_CONFIG_DIR || (0,
|
|
21110
|
+
return env.CLAUDE_CONFIG_DIR || process.env.CLAUDE_CONFIG_DIR || (0, import_path6.join)((0, import_os5.homedir)(), ".claude");
|
|
20284
21111
|
}
|
|
20285
21112
|
function encodeClaudeProjectDir(cwd) {
|
|
20286
21113
|
return cwd.replace(/[^a-zA-Z0-9]/g, "-");
|
|
20287
21114
|
}
|
|
20288
21115
|
function claudeSessionLogExists(input) {
|
|
20289
21116
|
if (!input.sessionId || !input.cwd) return false;
|
|
20290
|
-
const projectDir = (0,
|
|
20291
|
-
if (!(0,
|
|
20292
|
-
return (0,
|
|
21117
|
+
const projectDir = (0, import_path6.join)(input.home, "projects", encodeClaudeProjectDir(input.cwd));
|
|
21118
|
+
if (!(0, import_fs6.existsSync)(projectDir)) return false;
|
|
21119
|
+
return (0, import_fs6.existsSync)((0, import_path6.join)(projectDir, `${input.sessionId}.jsonl`));
|
|
20293
21120
|
}
|
|
20294
21121
|
var execFileAsync = (0, import_util4.promisify)(import_child_process4.execFile);
|
|
20295
21122
|
var flagSupportCache = /* @__PURE__ */ new Map();
|
|
@@ -20315,234 +21142,6 @@ async function cliSupportsFlag(command, flag, env = {}) {
|
|
|
20315
21142
|
flagSupportCache.set(key, supported);
|
|
20316
21143
|
return supported;
|
|
20317
21144
|
}
|
|
20318
|
-
function stringField(record2, key) {
|
|
20319
|
-
const value2 = record2[key];
|
|
20320
|
-
return typeof value2 === "string" && value2.trim().length > 0 ? value2 : void 0;
|
|
20321
|
-
}
|
|
20322
|
-
function backgroundTaskKeys(record2) {
|
|
20323
|
-
return [
|
|
20324
|
-
stringField(record2, "task_id"),
|
|
20325
|
-
stringField(record2, "taskId"),
|
|
20326
|
-
stringField(record2, "tool_use_id"),
|
|
20327
|
-
stringField(record2, "toolUseId"),
|
|
20328
|
-
stringField(record2, "id")
|
|
20329
|
-
].filter((key) => Boolean(key));
|
|
20330
|
-
}
|
|
20331
|
-
function backgroundTaskId(record2) {
|
|
20332
|
-
return stringField(record2, "task_id") ?? stringField(record2, "taskId");
|
|
20333
|
-
}
|
|
20334
|
-
function backgroundToolUseId(record2) {
|
|
20335
|
-
return stringField(record2, "tool_use_id") ?? stringField(record2, "toolUseId");
|
|
20336
|
-
}
|
|
20337
|
-
function registerBackgroundTaskIds(state, keys) {
|
|
20338
|
-
for (const key of keys) {
|
|
20339
|
-
if (!key) continue;
|
|
20340
|
-
if (!state.activeBackgroundTaskIds) state.activeBackgroundTaskIds = /* @__PURE__ */ new Set();
|
|
20341
|
-
state.activeBackgroundTaskIds.add(key);
|
|
20342
|
-
}
|
|
20343
|
-
}
|
|
20344
|
-
function registerBackgroundLauncher(state, toolUseId) {
|
|
20345
|
-
registerBackgroundTaskIds(state, [toolUseId]);
|
|
20346
|
-
if (!state.pendingLauncherToolIds) state.pendingLauncherToolIds = [];
|
|
20347
|
-
if (!state.pendingLauncherToolIds.includes(toolUseId)) {
|
|
20348
|
-
state.pendingLauncherToolIds.push(toolUseId);
|
|
20349
|
-
}
|
|
20350
|
-
}
|
|
20351
|
-
function drainNextUnlinkedBackgroundLauncher(state) {
|
|
20352
|
-
const launcherId = state.pendingLauncherToolIds?.shift();
|
|
20353
|
-
if (state.pendingLauncherToolIds?.length === 0) state.pendingLauncherToolIds = void 0;
|
|
20354
|
-
if (launcherId) clearBackgroundTaskIds(state, [launcherId]);
|
|
20355
|
-
return launcherId;
|
|
20356
|
-
}
|
|
20357
|
-
function registerBackgroundTaskRecord(state, record2, launcherToolUseId) {
|
|
20358
|
-
const taskId = backgroundTaskId(record2);
|
|
20359
|
-
let toolUseId = backgroundToolUseId(record2) ?? launcherToolUseId ?? void 0;
|
|
20360
|
-
if (!toolUseId && taskId) {
|
|
20361
|
-
const nextLauncher = state.pendingLauncherToolIds?.[0];
|
|
20362
|
-
if (nextLauncher) {
|
|
20363
|
-
toolUseId = nextLauncher;
|
|
20364
|
-
} else if (state.activeBackgroundTaskIds?.size === 1) {
|
|
20365
|
-
const [candidate] = state.activeBackgroundTaskIds;
|
|
20366
|
-
if (candidate && candidate !== taskId) toolUseId = candidate;
|
|
20367
|
-
}
|
|
20368
|
-
}
|
|
20369
|
-
registerBackgroundTaskIds(state, backgroundTaskKeys(record2));
|
|
20370
|
-
if (!taskId || !toolUseId) return;
|
|
20371
|
-
if (state.pendingLauncherToolIds) {
|
|
20372
|
-
const idx = state.pendingLauncherToolIds.indexOf(toolUseId);
|
|
20373
|
-
if (idx >= 0) state.pendingLauncherToolIds.splice(idx, 1);
|
|
20374
|
-
if (state.pendingLauncherToolIds.length === 0) state.pendingLauncherToolIds = void 0;
|
|
20375
|
-
}
|
|
20376
|
-
if (!state.backgroundToolIdByTaskId) state.backgroundToolIdByTaskId = /* @__PURE__ */ new Map();
|
|
20377
|
-
if (!state.backgroundTaskIdsByToolId) state.backgroundTaskIdsByToolId = /* @__PURE__ */ new Map();
|
|
20378
|
-
state.backgroundToolIdByTaskId.set(taskId, toolUseId);
|
|
20379
|
-
const taskIds = state.backgroundTaskIdsByToolId.get(toolUseId) ?? /* @__PURE__ */ new Set();
|
|
20380
|
-
taskIds.add(taskId);
|
|
20381
|
-
state.backgroundTaskIdsByToolId.set(toolUseId, taskIds);
|
|
20382
|
-
}
|
|
20383
|
-
function clearBackgroundTaskIds(state, keys) {
|
|
20384
|
-
const activeIds = state.activeBackgroundTaskIds;
|
|
20385
|
-
if (!activeIds) return;
|
|
20386
|
-
for (const key of keys) {
|
|
20387
|
-
if (!key) continue;
|
|
20388
|
-
activeIds.delete(key);
|
|
20389
|
-
const toolUseId = state.backgroundToolIdByTaskId?.get(key);
|
|
20390
|
-
if (toolUseId) {
|
|
20391
|
-
activeIds.delete(toolUseId);
|
|
20392
|
-
state.backgroundToolIdByTaskId?.delete(key);
|
|
20393
|
-
const taskIds2 = state.backgroundTaskIdsByToolId?.get(toolUseId);
|
|
20394
|
-
taskIds2?.delete(key);
|
|
20395
|
-
if (taskIds2?.size === 0) state.backgroundTaskIdsByToolId?.delete(toolUseId);
|
|
20396
|
-
}
|
|
20397
|
-
const taskIds = state.backgroundTaskIdsByToolId?.get(key);
|
|
20398
|
-
if (taskIds) {
|
|
20399
|
-
for (const taskId of taskIds) {
|
|
20400
|
-
activeIds.delete(taskId);
|
|
20401
|
-
state.backgroundToolIdByTaskId?.delete(taskId);
|
|
20402
|
-
}
|
|
20403
|
-
state.backgroundTaskIdsByToolId?.delete(key);
|
|
20404
|
-
}
|
|
20405
|
-
}
|
|
20406
|
-
if (state.pendingLauncherToolIds) {
|
|
20407
|
-
state.pendingLauncherToolIds = state.pendingLauncherToolIds.filter((id) => activeIds.has(id));
|
|
20408
|
-
if (state.pendingLauncherToolIds.length === 0) state.pendingLauncherToolIds = void 0;
|
|
20409
|
-
}
|
|
20410
|
-
if (activeIds.size === 0) state.activeBackgroundTaskIds = void 0;
|
|
20411
|
-
}
|
|
20412
|
-
function resolveBackgroundTaskToolUseId(state, record2) {
|
|
20413
|
-
const explicitToolUseId = backgroundToolUseId(record2);
|
|
20414
|
-
if (explicitToolUseId) return explicitToolUseId;
|
|
20415
|
-
const taskId = backgroundTaskId(record2);
|
|
20416
|
-
return taskId ? state.backgroundToolIdByTaskId?.get(taskId) : void 0;
|
|
20417
|
-
}
|
|
20418
|
-
var TERMINAL_BACKGROUND_STATUSES = /* @__PURE__ */ new Set([
|
|
20419
|
-
"complete",
|
|
20420
|
-
"completed",
|
|
20421
|
-
"done",
|
|
20422
|
-
"success",
|
|
20423
|
-
"succeeded",
|
|
20424
|
-
"failed",
|
|
20425
|
-
"failure",
|
|
20426
|
-
"error",
|
|
20427
|
-
"cancelled",
|
|
20428
|
-
"canceled",
|
|
20429
|
-
"aborted",
|
|
20430
|
-
"interrupted",
|
|
20431
|
-
"stopped"
|
|
20432
|
-
]);
|
|
20433
|
-
var NON_TERMINAL_BACKGROUND_STATUSES = /* @__PURE__ */ new Set([
|
|
20434
|
-
"running",
|
|
20435
|
-
"in_progress",
|
|
20436
|
-
"inprogress",
|
|
20437
|
-
"started",
|
|
20438
|
-
"pending",
|
|
20439
|
-
"active",
|
|
20440
|
-
"working",
|
|
20441
|
-
"queued"
|
|
20442
|
-
]);
|
|
20443
|
-
var ASYNC_LAUNCH_ACK_RE = /^(async agent launched successfully|background (?:task|agent|subagent) (?:launched|started|running)|task (?:launched|started) successfully)/i;
|
|
20444
|
-
function isTerminalBackgroundStatus(record2) {
|
|
20445
|
-
const status = stringField(record2, "status")?.toLowerCase();
|
|
20446
|
-
if (status && TERMINAL_BACKGROUND_STATUSES.has(status)) return true;
|
|
20447
|
-
if (status && NON_TERMINAL_BACKGROUND_STATUSES.has(status)) return false;
|
|
20448
|
-
return typeof record2.duration_ms === "number" || typeof record2.durationMs === "number" || typeof record2.total_tokens === "number" || typeof record2.totalTokens === "number" || typeof record2.tool_uses === "number" || typeof record2.toolUses === "number";
|
|
20449
|
-
}
|
|
20450
|
-
function isFailedBackgroundStatus(record2) {
|
|
20451
|
-
const status = stringField(record2, "status")?.toLowerCase();
|
|
20452
|
-
return status === "failed" || status === "failure" || status === "error" || status === "cancelled" || status === "canceled" || status === "aborted" || status === "interrupted";
|
|
20453
|
-
}
|
|
20454
|
-
function extractBackgroundTaskIdFromPayload(value2) {
|
|
20455
|
-
if (typeof value2 === "string") {
|
|
20456
|
-
const trimmed = value2.trim();
|
|
20457
|
-
if (!trimmed) return void 0;
|
|
20458
|
-
try {
|
|
20459
|
-
return extractBackgroundTaskIdFromPayload(JSON.parse(trimmed));
|
|
20460
|
-
} catch {
|
|
20461
|
-
const match = trimmed.match(/\btask[_-]?id["']?\s*[:=]\s*["']?([A-Za-z0-9_.-]+)/i) ?? trimmed.match(/\btasks\/([A-Za-z0-9_.-]+)/i);
|
|
20462
|
-
if (match?.[1]) return match[1];
|
|
20463
|
-
if (/^[A-Za-z0-9_-]{6,128}$/.test(trimmed) && /(?:task|bg|async|job|agent)/i.test(trimmed)) {
|
|
20464
|
-
return trimmed;
|
|
20465
|
-
}
|
|
20466
|
-
return void 0;
|
|
20467
|
-
}
|
|
20468
|
-
}
|
|
20469
|
-
if (!value2 || typeof value2 !== "object" || Array.isArray(value2)) return void 0;
|
|
20470
|
-
const record2 = value2;
|
|
20471
|
-
return stringField(record2, "task_id") ?? stringField(record2, "taskId") ?? stringField(record2, "agentId") ?? stringField(record2, "agent_id") ?? extractBackgroundTaskIdFromPayload(record2.value) ?? extractBackgroundTaskIdFromPayload(record2.result) ?? extractBackgroundTaskIdFromPayload(record2.data) ?? extractBackgroundTaskIdFromPayload(record2.content);
|
|
20472
|
-
}
|
|
20473
|
-
function looksLikeBackgroundLaunchAck(options) {
|
|
20474
|
-
const taskId = extractBackgroundTaskIdFromPayload(options.value) ?? extractBackgroundTaskIdFromPayload(options.content);
|
|
20475
|
-
const content = options.content.trim();
|
|
20476
|
-
const explicitAckText = ASYNC_LAUNCH_ACK_RE.test(content);
|
|
20477
|
-
if (!options.trackedUnlinkedLauncher) return { isAck: false, taskId };
|
|
20478
|
-
if (options.explicitBackground && taskId) return { isAck: true, taskId };
|
|
20479
|
-
if (explicitAckText) return { isAck: true, taskId };
|
|
20480
|
-
if (taskId && content.length > 0 && content.length < 400) {
|
|
20481
|
-
const record2 = options.value && typeof options.value === "object" && !Array.isArray(options.value) ? options.value : null;
|
|
20482
|
-
const looksStructured = record2 !== null || content.startsWith("{") || /^task[_-]?id\b/i.test(content) || content === taskId;
|
|
20483
|
-
if (looksStructured) return { isAck: true, taskId };
|
|
20484
|
-
}
|
|
20485
|
-
return { isAck: false, taskId };
|
|
20486
|
-
}
|
|
20487
|
-
function settleBackgroundTerminalNotification(kind, context, state, record2, options) {
|
|
20488
|
-
const toolUseId = resolveBackgroundTaskToolUseId(state, record2);
|
|
20489
|
-
const keys = backgroundTaskKeys(record2);
|
|
20490
|
-
const wasActive = !!toolUseId && state.activeBackgroundTaskIds?.has(toolUseId) === true || keys.some((key) => state.activeBackgroundTaskIds?.has(key) === true);
|
|
20491
|
-
if (toolUseId && wasActive) {
|
|
20492
|
-
options.emitToolResult(toolUseId, options.resultText, options.isError);
|
|
20493
|
-
clearBackgroundTaskIds(state, keys);
|
|
20494
|
-
maybeFinalizeDeferredResult(kind, context, state);
|
|
20495
|
-
return toolUseId;
|
|
20496
|
-
}
|
|
20497
|
-
clearBackgroundTaskIds(state, keys);
|
|
20498
|
-
const drainedLauncher = drainNextUnlinkedBackgroundLauncher(state);
|
|
20499
|
-
if (drainedLauncher) {
|
|
20500
|
-
options.emitToolResult(drainedLauncher, options.resultText, options.isError);
|
|
20501
|
-
}
|
|
20502
|
-
maybeFinalizeDeferredResult(kind, context, state);
|
|
20503
|
-
return drainedLauncher;
|
|
20504
|
-
}
|
|
20505
|
-
function finalizeStructuredResult(kind, state) {
|
|
20506
|
-
state.resultReceived = true;
|
|
20507
|
-
state.onResultReceived?.();
|
|
20508
|
-
if (state.stdin && !state.stdin.destroyed) {
|
|
20509
|
-
state.stdin.end();
|
|
20510
|
-
console.info(`[${kind}] Closed stdin after result event to signal CLI exit`);
|
|
20511
|
-
}
|
|
20512
|
-
}
|
|
20513
|
-
function deferOrFinalizeStructuredResult(kind, context, state) {
|
|
20514
|
-
const pendingAsks = context.presenter.pendingAskUserToolIds?.size ?? 0;
|
|
20515
|
-
if (pendingAsks > 0) {
|
|
20516
|
-
console.info(
|
|
20517
|
-
`[${kind}] Keeping stdin open \u2014 ${pendingAsks} interactive question(s) awaiting user response`
|
|
20518
|
-
);
|
|
20519
|
-
state.resultDeferredOnPendingAnswer = true;
|
|
20520
|
-
return "deferred_pending_answer";
|
|
20521
|
-
}
|
|
20522
|
-
const activeBackgroundTasks = state.activeBackgroundTaskIds?.size ?? 0;
|
|
20523
|
-
if (activeBackgroundTasks > 0) {
|
|
20524
|
-
console.info(
|
|
20525
|
-
`[${kind}] Keeping stdin open \u2014 ${activeBackgroundTasks} background task(s) still active`
|
|
20526
|
-
);
|
|
20527
|
-
state.resultDeferredOnBackgroundWork = true;
|
|
20528
|
-
return "deferred_background_work";
|
|
20529
|
-
}
|
|
20530
|
-
finalizeStructuredResult(kind, state);
|
|
20531
|
-
return "finalized";
|
|
20532
|
-
}
|
|
20533
|
-
function maybeFinalizeDeferredResult(kind, context, state) {
|
|
20534
|
-
if (!state.resultDeferredOnBackgroundWork && !state.resultDeferredOnPendingAnswer) return;
|
|
20535
|
-
if (context.presenter.pendingAskUserToolIds?.size || state.activeBackgroundTaskIds?.size) return;
|
|
20536
|
-
if (state.resultDeferredOnBackgroundWork) {
|
|
20537
|
-
state.awaitingPostBackgroundSynthesis = true;
|
|
20538
|
-
console.info(
|
|
20539
|
-
`[${kind}] Background work drained \u2014 awaiting post-subagent synthesis before stdin close`
|
|
20540
|
-
);
|
|
20541
|
-
return;
|
|
20542
|
-
}
|
|
20543
|
-
state.resultDeferredOnPendingAnswer = false;
|
|
20544
|
-
finalizeStructuredResult(kind, state);
|
|
20545
|
-
}
|
|
20546
21145
|
var DEBUG_ASK = process.env.ALAN_DEBUG_ASK === "1" || process.env.ALAN_DEBUG === "1";
|
|
20547
21146
|
function debugAskLog(message) {
|
|
20548
21147
|
if (DEBUG_ASK) console.info(message);
|
|
@@ -20580,22 +21179,22 @@ function extractToolResultContent(content) {
|
|
|
20580
21179
|
return "";
|
|
20581
21180
|
}).filter(Boolean).join("\n");
|
|
20582
21181
|
}
|
|
20583
|
-
function
|
|
21182
|
+
function stringField3(record2, key) {
|
|
20584
21183
|
const value2 = record2[key];
|
|
20585
21184
|
return typeof value2 === "string" && value2.trim().length > 0 ? value2 : void 0;
|
|
20586
21185
|
}
|
|
20587
21186
|
function isTerminalTaskNotification(record2) {
|
|
20588
|
-
const status =
|
|
21187
|
+
const status = stringField3(record2, "status")?.toLowerCase();
|
|
20589
21188
|
if (status && TERMINAL_TASK_NOTIFICATION_STATUSES.has(status)) return true;
|
|
20590
21189
|
if (status && NON_TERMINAL_TASK_NOTIFICATION_STATUSES.has(status)) return false;
|
|
20591
21190
|
return typeof record2.duration_ms === "number" || typeof record2.durationMs === "number" || typeof record2.total_tokens === "number" || typeof record2.totalTokens === "number" || typeof record2.tool_uses === "number" || typeof record2.toolUses === "number";
|
|
20592
21191
|
}
|
|
20593
21192
|
function isFailedTaskNotification(record2) {
|
|
20594
|
-
const status =
|
|
21193
|
+
const status = stringField3(record2, "status")?.toLowerCase();
|
|
20595
21194
|
return status === "failed" || status === "failure" || status === "error" || status === "cancelled" || status === "canceled";
|
|
20596
21195
|
}
|
|
20597
21196
|
function formatClaudeTaskNotificationResult(record2) {
|
|
20598
|
-
const status =
|
|
21197
|
+
const status = stringField3(record2, "status") ?? "completed";
|
|
20599
21198
|
const details = [`Subagent ${status}.`];
|
|
20600
21199
|
const durationMs = record2.duration_ms ?? record2.durationMs;
|
|
20601
21200
|
const toolUses = record2.tool_uses ?? record2.toolUses;
|
|
@@ -21032,29 +21631,29 @@ function normalizeCodexMcpToolResult(output) {
|
|
|
21032
21631
|
return raw;
|
|
21033
21632
|
}
|
|
21034
21633
|
function resolveCodexHome(env) {
|
|
21035
|
-
return env.CODEX_HOME || process.env.CODEX_HOME || (0,
|
|
21634
|
+
return env.CODEX_HOME || process.env.CODEX_HOME || (0, import_path7.join)((0, import_os6.homedir)(), ".codex");
|
|
21036
21635
|
}
|
|
21037
21636
|
function findCodexSessionLog(runtimeSessionId, codexHome) {
|
|
21038
|
-
if (!runtimeSessionId || !(0,
|
|
21039
|
-
const root = (0,
|
|
21040
|
-
if (!(0,
|
|
21637
|
+
if (!runtimeSessionId || !(0, import_fs7.existsSync)(codexHome)) return null;
|
|
21638
|
+
const root = (0, import_path7.join)(codexHome, "sessions");
|
|
21639
|
+
if (!(0, import_fs7.existsSync)(root)) return null;
|
|
21041
21640
|
const matches = [];
|
|
21042
21641
|
const stack = [root];
|
|
21043
21642
|
while (stack.length > 0) {
|
|
21044
21643
|
const dir = stack.pop();
|
|
21045
21644
|
let entries;
|
|
21046
21645
|
try {
|
|
21047
|
-
entries = (0,
|
|
21646
|
+
entries = (0, import_fs7.readdirSync)(dir, { withFileTypes: true });
|
|
21048
21647
|
} catch {
|
|
21049
21648
|
continue;
|
|
21050
21649
|
}
|
|
21051
21650
|
for (const entry of entries) {
|
|
21052
|
-
const path = (0,
|
|
21651
|
+
const path = (0, import_path7.join)(dir, entry.name);
|
|
21053
21652
|
if (entry.isDirectory()) {
|
|
21054
21653
|
stack.push(path);
|
|
21055
21654
|
} else if (entry.isFile() && entry.name.includes(runtimeSessionId) && entry.name.endsWith(".jsonl")) {
|
|
21056
21655
|
try {
|
|
21057
|
-
matches.push({ path, mtimeMs: (0,
|
|
21656
|
+
matches.push({ path, mtimeMs: (0, import_fs7.statSync)(path).mtimeMs });
|
|
21058
21657
|
} catch {
|
|
21059
21658
|
matches.push({ path, mtimeMs: 0 });
|
|
21060
21659
|
}
|
|
@@ -21108,21 +21707,21 @@ function firstUserMessageLineIndex(lines) {
|
|
|
21108
21707
|
const line = lines[index];
|
|
21109
21708
|
if (!line) continue;
|
|
21110
21709
|
const entry = parseJsonObject(line);
|
|
21111
|
-
const payload =
|
|
21710
|
+
const payload = asRecord2(entry?.payload);
|
|
21112
21711
|
if (payload?.type === "message" && payload.role === "user" && !isSyntheticUserRolloutMessage(payload)) {
|
|
21113
21712
|
return index;
|
|
21114
21713
|
}
|
|
21115
21714
|
}
|
|
21116
21715
|
return -1;
|
|
21117
21716
|
}
|
|
21118
|
-
function
|
|
21717
|
+
function asRecord2(value2) {
|
|
21119
21718
|
return value2 && typeof value2 === "object" ? value2 : null;
|
|
21120
21719
|
}
|
|
21121
21720
|
function rolloutTextContent(content) {
|
|
21122
21721
|
if (typeof content === "string") return content;
|
|
21123
21722
|
if (!Array.isArray(content)) return "";
|
|
21124
21723
|
return content.flatMap((block) => {
|
|
21125
|
-
const record2 =
|
|
21724
|
+
const record2 = asRecord2(block);
|
|
21126
21725
|
const text = record2?.text;
|
|
21127
21726
|
return typeof text === "string" ? [text] : [];
|
|
21128
21727
|
}).join("");
|
|
@@ -21151,14 +21750,14 @@ function collectCodexWorkerReplays(lines, state) {
|
|
|
21151
21750
|
const workersByThreadId = /* @__PURE__ */ new Map();
|
|
21152
21751
|
for (const line of lines) {
|
|
21153
21752
|
const entry = parseJsonObject(line);
|
|
21154
|
-
const payload =
|
|
21753
|
+
const payload = asRecord2(entry?.payload);
|
|
21155
21754
|
if (!payload) continue;
|
|
21156
21755
|
if (entry?.type === "response_item" && payload.type === "function_call" && payload.name === "spawn_agent") {
|
|
21157
21756
|
const namespace = typeof payload.namespace === "string" ? payload.namespace : "";
|
|
21158
21757
|
if (namespace !== "collaboration" && namespace !== "multi_agent_v1") continue;
|
|
21159
21758
|
const callId = typeof payload.call_id === "string" ? payload.call_id : "";
|
|
21160
21759
|
if (!callId) continue;
|
|
21161
|
-
const args =
|
|
21760
|
+
const args = asRecord2(parseMaybeJson(payload.arguments));
|
|
21162
21761
|
const taskName = typeof args?.task_name === "string" ? args.task_name : "";
|
|
21163
21762
|
const message = typeof args?.message === "string" ? args.message : "";
|
|
21164
21763
|
spawnByCallId.set(callId, {
|
|
@@ -21171,7 +21770,7 @@ function collectCodexWorkerReplays(lines, state) {
|
|
|
21171
21770
|
const callId = typeof payload.call_id === "string" ? payload.call_id : "";
|
|
21172
21771
|
const spawn32 = spawnByCallId.get(callId);
|
|
21173
21772
|
if (!spawn32) continue;
|
|
21174
|
-
const output =
|
|
21773
|
+
const output = asRecord2(parseMaybeJson(payload.output));
|
|
21175
21774
|
const threadId = typeof output?.agent_id === "string" ? output.agent_id : "";
|
|
21176
21775
|
if (!threadId) continue;
|
|
21177
21776
|
const nickname = typeof output?.nickname === "string" ? output.nickname : void 0;
|
|
@@ -21213,7 +21812,7 @@ function replayCodexWorkerTranscript(context, worker, codexHome, state) {
|
|
|
21213
21812
|
if (!state.codexWorkerSessionLogPathByThreadId)
|
|
21214
21813
|
state.codexWorkerSessionLogPathByThreadId = /* @__PURE__ */ new Map();
|
|
21215
21814
|
state.codexWorkerSessionLogPathByThreadId.set(worker.threadId, logPath);
|
|
21216
|
-
const allLines = (0,
|
|
21815
|
+
const allLines = (0, import_fs7.readFileSync)(logPath, "utf8").split(/\r?\n/).filter(Boolean);
|
|
21217
21816
|
const firstUserLineIndex = firstUserMessageLineIndex(allLines);
|
|
21218
21817
|
const lines = firstUserLineIndex >= 0 ? allLines.slice(firstUserLineIndex + 1) : allLines;
|
|
21219
21818
|
const emittedToolNames = /* @__PURE__ */ new Map();
|
|
@@ -21224,7 +21823,7 @@ function replayCodexWorkerTranscript(context, worker, codexHome, state) {
|
|
|
21224
21823
|
if (!line) continue;
|
|
21225
21824
|
const entry = parseJsonObject(line);
|
|
21226
21825
|
if (entry?.type !== "response_item") continue;
|
|
21227
|
-
const payload =
|
|
21826
|
+
const payload = asRecord2(entry.payload);
|
|
21228
21827
|
if (!payload) continue;
|
|
21229
21828
|
if (payload.type === "message" && payload.role === "assistant") {
|
|
21230
21829
|
const text = rolloutTextContent(payload.content);
|
|
@@ -21318,7 +21917,7 @@ function syncCodexWorkerEventsFromSessionLog(context, state) {
|
|
|
21318
21917
|
const logPath = state.codexSessionLogPath ?? findCodexSessionLog(runtimeSessionId, codexHome);
|
|
21319
21918
|
if (!logPath) return [];
|
|
21320
21919
|
state.codexSessionLogPath = logPath;
|
|
21321
|
-
const allLines = (0,
|
|
21920
|
+
const allLines = (0, import_fs7.readFileSync)(logPath, "utf8").split(/\r?\n/).filter(Boolean);
|
|
21322
21921
|
const latestUserLineIndex = latestUserMessageLineIndex(allLines);
|
|
21323
21922
|
const lines = latestUserLineIndex >= 0 ? allLines.slice(latestUserLineIndex + 1) : allLines;
|
|
21324
21923
|
const workers = collectCodexWorkerReplays(lines, state);
|
|
@@ -21357,7 +21956,7 @@ async function replayCodexMcpToolEventsFromSessionLog(context, state) {
|
|
|
21357
21956
|
const codexHome = resolveCodexHome(context.env);
|
|
21358
21957
|
const logPath = findCodexSessionLog(runtimeSessionId, codexHome);
|
|
21359
21958
|
if (!logPath) return;
|
|
21360
|
-
const allLines = (0,
|
|
21959
|
+
const allLines = (0, import_fs7.readFileSync)(logPath, "utf8").split(/\r?\n/).filter(Boolean);
|
|
21361
21960
|
const latestUserLineIndex = latestUserMessageLineIndex(allLines);
|
|
21362
21961
|
const lines = latestUserLineIndex >= 0 ? allLines.slice(latestUserLineIndex + 1) : allLines;
|
|
21363
21962
|
const streamedToolIds = state.codexStreamedToolIds ?? /* @__PURE__ */ new Set();
|
|
@@ -22207,7 +22806,7 @@ ${ctx.promptText}` : ctx.promptText;
|
|
|
22207
22806
|
};
|
|
22208
22807
|
}
|
|
22209
22808
|
var explicitBackgroundLaunchers = /* @__PURE__ */ new WeakMap();
|
|
22210
|
-
function
|
|
22809
|
+
function asRecord3(value2) {
|
|
22211
22810
|
return value2 && typeof value2 === "object" && !Array.isArray(value2) ? value2 : null;
|
|
22212
22811
|
}
|
|
22213
22812
|
function asString(value2) {
|
|
@@ -22338,7 +22937,7 @@ function handleCopilotStructuredEvent(parsed, context, state) {
|
|
|
22338
22937
|
case "tool.execution_start": {
|
|
22339
22938
|
const toolId = typeof data.toolCallId === "string" ? data.toolCallId : `copilot-tool-${Date.now()}`;
|
|
22340
22939
|
const rawName = typeof data.toolName === "string" ? data.toolName : "Copilot Tool";
|
|
22341
|
-
const rawArgs =
|
|
22940
|
+
const rawArgs = asRecord3(data.arguments) ?? {};
|
|
22342
22941
|
const softTrack = isCloudDelegateTool(rawName, rawArgs);
|
|
22343
22942
|
const localBg = isLocalBackgroundLauncher(rawName, rawArgs);
|
|
22344
22943
|
const args = softTrack || localBg ? normalizeLauncherArgs(rawArgs, softTrack) : rawArgs;
|
|
@@ -22497,7 +23096,7 @@ function createCopilotCliBackend(command = "copilot", defaultArgs = []) {
|
|
|
22497
23096
|
}
|
|
22498
23097
|
};
|
|
22499
23098
|
}
|
|
22500
|
-
function
|
|
23099
|
+
function asRecord4(value2) {
|
|
22501
23100
|
return typeof value2 === "object" && value2 !== null ? value2 : null;
|
|
22502
23101
|
}
|
|
22503
23102
|
function extractCursorToolEntry(toolCall) {
|
|
@@ -22519,12 +23118,12 @@ function formatCursorToolName(rawName, payload) {
|
|
|
22519
23118
|
return trimmed.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/^[a-z]/, (char) => char.toUpperCase());
|
|
22520
23119
|
}
|
|
22521
23120
|
function cursorTaskResultVariant(payload, variant) {
|
|
22522
|
-
const result =
|
|
23121
|
+
const result = asRecord4(payload.result);
|
|
22523
23122
|
if (!result) return null;
|
|
22524
|
-
const direct =
|
|
23123
|
+
const direct = asRecord4(result[variant]);
|
|
22525
23124
|
if (direct) return direct;
|
|
22526
|
-
const oneof =
|
|
22527
|
-
return oneof?.case === variant ?
|
|
23125
|
+
const oneof = asRecord4(result.result);
|
|
23126
|
+
return oneof?.case === variant ? asRecord4(oneof.value) : null;
|
|
22528
23127
|
}
|
|
22529
23128
|
function cursorSubagentType(value2) {
|
|
22530
23129
|
const normalize = (candidate) => {
|
|
@@ -22535,18 +23134,18 @@ function cursorSubagentType(value2) {
|
|
|
22535
23134
|
return trimmed;
|
|
22536
23135
|
};
|
|
22537
23136
|
if (typeof value2 === "string") return normalize(value2);
|
|
22538
|
-
const record2 =
|
|
23137
|
+
const record2 = asRecord4(value2);
|
|
22539
23138
|
if (!record2) return void 0;
|
|
22540
23139
|
if (typeof record2.case === "string" && record2.case) return normalize(record2.case);
|
|
22541
23140
|
if (typeof record2.type === "string" && record2.type) return normalize(record2.type);
|
|
22542
|
-
const nestedType =
|
|
23141
|
+
const nestedType = asRecord4(record2.type);
|
|
22543
23142
|
if (typeof nestedType?.case === "string" && nestedType.case) return normalize(nestedType.case);
|
|
22544
23143
|
return normalize(
|
|
22545
23144
|
Object.keys(nestedType ?? record2).find((key) => key !== "value" && key !== "case")
|
|
22546
23145
|
);
|
|
22547
23146
|
}
|
|
22548
23147
|
function cursorToolArgs(entry) {
|
|
22549
|
-
const args =
|
|
23148
|
+
const args = asRecord4(entry.payload.args) ?? asRecord4(entry.payload.arguments) ?? entry.payload;
|
|
22550
23149
|
if (entry.rawName !== "taskToolCall") return args;
|
|
22551
23150
|
const subagentType = cursorSubagentType(args.subagentType ?? args.subagent_type);
|
|
22552
23151
|
return {
|
|
@@ -22557,15 +23156,15 @@ function cursorToolArgs(entry) {
|
|
|
22557
23156
|
};
|
|
22558
23157
|
}
|
|
22559
23158
|
function cursorConversationStepValue(step, key) {
|
|
22560
|
-
const direct =
|
|
23159
|
+
const direct = asRecord4(step[key]);
|
|
22561
23160
|
if (direct) return direct;
|
|
22562
|
-
const message =
|
|
22563
|
-
return message?.case === key ?
|
|
23161
|
+
const message = asRecord4(step.message);
|
|
23162
|
+
return message?.case === key ? asRecord4(message.value) : null;
|
|
22564
23163
|
}
|
|
22565
23164
|
function cursorConversationStepText(steps) {
|
|
22566
23165
|
if (!Array.isArray(steps)) return "";
|
|
22567
23166
|
return steps.flatMap((step) => {
|
|
22568
|
-
const record2 =
|
|
23167
|
+
const record2 = asRecord4(step);
|
|
22569
23168
|
if (!record2) return [];
|
|
22570
23169
|
const assistant = cursorConversationStepValue(record2, "assistantMessage");
|
|
22571
23170
|
return typeof assistant?.text === "string" ? [assistant.text] : [];
|
|
@@ -22595,7 +23194,7 @@ function buildCursorToolResultText(result) {
|
|
|
22595
23194
|
function emitCursorSubagentConversationSteps(steps, parentToolUseId, presenter) {
|
|
22596
23195
|
if (!Array.isArray(steps)) return;
|
|
22597
23196
|
steps.forEach((step, index) => {
|
|
22598
|
-
const record2 =
|
|
23197
|
+
const record2 = asRecord4(step);
|
|
22599
23198
|
if (!record2) return;
|
|
22600
23199
|
const assistant = cursorConversationStepValue(record2, "assistantMessage");
|
|
22601
23200
|
if (typeof assistant?.text === "string" && assistant.text) {
|
|
@@ -22636,7 +23235,7 @@ function emitCursorSubagentTranscript(transcriptPath, parentToolUseId, presenter
|
|
|
22636
23235
|
}
|
|
22637
23236
|
let lines;
|
|
22638
23237
|
try {
|
|
22639
|
-
lines = (0,
|
|
23238
|
+
lines = (0, import_fs8.readFileSync)(transcriptPath, "utf8").split(/\r?\n/);
|
|
22640
23239
|
if (lines.at(-1) === "") lines.pop();
|
|
22641
23240
|
} catch {
|
|
22642
23241
|
return { found: false, processedLineCount: startLine, emittedEventCount: 0 };
|
|
@@ -22657,10 +23256,10 @@ function emitCursorSubagentTranscript(transcriptPath, parentToolUseId, presenter
|
|
|
22657
23256
|
}
|
|
22658
23257
|
processedLineCount = lineIndex + 1;
|
|
22659
23258
|
if (entry.role !== "assistant") continue;
|
|
22660
|
-
const message =
|
|
23259
|
+
const message = asRecord4(entry.message);
|
|
22661
23260
|
const content = Array.isArray(message?.content) ? message.content : [];
|
|
22662
23261
|
content.forEach((rawBlock, blockIndex) => {
|
|
22663
|
-
const block =
|
|
23262
|
+
const block = asRecord4(rawBlock);
|
|
22664
23263
|
if (!block) return;
|
|
22665
23264
|
const type = typeof block.type === "string" ? block.type : "";
|
|
22666
23265
|
const text = typeof block.text === "string" ? block.text : "";
|
|
@@ -22678,18 +23277,18 @@ function emitCursorSubagentTranscript(transcriptPath, parentToolUseId, presenter
|
|
|
22678
23277
|
const name = typeof block.name === "string" && block.name ? block.name : "Cursor Tool";
|
|
22679
23278
|
const toolId = typeof block.id === "string" && block.id || `${parentToolUseId}-transcript-${lineIndex}-${blockIndex}`;
|
|
22680
23279
|
emittedEventCount += 1;
|
|
22681
|
-
void presenter.onToolUse(name,
|
|
23280
|
+
void presenter.onToolUse(name, asRecord4(block.input) ?? {}, toolId, parentToolUseId);
|
|
22682
23281
|
});
|
|
22683
23282
|
}
|
|
22684
23283
|
return { found: true, processedLineCount, emittedEventCount };
|
|
22685
23284
|
}
|
|
22686
23285
|
function cursorTranscriptsRoot(context) {
|
|
22687
23286
|
const projectKey = context.cwd.replace(/^[/\\]+/, "").replace(/[/\\]+/g, "-");
|
|
22688
|
-
const home = context.env.HOME || process.env.HOME || (0,
|
|
22689
|
-
return (0,
|
|
23287
|
+
const home = context.env.HOME || process.env.HOME || (0, import_os7.homedir)();
|
|
23288
|
+
return (0, import_path8.join)(home, ".cursor", "projects", projectKey, "agent-transcripts");
|
|
22690
23289
|
}
|
|
22691
23290
|
function cursorTranscriptPathForAgent(context, agentId) {
|
|
22692
|
-
return (0,
|
|
23291
|
+
return (0, import_path8.join)(cursorTranscriptsRoot(context), agentId, `${agentId}.jsonl`);
|
|
22693
23292
|
}
|
|
22694
23293
|
function resolveCursorSubagentTranscriptPath(success2, context) {
|
|
22695
23294
|
const explicit = success2?.transcriptPath ?? success2?.transcript_path;
|
|
@@ -22699,14 +23298,14 @@ function resolveCursorSubagentTranscriptPath(success2, context) {
|
|
|
22699
23298
|
}
|
|
22700
23299
|
function cursorTranscriptUserText(transcriptPath) {
|
|
22701
23300
|
try {
|
|
22702
|
-
for (const line of (0,
|
|
23301
|
+
for (const line of (0, import_fs8.readFileSync)(transcriptPath, "utf8").split(/\r?\n/)) {
|
|
22703
23302
|
if (!line) continue;
|
|
22704
|
-
const entry =
|
|
23303
|
+
const entry = asRecord4(JSON.parse(line));
|
|
22705
23304
|
if (entry?.role !== "user") continue;
|
|
22706
|
-
const message =
|
|
23305
|
+
const message = asRecord4(entry.message);
|
|
22707
23306
|
const content = Array.isArray(message?.content) ? message.content : [];
|
|
22708
23307
|
return content.flatMap((block) => {
|
|
22709
|
-
const record2 =
|
|
23308
|
+
const record2 = asRecord4(block);
|
|
22710
23309
|
return typeof record2?.text === "string" ? [record2.text] : [];
|
|
22711
23310
|
}).join("");
|
|
22712
23311
|
}
|
|
@@ -22716,13 +23315,13 @@ function cursorTranscriptUserText(transcriptPath) {
|
|
|
22716
23315
|
}
|
|
22717
23316
|
function discoverCursorSubagentTranscript(context, state, task) {
|
|
22718
23317
|
const root = cursorTranscriptsRoot(context);
|
|
22719
|
-
if (!(0,
|
|
23318
|
+
if (!(0, import_fs8.existsSync)(root)) return void 0;
|
|
22720
23319
|
const prompt = task.prompt?.trim();
|
|
22721
23320
|
const description = task.description?.trim().toLowerCase();
|
|
22722
23321
|
const candidates = [];
|
|
22723
23322
|
let entries;
|
|
22724
23323
|
try {
|
|
22725
|
-
entries = (0,
|
|
23324
|
+
entries = (0, import_fs8.readdirSync)(root, { withFileTypes: true });
|
|
22726
23325
|
} catch {
|
|
22727
23326
|
return void 0;
|
|
22728
23327
|
}
|
|
@@ -22731,7 +23330,7 @@ function discoverCursorSubagentTranscript(context, state, task) {
|
|
|
22731
23330
|
const path = cursorTranscriptPathForAgent(context, entry.name);
|
|
22732
23331
|
let mtimeMs;
|
|
22733
23332
|
try {
|
|
22734
|
-
mtimeMs = (0,
|
|
23333
|
+
mtimeMs = (0, import_fs8.statSync)(path).mtimeMs;
|
|
22735
23334
|
} catch {
|
|
22736
23335
|
continue;
|
|
22737
23336
|
}
|
|
@@ -23157,7 +23756,7 @@ var DROID_TASK_OUTPUT_NAMES = /* @__PURE__ */ new Set(["taskoutput", "task_outpu
|
|
|
23157
23756
|
var DROID_TASK_STOP_NAMES = /* @__PURE__ */ new Set(["taskstop", "task_stop"]);
|
|
23158
23757
|
var pendingTaskIdByToolId = /* @__PURE__ */ new WeakMap();
|
|
23159
23758
|
var explicitBackgroundLaunchers2 = /* @__PURE__ */ new WeakMap();
|
|
23160
|
-
function
|
|
23759
|
+
function asRecord5(value2) {
|
|
23161
23760
|
return value2 && typeof value2 === "object" && !Array.isArray(value2) ? value2 : null;
|
|
23162
23761
|
}
|
|
23163
23762
|
function asString2(value2) {
|
|
@@ -23309,7 +23908,7 @@ function handleDroidStructuredEvent(parsed, context, state) {
|
|
|
23309
23908
|
const ack = looksLikeBackgroundLaunchAck({
|
|
23310
23909
|
content,
|
|
23311
23910
|
value: value2,
|
|
23312
|
-
explicitBackground: wasExplicitBackground2(state, toolId) || boolish2(
|
|
23911
|
+
explicitBackground: wasExplicitBackground2(state, toolId) || boolish2(asRecord5(value2)?.run_in_background),
|
|
23313
23912
|
trackedUnlinkedLauncher: trackedLauncher && !linkedBackground
|
|
23314
23913
|
});
|
|
23315
23914
|
if (ack.isAck && ack.taskId) {
|
|
@@ -23451,7 +24050,7 @@ function createDroidCliBackend(command = "droid", defaultArgs = []) {
|
|
|
23451
24050
|
};
|
|
23452
24051
|
}
|
|
23453
24052
|
var ACP_PROTOCOL_VERSION = 1;
|
|
23454
|
-
function
|
|
24053
|
+
function asRecord6(value2) {
|
|
23455
24054
|
return value2 && typeof value2 === "object" && !Array.isArray(value2) ? value2 : null;
|
|
23456
24055
|
}
|
|
23457
24056
|
function asString3(value2) {
|
|
@@ -23461,7 +24060,7 @@ function resumeSessionId(context) {
|
|
|
23461
24060
|
return context.config.runtimeSessionId?.trim() || context.config.providerSessionId?.trim() || "";
|
|
23462
24061
|
}
|
|
23463
24062
|
function chunkText(content) {
|
|
23464
|
-
const record2 =
|
|
24063
|
+
const record2 = asRecord6(content);
|
|
23465
24064
|
if (!record2) return "";
|
|
23466
24065
|
if (typeof record2.text === "string") return record2.text;
|
|
23467
24066
|
return chunkText(record2.content);
|
|
@@ -23477,8 +24076,8 @@ function toolResultText(update) {
|
|
|
23477
24076
|
return "";
|
|
23478
24077
|
}
|
|
23479
24078
|
function toolMetaName(update) {
|
|
23480
|
-
const meta3 =
|
|
23481
|
-
const tool =
|
|
24079
|
+
const meta3 = asRecord6(update._meta);
|
|
24080
|
+
const tool = asRecord6(meta3?.["x.ai/tool"]);
|
|
23482
24081
|
return asString3(tool?.name);
|
|
23483
24082
|
}
|
|
23484
24083
|
function normalizeToolKey2(name) {
|
|
@@ -23509,18 +24108,18 @@ function normalizeGrokSubagentInput(toolName, rawInput) {
|
|
|
23509
24108
|
return input;
|
|
23510
24109
|
}
|
|
23511
24110
|
function resolvePermission(params, context) {
|
|
23512
|
-
const record2 =
|
|
24111
|
+
const record2 = asRecord6(params);
|
|
23513
24112
|
const options = Array.isArray(record2?.options) ? record2?.options : [];
|
|
23514
|
-
const toolCall =
|
|
23515
|
-
const meta3 =
|
|
23516
|
-
const tool =
|
|
24113
|
+
const toolCall = asRecord6(record2?.toolCall);
|
|
24114
|
+
const meta3 = asRecord6(toolCall?._meta);
|
|
24115
|
+
const tool = asRecord6(meta3?.["x.ai/tool"]);
|
|
23517
24116
|
const isReadOnlyTool = tool?.read_only === true || asString3(tool?.kind) === "read";
|
|
23518
24117
|
const allow = !shouldUseReadOnlyRuntimePermissions(context.config) || isReadOnlyTool;
|
|
23519
24118
|
const allowKinds = ["allow_always", "allow_once", "allow"];
|
|
23520
24119
|
const rejectKinds = ["reject_always", "reject_once", "reject", "deny"];
|
|
23521
24120
|
const wanted = allow ? allowKinds : rejectKinds;
|
|
23522
|
-
const chosen = options.find((option) => wanted.includes(asString3(
|
|
23523
|
-
const optionId = asString3(
|
|
24121
|
+
const chosen = options.find((option) => wanted.includes(asString3(asRecord6(option)?.kind))) ?? (allow ? options[0] : options[options.length - 1]);
|
|
24122
|
+
const optionId = asString3(asRecord6(chosen)?.optionId);
|
|
23524
24123
|
if (!optionId) return { outcome: { outcome: "cancelled" } };
|
|
23525
24124
|
return { outcome: { outcome: "selected", optionId } };
|
|
23526
24125
|
}
|
|
@@ -23613,9 +24212,9 @@ function createGrokAcpDriver(imageFiles) {
|
|
|
23613
24212
|
forceFinalize(state);
|
|
23614
24213
|
return;
|
|
23615
24214
|
}
|
|
23616
|
-
const result =
|
|
24215
|
+
const result = asRecord6(message.result);
|
|
23617
24216
|
if (message.id === initId) {
|
|
23618
|
-
const modelState =
|
|
24217
|
+
const modelState = asRecord6(asRecord6(result?._meta)?.modelState);
|
|
23619
24218
|
const model = asString3(modelState?.currentModelId);
|
|
23620
24219
|
if (model) state.activeModel = model;
|
|
23621
24220
|
beginSession(context, state);
|
|
@@ -23629,7 +24228,7 @@ function createGrokAcpDriver(imageFiles) {
|
|
|
23629
24228
|
return;
|
|
23630
24229
|
}
|
|
23631
24230
|
if (message.id === promptId) {
|
|
23632
|
-
const meta3 =
|
|
24231
|
+
const meta3 = asRecord6(result?._meta);
|
|
23633
24232
|
const model = asString3(meta3?.modelId) || state.activeModel || (typeof context.config.selectedModel === "string" && context.config.selectedModel.trim() ? context.config.selectedModel.trim() : "grok");
|
|
23634
24233
|
const inputTokens = typeof meta3?.inputTokens === "number" ? meta3.inputTokens : 0;
|
|
23635
24234
|
const outputTokens = typeof meta3?.outputTokens === "number" ? meta3.outputTokens : 0;
|
|
@@ -23676,8 +24275,8 @@ function createGrokAcpDriver(imageFiles) {
|
|
|
23676
24275
|
}
|
|
23677
24276
|
}
|
|
23678
24277
|
function handleNotification(message, context, state) {
|
|
23679
|
-
const params =
|
|
23680
|
-
const update =
|
|
24278
|
+
const params = asRecord6(message.params);
|
|
24279
|
+
const update = asRecord6(params?.update);
|
|
23681
24280
|
if (!update || !isPromptActive) return;
|
|
23682
24281
|
const presenter = context.presenter;
|
|
23683
24282
|
switch (asString3(update.sessionUpdate)) {
|
|
@@ -23699,7 +24298,7 @@ function createGrokAcpDriver(imageFiles) {
|
|
|
23699
24298
|
case "tool_call": {
|
|
23700
24299
|
const toolId = asString3(update.toolCallId);
|
|
23701
24300
|
const rawName = asString3(update.title) || toolMetaName(update) || "Grok Tool";
|
|
23702
|
-
const rawInput =
|
|
24301
|
+
const rawInput = asRecord6(update.rawInput);
|
|
23703
24302
|
const isSubagent = isGrokSubagentTool(rawName, rawInput);
|
|
23704
24303
|
const toolName = isSubagent ? presentGrokSubagentName(rawName) : rawName;
|
|
23705
24304
|
const input = isSubagent ? normalizeGrokSubagentInput(rawName, rawInput) : rawInput ?? {};
|
|
@@ -23774,7 +24373,7 @@ function createGrokAcpDriver(imageFiles) {
|
|
|
23774
24373
|
if (line.trim().length > 0) void context.presenter.onLog(`[grok_cli] ${line}`);
|
|
23775
24374
|
return;
|
|
23776
24375
|
}
|
|
23777
|
-
const message =
|
|
24376
|
+
const message = asRecord6(parsed);
|
|
23778
24377
|
if (!message) return;
|
|
23779
24378
|
if (message.id !== void 0 && message.method === void 0) {
|
|
23780
24379
|
handleResponse(message, context, state);
|
|
@@ -23841,9 +24440,9 @@ function buildGrokAgentArgs(config2, defaultArgs = []) {
|
|
|
23841
24440
|
return args;
|
|
23842
24441
|
}
|
|
23843
24442
|
var DEFAULT_SKILL_ROOTS = [
|
|
23844
|
-
(0,
|
|
23845
|
-
(0,
|
|
23846
|
-
(0,
|
|
24443
|
+
(0, import_path9.join)((0, import_os8.homedir)(), ".agents", "skills"),
|
|
24444
|
+
(0, import_path9.join)((0, import_os8.homedir)(), ".claude", "skills"),
|
|
24445
|
+
(0, import_path9.join)((0, import_os8.homedir)(), ".config", "opencode", "skills")
|
|
23847
24446
|
];
|
|
23848
24447
|
function parseFrontmatter(content) {
|
|
23849
24448
|
if (!content.startsWith("---\n")) return {};
|
|
@@ -23859,12 +24458,12 @@ function parseFrontmatter(content) {
|
|
|
23859
24458
|
return result;
|
|
23860
24459
|
}
|
|
23861
24460
|
function listSkillFiles(root) {
|
|
23862
|
-
if (!(0,
|
|
24461
|
+
if (!(0, import_fs9.existsSync)(root)) return [];
|
|
23863
24462
|
const files = [];
|
|
23864
|
-
for (const entry of (0,
|
|
24463
|
+
for (const entry of (0, import_fs9.readdirSync)(root, { withFileTypes: true })) {
|
|
23865
24464
|
if (!entry.isDirectory()) continue;
|
|
23866
|
-
const skillPath = (0,
|
|
23867
|
-
if ((0,
|
|
24465
|
+
const skillPath = (0, import_path9.join)(root, entry.name, "SKILL.md");
|
|
24466
|
+
if ((0, import_fs9.existsSync)(skillPath)) files.push(skillPath);
|
|
23868
24467
|
}
|
|
23869
24468
|
return files;
|
|
23870
24469
|
}
|
|
@@ -23873,7 +24472,7 @@ function loadInstalledSkills(roots = DEFAULT_SKILL_ROOTS) {
|
|
|
23873
24472
|
for (const root of roots) {
|
|
23874
24473
|
for (const skillPath of listSkillFiles(root)) {
|
|
23875
24474
|
try {
|
|
23876
|
-
const frontmatter = parseFrontmatter((0,
|
|
24475
|
+
const frontmatter = parseFrontmatter((0, import_fs9.readFileSync)(skillPath, "utf8"));
|
|
23877
24476
|
const name = frontmatter.name;
|
|
23878
24477
|
const description = frontmatter.description;
|
|
23879
24478
|
if (!name || !description || skills.has(name)) continue;
|
|
@@ -23912,7 +24511,7 @@ var KIMI_SUBAGENT_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
|
23912
24511
|
"subagent"
|
|
23913
24512
|
]);
|
|
23914
24513
|
var explicitBackgroundLaunchers3 = /* @__PURE__ */ new WeakMap();
|
|
23915
|
-
function
|
|
24514
|
+
function asRecord7(value2) {
|
|
23916
24515
|
return value2 && typeof value2 === "object" && !Array.isArray(value2) ? value2 : null;
|
|
23917
24516
|
}
|
|
23918
24517
|
function asString4(value2) {
|
|
@@ -24094,7 +24693,7 @@ function handleKimiStructuredEvent(parsed, context, state) {
|
|
|
24094
24693
|
);
|
|
24095
24694
|
return true;
|
|
24096
24695
|
}
|
|
24097
|
-
const statusRecord =
|
|
24696
|
+
const statusRecord = asRecord7(
|
|
24098
24697
|
(() => {
|
|
24099
24698
|
try {
|
|
24100
24699
|
return JSON.parse(content);
|
|
@@ -24427,10 +25026,18 @@ var parseOpencodeStructuredLine = createStructuredLineParser(
|
|
|
24427
25026
|
"opencode_cli",
|
|
24428
25027
|
handleOpencodeStructuredEvent
|
|
24429
25028
|
);
|
|
25029
|
+
function normalizeOpenCodeVariant(value2) {
|
|
25030
|
+
const trimmed = value2?.trim();
|
|
25031
|
+
const containsControlCharacter = Array.from(trimmed ?? "").some((character) => {
|
|
25032
|
+
const code = character.charCodeAt(0);
|
|
25033
|
+
return code <= 31 || code === 127;
|
|
25034
|
+
});
|
|
25035
|
+
if (!trimmed || trimmed.length > 256 || containsControlCharacter) return null;
|
|
25036
|
+
return trimmed;
|
|
25037
|
+
}
|
|
24430
25038
|
function buildOpencodeEffortArgs(selectedEffortLevel) {
|
|
24431
|
-
const
|
|
24432
|
-
|
|
24433
|
-
return ["--variant", trimmed];
|
|
25039
|
+
const variant = normalizeOpenCodeVariant(selectedEffortLevel);
|
|
25040
|
+
return variant ? ["--variant", variant] : [];
|
|
24434
25041
|
}
|
|
24435
25042
|
function createOpencodeCliBackend(command = "opencode", defaultArgs = []) {
|
|
24436
25043
|
return {
|
|
@@ -24547,9 +25154,27 @@ var SERVER_LISTENING_PATTERN = /listening on (https?:\/\/\S+)/i;
|
|
|
24547
25154
|
var STARTUP_TIMEOUT_MS = 2e4;
|
|
24548
25155
|
var HEALTH_POLL_INTERVAL_MS = 200;
|
|
24549
25156
|
var HEALTH_POLL_MAX_ATTEMPTS = 50;
|
|
25157
|
+
var LEASE_IDLE_TTL_MS = 10 * 60 * 1e3;
|
|
25158
|
+
var serveLeases = /* @__PURE__ */ new Map();
|
|
25159
|
+
function leaseKeyFor(context) {
|
|
25160
|
+
const conversationId = context.config.conversationId?.trim();
|
|
25161
|
+
return conversationId ? `conv:${conversationId}` : null;
|
|
25162
|
+
}
|
|
25163
|
+
function isLeaseUsable(lease) {
|
|
25164
|
+
const alive = lease.child.exitCode === null && lease.child.signalCode === null;
|
|
25165
|
+
const fresh = Date.now() - lease.lastUsedAtMs <= LEASE_IDLE_TTL_MS;
|
|
25166
|
+
return alive && fresh;
|
|
25167
|
+
}
|
|
25168
|
+
function evictLease(key) {
|
|
25169
|
+
if (!key) return;
|
|
25170
|
+
const lease = serveLeases.get(key);
|
|
25171
|
+
if (!lease) return;
|
|
25172
|
+
serveLeases.delete(key);
|
|
25173
|
+
killProcessTree(lease.child.pid, { signal: "SIGTERM", child: lease.child });
|
|
25174
|
+
}
|
|
24550
25175
|
function startOpenCodeServer(command, context) {
|
|
24551
25176
|
const child = spawnCli(command, ["serve", "--port", "0", "--hostname", "127.0.0.1"], context);
|
|
24552
|
-
const ready = new Promise((
|
|
25177
|
+
const ready = new Promise((resolve42, reject) => {
|
|
24553
25178
|
let settled = false;
|
|
24554
25179
|
const timeout = setTimeout(() => {
|
|
24555
25180
|
if (settled) return;
|
|
@@ -24567,7 +25192,7 @@ function startOpenCodeServer(command, context) {
|
|
|
24567
25192
|
if (!match) return;
|
|
24568
25193
|
settled = true;
|
|
24569
25194
|
clearTimeout(timeout);
|
|
24570
|
-
|
|
25195
|
+
resolve42({ baseUrl: match[1].replace(/\/$/, "") });
|
|
24571
25196
|
};
|
|
24572
25197
|
stdoutRl.on("line", checkLine);
|
|
24573
25198
|
stderrRl.on("line", (line) => {
|
|
@@ -24605,7 +25230,7 @@ async function waitForHealthy(baseUrl, signal) {
|
|
|
24605
25230
|
}
|
|
24606
25231
|
} catch {
|
|
24607
25232
|
}
|
|
24608
|
-
await new Promise((
|
|
25233
|
+
await new Promise((resolve42) => setTimeout(resolve42, HEALTH_POLL_INTERVAL_MS));
|
|
24609
25234
|
}
|
|
24610
25235
|
throw new Error(`opencode server at ${baseUrl} did not become healthy in time`);
|
|
24611
25236
|
}
|
|
@@ -24642,27 +25267,30 @@ function buildPromptParts(promptText, imageFiles, attachmentFiles) {
|
|
|
24642
25267
|
type: "file",
|
|
24643
25268
|
mime: file2.mimeType,
|
|
24644
25269
|
filename: file2.filename,
|
|
24645
|
-
url: (0,
|
|
25270
|
+
url: (0, import_url2.pathToFileURL)(file2.path).href
|
|
24646
25271
|
})
|
|
24647
25272
|
);
|
|
24648
25273
|
return [...attachments, { type: "text", text: promptText }];
|
|
24649
25274
|
}
|
|
24650
|
-
|
|
25275
|
+
function buildOpenCodePromptRequest(context, parts2) {
|
|
24651
25276
|
const model = context.config.selectedModel?.trim();
|
|
24652
25277
|
const modelBody = model?.includes("/") ? (() => {
|
|
24653
25278
|
const slashIndex = model.indexOf("/");
|
|
24654
25279
|
return { providerID: model.slice(0, slashIndex), modelID: model.slice(slashIndex + 1) };
|
|
24655
25280
|
})() : void 0;
|
|
24656
|
-
const variant = context.config.selectedEffortLevel
|
|
25281
|
+
const variant = normalizeOpenCodeVariant(context.config.selectedEffortLevel);
|
|
25282
|
+
return {
|
|
25283
|
+
parts: parts2,
|
|
25284
|
+
...modelBody ? { model: modelBody } : {},
|
|
25285
|
+
...variant ? { variant } : {}
|
|
25286
|
+
};
|
|
25287
|
+
}
|
|
25288
|
+
async function sendPrompt(baseUrl, sessionId, context, parts2, signal) {
|
|
24657
25289
|
const response = await fetch(`${baseUrl}/session/${encodeURIComponent(sessionId)}/message`, {
|
|
24658
25290
|
method: "POST",
|
|
24659
25291
|
signal,
|
|
24660
25292
|
headers: { "Content-Type": "application/json" },
|
|
24661
|
-
body: JSON.stringify(
|
|
24662
|
-
parts: parts2,
|
|
24663
|
-
...modelBody ? { model: modelBody } : {},
|
|
24664
|
-
...variant && isEffortLevel(variant) ? { variant } : {}
|
|
24665
|
-
})
|
|
25293
|
+
body: JSON.stringify(buildOpenCodePromptRequest(context, parts2))
|
|
24666
25294
|
});
|
|
24667
25295
|
if (!response.ok) {
|
|
24668
25296
|
const text = await response.text().catch(() => "");
|
|
@@ -24679,6 +25307,18 @@ async function replyToPermission(baseUrl, requestId, reply, signal) {
|
|
|
24679
25307
|
console.warn("[opencode_serve] Failed to reply to permission request", requestId, error2);
|
|
24680
25308
|
});
|
|
24681
25309
|
}
|
|
25310
|
+
var NON_INTERACTIVE_PERMISSION_KINDS = /* @__PURE__ */ new Set(["question", "plan_enter", "plan_exit"]);
|
|
25311
|
+
function decideAndReplyToPermission(presenter, baseUrl, properties, readOnly, signal, origin) {
|
|
25312
|
+
const requestId = getString(properties.id);
|
|
25313
|
+
if (!requestId) return;
|
|
25314
|
+
const permissionKind = getString(properties.permission) || "an action";
|
|
25315
|
+
const nonInteractive = NON_INTERACTIVE_PERMISSION_KINDS.has(permissionKind);
|
|
25316
|
+
const reply = nonInteractive || readOnly ? "reject" : "once";
|
|
25317
|
+
const subject = origin === "root" ? "OpenCode" : "OpenCode's background session";
|
|
25318
|
+
const message = nonInteractive ? `${subject} tried to ${permissionKind.replace(/_/g, " ")} \u2014 denied (Alan does not yet support interactive requests for OpenCode).` : readOnly ? `${subject} requested permission to ${permissionKind} \u2014 automatically denied (read-only session).` : `${subject} requested permission to ${permissionKind} \u2014 automatically approved (autonomous mode).`;
|
|
25319
|
+
emitSessionNotice(presenter, "permission_decision", message);
|
|
25320
|
+
void replyToPermission(baseUrl, requestId, reply, signal);
|
|
25321
|
+
}
|
|
24682
25322
|
function buildAgentResult(state, sessionId, aborted2) {
|
|
24683
25323
|
if (aborted2) {
|
|
24684
25324
|
return {
|
|
@@ -24726,7 +25366,13 @@ function createOpencodeServeBackend(command = "opencode") {
|
|
|
24726
25366
|
);
|
|
24727
25367
|
const runContext = withAutonomousOpenCodePermissions(context);
|
|
24728
25368
|
const readOnly = shouldUseReadOnlyRuntimePermissions(context.config);
|
|
24729
|
-
const
|
|
25369
|
+
const leaseKey = leaseKeyFor(context);
|
|
25370
|
+
const existingLease = leaseKey ? serveLeases.get(leaseKey) : void 0;
|
|
25371
|
+
const reuseLease = Boolean(existingLease && isLeaseUsable(existingLease));
|
|
25372
|
+
if (existingLease && !reuseLease) evictLease(leaseKey);
|
|
25373
|
+
const spawnedServer = reuseLease && existingLease ? null : startOpenCodeServer(command, runContext);
|
|
25374
|
+
const child = reuseLease && existingLease ? existingLease.child : spawnedServer.child;
|
|
25375
|
+
const ready = reuseLease && existingLease ? Promise.resolve({ baseUrl: existingLease.baseUrl }) : spawnedServer.ready;
|
|
24730
25376
|
const state = { process: child, iterations: 0, summary: "" };
|
|
24731
25377
|
context.onProcessSpawned?.(child);
|
|
24732
25378
|
context.registerLivenessProbe?.(() => ({
|
|
@@ -24739,13 +25385,19 @@ function createOpencodeServeBackend(command = "opencode") {
|
|
|
24739
25385
|
const onAbort = () => {
|
|
24740
25386
|
aborted2 = true;
|
|
24741
25387
|
sseClose?.();
|
|
25388
|
+
if (leaseKey) serveLeases.delete(leaseKey);
|
|
24742
25389
|
killProcessTree(child.pid, { signal: "SIGTERM", child });
|
|
24743
25390
|
};
|
|
24744
25391
|
context.abortController.signal.addEventListener("abort", onAbort, { once: true });
|
|
24745
25392
|
try {
|
|
24746
25393
|
const server = await ready;
|
|
24747
25394
|
state.lastRawOutputAtMs = Date.now();
|
|
24748
|
-
|
|
25395
|
+
if (!reuseLease) {
|
|
25396
|
+
await waitForHealthy(server.baseUrl, context.abortController.signal);
|
|
25397
|
+
}
|
|
25398
|
+
if (leaseKey) {
|
|
25399
|
+
serveLeases.set(leaseKey, { child, baseUrl: server.baseUrl, lastUsedAtMs: Date.now() });
|
|
25400
|
+
}
|
|
24749
25401
|
const session = await resolveSession(
|
|
24750
25402
|
server.baseUrl,
|
|
24751
25403
|
runContext,
|
|
@@ -24803,17 +25455,94 @@ function createOpencodeServeBackend(command = "opencode") {
|
|
|
24803
25455
|
} finally {
|
|
24804
25456
|
context.abortController.signal.removeEventListener("abort", onAbort);
|
|
24805
25457
|
sseClose?.();
|
|
24806
|
-
|
|
25458
|
+
const wasAborted = aborted2 || context.abortController.signal.aborted;
|
|
25459
|
+
if (wasAborted || !leaseKey) {
|
|
25460
|
+
if (leaseKey) serveLeases.delete(leaseKey);
|
|
25461
|
+
killProcessTree(child.pid, { signal: "SIGTERM", child });
|
|
25462
|
+
} else {
|
|
25463
|
+
const lease = serveLeases.get(leaseKey);
|
|
25464
|
+
if (lease) lease.lastUsedAtMs = Date.now();
|
|
25465
|
+
}
|
|
24807
25466
|
cleanupImages();
|
|
24808
25467
|
cleanupFiles();
|
|
24809
25468
|
}
|
|
24810
25469
|
}
|
|
24811
25470
|
};
|
|
24812
25471
|
}
|
|
25472
|
+
function resolveChildSessionLauncherToolId(state, eventSessionId) {
|
|
25473
|
+
const existing = state.backgroundToolIdByTaskId?.get(eventSessionId);
|
|
25474
|
+
if (existing) return existing;
|
|
25475
|
+
registerBackgroundTaskRecord(state, { task_id: eventSessionId });
|
|
25476
|
+
return state.backgroundToolIdByTaskId?.get(eventSessionId);
|
|
25477
|
+
}
|
|
25478
|
+
function handleOpenCodeChildSessionEvent(event, eventSessionId, context, state, readOnly, baseUrl) {
|
|
25479
|
+
const properties = event.properties;
|
|
25480
|
+
switch (event.type) {
|
|
25481
|
+
case "message.updated": {
|
|
25482
|
+
const info = getRecord(properties.info);
|
|
25483
|
+
if (getString(info?.role) === "user") {
|
|
25484
|
+
const messageId = getString(info?.id);
|
|
25485
|
+
if (messageId) {
|
|
25486
|
+
state.opencodeUserMessageIds ??= /* @__PURE__ */ new Set();
|
|
25487
|
+
state.opencodeUserMessageIds.add(messageId);
|
|
25488
|
+
}
|
|
25489
|
+
}
|
|
25490
|
+
return false;
|
|
25491
|
+
}
|
|
25492
|
+
case "message.part.updated": {
|
|
25493
|
+
const part = getRecord(properties.part);
|
|
25494
|
+
if (!part) return false;
|
|
25495
|
+
const messageId = getString(part.messageID);
|
|
25496
|
+
if (messageId && state.opencodeUserMessageIds?.has(messageId)) return false;
|
|
25497
|
+
const parentToolUseId = resolveChildSessionLauncherToolId(state, eventSessionId);
|
|
25498
|
+
if (!parentToolUseId && !state.opencodeUnlinkedChildSessionIds?.has(eventSessionId)) {
|
|
25499
|
+
state.opencodeUnlinkedChildSessionIds ??= /* @__PURE__ */ new Set();
|
|
25500
|
+
state.opencodeUnlinkedChildSessionIds.add(eventSessionId);
|
|
25501
|
+
void context.presenter.onLog(
|
|
25502
|
+
`[opencode] Background session ${eventSessionId} is active (no linked launcher \u2014 showing at top level)`
|
|
25503
|
+
);
|
|
25504
|
+
}
|
|
25505
|
+
mapOpencodePart(part, context, state, { parentToolUseId });
|
|
25506
|
+
return false;
|
|
25507
|
+
}
|
|
25508
|
+
case "message.part.delta":
|
|
25509
|
+
return false;
|
|
25510
|
+
case "permission.asked": {
|
|
25511
|
+
decideAndReplyToPermission(
|
|
25512
|
+
context.presenter,
|
|
25513
|
+
baseUrl,
|
|
25514
|
+
properties,
|
|
25515
|
+
readOnly,
|
|
25516
|
+
context.abortController.signal,
|
|
25517
|
+
"background session"
|
|
25518
|
+
);
|
|
25519
|
+
return false;
|
|
25520
|
+
}
|
|
25521
|
+
case "session.error": {
|
|
25522
|
+
const errorRecord = getRecord(properties.error);
|
|
25523
|
+
const message = getString(errorRecord?.message) || getString(properties.error) || "Background OpenCode session error.";
|
|
25524
|
+
void context.presenter.onLog(
|
|
25525
|
+
`[opencode] Background session ${eventSessionId} error: ${message}`
|
|
25526
|
+
);
|
|
25527
|
+
return false;
|
|
25528
|
+
}
|
|
25529
|
+
default:
|
|
25530
|
+
return false;
|
|
25531
|
+
}
|
|
25532
|
+
}
|
|
24813
25533
|
function handleOpenCodeServeEvent(event, sessionId, context, state, readOnly, baseUrl) {
|
|
24814
25534
|
const properties = event.properties;
|
|
24815
25535
|
const eventSessionId = getString(properties.sessionID);
|
|
24816
|
-
if (eventSessionId && eventSessionId !== sessionId)
|
|
25536
|
+
if (eventSessionId && eventSessionId !== sessionId) {
|
|
25537
|
+
return handleOpenCodeChildSessionEvent(
|
|
25538
|
+
event,
|
|
25539
|
+
eventSessionId,
|
|
25540
|
+
context,
|
|
25541
|
+
state,
|
|
25542
|
+
readOnly,
|
|
25543
|
+
baseUrl
|
|
25544
|
+
);
|
|
25545
|
+
}
|
|
24817
25546
|
switch (event.type) {
|
|
24818
25547
|
// Live-verified: the SSE bus emits a message.updated (and matching
|
|
24819
25548
|
// message.part.updated) for the USER's own message too, not just the
|
|
@@ -24843,15 +25572,14 @@ function handleOpenCodeServeEvent(event, sessionId, context, state, readOnly, ba
|
|
|
24843
25572
|
case "message.part.delta":
|
|
24844
25573
|
return false;
|
|
24845
25574
|
case "permission.asked": {
|
|
24846
|
-
|
|
24847
|
-
|
|
24848
|
-
|
|
24849
|
-
|
|
24850
|
-
|
|
24851
|
-
|
|
24852
|
-
|
|
24853
|
-
|
|
24854
|
-
}
|
|
25575
|
+
decideAndReplyToPermission(
|
|
25576
|
+
context.presenter,
|
|
25577
|
+
baseUrl,
|
|
25578
|
+
properties,
|
|
25579
|
+
readOnly,
|
|
25580
|
+
context.abortController.signal,
|
|
25581
|
+
"root"
|
|
25582
|
+
);
|
|
24855
25583
|
return false;
|
|
24856
25584
|
}
|
|
24857
25585
|
case "session.error": {
|
|
@@ -25024,22 +25752,31 @@ function parseRepoNamespace(command) {
|
|
|
25024
25752
|
};
|
|
25025
25753
|
}
|
|
25026
25754
|
function hasSkillLayout(dir) {
|
|
25027
|
-
return SKILL_LAYOUT_PARTS.some((parts2) => (0,
|
|
25755
|
+
return SKILL_LAYOUT_PARTS.some((parts2) => (0, import_fs10.existsSync)((0, import_path10.join)(dir, ...parts2)));
|
|
25028
25756
|
}
|
|
25029
25757
|
function isGitRepo(dir) {
|
|
25030
|
-
return (0,
|
|
25758
|
+
return (0, import_fs10.existsSync)((0, import_path10.join)(dir, ".git"));
|
|
25031
25759
|
}
|
|
25032
25760
|
function isLeafProjectRoot(dir) {
|
|
25033
25761
|
return isGitRepo(dir) || hasSkillLayout(dir);
|
|
25034
25762
|
}
|
|
25035
25763
|
function skillDirsForRoot(root) {
|
|
25036
|
-
return SKILL_LAYOUT_PARTS.map((parts2) => (0,
|
|
25764
|
+
return SKILL_LAYOUT_PARTS.map((parts2) => (0, import_path10.join)(root, ...parts2));
|
|
25765
|
+
}
|
|
25766
|
+
function pluginSkillDirsForRoot(root) {
|
|
25767
|
+
const pluginsDir = (0, import_path10.join)(root, ".agents", "plugins");
|
|
25768
|
+
if (!(0, import_fs10.existsSync)(pluginsDir)) return [];
|
|
25769
|
+
try {
|
|
25770
|
+
return (0, import_fs10.readdirSync)(pluginsDir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => (0, import_path10.join)(pluginsDir, entry.name, "skills"));
|
|
25771
|
+
} catch {
|
|
25772
|
+
return [];
|
|
25773
|
+
}
|
|
25037
25774
|
}
|
|
25038
25775
|
function listImmediateChildDirs(cwd) {
|
|
25039
|
-
if (!(0,
|
|
25776
|
+
if (!(0, import_fs10.existsSync)(cwd)) return [];
|
|
25040
25777
|
let entries = [];
|
|
25041
25778
|
try {
|
|
25042
|
-
entries = (0,
|
|
25779
|
+
entries = (0, import_fs10.readdirSync)(cwd, { withFileTypes: true });
|
|
25043
25780
|
} catch {
|
|
25044
25781
|
return [];
|
|
25045
25782
|
}
|
|
@@ -25047,40 +25784,50 @@ function listImmediateChildDirs(cwd) {
|
|
|
25047
25784
|
for (const entry of entries) {
|
|
25048
25785
|
if (!entry.isDirectory()) continue;
|
|
25049
25786
|
if (entry.name.startsWith(".")) continue;
|
|
25050
|
-
children.push((0,
|
|
25787
|
+
children.push((0, import_path10.join)(cwd, entry.name));
|
|
25051
25788
|
}
|
|
25052
25789
|
return children;
|
|
25053
25790
|
}
|
|
25054
25791
|
function projectCandidateRoots(cwd) {
|
|
25055
25792
|
if (!cwd) return [];
|
|
25056
|
-
const roots = [...skillDirsForRoot(cwd)];
|
|
25793
|
+
const roots = [...skillDirsForRoot(cwd), ...pluginSkillDirsForRoot(cwd)];
|
|
25057
25794
|
if (!isLeafProjectRoot(cwd)) {
|
|
25058
25795
|
for (const child of listImmediateChildDirs(cwd)) {
|
|
25059
25796
|
roots.push(...skillDirsForRoot(child));
|
|
25797
|
+
roots.push(...pluginSkillDirsForRoot(child));
|
|
25060
25798
|
}
|
|
25061
25799
|
}
|
|
25062
25800
|
return Array.from(new Set(roots));
|
|
25063
25801
|
}
|
|
25064
|
-
function globalCandidateRoots() {
|
|
25065
|
-
|
|
25802
|
+
function globalCandidateRoots(home) {
|
|
25803
|
+
const antigravityConfig = (0, import_path10.join)(home, ".gemini", "config");
|
|
25804
|
+
return Array.from(
|
|
25805
|
+
/* @__PURE__ */ new Set([
|
|
25806
|
+
...skillDirsForRoot(home),
|
|
25807
|
+
(0, import_path10.join)(antigravityConfig, "skills"),
|
|
25808
|
+
...pluginSkillDirsForRoot(antigravityConfig)
|
|
25809
|
+
])
|
|
25810
|
+
);
|
|
25066
25811
|
}
|
|
25067
25812
|
function namespacedCandidateRoots(cwd, repoLabel) {
|
|
25068
25813
|
const roots = [];
|
|
25069
25814
|
if (cwd) {
|
|
25070
|
-
roots.push(...skillDirsForRoot((0,
|
|
25815
|
+
roots.push(...skillDirsForRoot((0, import_path10.join)(cwd, repoLabel)));
|
|
25816
|
+
roots.push(...pluginSkillDirsForRoot((0, import_path10.join)(cwd, repoLabel)));
|
|
25071
25817
|
const base = cwd.replace(/[/\\]+$/, "").split(/[/\\]/).pop();
|
|
25072
25818
|
if (base === repoLabel) {
|
|
25073
25819
|
roots.push(...skillDirsForRoot(cwd));
|
|
25820
|
+
roots.push(...pluginSkillDirsForRoot(cwd));
|
|
25074
25821
|
}
|
|
25075
25822
|
}
|
|
25076
25823
|
return Array.from(new Set(roots));
|
|
25077
25824
|
}
|
|
25078
25825
|
function readSkillAt(root, command) {
|
|
25079
|
-
const skillPath = (0,
|
|
25080
|
-
if (!(0,
|
|
25826
|
+
const skillPath = (0, import_path10.join)(root, command, "SKILL.md");
|
|
25827
|
+
if (!(0, import_fs10.existsSync)(skillPath)) return null;
|
|
25081
25828
|
let content;
|
|
25082
25829
|
try {
|
|
25083
|
-
content = (0,
|
|
25830
|
+
content = (0, import_fs10.readFileSync)(skillPath, "utf-8");
|
|
25084
25831
|
} catch {
|
|
25085
25832
|
return null;
|
|
25086
25833
|
}
|
|
@@ -25103,7 +25850,7 @@ function collectMatches(roots, command, userRequest) {
|
|
|
25103
25850
|
}
|
|
25104
25851
|
return matches;
|
|
25105
25852
|
}
|
|
25106
|
-
function resolveSkillInvocation(text, cwd) {
|
|
25853
|
+
function resolveSkillInvocation(text, cwd, home = (0, import_os9.homedir)()) {
|
|
25107
25854
|
const parsed = parseSkillInvocation(text);
|
|
25108
25855
|
if (!parsed) return null;
|
|
25109
25856
|
const projectExact = collectMatches(
|
|
@@ -25115,7 +25862,11 @@ function resolveSkillInvocation(text, cwd) {
|
|
|
25115
25862
|
if (projectExact.length > 1) {
|
|
25116
25863
|
return null;
|
|
25117
25864
|
}
|
|
25118
|
-
const globalExact = collectMatches(
|
|
25865
|
+
const globalExact = collectMatches(
|
|
25866
|
+
globalCandidateRoots(home),
|
|
25867
|
+
parsed.command,
|
|
25868
|
+
parsed.userRequest
|
|
25869
|
+
);
|
|
25119
25870
|
if (globalExact.length === 1) return globalExact[0];
|
|
25120
25871
|
const namespaced = parseRepoNamespace(parsed.command);
|
|
25121
25872
|
if (!namespaced) return null;
|
|
@@ -25132,8 +25883,8 @@ function resolveSkillInvocation(text, cwd) {
|
|
|
25132
25883
|
}
|
|
25133
25884
|
return null;
|
|
25134
25885
|
}
|
|
25135
|
-
function expandSkillInvocationPrompt(text, cwd) {
|
|
25136
|
-
const invocation = resolveSkillInvocation(text, cwd);
|
|
25886
|
+
function expandSkillInvocationPrompt(text, cwd, home = (0, import_os9.homedir)()) {
|
|
25887
|
+
const invocation = resolveSkillInvocation(text, cwd, home);
|
|
25137
25888
|
if (!invocation) return { text, invocation: null };
|
|
25138
25889
|
const request = invocation.userRequest || "(No additional request text was provided.)";
|
|
25139
25890
|
return {
|
|
@@ -25157,7 +25908,6 @@ var DROID_DEFAULT_MODEL = "claude-opus-4-7";
|
|
|
25157
25908
|
var AGENT_ACTIVITY_HEARTBEAT_MS = 1e4;
|
|
25158
25909
|
function normalizeBackendKind(kind) {
|
|
25159
25910
|
if (kind === "codex") return "codex_app_server";
|
|
25160
|
-
if (kind === "gemini" || kind === "gemini_cli") return "antigravity_cli";
|
|
25161
25911
|
return kind || "claude_cli";
|
|
25162
25912
|
}
|
|
25163
25913
|
function firstCatalogModelId(backendKind) {
|
|
@@ -25567,18 +26317,18 @@ ${runtimeConfig.task}` } : {}
|
|
|
25567
26317
|
`[base-machine-agent] Transient error (attempt ${attempt + 1}/${_BaseMachineAgent.MAX_RETRIES + 1}), retrying in ${delayMs}ms: ${lastResult.error}`
|
|
25568
26318
|
);
|
|
25569
26319
|
void this.presenter.onLog(`Transient error, retrying in ${Math.round(delayMs / 1e3)}s...`);
|
|
25570
|
-
await new Promise((
|
|
26320
|
+
await new Promise((resolve42) => {
|
|
25571
26321
|
const signal = this.abortController?.signal;
|
|
25572
26322
|
if (signal?.aborted) {
|
|
25573
|
-
|
|
26323
|
+
resolve42();
|
|
25574
26324
|
return;
|
|
25575
26325
|
}
|
|
25576
|
-
const timeoutId = setTimeout(
|
|
26326
|
+
const timeoutId = setTimeout(resolve42, delayMs);
|
|
25577
26327
|
signal?.addEventListener(
|
|
25578
26328
|
"abort",
|
|
25579
26329
|
() => {
|
|
25580
26330
|
clearTimeout(timeoutId);
|
|
25581
|
-
|
|
26331
|
+
resolve42();
|
|
25582
26332
|
},
|
|
25583
26333
|
{ once: true }
|
|
25584
26334
|
);
|
|
@@ -25748,14 +26498,14 @@ function normalizePath2(candidate, cwd) {
|
|
|
25748
26498
|
} catch {
|
|
25749
26499
|
}
|
|
25750
26500
|
if (path.startsWith("~/")) return null;
|
|
25751
|
-
if ((0,
|
|
25752
|
-
return cwd ? (0,
|
|
26501
|
+
if ((0, import_path11.isAbsolute)(path)) return path;
|
|
26502
|
+
return cwd ? (0, import_path11.join)(cwd, path) : null;
|
|
25753
26503
|
}
|
|
25754
26504
|
function resolveToolCwd(cwd, toolInput) {
|
|
25755
26505
|
if (!isRecord(toolInput)) return cwd;
|
|
25756
26506
|
const raw = typeof toolInput.cwd === "string" ? toolInput.cwd : typeof toolInput.workdir === "string" ? toolInput.workdir : typeof toolInput.workingDirectory === "string" ? toolInput.workingDirectory : null;
|
|
25757
26507
|
if (!raw) return cwd;
|
|
25758
|
-
return (0,
|
|
26508
|
+
return (0, import_path11.isAbsolute)(raw) || !cwd ? raw : (0, import_path11.join)(cwd, raw);
|
|
25759
26509
|
}
|
|
25760
26510
|
function extractBrowserMediaPathHints(content, cwd, toolName, options = {}, kind = "video") {
|
|
25761
26511
|
if (!isAgentBrowserMediaInvocation(toolName, content, options.toolInput, kind)) return [];
|
|
@@ -25798,19 +26548,19 @@ function extractGeneratedImagesFromToolResult(toolId, content, cwd, toolName, op
|
|
|
25798
26548
|
const effectiveCwd = resolveToolCwd(cwd, options.toolInput);
|
|
25799
26549
|
for (const candidate of extractPathCandidates(content, options)) {
|
|
25800
26550
|
const path = normalizePath2(candidate, effectiveCwd);
|
|
25801
|
-
if (!path || seen.has(path) || !(0,
|
|
26551
|
+
if (!path || seen.has(path) || !(0, import_fs11.existsSync)(path)) continue;
|
|
25802
26552
|
seen.add(path);
|
|
25803
|
-
const ext = (0,
|
|
26553
|
+
const ext = (0, import_path11.extname)(path).toLowerCase();
|
|
25804
26554
|
const mimeType = IMAGE_MIME_BY_EXT[ext];
|
|
25805
26555
|
if (!mimeType) continue;
|
|
25806
|
-
const stat = (0,
|
|
26556
|
+
const stat = (0, import_fs11.statSync)(path);
|
|
25807
26557
|
if (!stat.isFile() || stat.size <= 0 || stat.size > MAX_GENERATED_IMAGE_BYTES) continue;
|
|
25808
|
-
const buffer = (0,
|
|
26558
|
+
const buffer = (0, import_fs11.readFileSync)(path);
|
|
25809
26559
|
const { width, height } = readImageDimensions2(buffer, mimeType);
|
|
25810
26560
|
images.push({
|
|
25811
26561
|
type: "generated_image",
|
|
25812
26562
|
id: (0, import_crypto4.randomUUID)(),
|
|
25813
|
-
filename: (0,
|
|
26563
|
+
filename: (0, import_path11.basename)(path),
|
|
25814
26564
|
mimeType,
|
|
25815
26565
|
size: buffer.length,
|
|
25816
26566
|
width,
|
|
@@ -25837,20 +26587,20 @@ function extractSessionMediaFromToolResult(toolId, content, cwd, toolName, optio
|
|
|
25837
26587
|
const mimeByExt = kind === "video" ? VIDEO_MIME_BY_EXT : IMAGE_MIME_BY_EXT;
|
|
25838
26588
|
for (const candidate of extractPathCandidates(content, options, extensionsPattern)) {
|
|
25839
26589
|
const path = normalizePath2(candidate, effectiveCwd);
|
|
25840
|
-
if (!path || seen.has(path) || !(0,
|
|
26590
|
+
if (!path || seen.has(path) || !(0, import_fs11.existsSync)(path)) continue;
|
|
25841
26591
|
seen.add(path);
|
|
25842
|
-
const ext = (0,
|
|
26592
|
+
const ext = (0, import_path11.extname)(path).toLowerCase();
|
|
25843
26593
|
const mimeType = mimeByExt[ext];
|
|
25844
26594
|
if (!mimeType) continue;
|
|
25845
|
-
const stat = (0,
|
|
26595
|
+
const stat = (0, import_fs11.statSync)(path);
|
|
25846
26596
|
if (!stat.isFile() || stat.size <= 0 || stat.size > maxBytes) continue;
|
|
25847
|
-
const buffer = (0,
|
|
26597
|
+
const buffer = (0, import_fs11.readFileSync)(path);
|
|
25848
26598
|
const dimensions = kind === "image" ? readImageDimensions2(buffer, mimeType) : null;
|
|
25849
26599
|
media.push({
|
|
25850
26600
|
type: "session_media",
|
|
25851
26601
|
kind,
|
|
25852
26602
|
id: (0, import_crypto4.randomUUID)(),
|
|
25853
|
-
filename: (0,
|
|
26603
|
+
filename: (0, import_path11.basename)(path),
|
|
25854
26604
|
mimeType,
|
|
25855
26605
|
size: buffer.length,
|
|
25856
26606
|
width: dimensions?.width,
|
|
@@ -25896,6 +26646,14 @@ var MCP_INSPECTION_PLANS = {
|
|
|
25896
26646
|
args: ["mcp", "list"],
|
|
25897
26647
|
updateGuidance: "Update OpenCode CLI",
|
|
25898
26648
|
requireExpectedUrl: false
|
|
26649
|
+
},
|
|
26650
|
+
opencode_serve: {
|
|
26651
|
+
backendKind: "opencode_serve",
|
|
26652
|
+
providerLabel: "OpenCode CLI",
|
|
26653
|
+
command: "opencode",
|
|
26654
|
+
args: ["mcp", "list"],
|
|
26655
|
+
updateGuidance: "Update OpenCode CLI",
|
|
26656
|
+
requireExpectedUrl: false
|
|
25899
26657
|
}
|
|
25900
26658
|
};
|
|
25901
26659
|
var UNSUPPORTED_COMMAND_PATTERN = /unknown (?:command|subcommand)|unrecognized (?:command|subcommand)|unexpected argument|invalid command|not a recognized command/i;
|
|
@@ -26065,8 +26823,8 @@ async function withTimeout(promise2, timeoutMs, fallback) {
|
|
|
26065
26823
|
try {
|
|
26066
26824
|
return await Promise.race([
|
|
26067
26825
|
promise2,
|
|
26068
|
-
new Promise((
|
|
26069
|
-
timer = setTimeout(() =>
|
|
26826
|
+
new Promise((resolve9) => {
|
|
26827
|
+
timer = setTimeout(() => resolve9(fallback), timeoutMs);
|
|
26070
26828
|
})
|
|
26071
26829
|
]);
|
|
26072
26830
|
} finally {
|
|
@@ -26079,7 +26837,7 @@ async function collectCodexLimits(env) {
|
|
|
26079
26837
|
const codexCommand = resolveExecutable("codex", runtimeEnv, "ALAN_CODEX_PATH");
|
|
26080
26838
|
if (!codexCommand)
|
|
26081
26839
|
return [];
|
|
26082
|
-
return withTimeout(new Promise((
|
|
26840
|
+
return withTimeout(new Promise((resolve9) => {
|
|
26083
26841
|
const child = (0, import_node_child_process2.spawn)(codexCommand, ["-s", "read-only", "-a", "untrusted", "app-server"], {
|
|
26084
26842
|
env: runtimeEnv,
|
|
26085
26843
|
stdio: ["pipe", "pipe", "ignore"]
|
|
@@ -26091,7 +26849,7 @@ async function collectCodexLimits(env) {
|
|
|
26091
26849
|
pending.clear();
|
|
26092
26850
|
if (!child.killed)
|
|
26093
26851
|
child.kill();
|
|
26094
|
-
|
|
26852
|
+
resolve9(windows);
|
|
26095
26853
|
};
|
|
26096
26854
|
const request = (method, params = {}) => {
|
|
26097
26855
|
const id = nextId++;
|
|
@@ -28924,9 +29682,9 @@ var Socket2 = class extends Emitter {
|
|
|
28924
29682
|
* @return a Promise that will be fulfilled when the server acknowledges the event
|
|
28925
29683
|
*/
|
|
28926
29684
|
emitWithAck(ev, ...args) {
|
|
28927
|
-
return new Promise((
|
|
29685
|
+
return new Promise((resolve9, reject) => {
|
|
28928
29686
|
const fn = (arg1, arg2) => {
|
|
28929
|
-
return arg1 ? reject(arg1) :
|
|
29687
|
+
return arg1 ? reject(arg1) : resolve9(arg2);
|
|
28930
29688
|
};
|
|
28931
29689
|
fn.withError = true;
|
|
28932
29690
|
args.push(fn);
|
|
@@ -31066,7 +31824,9 @@ var INSTALLABLE_PROVIDER_PACKAGES = {
|
|
|
31066
31824
|
claude_cli: { npmPackage: "@anthropic-ai/claude-code", command: "claude", label: "Claude Code" },
|
|
31067
31825
|
codex_app_server: { npmPackage: "@openai/codex", command: "codex", label: "Codex" },
|
|
31068
31826
|
copilot_cli: { npmPackage: "@github/copilot", command: "copilot", label: "Copilot" },
|
|
31069
|
-
opencode_cli: { npmPackage: "opencode-ai", command: "opencode", label: "opencode" }
|
|
31827
|
+
opencode_cli: { npmPackage: "opencode-ai", command: "opencode", label: "opencode" },
|
|
31828
|
+
// Server transport installs the same "opencode" binary.
|
|
31829
|
+
opencode_serve: { npmPackage: "opencode-ai", command: "opencode", label: "opencode" }
|
|
31070
31830
|
};
|
|
31071
31831
|
var INSTALL_TIMEOUT_MS = 12e4;
|
|
31072
31832
|
var installOutcomes = /* @__PURE__ */ new Map();
|
|
@@ -31085,7 +31845,7 @@ function pinnedVersion(npmPackage) {
|
|
|
31085
31845
|
return "latest";
|
|
31086
31846
|
}
|
|
31087
31847
|
function runNpmInstall(installSpec, env, timeoutMs) {
|
|
31088
|
-
return new Promise((
|
|
31848
|
+
return new Promise((resolve9) => {
|
|
31089
31849
|
const isWin = (0, import_node_os5.platform)() === "win32";
|
|
31090
31850
|
let child;
|
|
31091
31851
|
try {
|
|
@@ -31097,7 +31857,7 @@ function runNpmInstall(installSpec, env, timeoutMs) {
|
|
|
31097
31857
|
stdio: ["ignore", "pipe", "pipe"]
|
|
31098
31858
|
});
|
|
31099
31859
|
} catch (error2) {
|
|
31100
|
-
|
|
31860
|
+
resolve9({ status: null, stdout: "", stderr: "", error: error2 });
|
|
31101
31861
|
return;
|
|
31102
31862
|
}
|
|
31103
31863
|
let stdout = "";
|
|
@@ -31108,10 +31868,10 @@ function runNpmInstall(installSpec, env, timeoutMs) {
|
|
|
31108
31868
|
child.stderr?.setEncoding("utf8").on("data", (chunk) => {
|
|
31109
31869
|
stderr += chunk;
|
|
31110
31870
|
});
|
|
31111
|
-
child.once("error", (error2) =>
|
|
31871
|
+
child.once("error", (error2) => resolve9({ status: null, stdout, stderr, error: error2 }));
|
|
31112
31872
|
child.once(
|
|
31113
31873
|
"close",
|
|
31114
|
-
(status, signal) =>
|
|
31874
|
+
(status, signal) => resolve9({
|
|
31115
31875
|
status,
|
|
31116
31876
|
stdout,
|
|
31117
31877
|
stderr,
|
|
@@ -45268,7 +46028,7 @@ var Protocol = class {
|
|
|
45268
46028
|
return;
|
|
45269
46029
|
}
|
|
45270
46030
|
const pollInterval = task2.pollInterval ?? this._options?.defaultTaskPollInterval ?? 1e3;
|
|
45271
|
-
await new Promise((
|
|
46031
|
+
await new Promise((resolve9) => setTimeout(resolve9, pollInterval));
|
|
45272
46032
|
options?.signal?.throwIfAborted();
|
|
45273
46033
|
}
|
|
45274
46034
|
} catch (error2) {
|
|
@@ -45285,7 +46045,7 @@ var Protocol = class {
|
|
|
45285
46045
|
*/
|
|
45286
46046
|
request(request, resultSchema, options) {
|
|
45287
46047
|
const { relatedRequestId, resumptionToken, onresumptiontoken, task, relatedTask } = options ?? {};
|
|
45288
|
-
return new Promise((
|
|
46048
|
+
return new Promise((resolve9, reject) => {
|
|
45289
46049
|
const earlyReject = (error2) => {
|
|
45290
46050
|
reject(error2);
|
|
45291
46051
|
};
|
|
@@ -45363,7 +46123,7 @@ var Protocol = class {
|
|
|
45363
46123
|
if (!parseResult.success) {
|
|
45364
46124
|
reject(parseResult.error);
|
|
45365
46125
|
} else {
|
|
45366
|
-
|
|
46126
|
+
resolve9(parseResult.data);
|
|
45367
46127
|
}
|
|
45368
46128
|
} catch (error2) {
|
|
45369
46129
|
reject(error2);
|
|
@@ -45624,12 +46384,12 @@ var Protocol = class {
|
|
|
45624
46384
|
}
|
|
45625
46385
|
} catch {
|
|
45626
46386
|
}
|
|
45627
|
-
return new Promise((
|
|
46387
|
+
return new Promise((resolve9, reject) => {
|
|
45628
46388
|
if (signal.aborted) {
|
|
45629
46389
|
reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
|
|
45630
46390
|
return;
|
|
45631
46391
|
}
|
|
45632
|
-
const timeoutId = setTimeout(
|
|
46392
|
+
const timeoutId = setTimeout(resolve9, interval);
|
|
45633
46393
|
signal.addEventListener("abort", () => {
|
|
45634
46394
|
clearTimeout(timeoutId);
|
|
45635
46395
|
reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
|
|
@@ -47978,7 +48738,7 @@ function skipVoid(str, ptr, banNewLines, banComments) {
|
|
|
47978
48738
|
}
|
|
47979
48739
|
return ptr;
|
|
47980
48740
|
}
|
|
47981
|
-
function skipUntil(str, ptr,
|
|
48741
|
+
function skipUntil(str, ptr, sep4, end, banNewLines = false) {
|
|
47982
48742
|
if (!end) {
|
|
47983
48743
|
ptr = indexOfNewline(str, ptr);
|
|
47984
48744
|
return ptr < 0 ? str.length : ptr;
|
|
@@ -47987,7 +48747,7 @@ function skipUntil(str, ptr, sep3, end, banNewLines = false) {
|
|
|
47987
48747
|
let c = str[i];
|
|
47988
48748
|
if (c === "#") {
|
|
47989
48749
|
i = indexOfNewline(str, i);
|
|
47990
|
-
} else if (c ===
|
|
48750
|
+
} else if (c === sep4) {
|
|
47991
48751
|
return i + 1;
|
|
47992
48752
|
} else if (c === end || banNewLines && (c === "\n" || c === "\r" && str[i + 1] === "\n")) {
|
|
47993
48753
|
return i;
|
|
@@ -48716,7 +49476,7 @@ async function waitForConfigLock(lockPath) {
|
|
|
48716
49476
|
if (Date.now() - startedAt >= CONFIG_LOCK_WAIT_MS) {
|
|
48717
49477
|
throw new Error(`Alan could not safely update ${lockPath.slice(0, -".alan-lock".length)}`);
|
|
48718
49478
|
}
|
|
48719
|
-
await new Promise((
|
|
49479
|
+
await new Promise((resolve9) => setTimeout(resolve9, CONFIG_LOCK_POLL_MS));
|
|
48720
49480
|
}
|
|
48721
49481
|
}
|
|
48722
49482
|
}
|
|
@@ -48740,10 +49500,11 @@ function parseJsonObject2(path, content) {
|
|
|
48740
49500
|
);
|
|
48741
49501
|
}
|
|
48742
49502
|
function mergeJsonConfig(path, existingContent, desiredContent) {
|
|
48743
|
-
|
|
48744
|
-
|
|
49503
|
+
const normalizedExisting = existingContent?.trim() ? existingContent : null;
|
|
49504
|
+
if (normalizedExisting !== null) {
|
|
49505
|
+
parseJsonObject2(path, normalizedExisting);
|
|
48745
49506
|
}
|
|
48746
|
-
return mergeAlanMcpJsonConfig(
|
|
49507
|
+
return mergeAlanMcpJsonConfig(normalizedExisting, desiredContent);
|
|
48747
49508
|
}
|
|
48748
49509
|
function assertValidExistingToml(path, content) {
|
|
48749
49510
|
try {
|
|
@@ -49031,6 +49792,10 @@ function readAlanMcpRegistration(path) {
|
|
|
49031
49792
|
const url4 = normalizeHttpUrl(server.httpUrl);
|
|
49032
49793
|
return url4 ? { url: url4, headers } : null;
|
|
49033
49794
|
}
|
|
49795
|
+
if (path.endsWith("/.gemini/config/mcp_config.json")) {
|
|
49796
|
+
const url4 = normalizeHttpUrl(server.serverUrl);
|
|
49797
|
+
return url4 ? { url: url4, headers } : null;
|
|
49798
|
+
}
|
|
49034
49799
|
const url3 = server.type === "http" ? normalizeHttpUrl(server.url) : null;
|
|
49035
49800
|
return url3 ? { url: url3, headers } : null;
|
|
49036
49801
|
} catch {
|
|
@@ -49089,7 +49854,7 @@ function failureFromError(error2, paths) {
|
|
|
49089
49854
|
};
|
|
49090
49855
|
}
|
|
49091
49856
|
async function waitBeforeRetry() {
|
|
49092
|
-
await new Promise((
|
|
49857
|
+
await new Promise((resolve9) => setTimeout(resolve9, RETRY_DELAY_MS2));
|
|
49093
49858
|
}
|
|
49094
49859
|
async function probeAlanMcpReadiness(registration, options = {}) {
|
|
49095
49860
|
const paths = options.paths ?? [];
|
|
@@ -49630,11 +50395,25 @@ function parseOpenCodeVerboseModelOutput(text) {
|
|
|
49630
50395
|
}
|
|
49631
50396
|
return entries;
|
|
49632
50397
|
}
|
|
50398
|
+
function extractOpenCodeModelCapabilitiesFromVerboseOutput(text) {
|
|
50399
|
+
return parseOpenCodeVerboseModelOutput(text).filter((entry) => entry.id.startsWith("opencode/")).map((entry) => ({
|
|
50400
|
+
id: entry.id,
|
|
50401
|
+
variants: entry.reasoning ? entry.variants.filter((variant) => {
|
|
50402
|
+
const trimmed = variant.trim();
|
|
50403
|
+
return Boolean(trimmed) && trimmed.length <= 256 && !Array.from(trimmed).some((character) => {
|
|
50404
|
+
const code = character.charCodeAt(0);
|
|
50405
|
+
return code <= 31 || code === 127;
|
|
50406
|
+
});
|
|
50407
|
+
}) : []
|
|
50408
|
+
}));
|
|
50409
|
+
}
|
|
49633
50410
|
function extractOpenCodeDiscoveredModelIdsFromVerboseOutput(text) {
|
|
49634
|
-
const entries =
|
|
50411
|
+
const entries = extractOpenCodeModelCapabilitiesFromVerboseOutput(text);
|
|
49635
50412
|
const ids = [];
|
|
49636
50413
|
for (const entry of entries) {
|
|
49637
|
-
const knownVariants = entry.
|
|
50414
|
+
const knownVariants = entry.variants.filter(
|
|
50415
|
+
(variant) => OPENCODE_KNOWN_VARIANT_KEYS.has(variant)
|
|
50416
|
+
);
|
|
49638
50417
|
if (knownVariants.length === 0) {
|
|
49639
50418
|
ids.push(entry.id);
|
|
49640
50419
|
continue;
|
|
@@ -49720,7 +50499,8 @@ function extractClaudeModelIdsFromExecutable(executable) {
|
|
|
49720
50499
|
}
|
|
49721
50500
|
}
|
|
49722
50501
|
function getCatalogModelIds(provider) {
|
|
49723
|
-
|
|
50502
|
+
const catalogProvider = provider === "opencode_serve" ? "opencode_cli" : provider;
|
|
50503
|
+
return [...CATALOG_MODEL_IDS_BY_PROVIDER[catalogProvider] ?? []];
|
|
49724
50504
|
}
|
|
49725
50505
|
function withModelProbeEnv(env) {
|
|
49726
50506
|
const term = env.TERM;
|
|
@@ -49810,14 +50590,14 @@ async function discoverGenericModels(executable, env) {
|
|
|
49810
50590
|
}
|
|
49811
50591
|
var CATALOG_ONLY_PROVIDERS = /* @__PURE__ */ new Set(["supatest_cli", "droid_cli", "copilot_cli"]);
|
|
49812
50592
|
function supportsProviderModelDiscovery(provider) {
|
|
49813
|
-
return provider in CATALOG_MODEL_IDS_BY_PROVIDER;
|
|
50593
|
+
return provider === "opencode_serve" || provider in CATALOG_MODEL_IDS_BY_PROVIDER;
|
|
49814
50594
|
}
|
|
49815
50595
|
async function discoverProviderModels(provider, executable, env) {
|
|
49816
50596
|
if (CATALOG_ONLY_PROVIDERS.has(provider)) {
|
|
49817
50597
|
return getCatalogModelIds(provider);
|
|
49818
50598
|
}
|
|
49819
50599
|
let probed = [];
|
|
49820
|
-
if (provider === "opencode_cli") {
|
|
50600
|
+
if (provider === "opencode_cli" || provider === "opencode_serve") {
|
|
49821
50601
|
probed = await discoverOpenCodeModels(executable, env);
|
|
49822
50602
|
} else if (provider === "antigravity_cli") {
|
|
49823
50603
|
probed = await discoverAntigravityModels(executable, env);
|
|
@@ -50003,8 +50783,8 @@ var RunStartGate = class {
|
|
|
50003
50783
|
async acquire() {
|
|
50004
50784
|
const previous = this.tail;
|
|
50005
50785
|
let releaseCurrent;
|
|
50006
|
-
const current = new Promise((
|
|
50007
|
-
releaseCurrent =
|
|
50786
|
+
const current = new Promise((resolve9) => {
|
|
50787
|
+
releaseCurrent = resolve9;
|
|
50008
50788
|
});
|
|
50009
50789
|
this.tail = previous.then(() => current);
|
|
50010
50790
|
await previous;
|
|
@@ -50331,7 +51111,7 @@ var SuspensionDetector = class {
|
|
|
50331
51111
|
};
|
|
50332
51112
|
|
|
50333
51113
|
// src/version.ts
|
|
50334
|
-
var AGENT_VERSION = "0.1.
|
|
51114
|
+
var AGENT_VERSION = "0.1.55";
|
|
50335
51115
|
|
|
50336
51116
|
// src/workspace-relocation.ts
|
|
50337
51117
|
var import_node_child_process6 = require("child_process");
|
|
@@ -50415,6 +51195,9 @@ var WORKSPACE_LEASE_GIT_TIMEOUT_MS = parsePositiveMs(
|
|
|
50415
51195
|
process.env.ALAN_WORKSPACE_LEASE_GIT_TIMEOUT_MS,
|
|
50416
51196
|
2e3
|
|
50417
51197
|
);
|
|
51198
|
+
function applicationCodeForWorkspaceLeaseFailure(code) {
|
|
51199
|
+
return code === "workspace_lease_branch_changed" ? "app.workspace.branch_changed" : "app.workspace.missing";
|
|
51200
|
+
}
|
|
50418
51201
|
function gitValue(cwd, args) {
|
|
50419
51202
|
const result = (0, import_node_child_process7.spawnSync)("git", ["-C", cwd, ...args], {
|
|
50420
51203
|
encoding: "utf8",
|
|
@@ -50439,8 +51222,8 @@ var DEFAULT_PROBE2 = {
|
|
|
50439
51222
|
const repositoryRoot = gitValue(canonicalWorkspacePath, ["rev-parse", "--show-toplevel"]);
|
|
50440
51223
|
const gitDirectory = gitValue(canonicalWorkspacePath, ["rev-parse", "--git-dir"]);
|
|
50441
51224
|
const commonDirectory = gitValue(canonicalWorkspacePath, ["rev-parse", "--git-common-dir"]);
|
|
50442
|
-
const branch = gitValue(canonicalWorkspacePath, ["
|
|
50443
|
-
if (!repositoryRoot || !gitDirectory || !commonDirectory
|
|
51225
|
+
const branch = gitValue(canonicalWorkspacePath, ["branch", "--show-current"]) ?? "";
|
|
51226
|
+
if (!repositoryRoot || !gitDirectory || !commonDirectory) return null;
|
|
50444
51227
|
const remote = gitValue(canonicalWorkspacePath, ["config", "--get", "remote.origin.url"]);
|
|
50445
51228
|
const remoteIdentity = remote ? normalizeRepositoryIdentity(remote) : null;
|
|
50446
51229
|
return {
|
|
@@ -50464,18 +51247,22 @@ var DEFAULT_PROBE2 = {
|
|
|
50464
51247
|
}
|
|
50465
51248
|
}
|
|
50466
51249
|
};
|
|
50467
|
-
|
|
51250
|
+
var IDENTITY_FAILURE_MESSAGES = {
|
|
51251
|
+
workspace_lease_unavailable: "The workspace or Git checkout became unavailable while the run was active. Restore it and start a new run.",
|
|
51252
|
+
workspace_lease_path_changed: "The selected workspace folder changed while the run was active. The run stopped before continuing; choose the correct folder and start a new run.",
|
|
51253
|
+
workspace_lease_repository_changed: "The workspace now points to a different repository or worktree. The run stopped before continuing; restore the original checkout and start a new run."
|
|
51254
|
+
};
|
|
51255
|
+
function identityFailure(code, target) {
|
|
50468
51256
|
return {
|
|
50469
|
-
code
|
|
50470
|
-
message:
|
|
50471
|
-
workspacePath: target.workspacePath
|
|
50472
|
-
expectedBranch: target.expectedBranch
|
|
51257
|
+
code,
|
|
51258
|
+
message: IDENTITY_FAILURE_MESSAGES[code],
|
|
51259
|
+
workspacePath: target.workspacePath
|
|
50473
51260
|
};
|
|
50474
51261
|
}
|
|
50475
51262
|
function branchFailure(target, expectedBranch, actualBranch) {
|
|
50476
51263
|
return {
|
|
50477
51264
|
code: "workspace_lease_branch_changed",
|
|
50478
|
-
message: `The workspace branch changed from ${expectedBranch} to ${actualBranch} while the run was active. Restore ${expectedBranch} and start a new run.`,
|
|
51265
|
+
message: `The workspace branch changed from ${expectedBranch} to ${actualBranch || "detached HEAD"} while the run was active. Restore ${expectedBranch} and start a new run.`,
|
|
50479
51266
|
workspacePath: target.workspacePath,
|
|
50480
51267
|
expectedBranch,
|
|
50481
51268
|
actualBranch
|
|
@@ -50491,7 +51278,12 @@ var WorkspaceRunLease = class _WorkspaceRunLease {
|
|
|
50491
51278
|
for (const target of targets) {
|
|
50492
51279
|
const normalizedTarget = { ...target, workspacePath: (0, import_node_path11.resolve)(target.workspacePath) };
|
|
50493
51280
|
const identity = probe.snapshot(normalizedTarget.workspacePath);
|
|
50494
|
-
if (!identity)
|
|
51281
|
+
if (!identity) {
|
|
51282
|
+
return {
|
|
51283
|
+
lease: null,
|
|
51284
|
+
failure: identityFailure("workspace_lease_unavailable", normalizedTarget)
|
|
51285
|
+
};
|
|
51286
|
+
}
|
|
50495
51287
|
if (normalizedTarget.expectedBranch && identity.branch !== normalizedTarget.expectedBranch) {
|
|
50496
51288
|
return {
|
|
50497
51289
|
lease: null,
|
|
@@ -50512,81 +51304,49 @@ var WorkspaceRunLease = class _WorkspaceRunLease {
|
|
|
50512
51304
|
/**
|
|
50513
51305
|
* Classify the lease state for the run monitor.
|
|
50514
51306
|
*
|
|
50515
|
-
*
|
|
50516
|
-
*
|
|
50517
|
-
*
|
|
50518
|
-
*
|
|
50519
|
-
*
|
|
50520
|
-
*
|
|
50521
|
-
*
|
|
51307
|
+
* Checks workspace identity only — path, repository, worktree. The branch is
|
|
51308
|
+
* deliberately not checked here: it is working state, not identity, and the supervised
|
|
51309
|
+
* process is a coding agent. A conflicted rebase leaves HEAD detached for as long as
|
|
51310
|
+
* the agent takes to resolve it, so any mid-run branch assertion kills that run. What
|
|
51311
|
+
* keeps work in the right place is the worktree's path and git-dir identity, both
|
|
51312
|
+
* fenced below, plus `assertExpectedBranch` in binding-switch-git.ts at apply time.
|
|
51313
|
+
* `capture()` still refuses to start a run on the wrong branch.
|
|
51314
|
+
*
|
|
51315
|
+
* `transient: true` means retryable — a git probe that timed out under OS throttling
|
|
51316
|
+
* while the path still exists. `transient: false` is definitive and fails fast.
|
|
50522
51317
|
*/
|
|
50523
51318
|
verifyDetailed() {
|
|
50524
|
-
for (const
|
|
50525
|
-
const current = this.probe.snapshot(
|
|
51319
|
+
for (const { target, identity } of this.captured) {
|
|
51320
|
+
const current = this.probe.snapshot(target.workspacePath);
|
|
50526
51321
|
if (!current) {
|
|
50527
|
-
const pathGone = this.probe.pathExists?.(
|
|
50528
|
-
return { failure: unavailableFailure(captured.target), transient: !pathGone };
|
|
50529
|
-
}
|
|
50530
|
-
if (current.workspaceIdentity !== captured.identity.workspaceIdentity) {
|
|
51322
|
+
const pathGone = this.probe.pathExists?.(target.workspacePath) === false;
|
|
50531
51323
|
return {
|
|
50532
|
-
failure:
|
|
50533
|
-
|
|
50534
|
-
message: "The selected workspace folder changed while the run was active. The run stopped before continuing; choose the correct folder and start a new run.",
|
|
50535
|
-
workspacePath: captured.target.workspacePath,
|
|
50536
|
-
expectedBranch: captured.identity.branch,
|
|
50537
|
-
actualBranch: current.branch
|
|
50538
|
-
},
|
|
50539
|
-
transient: false
|
|
51324
|
+
failure: identityFailure("workspace_lease_unavailable", target),
|
|
51325
|
+
transient: !pathGone
|
|
50540
51326
|
};
|
|
50541
51327
|
}
|
|
50542
|
-
if (current.
|
|
51328
|
+
if (current.workspaceIdentity !== identity.workspaceIdentity) {
|
|
50543
51329
|
return {
|
|
50544
|
-
failure:
|
|
50545
|
-
code: "workspace_lease_repository_changed",
|
|
50546
|
-
message: "The workspace now points to a different repository or worktree. The run stopped before continuing; restore the original checkout and start a new run.",
|
|
50547
|
-
workspacePath: captured.target.workspacePath,
|
|
50548
|
-
expectedBranch: captured.identity.branch,
|
|
50549
|
-
actualBranch: current.branch
|
|
50550
|
-
},
|
|
51330
|
+
failure: identityFailure("workspace_lease_path_changed", target),
|
|
50551
51331
|
transient: false
|
|
50552
51332
|
};
|
|
50553
51333
|
}
|
|
50554
|
-
if (current.
|
|
51334
|
+
if (current.repositoryIdentity !== identity.repositoryIdentity || current.worktreeIdentity !== identity.worktreeIdentity) {
|
|
50555
51335
|
return {
|
|
50556
|
-
failure:
|
|
51336
|
+
failure: identityFailure("workspace_lease_repository_changed", target),
|
|
50557
51337
|
transient: false
|
|
50558
51338
|
};
|
|
50559
51339
|
}
|
|
50560
51340
|
}
|
|
50561
51341
|
return { failure: null, transient: false };
|
|
50562
51342
|
}
|
|
51343
|
+
/**
|
|
51344
|
+
* Failure-only view of {@link verifyDetailed}. Kept as a thin delegation rather than a
|
|
51345
|
+
* second copy of the checks: the two implementations previously duplicated all four
|
|
51346
|
+
* comparisons and had to be edited in lockstep.
|
|
51347
|
+
*/
|
|
50563
51348
|
verify() {
|
|
50564
|
-
|
|
50565
|
-
const current = this.probe.snapshot(captured.target.workspacePath);
|
|
50566
|
-
if (!current) return unavailableFailure(captured.target);
|
|
50567
|
-
if (current.workspaceIdentity !== captured.identity.workspaceIdentity) {
|
|
50568
|
-
return {
|
|
50569
|
-
code: "workspace_lease_path_changed",
|
|
50570
|
-
message: "The selected workspace folder changed while the run was active. The run stopped before continuing; choose the correct folder and start a new run.",
|
|
50571
|
-
workspacePath: captured.target.workspacePath,
|
|
50572
|
-
expectedBranch: captured.identity.branch,
|
|
50573
|
-
actualBranch: current.branch
|
|
50574
|
-
};
|
|
50575
|
-
}
|
|
50576
|
-
if (current.repositoryIdentity !== captured.identity.repositoryIdentity || current.worktreeIdentity !== captured.identity.worktreeIdentity) {
|
|
50577
|
-
return {
|
|
50578
|
-
code: "workspace_lease_repository_changed",
|
|
50579
|
-
message: "The workspace now points to a different repository or worktree. The run stopped before continuing; restore the original checkout and start a new run.",
|
|
50580
|
-
workspacePath: captured.target.workspacePath,
|
|
50581
|
-
expectedBranch: captured.identity.branch,
|
|
50582
|
-
actualBranch: current.branch
|
|
50583
|
-
};
|
|
50584
|
-
}
|
|
50585
|
-
if (current.branch !== captured.identity.branch) {
|
|
50586
|
-
return branchFailure(captured.target, captured.identity.branch, current.branch);
|
|
50587
|
-
}
|
|
50588
|
-
}
|
|
50589
|
-
return null;
|
|
51349
|
+
return this.verifyDetailed().failure;
|
|
50590
51350
|
}
|
|
50591
51351
|
};
|
|
50592
51352
|
var FRESH_LEASE_MONITOR_STATE = {
|
|
@@ -52037,11 +52797,10 @@ function getLocalApiPort(args, stored) {
|
|
|
52037
52797
|
}
|
|
52038
52798
|
function sleep(ms) {
|
|
52039
52799
|
if (ms <= 0) return Promise.resolve();
|
|
52040
|
-
return new Promise((
|
|
52800
|
+
return new Promise((resolve9) => setTimeout(resolve9, ms));
|
|
52041
52801
|
}
|
|
52042
52802
|
function normalizeBackendKind2(backendKind) {
|
|
52043
52803
|
if (backendKind === "codex") return "codex_app_server";
|
|
52044
|
-
if (backendKind === "gemini" || backendKind === "gemini_cli") return "antigravity_cli";
|
|
52045
52804
|
return backendKind;
|
|
52046
52805
|
}
|
|
52047
52806
|
function providerModelCacheKey(provider, executable) {
|
|
@@ -52523,7 +53282,10 @@ var RuntimePresenter = class {
|
|
|
52523
53282
|
}
|
|
52524
53283
|
failWorkspaceLease(failure) {
|
|
52525
53284
|
return this.failApplicationProblem({
|
|
52526
|
-
|
|
53285
|
+
// A branch change is not a missing workspace. Reporting both as
|
|
53286
|
+
// `app.workspace.missing` told the user to "choose or relocate the project
|
|
53287
|
+
// folder" for a folder that never moved.
|
|
53288
|
+
code: applicationCodeForWorkspaceLeaseFailure(failure.code),
|
|
52527
53289
|
detail: failure.message,
|
|
52528
53290
|
component: "agent-manager-workspace-lease",
|
|
52529
53291
|
phase: "delivery"
|
|
@@ -52776,7 +53538,7 @@ async function setupDaemon(args) {
|
|
|
52776
53538
|
}
|
|
52777
53539
|
const retriableStatus = response && (response.status === 408 || response.status === 429 || response.status >= 500);
|
|
52778
53540
|
if (response && (!retriableStatus || response.ok) || attempt === 3) break;
|
|
52779
|
-
await new Promise((
|
|
53541
|
+
await new Promise((resolve9) => setTimeout(resolve9, attempt * 100));
|
|
52780
53542
|
}
|
|
52781
53543
|
if (!response) {
|
|
52782
53544
|
const detail = transportError instanceof Error ? transportError.message : String(transportError);
|
|
@@ -53145,7 +53907,11 @@ async function startDaemon(args) {
|
|
|
53145
53907
|
try {
|
|
53146
53908
|
response = await fetch(`${stored.apiUrl}/public/runtimes/${runtimeId}/tokens/renew`, {
|
|
53147
53909
|
method: "POST",
|
|
53148
|
-
headers: {
|
|
53910
|
+
headers: {
|
|
53911
|
+
authorization: `Bearer ${runtimeRenewalToken}`,
|
|
53912
|
+
"content-type": "application/json"
|
|
53913
|
+
},
|
|
53914
|
+
body: "{}",
|
|
53149
53915
|
signal: AbortSignal.timeout(1e4)
|
|
53150
53916
|
});
|
|
53151
53917
|
transportError = null;
|
|
@@ -53820,7 +54586,8 @@ async function startDaemon(args) {
|
|
|
53820
54586
|
const runFailure = buildApplicationRunFailure({
|
|
53821
54587
|
conversationId: payload.conversationId,
|
|
53822
54588
|
runId: payload.runId,
|
|
53823
|
-
|
|
54589
|
+
// A run dispatched onto the wrong branch is also not a missing workspace.
|
|
54590
|
+
code: applicationCodeForWorkspaceLeaseFailure(failure.code),
|
|
53824
54591
|
detail: failure.message,
|
|
53825
54592
|
component: "agent-manager-workspace-lease",
|
|
53826
54593
|
phase: "dispatch"
|
|
@@ -54297,7 +55064,7 @@ async function startDaemon(args) {
|
|
|
54297
55064
|
`${describeOccupiedLocalDaemon(localApiPort)} The token in ${getConfigPath()} no longer matches the running daemon; quit Alan desktop or run setup again.`
|
|
54298
55065
|
);
|
|
54299
55066
|
}
|
|
54300
|
-
const localApiListening = new Promise((
|
|
55067
|
+
const localApiListening = new Promise((resolve9, reject) => {
|
|
54301
55068
|
const onError = (error2) => {
|
|
54302
55069
|
clearInterval(heartbeat);
|
|
54303
55070
|
clearInterval(versionRefresh);
|
|
@@ -54327,7 +55094,7 @@ async function startDaemon(args) {
|
|
|
54327
55094
|
if (address && typeof address === "object") localApiPort = address.port;
|
|
54328
55095
|
pushLog(`local_api listening port=${localApiPort}`);
|
|
54329
55096
|
console.info("[alan-agent] Local daemon API listening", { port: localApiPort });
|
|
54330
|
-
|
|
55097
|
+
resolve9();
|
|
54331
55098
|
});
|
|
54332
55099
|
});
|
|
54333
55100
|
try {
|
|
@@ -54347,7 +55114,7 @@ async function startDaemon(args) {
|
|
|
54347
55114
|
clearInterval(workspaceLeaseMonitor);
|
|
54348
55115
|
suspensionDetector.stop();
|
|
54349
55116
|
socket.disconnect();
|
|
54350
|
-
await new Promise((
|
|
55117
|
+
await new Promise((resolve9) => localServer.close(() => resolve9()));
|
|
54351
55118
|
releaseOwnerLease();
|
|
54352
55119
|
releaseStartupLease();
|
|
54353
55120
|
throw error2;
|
|
@@ -54367,8 +55134,8 @@ async function startDaemon(args) {
|
|
|
54367
55134
|
}
|
|
54368
55135
|
activeAgents.clear();
|
|
54369
55136
|
socket.disconnect();
|
|
54370
|
-
await new Promise((
|
|
54371
|
-
localServer.close(() =>
|
|
55137
|
+
await new Promise((resolve9) => {
|
|
55138
|
+
localServer.close(() => resolve9());
|
|
54372
55139
|
});
|
|
54373
55140
|
} finally {
|
|
54374
55141
|
sleepInhibitor.dispose();
|
|
@@ -55313,9 +56080,9 @@ var WSClient = class {
|
|
|
55313
56080
|
});
|
|
55314
56081
|
}
|
|
55315
56082
|
waitForConnection(timeoutMs = 15e3) {
|
|
55316
|
-
return new Promise((
|
|
56083
|
+
return new Promise((resolve9, reject) => {
|
|
55317
56084
|
if (this.socket.connected) {
|
|
55318
|
-
|
|
56085
|
+
resolve9();
|
|
55319
56086
|
return;
|
|
55320
56087
|
}
|
|
55321
56088
|
const timeout = setTimeout(
|
|
@@ -55324,7 +56091,7 @@ var WSClient = class {
|
|
|
55324
56091
|
);
|
|
55325
56092
|
this.socket.once("connect", () => {
|
|
55326
56093
|
clearTimeout(timeout);
|
|
55327
|
-
|
|
56094
|
+
resolve9();
|
|
55328
56095
|
});
|
|
55329
56096
|
this.socket.once("connect_error", (err) => {
|
|
55330
56097
|
clearTimeout(timeout);
|
|
@@ -55506,9 +56273,9 @@ async function runSandbox(config2) {
|
|
|
55506
56273
|
onUserMessage: (payload) => {
|
|
55507
56274
|
if (payload === null) {
|
|
55508
56275
|
if (pendingMessageResolve) {
|
|
55509
|
-
const
|
|
56276
|
+
const resolve9 = pendingMessageResolve;
|
|
55510
56277
|
pendingMessageResolve = null;
|
|
55511
|
-
|
|
56278
|
+
resolve9(null);
|
|
55512
56279
|
}
|
|
55513
56280
|
return;
|
|
55514
56281
|
}
|
|
@@ -55530,9 +56297,9 @@ async function runSandbox(config2) {
|
|
|
55530
56297
|
fileCount: payload.files?.length ?? 0
|
|
55531
56298
|
});
|
|
55532
56299
|
if (pendingMessageResolve) {
|
|
55533
|
-
const
|
|
56300
|
+
const resolve9 = pendingMessageResolve;
|
|
55534
56301
|
pendingMessageResolve = null;
|
|
55535
|
-
|
|
56302
|
+
resolve9(payload);
|
|
55536
56303
|
} else {
|
|
55537
56304
|
queuedMessages.push(payload);
|
|
55538
56305
|
}
|
|
@@ -55751,8 +56518,8 @@ async function runSandbox(config2) {
|
|
|
55751
56518
|
});
|
|
55752
56519
|
if (stopped) break;
|
|
55753
56520
|
}
|
|
55754
|
-
const nextPayload = queuedMessages.shift() ?? await new Promise((
|
|
55755
|
-
pendingMessageResolve =
|
|
56521
|
+
const nextPayload = queuedMessages.shift() ?? await new Promise((resolve9) => {
|
|
56522
|
+
pendingMessageResolve = resolve9;
|
|
55756
56523
|
});
|
|
55757
56524
|
if (nextPayload === null || stopped) {
|
|
55758
56525
|
break;
|