@aiden-ade/sandbox-agent 0.1.32 → 0.1.33
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/__tests__/cli-executable.test.d.ts +2 -0
- package/dist/__tests__/cli-executable.test.d.ts.map +1 -0
- package/dist/__tests__/cli-executable.test.js +83 -0
- package/dist/__tests__/cli-executable.test.js.map +1 -0
- package/dist/__tests__/cli-help.test.d.ts +2 -0
- package/dist/__tests__/cli-help.test.d.ts.map +1 -0
- package/dist/__tests__/cli-help.test.js +33 -0
- package/dist/__tests__/cli-help.test.js.map +1 -0
- package/dist/__tests__/core-agent-workflow-context.test.d.ts +2 -0
- package/dist/__tests__/core-agent-workflow-context.test.d.ts.map +1 -0
- package/dist/__tests__/core-agent-workflow-context.test.js +50 -0
- package/dist/__tests__/core-agent-workflow-context.test.js.map +1 -0
- package/dist/__tests__/daemon-socket.integration.test.d.ts +2 -0
- package/dist/__tests__/daemon-socket.integration.test.d.ts.map +1 -0
- package/dist/__tests__/daemon-socket.integration.test.js +156 -0
- package/dist/__tests__/daemon-socket.integration.test.js.map +1 -0
- package/dist/__tests__/daemon.test.d.ts +2 -0
- package/dist/__tests__/daemon.test.d.ts.map +1 -0
- package/dist/__tests__/daemon.test.js +1014 -0
- package/dist/__tests__/daemon.test.js.map +1 -0
- package/dist/__tests__/generated-images.test.d.ts +2 -0
- package/dist/__tests__/generated-images.test.d.ts.map +1 -0
- package/dist/__tests__/generated-images.test.js +50 -0
- package/dist/__tests__/generated-images.test.js.map +1 -0
- package/dist/__tests__/sandbox-workflow-context.test.d.ts +2 -0
- package/dist/__tests__/sandbox-workflow-context.test.d.ts.map +1 -0
- package/dist/__tests__/sandbox-workflow-context.test.js +66 -0
- package/dist/__tests__/sandbox-workflow-context.test.js.map +1 -0
- package/dist/aiden-system-prompt.d.ts +6 -0
- package/dist/aiden-system-prompt.d.ts.map +1 -0
- package/dist/aiden-system-prompt.js +6 -0
- package/dist/aiden-system-prompt.js.map +1 -0
- package/dist/cli-executable.d.ts +58 -0
- package/dist/cli-executable.d.ts.map +1 -0
- package/dist/cli-executable.js +301 -0
- package/dist/cli-executable.js.map +1 -0
- package/dist/cli-help.d.ts +7 -0
- package/dist/cli-help.d.ts.map +1 -0
- package/dist/cli-help.js +45 -0
- package/dist/cli-help.js.map +1 -0
- package/dist/core-agent.d.ts +37 -0
- package/dist/core-agent.d.ts.map +1 -0
- package/dist/core-agent.js +337 -0
- package/dist/core-agent.js.map +1 -0
- package/dist/daemon.d.ts +46 -0
- package/dist/daemon.d.ts.map +1 -0
- package/dist/daemon.js +876 -0
- package/dist/daemon.js.map +1 -0
- package/dist/generated-images.d.ts +4 -0
- package/dist/generated-images.d.ts.map +1 -0
- package/dist/generated-images.js +142 -0
- package/dist/generated-images.js.map +1 -0
- package/dist/index.cjs +770 -256
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +118 -0
- package/dist/index.js.map +1 -0
- package/dist/runtime-backends.d.ts +2 -0
- package/dist/runtime-backends.d.ts.map +1 -0
- package/dist/runtime-backends.js +2 -0
- package/dist/runtime-backends.js.map +1 -0
- package/dist/sandbox.d.ts +31 -0
- package/dist/sandbox.d.ts.map +1 -0
- package/dist/sandbox.js +215 -0
- package/dist/sandbox.js.map +1 -0
- package/dist/types.d.ts +6 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/dist/updater.d.ts +15 -0
- package/dist/updater.d.ts.map +1 -0
- package/dist/updater.js +50 -0
- package/dist/updater.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +2 -0
- package/dist/version.js.map +1 -0
- package/dist/web-presenter.d.ts +36 -0
- package/dist/web-presenter.d.ts.map +1 -0
- package/dist/web-presenter.js +125 -0
- package/dist/web-presenter.js.map +1 -0
- package/dist/ws-client.d.ts +114 -0
- package/dist/ws-client.d.ts.map +1 -0
- package/dist/ws-client.js +97 -0
- package/dist/ws-client.js.map +1 -0
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -9255,7 +9255,7 @@ function resolveAgentConfigFileName(profile) {
|
|
|
9255
9255
|
case "production":
|
|
9256
9256
|
return "config.json";
|
|
9257
9257
|
case "local":
|
|
9258
|
-
return "config-
|
|
9258
|
+
return "config-local.json";
|
|
9259
9259
|
case "staging":
|
|
9260
9260
|
return "config-staging.json";
|
|
9261
9261
|
case "custom":
|
|
@@ -13345,7 +13345,7 @@ Use these tools, in roughly this order of frequency:
|
|
|
13345
13345
|
5. \`get_session_context\` \u2014 check what a worker accomplished
|
|
13346
13346
|
6. \`update_task\` \u2014 keep status, priority, labels current
|
|
13347
13347
|
7. \`send_session_message\` / \`start_task_session\` \u2014 continue a specific session or force a new session only when needed
|
|
13348
|
-
8. \`list_sessions\` / \`search\` / \`Read\` / \`Glob\` / \`Grep\` \u2014 situational awareness
|
|
13348
|
+
8. \`list_sessions\` / \`search\` / \`search_code_context\` / \`Read\` / \`Glob\` / \`Grep\` \u2014 situational awareness (\`search_code_context\` before grep for codebase discovery or implementation-answer questions; read exact cited files before claiming behavior)
|
|
13349
13349
|
9. \`get_task_memory\` / \`update_task_memory\` \u2014 compatibility memory tools for older task summaries and session outcomes
|
|
13350
13350
|
10. \`create_plan\` \u2014 document implementation plans and durable specs as artifacts
|
|
13351
13351
|
11. \`add_task_comment\` \u2014 human-facing collaboration: answer questions, post explicit status updates, escalate blockers, or leave comments the user asked you to post. Do not use comments as running notes or memory.
|
|
@@ -13452,7 +13452,7 @@ You are a flexible general-purpose agent (an Aiden agent profile) for work that
|
|
|
13452
13452
|
|
|
13453
13453
|
Your name is Aiden, General Agent.
|
|
13454
13454
|
|
|
13455
|
-
Clarify the goal only when required, inspect the relevant context first, then complete the requested work directly. Keep changes focused, avoid unrelated refactors, and validate the result before reporting back.
|
|
13455
|
+
Clarify the goal only when required, inspect the relevant context first, then complete the requested work directly. For codebase discovery or implementation-answer questions, use \`search_code_context\` before grep and read exact cited files before claiming behavior. Keep changes focused, avoid unrelated refactors, and validate the result before reporting back.
|
|
13456
13456
|
|
|
13457
13457
|
Non-trivial implementations include tests. Break and plan before building when scope is wide.
|
|
13458
13458
|
|
|
@@ -13475,10 +13475,18 @@ Your job is to be the user's always-available teammate: answer questions, inspec
|
|
|
13475
13475
|
## How to work
|
|
13476
13476
|
|
|
13477
13477
|
1. Start from the current team/chat context before asking for details.
|
|
13478
|
-
2.
|
|
13479
|
-
3.
|
|
13480
|
-
4.
|
|
13481
|
-
5. For
|
|
13478
|
+
2. For codebase location, behavior, or implementation-answer questions, call \`search_code_context\` via Aiden MCP before grep or filesystem search, then read the exact cited files before claiming behavior.
|
|
13479
|
+
3. Clarify only when the request has multiple plausible meanings.
|
|
13480
|
+
4. Keep responses concise, concrete, and tied to the user's next step.
|
|
13481
|
+
5. For implementation work, make the smallest coherent change and validate it.
|
|
13482
|
+
6. For plans, PRDs, reviews, and test reports, use structured Aiden artifacts when task context exists.
|
|
13483
|
+
|
|
13484
|
+
## Primary tools (code discovery)
|
|
13485
|
+
|
|
13486
|
+
- \`mcp__aiden__search_code_context\` / \`search_code_context\` \u2014 find where code lives or how behavior is implemented (**use this first**)
|
|
13487
|
+
- \`mcp__aiden__code_context_status\` \u2014 confirm the team index is ready
|
|
13488
|
+
- \`Read\`, \`Grep\` \u2014 only after you have paths from the index, or for line-level edits in known files; read exact cited files before answering exact questions
|
|
13489
|
+
- Do **not** run repo-wide \`grep\` / \`rg\` / Bash find for "where is X" or "how does this work" questions when MCP code-context tools are available
|
|
13482
13490
|
|
|
13483
13491
|
## Rules
|
|
13484
13492
|
|
|
@@ -13524,7 +13532,8 @@ Workflow: Listen \u2192 Understand \u2192 Break down \u2192 Plan \u2192 Build \u
|
|
|
13524
13532
|
|
|
13525
13533
|
## Primary tools
|
|
13526
13534
|
|
|
13527
|
-
- \`
|
|
13535
|
+
- \`mcp__aiden__search_code_context\` / \`search_code_context\` \u2014 find where code lives or how behavior is implemented (use BEFORE grep for discovery and implementation-answer questions)
|
|
13536
|
+
- \`Read\`, \`Glob\`, \`Grep\` \u2014 read exact cited files or narrow search after you have paths from the index
|
|
13528
13537
|
- \`Edit\`, \`Write\` \u2014 make changes; prefer \`Edit\` over \`Write\` for existing files
|
|
13529
13538
|
- \`Bash\` \u2014 run type-checks, tests, and read-only commands; never skip validation
|
|
13530
13539
|
- \`get_session_context\` \u2014 check what prior sessions already did before redoing work
|
|
@@ -14015,6 +14024,47 @@ If neither native ask nor the MCP ask tool is available, ask ONE short plain-tex
|
|
|
14015
14024
|
|
|
14016
14025
|
### After the tool call
|
|
14017
14026
|
The ask tool returns an empty/ack result and does NOT wait. Immediately end your turn. At most one short line like "Please pick an option above." \u2014 no restating the full questions in markdown. The user's answer (or skip) arrives as the next user message; continue from there.`;
|
|
14027
|
+
function buildAidenTeamScopePrompt(teamId) {
|
|
14028
|
+
return [
|
|
14029
|
+
`You are operating within team \`${teamId}\`.`,
|
|
14030
|
+
"Use this teamId for MCP tools that accept it (search, list_tasks, search_code_context, etc.).",
|
|
14031
|
+
"On code-context tools, teamId auto-resolves from the Aiden session when omitted \u2014 never invent or guess a teamId.",
|
|
14032
|
+
"Do not call list_teams."
|
|
14033
|
+
].join(" ");
|
|
14034
|
+
}
|
|
14035
|
+
var AIDEN_CODE_CONTEXT_PROMPT = `## Codebase index (required for code discovery)
|
|
14036
|
+
|
|
14037
|
+
This team has an indexed codebase. For questions about where code lives, how something works, how to answer from the codebase, or which files to read, use Aiden MCP code-context tools BEFORE local grep/find/bash search.
|
|
14038
|
+
|
|
14039
|
+
### Required path for codebase questions
|
|
14040
|
+
Examples: "where is X configured", "which file handles Y", "how does Z work", "find code that \u2026", "why does this behavior happen?"
|
|
14041
|
+
1. Call \`mcp__aiden__search_code_context\` (MCP tool: \`search_code_context\`) with hybrid mode and topK 5.
|
|
14042
|
+
2. Optionally call \`mcp__aiden__code_context_status\` first when unsure indexing is ready.
|
|
14043
|
+
3. Use the result citations to choose exact paths, then \`Read\` those files before making claims, proposing edits, or changing code.
|
|
14044
|
+
4. For exact symbols, constants, routes, schema fields, or line-level behavior, verify in the cited file with \`Read\` or narrow \`Grep\` before answering.
|
|
14045
|
+
|
|
14046
|
+
### Do NOT do this first
|
|
14047
|
+
- Do NOT start with \`grep\`, \`rg\`, \`find\`, or broad Bash filesystem search for codebase discovery or implementation-answer questions when \`search_code_context\` is available.
|
|
14048
|
+
- Do NOT use graphify or local graph tools for semantic "where is this implemented" questions \u2014 use \`search_code_context\`.
|
|
14049
|
+
- \`Read\` / \`Grep\` / \`Glob\` are for after you have specific paths from the index, or for line-level work in files already identified.
|
|
14050
|
+
|
|
14051
|
+
### Follow-ups
|
|
14052
|
+
- Import/caller structure: \`code_graph_query\` after search when available.
|
|
14053
|
+
- Current breakage: \`code_lsp_diagnostics\` when available.
|
|
14054
|
+
|
|
14055
|
+
If search returns no strong matches, say so and try one targeted local search in the most likely package \u2014 not repo-wide grep.`;
|
|
14056
|
+
function buildAidenTeamCodeContextOverlay(teamId) {
|
|
14057
|
+
return [buildAidenTeamScopePrompt(teamId), AIDEN_CODE_CONTEXT_PROMPT].join("\n\n");
|
|
14058
|
+
}
|
|
14059
|
+
function buildCodeDiscoveryEnforcementTail() {
|
|
14060
|
+
return [
|
|
14061
|
+
"## MANDATORY \u2014 team code index (do this before Grep/graphify)",
|
|
14062
|
+
"1. For codebase discovery or implementation-answer questions, call `mcp__aiden__search_code_context` (hybrid, topK 5). Omit teamId \u2014 Aiden session headers resolve it.",
|
|
14063
|
+
"2. Optionally `mcp__aiden__code_context_status` if indexing readiness is unclear.",
|
|
14064
|
+
"3. Read the exact cited files before answering, claiming behavior, or editing code; use narrow `Grep` only inside known paths.",
|
|
14065
|
+
"Repo-wide grep, graphify, or Bash find **before** MCP on discovery/implementation-answer questions fails the task."
|
|
14066
|
+
].join("\n");
|
|
14067
|
+
}
|
|
14018
14068
|
var PLAN_MODE_PROMPT = [
|
|
14019
14069
|
"You are in Aiden plan mode.",
|
|
14020
14070
|
"Analyze the task, inspect the relevant code and context, and produce a concrete implementation plan.",
|
|
@@ -14052,6 +14102,7 @@ function getAidenAgentPrompt(agentId) {
|
|
|
14052
14102
|
}
|
|
14053
14103
|
|
|
14054
14104
|
// ../shared/dist/types/frontend.js
|
|
14105
|
+
var EFFORT_LEVELS = ["minimal", "low", "medium", "high", "xhigh", "max", "ultra"];
|
|
14055
14106
|
var CLAUDE_48_EFFORT_LEVELS = [
|
|
14056
14107
|
"minimal",
|
|
14057
14108
|
"low",
|
|
@@ -14338,9 +14389,18 @@ var CLAUDE_5_EFFORT_LEVELS2 = [
|
|
|
14338
14389
|
var CODEX_5X_EFFORT_LEVELS2 = ["low", "medium", "high", "xhigh"];
|
|
14339
14390
|
var GPT_5_5_EFFORT_LEVELS = ["minimal", "low", "medium", "high", "xhigh"];
|
|
14340
14391
|
var GPT_5_4_EFFORT_LEVELS = ["low", "medium", "high"];
|
|
14392
|
+
var GPT_5_6_EFFORT_LEVELS = [
|
|
14393
|
+
"low",
|
|
14394
|
+
"medium",
|
|
14395
|
+
"high",
|
|
14396
|
+
"xhigh",
|
|
14397
|
+
"max",
|
|
14398
|
+
"ultra"
|
|
14399
|
+
];
|
|
14341
14400
|
var CURSOR_EFFORT_SUFFIXES = [
|
|
14342
14401
|
{ suffix: "-extra-high", level: "xhigh" },
|
|
14343
14402
|
{ suffix: "-xhigh", level: "xhigh" },
|
|
14403
|
+
{ suffix: "-ultra", level: "ultra" },
|
|
14344
14404
|
{ suffix: "-max", level: "max" },
|
|
14345
14405
|
{ suffix: "-high", level: "high" },
|
|
14346
14406
|
{ suffix: "-medium", level: "medium" },
|
|
@@ -14436,7 +14496,11 @@ function mergeEffortLevels(existing, discovered) {
|
|
|
14436
14496
|
const merged = new Set(existing ?? []);
|
|
14437
14497
|
for (const level of discovered)
|
|
14438
14498
|
merged.add(level);
|
|
14439
|
-
return
|
|
14499
|
+
return orderEffortLevels(merged);
|
|
14500
|
+
}
|
|
14501
|
+
function orderEffortLevels(levels) {
|
|
14502
|
+
const set = levels instanceof Set ? levels : new Set(levels);
|
|
14503
|
+
return EFFORT_LEVELS.filter((level) => set.has(level));
|
|
14440
14504
|
}
|
|
14441
14505
|
function lookupKnownModelCapabilities(modelId) {
|
|
14442
14506
|
for (const catalog of [AVAILABLE_MODELS, CURSOR_AGENT_MODELS]) {
|
|
@@ -14460,6 +14524,13 @@ function inferSlugModelCapabilities(providerKind, modelId) {
|
|
|
14460
14524
|
if (id === "gpt-5.4" || id === "gpt-5.4-mini") {
|
|
14461
14525
|
return { contextWindows: [], effortLevels: GPT_5_4_EFFORT_LEVELS };
|
|
14462
14526
|
}
|
|
14527
|
+
if (/^gpt-5\.6-/.test(id)) {
|
|
14528
|
+
const hasUltra = id.includes("-sol") || id.includes("-terra");
|
|
14529
|
+
return {
|
|
14530
|
+
contextWindows: [],
|
|
14531
|
+
effortLevels: hasUltra ? GPT_5_6_EFFORT_LEVELS : GPT_5_6_EFFORT_LEVELS.filter((level) => level !== "ultra")
|
|
14532
|
+
};
|
|
14533
|
+
}
|
|
14463
14534
|
if (id.includes("codex") || /^gpt-5\.[0-3]/.test(id)) {
|
|
14464
14535
|
return { contextWindows: [], effortLevels: CODEX_5X_EFFORT_LEVELS2 };
|
|
14465
14536
|
}
|
|
@@ -14630,13 +14701,18 @@ function catalogModelsForProvider(providerKind, modelsFromConfig) {
|
|
|
14630
14701
|
}
|
|
14631
14702
|
|
|
14632
14703
|
// ../agent-core/dist/index.js
|
|
14633
|
-
var import_child_process = require("child_process");
|
|
14634
14704
|
var import_fs2 = require("fs");
|
|
14635
14705
|
var import_os2 = require("os");
|
|
14636
14706
|
var import_path2 = require("path");
|
|
14707
|
+
var import_child_process = require("child_process");
|
|
14708
|
+
var import_fs3 = require("fs");
|
|
14709
|
+
var import_os3 = require("os");
|
|
14710
|
+
var import_path3 = require("path");
|
|
14637
14711
|
var import_readline = require("readline");
|
|
14638
14712
|
var import_child_process2 = require("child_process");
|
|
14639
14713
|
var import_crypto = require("crypto");
|
|
14714
|
+
var import_child_process3 = require("child_process");
|
|
14715
|
+
var import_util10 = require("util");
|
|
14640
14716
|
|
|
14641
14717
|
// ../shared/dist/constants/agent.js
|
|
14642
14718
|
var INTERACTIVE_TOOL_NAMES = /* @__PURE__ */ new Set(["askuserquestion", "exitplanmode", "enterplanmode"]);
|
|
@@ -14925,18 +15001,289 @@ var PRIORITY_OPTIONS = [
|
|
|
14925
15001
|
];
|
|
14926
15002
|
|
|
14927
15003
|
// ../agent-core/dist/index.js
|
|
14928
|
-
var import_fs3 = require("fs");
|
|
14929
|
-
var import_os3 = require("os");
|
|
14930
|
-
var import_path3 = require("path");
|
|
14931
15004
|
var import_fs4 = require("fs");
|
|
14932
15005
|
var import_os4 = require("os");
|
|
14933
15006
|
var import_path4 = require("path");
|
|
14934
15007
|
var import_fs5 = require("fs");
|
|
14935
15008
|
var import_os5 = require("os");
|
|
14936
15009
|
var import_path5 = require("path");
|
|
14937
|
-
var import_crypto2 = require("crypto");
|
|
14938
15010
|
var import_fs6 = require("fs");
|
|
15011
|
+
var import_os6 = require("os");
|
|
14939
15012
|
var import_path6 = require("path");
|
|
15013
|
+
var import_crypto2 = require("crypto");
|
|
15014
|
+
var import_fs7 = require("fs");
|
|
15015
|
+
var import_path7 = require("path");
|
|
15016
|
+
var MANAGED_AIDEN_MCP_SERVER_NAMES = [
|
|
15017
|
+
"aiden",
|
|
15018
|
+
"aiden-prod",
|
|
15019
|
+
"aiden-staging",
|
|
15020
|
+
"aiden-local"
|
|
15021
|
+
];
|
|
15022
|
+
function parseJsonSafe(content) {
|
|
15023
|
+
if (!content) return {};
|
|
15024
|
+
try {
|
|
15025
|
+
return JSON.parse(content);
|
|
15026
|
+
} catch {
|
|
15027
|
+
return {};
|
|
15028
|
+
}
|
|
15029
|
+
}
|
|
15030
|
+
function readFileOrNull(path) {
|
|
15031
|
+
try {
|
|
15032
|
+
if ((0, import_fs2.existsSync)(path)) return (0, import_fs2.readFileSync)(path, "utf-8");
|
|
15033
|
+
} catch {
|
|
15034
|
+
}
|
|
15035
|
+
return null;
|
|
15036
|
+
}
|
|
15037
|
+
function writeFileSafe(path, content) {
|
|
15038
|
+
(0, import_fs2.mkdirSync)((0, import_path2.dirname)(path), { recursive: true });
|
|
15039
|
+
(0, import_fs2.writeFileSync)(path, content, "utf-8");
|
|
15040
|
+
}
|
|
15041
|
+
function formatTomlKey2(key) {
|
|
15042
|
+
return /^[A-Za-z0-9_-]+$/.test(key) ? key : JSON.stringify(key);
|
|
15043
|
+
}
|
|
15044
|
+
function parseJsonStringOrNull(raw) {
|
|
15045
|
+
try {
|
|
15046
|
+
const value2 = JSON.parse(raw);
|
|
15047
|
+
return typeof value2 === "string" ? value2 : null;
|
|
15048
|
+
} catch {
|
|
15049
|
+
return null;
|
|
15050
|
+
}
|
|
15051
|
+
}
|
|
15052
|
+
function splitTomlInlineEntries(body) {
|
|
15053
|
+
const entries = [];
|
|
15054
|
+
let current = "";
|
|
15055
|
+
let inString = false;
|
|
15056
|
+
let escaping = false;
|
|
15057
|
+
for (const char of body) {
|
|
15058
|
+
if (escaping) {
|
|
15059
|
+
current += char;
|
|
15060
|
+
escaping = false;
|
|
15061
|
+
continue;
|
|
15062
|
+
}
|
|
15063
|
+
if (char === "\\") {
|
|
15064
|
+
current += char;
|
|
15065
|
+
escaping = inString;
|
|
15066
|
+
continue;
|
|
15067
|
+
}
|
|
15068
|
+
if (char === '"') inString = !inString;
|
|
15069
|
+
if (char === "," && !inString) {
|
|
15070
|
+
if (current.trim()) entries.push(current.trim());
|
|
15071
|
+
current = "";
|
|
15072
|
+
continue;
|
|
15073
|
+
}
|
|
15074
|
+
current += char;
|
|
15075
|
+
}
|
|
15076
|
+
if (current.trim()) entries.push(current.trim());
|
|
15077
|
+
return entries;
|
|
15078
|
+
}
|
|
15079
|
+
function parseTomlInlineStringTable(raw) {
|
|
15080
|
+
const trimmed = raw.trim();
|
|
15081
|
+
if (!trimmed.startsWith("{") || !trimmed.endsWith("}")) return {};
|
|
15082
|
+
const body = trimmed.slice(1, -1).trim();
|
|
15083
|
+
if (!body) return {};
|
|
15084
|
+
const headers = {};
|
|
15085
|
+
for (const entry of splitTomlInlineEntries(body)) {
|
|
15086
|
+
const equalsIndex = entry.indexOf("=");
|
|
15087
|
+
if (equalsIndex < 0) continue;
|
|
15088
|
+
const rawKey = entry.slice(0, equalsIndex).trim();
|
|
15089
|
+
const rawValue = entry.slice(equalsIndex + 1).trim();
|
|
15090
|
+
const key = rawKey.startsWith('"') ? parseJsonStringOrNull(rawKey) : rawKey;
|
|
15091
|
+
const value2 = rawValue.startsWith('"') ? parseJsonStringOrNull(rawValue) : rawValue;
|
|
15092
|
+
if (key && value2 !== null) headers[key] = value2;
|
|
15093
|
+
}
|
|
15094
|
+
return headers;
|
|
15095
|
+
}
|
|
15096
|
+
function buildTomlInlineStringTable(record) {
|
|
15097
|
+
return `{ ${Object.entries(record).map(([key, value2]) => `${formatTomlKey2(key)} = ${JSON.stringify(value2)}`).join(", ")} }`;
|
|
15098
|
+
}
|
|
15099
|
+
function findManagedAidenServer(servers) {
|
|
15100
|
+
for (const name of MANAGED_AIDEN_MCP_SERVER_NAMES) {
|
|
15101
|
+
const server = servers[name];
|
|
15102
|
+
if (server && typeof server === "object") {
|
|
15103
|
+
return { name, server };
|
|
15104
|
+
}
|
|
15105
|
+
}
|
|
15106
|
+
return null;
|
|
15107
|
+
}
|
|
15108
|
+
function buildSessionHeaders(input) {
|
|
15109
|
+
const headers = {
|
|
15110
|
+
"x-conversation-id": input.conversationId
|
|
15111
|
+
};
|
|
15112
|
+
if (input.teamId) headers["x-team-id"] = input.teamId;
|
|
15113
|
+
if (input.allowedTools?.length) {
|
|
15114
|
+
headers["x-allowed-tools"] = input.allowedTools.join(",");
|
|
15115
|
+
}
|
|
15116
|
+
return headers;
|
|
15117
|
+
}
|
|
15118
|
+
function getTomlSectionName(line) {
|
|
15119
|
+
const match = line.match(/^\s*\[mcp_servers\.(?:"([^"]+)"|([A-Za-z0-9_-]+))\]\s*$/);
|
|
15120
|
+
return match?.[1] ?? match?.[2] ?? null;
|
|
15121
|
+
}
|
|
15122
|
+
function patchCodexTomlMcpConfig(content, sessionHeaders) {
|
|
15123
|
+
const newline = content.includes("\r\n") ? "\r\n" : "\n";
|
|
15124
|
+
const lines = content.split(/\r?\n/);
|
|
15125
|
+
const sectionStart = lines.findIndex((line) => {
|
|
15126
|
+
const name = getTomlSectionName(line);
|
|
15127
|
+
return Boolean(name && MANAGED_AIDEN_MCP_SERVER_NAMES.includes(name));
|
|
15128
|
+
});
|
|
15129
|
+
if (sectionStart < 0) return null;
|
|
15130
|
+
let sectionEnd = lines.findIndex((line, index) => index > sectionStart && /^\s*\[/.test(line));
|
|
15131
|
+
if (sectionEnd < 0) sectionEnd = lines.length;
|
|
15132
|
+
const headerLineIndex = lines.findIndex(
|
|
15133
|
+
(line, index) => index > sectionStart && index < sectionEnd && /^\s*http_headers\s*=/.test(line)
|
|
15134
|
+
);
|
|
15135
|
+
if (headerLineIndex >= 0) {
|
|
15136
|
+
const rawInlineTable = lines[headerLineIndex]?.replace(/^\s*http_headers\s*=\s*/, "") ?? "";
|
|
15137
|
+
const currentHeaders = parseTomlInlineStringTable(rawInlineTable);
|
|
15138
|
+
lines[headerLineIndex] = `http_headers = ${buildTomlInlineStringTable({
|
|
15139
|
+
...currentHeaders,
|
|
15140
|
+
...sessionHeaders
|
|
15141
|
+
})}`;
|
|
15142
|
+
} else {
|
|
15143
|
+
const insertAfterUrl = lines.findIndex(
|
|
15144
|
+
(line, index) => index > sectionStart && index < sectionEnd && /^\s*url\s*=/.test(line)
|
|
15145
|
+
);
|
|
15146
|
+
lines.splice(
|
|
15147
|
+
insertAfterUrl >= 0 ? insertAfterUrl + 1 : sectionStart + 1,
|
|
15148
|
+
0,
|
|
15149
|
+
`http_headers = ${buildTomlInlineStringTable(sessionHeaders)}`
|
|
15150
|
+
);
|
|
15151
|
+
}
|
|
15152
|
+
const updated = lines.join(newline);
|
|
15153
|
+
return updated.endsWith(newline) ? updated : `${updated}${newline}`;
|
|
15154
|
+
}
|
|
15155
|
+
function patchCodexTomlMcpTarget(target, sessionHeaders) {
|
|
15156
|
+
if (!(0, import_fs2.existsSync)(target.guardDir)) return false;
|
|
15157
|
+
const existing = readFileOrNull(target.configPath);
|
|
15158
|
+
if (existing === null) return false;
|
|
15159
|
+
const updated = patchCodexTomlMcpConfig(existing, sessionHeaders);
|
|
15160
|
+
if (updated === null || updated === existing) return false;
|
|
15161
|
+
writeFileSafe(target.configPath, updated);
|
|
15162
|
+
return true;
|
|
15163
|
+
}
|
|
15164
|
+
function patchJsonMcpTarget(target, sessionHeaders) {
|
|
15165
|
+
if (!(0, import_fs2.existsSync)(target.guardDir)) return false;
|
|
15166
|
+
const existing = readFileOrNull(target.configPath);
|
|
15167
|
+
const config = parseJsonSafe(existing);
|
|
15168
|
+
const servers = target.readServers(config);
|
|
15169
|
+
const match = findManagedAidenServer(servers);
|
|
15170
|
+
if (!match) return false;
|
|
15171
|
+
const currentHeaders = target.readHeaders(match.server) ?? {};
|
|
15172
|
+
target.writeHeaders(match.server, { ...currentHeaders, ...sessionHeaders });
|
|
15173
|
+
servers[match.name] = match.server;
|
|
15174
|
+
target.writeServers(config, servers);
|
|
15175
|
+
writeFileSafe(target.configPath, `${JSON.stringify(config, null, 2)}
|
|
15176
|
+
`);
|
|
15177
|
+
return true;
|
|
15178
|
+
}
|
|
15179
|
+
function jsonMcpServersTarget(cli, home, configRelativePath, guardRelativePath) {
|
|
15180
|
+
const configPath = (0, import_path2.join)(home, ...configRelativePath);
|
|
15181
|
+
const guardDir = guardRelativePath.length > 0 ? (0, import_path2.join)(home, ...guardRelativePath) : home;
|
|
15182
|
+
return {
|
|
15183
|
+
cli,
|
|
15184
|
+
configPath,
|
|
15185
|
+
guardDir,
|
|
15186
|
+
readServers: (config) => config.mcpServers ?? {},
|
|
15187
|
+
writeServers: (config, servers) => {
|
|
15188
|
+
config.mcpServers = servers;
|
|
15189
|
+
},
|
|
15190
|
+
readHeaders: (server) => server.headers,
|
|
15191
|
+
writeHeaders: (server, headers) => {
|
|
15192
|
+
server.headers = headers;
|
|
15193
|
+
}
|
|
15194
|
+
};
|
|
15195
|
+
}
|
|
15196
|
+
function buildCodexTomlTargets(home) {
|
|
15197
|
+
return [
|
|
15198
|
+
{
|
|
15199
|
+
cli: "Codex",
|
|
15200
|
+
configPath: (0, import_path2.join)(home, ".codex", "config.toml"),
|
|
15201
|
+
guardDir: (0, import_path2.join)(home, ".codex")
|
|
15202
|
+
}
|
|
15203
|
+
];
|
|
15204
|
+
}
|
|
15205
|
+
function buildJsonTargets(home) {
|
|
15206
|
+
return [
|
|
15207
|
+
jsonMcpServersTarget("Cursor", home, [".cursor", "mcp.json"], [".cursor"]),
|
|
15208
|
+
jsonMcpServersTarget("Claude Code", home, [".claude.json"], []),
|
|
15209
|
+
jsonMcpServersTarget("Kimi CLI", home, [".kimi", "mcp.json"], [".kimi"]),
|
|
15210
|
+
jsonMcpServersTarget("Factory Droid", home, [".factory", "mcp.json"], [".factory"]),
|
|
15211
|
+
{
|
|
15212
|
+
cli: "OpenCode",
|
|
15213
|
+
configPath: (0, import_path2.join)(home, ".config", "opencode", "opencode.json"),
|
|
15214
|
+
guardDir: (0, import_path2.join)(home, ".config", "opencode"),
|
|
15215
|
+
readServers: (config) => config.mcp ?? {},
|
|
15216
|
+
writeServers: (config, servers) => {
|
|
15217
|
+
config.mcp = servers;
|
|
15218
|
+
},
|
|
15219
|
+
readHeaders: (server) => server.headers,
|
|
15220
|
+
writeHeaders: (server, headers) => {
|
|
15221
|
+
server.headers = headers;
|
|
15222
|
+
}
|
|
15223
|
+
},
|
|
15224
|
+
{
|
|
15225
|
+
cli: "Amp",
|
|
15226
|
+
configPath: (0, import_path2.join)(home, ".config", "amp", "settings.json"),
|
|
15227
|
+
guardDir: (0, import_path2.join)(home, ".config", "amp"),
|
|
15228
|
+
readServers: (config) => config["amp.mcpServers"] ?? {},
|
|
15229
|
+
writeServers: (config, servers) => {
|
|
15230
|
+
config["amp.mcpServers"] = servers;
|
|
15231
|
+
},
|
|
15232
|
+
readHeaders: (server) => server.headers,
|
|
15233
|
+
writeHeaders: (server, headers) => {
|
|
15234
|
+
server.headers = headers;
|
|
15235
|
+
}
|
|
15236
|
+
},
|
|
15237
|
+
{
|
|
15238
|
+
cli: "Antigravity",
|
|
15239
|
+
configPath: (0, import_path2.join)(home, ".gemini", "settings.json"),
|
|
15240
|
+
guardDir: (0, import_path2.join)(home, ".gemini"),
|
|
15241
|
+
readServers: (config) => config.mcpServers ?? {},
|
|
15242
|
+
writeServers: (config, servers) => {
|
|
15243
|
+
config.mcpServers = servers;
|
|
15244
|
+
},
|
|
15245
|
+
readHeaders: (server) => server.headers,
|
|
15246
|
+
writeHeaders: (server, headers) => {
|
|
15247
|
+
server.headers = headers;
|
|
15248
|
+
}
|
|
15249
|
+
},
|
|
15250
|
+
{
|
|
15251
|
+
cli: "Antigravity CLI",
|
|
15252
|
+
configPath: (0, import_path2.join)(home, ".gemini", "antigravity-cli", "settings.json"),
|
|
15253
|
+
guardDir: (0, import_path2.join)(home, ".gemini"),
|
|
15254
|
+
readServers: (config) => config.mcpServers ?? {},
|
|
15255
|
+
writeServers: (config, servers) => {
|
|
15256
|
+
config.mcpServers = servers;
|
|
15257
|
+
},
|
|
15258
|
+
readHeaders: (server) => server.headers,
|
|
15259
|
+
writeHeaders: (server, headers) => {
|
|
15260
|
+
server.headers = headers;
|
|
15261
|
+
}
|
|
15262
|
+
}
|
|
15263
|
+
];
|
|
15264
|
+
}
|
|
15265
|
+
function syncAidenMcpSessionHeaders(input) {
|
|
15266
|
+
const home = input.homeDir ?? (0, import_os2.homedir)();
|
|
15267
|
+
const sessionHeaders = buildSessionHeaders(input);
|
|
15268
|
+
const written = [];
|
|
15269
|
+
for (const target of buildCodexTomlTargets(home)) {
|
|
15270
|
+
try {
|
|
15271
|
+
if (patchCodexTomlMcpTarget(target, sessionHeaders)) {
|
|
15272
|
+
written.push(target.cli);
|
|
15273
|
+
}
|
|
15274
|
+
} catch {
|
|
15275
|
+
}
|
|
15276
|
+
}
|
|
15277
|
+
for (const target of buildJsonTargets(home)) {
|
|
15278
|
+
try {
|
|
15279
|
+
if (patchJsonMcpTarget(target, sessionHeaders)) {
|
|
15280
|
+
written.push(target.cli);
|
|
15281
|
+
}
|
|
15282
|
+
} catch {
|
|
15283
|
+
}
|
|
15284
|
+
}
|
|
15285
|
+
return written;
|
|
15286
|
+
}
|
|
14940
15287
|
function buildPromptWithSystem(config, promptText) {
|
|
14941
15288
|
const parts2 = [
|
|
14942
15289
|
config.systemPrompt?.trim(),
|
|
@@ -14961,16 +15308,16 @@ function imageFileExtension(mimeType) {
|
|
|
14961
15308
|
}
|
|
14962
15309
|
function createImageTempDirectory(cwd) {
|
|
14963
15310
|
const candidates = [
|
|
14964
|
-
cwd ? (0,
|
|
14965
|
-
(0,
|
|
15311
|
+
cwd ? (0, import_path3.join)(cwd, ".aiden-images-") : null,
|
|
15312
|
+
(0, import_path3.join)((0, import_os3.tmpdir)(), "aiden-images-")
|
|
14966
15313
|
].filter((value2) => Boolean(value2));
|
|
14967
15314
|
for (const candidate of candidates) {
|
|
14968
15315
|
try {
|
|
14969
|
-
return (0,
|
|
15316
|
+
return (0, import_fs3.mkdtempSync)(candidate);
|
|
14970
15317
|
} catch {
|
|
14971
15318
|
}
|
|
14972
15319
|
}
|
|
14973
|
-
return (0,
|
|
15320
|
+
return (0, import_fs3.mkdtempSync)((0, import_path3.join)((0, import_os3.tmpdir)(), "aiden-images-"));
|
|
14974
15321
|
}
|
|
14975
15322
|
function safeFilename(filename) {
|
|
14976
15323
|
const safe = filename.replace(/[^a-zA-Z0-9._-]/g, "_").replace(/^_+/, "");
|
|
@@ -14984,8 +15331,8 @@ function writeImagesToTempFiles(images, cwd) {
|
|
|
14984
15331
|
const files = [];
|
|
14985
15332
|
for (const img of images) {
|
|
14986
15333
|
const ext = imageFileExtension(img.mimeType);
|
|
14987
|
-
const filePath = (0,
|
|
14988
|
-
(0,
|
|
15334
|
+
const filePath = (0, import_path3.join)(directory, `aiden-img-${img.id}.${ext}`);
|
|
15335
|
+
(0, import_fs3.writeFileSync)(filePath, Buffer.from(img.data, "base64"));
|
|
14989
15336
|
paths.push(filePath);
|
|
14990
15337
|
files.push({
|
|
14991
15338
|
filename: img.filename,
|
|
@@ -15000,7 +15347,7 @@ function writeImagesToTempFiles(images, cwd) {
|
|
|
15000
15347
|
files,
|
|
15001
15348
|
cleanup: () => {
|
|
15002
15349
|
try {
|
|
15003
|
-
(0,
|
|
15350
|
+
(0, import_fs3.rmSync)(directory, { recursive: true, force: true });
|
|
15004
15351
|
} catch {
|
|
15005
15352
|
}
|
|
15006
15353
|
}
|
|
@@ -15026,8 +15373,8 @@ function writeFilesToTempFiles(files, cwd) {
|
|
|
15026
15373
|
}
|
|
15027
15374
|
for (const file of dataFiles) {
|
|
15028
15375
|
if (!directory || file.data === void 0) continue;
|
|
15029
|
-
const filePath = (0,
|
|
15030
|
-
(0,
|
|
15376
|
+
const filePath = (0, import_path3.join)(directory, `${file.id}-${safeFilename(file.filename)}`);
|
|
15377
|
+
(0, import_fs3.writeFileSync)(filePath, Buffer.from(file.data, "base64"));
|
|
15031
15378
|
paths.push(filePath);
|
|
15032
15379
|
tempFiles.push({
|
|
15033
15380
|
filename: file.filename,
|
|
@@ -15042,7 +15389,7 @@ function writeFilesToTempFiles(files, cwd) {
|
|
|
15042
15389
|
cleanup: () => {
|
|
15043
15390
|
if (!directory) return;
|
|
15044
15391
|
try {
|
|
15045
|
-
(0,
|
|
15392
|
+
(0, import_fs3.rmSync)(directory, { recursive: true, force: true });
|
|
15046
15393
|
} catch {
|
|
15047
15394
|
}
|
|
15048
15395
|
}
|
|
@@ -15964,6 +16311,30 @@ function createAntigravityCliBackend(command = "agy", defaultArgs = []) {
|
|
|
15964
16311
|
}
|
|
15965
16312
|
};
|
|
15966
16313
|
}
|
|
16314
|
+
var execFileAsync = (0, import_util10.promisify)(import_child_process3.execFile);
|
|
16315
|
+
var flagSupportCache = /* @__PURE__ */ new Map();
|
|
16316
|
+
function helpAdvertisesFlag(helpText, flag) {
|
|
16317
|
+
return helpText.includes(flag);
|
|
16318
|
+
}
|
|
16319
|
+
async function cliSupportsFlag(command, flag, env = {}) {
|
|
16320
|
+
const key = `${command}::${flag}`;
|
|
16321
|
+
const cached = flagSupportCache.get(key);
|
|
16322
|
+
if (cached !== void 0) return cached;
|
|
16323
|
+
let supported = false;
|
|
16324
|
+
try {
|
|
16325
|
+
const { stdout, stderr } = await execFileAsync(command, ["--help"], {
|
|
16326
|
+
env: { ...process.env, ...env },
|
|
16327
|
+
timeout: 5e3,
|
|
16328
|
+
maxBuffer: 4 * 1024 * 1024
|
|
16329
|
+
});
|
|
16330
|
+
supported = helpAdvertisesFlag(`${stdout ?? ""}${stderr ?? ""}`, flag);
|
|
16331
|
+
} catch (error) {
|
|
16332
|
+
const withOutput = error;
|
|
16333
|
+
supported = helpAdvertisesFlag(`${withOutput.stdout ?? ""}${withOutput.stderr ?? ""}`, flag);
|
|
16334
|
+
}
|
|
16335
|
+
flagSupportCache.set(key, supported);
|
|
16336
|
+
return supported;
|
|
16337
|
+
}
|
|
15967
16338
|
function stringField(record, key) {
|
|
15968
16339
|
const value2 = record[key];
|
|
15969
16340
|
return typeof value2 === "string" && value2.trim().length > 0 ? value2 : void 0;
|
|
@@ -16333,13 +16704,13 @@ function createClaudeCliBackend(command = "claude", defaultArgs = []) {
|
|
|
16333
16704
|
args.push("--disallowedTools", disallowedTools.join(","));
|
|
16334
16705
|
}
|
|
16335
16706
|
const resumeId = context.config.runtimeSessionId?.trim() || context.config.providerSessionId?.trim();
|
|
16336
|
-
if (!resumeId) {
|
|
16337
|
-
|
|
16338
|
-
|
|
16339
|
-
|
|
16340
|
-
|
|
16341
|
-
|
|
16342
|
-
|
|
16707
|
+
if (!resumeId && context.config.systemPrompt?.trim()) {
|
|
16708
|
+
args.push("--system-prompt", context.config.systemPrompt.trim());
|
|
16709
|
+
} else if (resumeId && context.config.systemPromptAppend?.trim()) {
|
|
16710
|
+
args.push("--append-system-prompt", context.config.systemPromptAppend.trim());
|
|
16711
|
+
}
|
|
16712
|
+
if (context.config.teamId?.trim() && await cliSupportsFlag(command, "--approve-mcps", context.env)) {
|
|
16713
|
+
args.push("--approve-mcps");
|
|
16343
16714
|
}
|
|
16344
16715
|
const baseModel = context.config.selectedModel?.trim();
|
|
16345
16716
|
if (baseModel) {
|
|
@@ -16424,26 +16795,26 @@ function normalizeCodexMcpToolResult(output) {
|
|
|
16424
16795
|
return raw;
|
|
16425
16796
|
}
|
|
16426
16797
|
function findCodexSessionLog(runtimeSessionId, codexHome) {
|
|
16427
|
-
if (!runtimeSessionId || !(0,
|
|
16428
|
-
const root = (0,
|
|
16429
|
-
if (!(0,
|
|
16798
|
+
if (!runtimeSessionId || !(0, import_fs4.existsSync)(codexHome)) return null;
|
|
16799
|
+
const root = (0, import_path4.join)(codexHome, "sessions");
|
|
16800
|
+
if (!(0, import_fs4.existsSync)(root)) return null;
|
|
16430
16801
|
const matches = [];
|
|
16431
16802
|
const stack = [root];
|
|
16432
16803
|
while (stack.length > 0) {
|
|
16433
16804
|
const dir = stack.pop();
|
|
16434
16805
|
let entries;
|
|
16435
16806
|
try {
|
|
16436
|
-
entries = (0,
|
|
16807
|
+
entries = (0, import_fs4.readdirSync)(dir, { withFileTypes: true });
|
|
16437
16808
|
} catch {
|
|
16438
16809
|
continue;
|
|
16439
16810
|
}
|
|
16440
16811
|
for (const entry of entries) {
|
|
16441
|
-
const path = (0,
|
|
16812
|
+
const path = (0, import_path4.join)(dir, entry.name);
|
|
16442
16813
|
if (entry.isDirectory()) {
|
|
16443
16814
|
stack.push(path);
|
|
16444
16815
|
} else if (entry.isFile() && entry.name.includes(runtimeSessionId) && entry.name.endsWith(".jsonl")) {
|
|
16445
16816
|
try {
|
|
16446
|
-
matches.push({ path, mtimeMs: (0,
|
|
16817
|
+
matches.push({ path, mtimeMs: (0, import_fs4.statSync)(path).mtimeMs });
|
|
16447
16818
|
} catch {
|
|
16448
16819
|
matches.push({ path, mtimeMs: 0 });
|
|
16449
16820
|
}
|
|
@@ -16476,10 +16847,10 @@ function latestUserMessageLineIndex(lines) {
|
|
|
16476
16847
|
async function replayCodexMcpToolEventsFromSessionLog(context, state) {
|
|
16477
16848
|
const runtimeSessionId = state.runtimeSessionId;
|
|
16478
16849
|
if (!runtimeSessionId) return;
|
|
16479
|
-
const codexHome = context.env.CODEX_HOME || process.env.CODEX_HOME || (0,
|
|
16850
|
+
const codexHome = context.env.CODEX_HOME || process.env.CODEX_HOME || (0, import_path4.join)((0, import_os4.homedir)(), ".codex");
|
|
16480
16851
|
const logPath = findCodexSessionLog(runtimeSessionId, codexHome);
|
|
16481
16852
|
if (!logPath) return;
|
|
16482
|
-
const allLines = (0,
|
|
16853
|
+
const allLines = (0, import_fs4.readFileSync)(logPath, "utf8").split(/\r?\n/).filter(Boolean);
|
|
16483
16854
|
const latestUserLineIndex = latestUserMessageLineIndex(allLines);
|
|
16484
16855
|
const lines = latestUserLineIndex >= 0 ? allLines.slice(latestUserLineIndex + 1) : allLines;
|
|
16485
16856
|
const emittedToolIds = /* @__PURE__ */ new Set();
|
|
@@ -17117,6 +17488,7 @@ function createCursorAgentCliBackend(command = "cursor-agent", defaultArgs = [])
|
|
|
17117
17488
|
context.config.images,
|
|
17118
17489
|
context.cwd
|
|
17119
17490
|
);
|
|
17491
|
+
const approveMcps = context.config.teamId?.trim() ? await cliSupportsFlag(command, "--approve-mcps", context.env) : false;
|
|
17120
17492
|
try {
|
|
17121
17493
|
return await createGenericCliBackend({
|
|
17122
17494
|
kind: "cursor_agent_cli",
|
|
@@ -17129,10 +17501,12 @@ function createCursorAgentCliBackend(command = "cursor-agent", defaultArgs = [])
|
|
|
17129
17501
|
"--output-format",
|
|
17130
17502
|
"stream-json",
|
|
17131
17503
|
"--trust",
|
|
17132
|
-
"--approve-mcps",
|
|
17133
17504
|
"--workspace",
|
|
17134
17505
|
ctx.cwd
|
|
17135
17506
|
];
|
|
17507
|
+
if (approveMcps) {
|
|
17508
|
+
args.push("--approve-mcps");
|
|
17509
|
+
}
|
|
17136
17510
|
const resumeId = ctx.config.runtimeSessionId?.trim() || ctx.config.providerSessionId?.trim();
|
|
17137
17511
|
if (shouldForceCursorAgent(ctx.config)) args.push("--force");
|
|
17138
17512
|
if (ctx.config.mode === "plan" || ctx.config.mode === "review") {
|
|
@@ -17167,7 +17541,12 @@ function createCursorAgentCliBackend(command = "cursor-agent", defaultArgs = [])
|
|
|
17167
17541
|
// with zero output; without this watchdog only the 30-min server reaper
|
|
17168
17542
|
// would end the run.
|
|
17169
17543
|
startupTimeoutMs: 18e4,
|
|
17170
|
-
augmentPrompt: (ctx) =>
|
|
17544
|
+
augmentPrompt: (ctx) => {
|
|
17545
|
+
const prompt = buildPromptWithImagePathReferences(ctx, imageFiles);
|
|
17546
|
+
return ctx.config.teamId?.trim() ? `${prompt}
|
|
17547
|
+
|
|
17548
|
+
${buildCodeDiscoveryEnforcementTail()}` : prompt;
|
|
17549
|
+
},
|
|
17171
17550
|
parseStructuredLine: parseCursorStructuredLine
|
|
17172
17551
|
}).run(context);
|
|
17173
17552
|
} finally {
|
|
@@ -17305,174 +17684,259 @@ function createDroidCliBackend(command = "droid", defaultArgs = []) {
|
|
|
17305
17684
|
}
|
|
17306
17685
|
};
|
|
17307
17686
|
}
|
|
17687
|
+
var ACP_PROTOCOL_VERSION = 1;
|
|
17308
17688
|
function asRecord(value2) {
|
|
17309
|
-
return value2 && typeof value2 === "object" ? value2 : null;
|
|
17689
|
+
return value2 && typeof value2 === "object" && !Array.isArray(value2) ? value2 : null;
|
|
17310
17690
|
}
|
|
17311
|
-
function
|
|
17312
|
-
|
|
17313
|
-
|
|
17314
|
-
|
|
17691
|
+
function asString(value2) {
|
|
17692
|
+
return typeof value2 === "string" ? value2 : "";
|
|
17693
|
+
}
|
|
17694
|
+
function resumeSessionId(context) {
|
|
17695
|
+
return context.config.runtimeSessionId?.trim() || context.config.providerSessionId?.trim() || "";
|
|
17696
|
+
}
|
|
17697
|
+
function chunkText(content) {
|
|
17698
|
+
const record = asRecord(content);
|
|
17699
|
+
if (!record) return "";
|
|
17700
|
+
if (typeof record.text === "string") return record.text;
|
|
17701
|
+
return chunkText(record.content);
|
|
17702
|
+
}
|
|
17703
|
+
function toolResultText(update) {
|
|
17704
|
+
const content = update.content;
|
|
17705
|
+
if (Array.isArray(content)) {
|
|
17706
|
+
const parts2 = content.map((item) => chunkText(item)).filter((text) => text.length > 0);
|
|
17707
|
+
if (parts2.length) return parts2.join("\n");
|
|
17315
17708
|
}
|
|
17316
|
-
const
|
|
17317
|
-
if (
|
|
17318
|
-
|
|
17319
|
-
|
|
17320
|
-
|
|
17709
|
+
const rawOutput = update.rawOutput;
|
|
17710
|
+
if (rawOutput !== void 0) return JSON.stringify(rawOutput, null, 2);
|
|
17711
|
+
return "";
|
|
17712
|
+
}
|
|
17713
|
+
function toolMetaName(update) {
|
|
17714
|
+
const meta = asRecord(update._meta);
|
|
17715
|
+
const tool = asRecord(meta?.["x.ai/tool"]);
|
|
17716
|
+
return asString(tool?.name);
|
|
17717
|
+
}
|
|
17718
|
+
function resolvePermission(params, context) {
|
|
17719
|
+
const record = asRecord(params);
|
|
17720
|
+
const options = Array.isArray(record?.options) ? record?.options : [];
|
|
17721
|
+
const toolCall = asRecord(record?.toolCall);
|
|
17722
|
+
const meta = asRecord(toolCall?._meta);
|
|
17723
|
+
const tool = asRecord(meta?.["x.ai/tool"]);
|
|
17724
|
+
const isReadOnlyTool = tool?.read_only === true || asString(tool?.kind) === "read";
|
|
17725
|
+
const allow = !shouldUseReadOnlyRuntimePermissions(context.config) || isReadOnlyTool;
|
|
17726
|
+
const allowKinds = ["allow_always", "allow_once", "allow"];
|
|
17727
|
+
const rejectKinds = ["reject_always", "reject_once", "reject", "deny"];
|
|
17728
|
+
const wanted = allow ? allowKinds : rejectKinds;
|
|
17729
|
+
const chosen = options.find((option) => wanted.includes(asString(asRecord(option)?.kind))) ?? (allow ? options[0] : options[options.length - 1]);
|
|
17730
|
+
const optionId = asString(asRecord(chosen)?.optionId);
|
|
17731
|
+
if (!optionId) return { outcome: { outcome: "cancelled" } };
|
|
17732
|
+
return { outcome: { outcome: "selected", optionId } };
|
|
17733
|
+
}
|
|
17734
|
+
function createGrokAcpDriver(imageFiles) {
|
|
17735
|
+
let stdin = null;
|
|
17736
|
+
let nextId = 0;
|
|
17737
|
+
let initId = -1;
|
|
17738
|
+
let sessionOpId = -1;
|
|
17739
|
+
let promptId = -1;
|
|
17740
|
+
let attemptedNewSession = false;
|
|
17741
|
+
let finalized = false;
|
|
17742
|
+
function write(message) {
|
|
17743
|
+
try {
|
|
17744
|
+
stdin?.write(`${JSON.stringify(message)}
|
|
17745
|
+
`);
|
|
17746
|
+
} catch {
|
|
17321
17747
|
}
|
|
17322
17748
|
}
|
|
17323
|
-
|
|
17324
|
-
|
|
17325
|
-
|
|
17326
|
-
|
|
17327
|
-
const value2 = parsed[key];
|
|
17328
|
-
if (typeof value2 === "string" && value2.trim()) return value2.trim();
|
|
17749
|
+
function request(method, params) {
|
|
17750
|
+
const id = ++nextId;
|
|
17751
|
+
write({ jsonrpc: "2.0", id, method, params });
|
|
17752
|
+
return id;
|
|
17329
17753
|
}
|
|
17330
|
-
|
|
17331
|
-
|
|
17332
|
-
for (const key of ["id", "toolCallId", "callId"]) {
|
|
17333
|
-
const value2 = toolCall[key];
|
|
17334
|
-
if (typeof value2 === "string" && value2.trim()) return value2.trim();
|
|
17335
|
-
}
|
|
17754
|
+
function respond(id, result) {
|
|
17755
|
+
write({ jsonrpc: "2.0", id, result });
|
|
17336
17756
|
}
|
|
17337
|
-
|
|
17338
|
-
|
|
17339
|
-
|
|
17340
|
-
for (const key of ["args", "arguments", "input", "params"]) {
|
|
17341
|
-
if (parsed[key] !== void 0) return parsed[key];
|
|
17757
|
+
function newSession(context) {
|
|
17758
|
+
attemptedNewSession = true;
|
|
17759
|
+
sessionOpId = request("session/new", { cwd: context.cwd, mcpServers: [] });
|
|
17342
17760
|
}
|
|
17343
|
-
|
|
17344
|
-
|
|
17345
|
-
|
|
17346
|
-
|
|
17761
|
+
function beginSession(context, state) {
|
|
17762
|
+
const resume = resumeSessionId(context);
|
|
17763
|
+
if (resume) {
|
|
17764
|
+
state.runtimeSessionId = resume;
|
|
17765
|
+
sessionOpId = request("session/load", {
|
|
17766
|
+
sessionId: resume,
|
|
17767
|
+
cwd: context.cwd,
|
|
17768
|
+
mcpServers: []
|
|
17769
|
+
});
|
|
17770
|
+
return;
|
|
17347
17771
|
}
|
|
17772
|
+
newSession(context);
|
|
17348
17773
|
}
|
|
17349
|
-
|
|
17350
|
-
|
|
17351
|
-
|
|
17352
|
-
|
|
17353
|
-
|
|
17354
|
-
|
|
17774
|
+
function sendPrompt(context, state) {
|
|
17775
|
+
const text = buildPromptWithImagePathReferences(context, imageFiles);
|
|
17776
|
+
promptId = request("session/prompt", {
|
|
17777
|
+
sessionId: state.runtimeSessionId,
|
|
17778
|
+
prompt: [{ type: "text", text }]
|
|
17779
|
+
});
|
|
17355
17780
|
}
|
|
17356
|
-
|
|
17357
|
-
|
|
17358
|
-
|
|
17359
|
-
|
|
17360
|
-
|
|
17361
|
-
|
|
17362
|
-
|
|
17363
|
-
|
|
17364
|
-
if (typeof value2 === "string" && value2.trim()) {
|
|
17365
|
-
state.runtimeSessionId = value2.trim();
|
|
17366
|
-
break;
|
|
17781
|
+
function finalize(state) {
|
|
17782
|
+
if (finalized) return;
|
|
17783
|
+
finalized = true;
|
|
17784
|
+
state.resultReceived = true;
|
|
17785
|
+
state.onResultReceived?.();
|
|
17786
|
+
try {
|
|
17787
|
+
stdin?.end();
|
|
17788
|
+
} catch {
|
|
17367
17789
|
}
|
|
17368
17790
|
}
|
|
17369
|
-
|
|
17370
|
-
|
|
17371
|
-
|
|
17372
|
-
|
|
17373
|
-
case "thought":
|
|
17374
|
-
case "thinking":
|
|
17375
|
-
case "reasoning": {
|
|
17376
|
-
const text = typeof parsed.data === "string" ? parsed.data : "";
|
|
17377
|
-
if (!text) return true;
|
|
17378
|
-
state.iterations = Math.max(state.iterations, 1);
|
|
17379
|
-
void presenter.onThinking(text);
|
|
17380
|
-
return true;
|
|
17791
|
+
function handleResponse(message, context, state) {
|
|
17792
|
+
if (message.error && message.id === sessionOpId && !attemptedNewSession) {
|
|
17793
|
+
newSession(context);
|
|
17794
|
+
return;
|
|
17381
17795
|
}
|
|
17382
|
-
|
|
17383
|
-
|
|
17384
|
-
|
|
17385
|
-
|
|
17386
|
-
|
|
17387
|
-
state.iterations = Math.max(state.iterations, 1);
|
|
17388
|
-
state.summary += text;
|
|
17389
|
-
void presenter.onAssistantText(text);
|
|
17390
|
-
return true;
|
|
17796
|
+
if (message.error) {
|
|
17797
|
+
state.error = message.error.message?.trim() || "Grok agent error";
|
|
17798
|
+
void context.presenter.onError(state.error);
|
|
17799
|
+
finalize(state);
|
|
17800
|
+
return;
|
|
17391
17801
|
}
|
|
17392
|
-
|
|
17393
|
-
|
|
17394
|
-
|
|
17395
|
-
|
|
17396
|
-
|
|
17397
|
-
|
|
17398
|
-
|
|
17399
|
-
const subtype = typeof parsed.subtype === "string" ? parsed.subtype : "";
|
|
17400
|
-
const status = typeof parsed.status === "string" ? parsed.status : "";
|
|
17401
|
-
state.iterations = Math.max(state.iterations, 1);
|
|
17402
|
-
if (subtype === "completed" || subtype === "result" || status === "completed" || status === "done" || parsed.result !== void 0 || parsed.output !== void 0) {
|
|
17403
|
-
void presenter.onToolResult?.(toolId, extractToolResultText(parsed));
|
|
17404
|
-
return true;
|
|
17405
|
-
}
|
|
17406
|
-
void presenter.onToolUse(toolName, toolArgs, toolId);
|
|
17407
|
-
return true;
|
|
17802
|
+
const result = asRecord(message.result);
|
|
17803
|
+
if (message.id === initId) {
|
|
17804
|
+
const modelState = asRecord(asRecord(result?._meta)?.modelState);
|
|
17805
|
+
const model = asString(modelState?.currentModelId);
|
|
17806
|
+
if (model) state.activeModel = model;
|
|
17807
|
+
beginSession(context, state);
|
|
17808
|
+
return;
|
|
17408
17809
|
}
|
|
17409
|
-
|
|
17410
|
-
|
|
17411
|
-
|
|
17810
|
+
if (message.id === sessionOpId) {
|
|
17811
|
+
const sessionId = asString(result?.sessionId);
|
|
17812
|
+
if (sessionId) state.runtimeSessionId = sessionId;
|
|
17412
17813
|
state.iterations = Math.max(state.iterations, 1);
|
|
17413
|
-
|
|
17414
|
-
return
|
|
17415
|
-
}
|
|
17416
|
-
case "error": {
|
|
17417
|
-
const message = typeof parsed.message === "string" && parsed.message.trim() ? parsed.message.trim() : typeof parsed.data === "string" && parsed.data.trim() ? parsed.data.trim() : "Grok Build run failed";
|
|
17418
|
-
state.error = message;
|
|
17419
|
-
void presenter.onError(message);
|
|
17420
|
-
state.resultReceived = true;
|
|
17421
|
-
state.onResultReceived?.();
|
|
17422
|
-
return true;
|
|
17814
|
+
sendPrompt(context, state);
|
|
17815
|
+
return;
|
|
17423
17816
|
}
|
|
17424
|
-
|
|
17425
|
-
|
|
17426
|
-
const
|
|
17817
|
+
if (message.id === promptId) {
|
|
17818
|
+
const meta = asRecord(result?._meta);
|
|
17819
|
+
const model = asString(meta?.modelId) || state.activeModel || (typeof context.config.selectedModel === "string" && context.config.selectedModel.trim() ? context.config.selectedModel.trim() : "grok");
|
|
17820
|
+
const inputTokens = typeof meta?.inputTokens === "number" ? meta.inputTokens : 0;
|
|
17821
|
+
const outputTokens = typeof meta?.outputTokens === "number" ? meta.outputTokens : 0;
|
|
17822
|
+
const cacheReadTokens = typeof meta?.cachedReadTokens === "number" ? meta.cachedReadTokens : 0;
|
|
17427
17823
|
state.iterations = Math.max(state.iterations, 1);
|
|
17428
17824
|
state.usage = {
|
|
17429
|
-
model
|
|
17825
|
+
model,
|
|
17430
17826
|
numTurns: Math.max(state.iterations, 1),
|
|
17431
|
-
durationMs:
|
|
17432
|
-
inputTokens
|
|
17433
|
-
outputTokens
|
|
17434
|
-
cacheReadTokens
|
|
17827
|
+
durationMs: 0,
|
|
17828
|
+
inputTokens,
|
|
17829
|
+
outputTokens,
|
|
17830
|
+
cacheReadTokens,
|
|
17435
17831
|
cacheCreationTokens: 0,
|
|
17436
17832
|
costUsd: 0
|
|
17437
17833
|
};
|
|
17438
|
-
void presenter.onUsageUpdate?.({
|
|
17439
|
-
model
|
|
17440
|
-
inputTokens
|
|
17441
|
-
outputTokens
|
|
17442
|
-
cacheReadTokens
|
|
17834
|
+
void context.presenter.onUsageUpdate?.({
|
|
17835
|
+
model,
|
|
17836
|
+
inputTokens,
|
|
17837
|
+
outputTokens,
|
|
17838
|
+
cacheReadTokens,
|
|
17443
17839
|
cacheCreationTokens: 0
|
|
17444
17840
|
});
|
|
17445
|
-
|
|
17841
|
+
const stopReason = asString(result?.stopReason).toLowerCase();
|
|
17842
|
+
if (stopReason.includes("error") && !state.error) {
|
|
17446
17843
|
state.error = "Grok Build run failed";
|
|
17447
|
-
void presenter.onError(state.error);
|
|
17844
|
+
void context.presenter.onError(state.error);
|
|
17448
17845
|
}
|
|
17449
|
-
state
|
|
17450
|
-
|
|
17451
|
-
|
|
17846
|
+
finalize(state);
|
|
17847
|
+
}
|
|
17848
|
+
}
|
|
17849
|
+
function handleServerRequest(message, context, _state) {
|
|
17850
|
+
const id = message.id;
|
|
17851
|
+
switch (message.method) {
|
|
17852
|
+
case "session/request_permission":
|
|
17853
|
+
respond(id, resolvePermission(message.params, context));
|
|
17854
|
+
return;
|
|
17855
|
+
case "fs/read_text_file":
|
|
17856
|
+
respond(id, { content: "" });
|
|
17857
|
+
return;
|
|
17858
|
+
default:
|
|
17859
|
+
respond(id, null);
|
|
17860
|
+
}
|
|
17861
|
+
}
|
|
17862
|
+
function handleNotification(message, context, state) {
|
|
17863
|
+
const params = asRecord(message.params);
|
|
17864
|
+
const update = asRecord(params?.update);
|
|
17865
|
+
if (!update) return;
|
|
17866
|
+
const presenter = context.presenter;
|
|
17867
|
+
switch (asString(update.sessionUpdate)) {
|
|
17868
|
+
case "agent_thought_chunk": {
|
|
17869
|
+
const text = chunkText(update.content);
|
|
17870
|
+
if (!text) return;
|
|
17871
|
+
state.iterations = Math.max(state.iterations, 1);
|
|
17872
|
+
void presenter.onThinking(text);
|
|
17873
|
+
return;
|
|
17874
|
+
}
|
|
17875
|
+
case "agent_message_chunk": {
|
|
17876
|
+
const text = chunkText(update.content);
|
|
17877
|
+
if (!text) return;
|
|
17878
|
+
state.iterations = Math.max(state.iterations, 1);
|
|
17879
|
+
state.summary += text;
|
|
17880
|
+
void presenter.onAssistantText(text);
|
|
17881
|
+
return;
|
|
17882
|
+
}
|
|
17883
|
+
case "tool_call": {
|
|
17884
|
+
const toolId = asString(update.toolCallId);
|
|
17885
|
+
const toolName = asString(update.title) || toolMetaName(update) || "Grok Tool";
|
|
17886
|
+
const input = update.rawInput ?? {};
|
|
17887
|
+
state.iterations = Math.max(state.iterations, 1);
|
|
17888
|
+
void presenter.onToolUse(toolName, input, toolId);
|
|
17889
|
+
return;
|
|
17890
|
+
}
|
|
17891
|
+
case "tool_call_update": {
|
|
17892
|
+
const status = asString(update.status).toLowerCase();
|
|
17893
|
+
if (status !== "completed" && status !== "failed" && status !== "error") return;
|
|
17894
|
+
const toolId = asString(update.toolCallId);
|
|
17895
|
+
void presenter.onToolResult?.(toolId, toolResultText(update));
|
|
17896
|
+
return;
|
|
17897
|
+
}
|
|
17898
|
+
default:
|
|
17899
|
+
return;
|
|
17452
17900
|
}
|
|
17453
|
-
default:
|
|
17454
|
-
return false;
|
|
17455
17901
|
}
|
|
17902
|
+
function handleLine(line, context, state) {
|
|
17903
|
+
if (!stdin && state.stdin) stdin = state.stdin;
|
|
17904
|
+
let parsed;
|
|
17905
|
+
try {
|
|
17906
|
+
parsed = JSON.parse(line);
|
|
17907
|
+
} catch {
|
|
17908
|
+
if (line.trim().length > 0) void context.presenter.onLog(`[grok_cli] ${line}`);
|
|
17909
|
+
return;
|
|
17910
|
+
}
|
|
17911
|
+
const message = asRecord(parsed);
|
|
17912
|
+
if (!message) return;
|
|
17913
|
+
if (message.id !== void 0 && message.method === void 0) {
|
|
17914
|
+
handleResponse(message, context, state);
|
|
17915
|
+
return;
|
|
17916
|
+
}
|
|
17917
|
+
if (message.method && message.id !== void 0) {
|
|
17918
|
+
handleServerRequest(message, context, state);
|
|
17919
|
+
return;
|
|
17920
|
+
}
|
|
17921
|
+
if (message.method) {
|
|
17922
|
+
handleNotification(message, context, state);
|
|
17923
|
+
}
|
|
17924
|
+
}
|
|
17925
|
+
function start(stdinStream, _context) {
|
|
17926
|
+
stdin = stdinStream;
|
|
17927
|
+
initId = request("initialize", {
|
|
17928
|
+
protocolVersion: ACP_PROTOCOL_VERSION,
|
|
17929
|
+
clientCapabilities: {
|
|
17930
|
+
fs: { readTextFile: false, writeTextFile: false },
|
|
17931
|
+
terminal: false
|
|
17932
|
+
}
|
|
17933
|
+
});
|
|
17934
|
+
}
|
|
17935
|
+
return { start, handleLine };
|
|
17456
17936
|
}
|
|
17457
|
-
var parseGrokStructuredLine = createStructuredLineParser(
|
|
17458
|
-
"grok_cli",
|
|
17459
|
-
handleGrokStructuredEvent
|
|
17460
|
-
);
|
|
17461
17937
|
function isGrokCliModelId(model) {
|
|
17462
17938
|
return model === "auto" || /^grok-/.test(model) || /^grok_/.test(model) || model.startsWith("grok-composer-");
|
|
17463
17939
|
}
|
|
17464
|
-
function resolveGrokPermissionMode(config) {
|
|
17465
|
-
if (shouldUseReadOnlyRuntimePermissions(config)) return "plan";
|
|
17466
|
-
switch (config.mode) {
|
|
17467
|
-
case "plan":
|
|
17468
|
-
case "review":
|
|
17469
|
-
return "plan";
|
|
17470
|
-
case "ask":
|
|
17471
|
-
return "dontAsk";
|
|
17472
|
-
default:
|
|
17473
|
-
return "bypassPermissions";
|
|
17474
|
-
}
|
|
17475
|
-
}
|
|
17476
17940
|
function createGrokCliBackend(command = "grok", defaultArgs = []) {
|
|
17477
17941
|
return {
|
|
17478
17942
|
kind: "grok_cli",
|
|
@@ -17482,34 +17946,17 @@ function createGrokCliBackend(command = "grok", defaultArgs = []) {
|
|
|
17482
17946
|
context.config.images,
|
|
17483
17947
|
context.cwd
|
|
17484
17948
|
);
|
|
17949
|
+
const driver = createGrokAcpDriver(imageFiles);
|
|
17485
17950
|
try {
|
|
17486
17951
|
return await createGenericCliBackend({
|
|
17487
17952
|
kind: "grok_cli",
|
|
17488
17953
|
supportTier: "structured",
|
|
17489
17954
|
command,
|
|
17490
17955
|
args: [],
|
|
17491
|
-
buildArgs: (ctx
|
|
17492
|
-
|
|
17493
|
-
|
|
17494
|
-
|
|
17495
|
-
"--output-format",
|
|
17496
|
-
"streaming-json",
|
|
17497
|
-
"--cwd",
|
|
17498
|
-
ctx.cwd,
|
|
17499
|
-
"--permission-mode",
|
|
17500
|
-
resolveGrokPermissionMode(ctx.config)
|
|
17501
|
-
];
|
|
17502
|
-
if (!shouldUseReadOnlyRuntimePermissions(ctx.config)) {
|
|
17503
|
-
args.push("--always-approve");
|
|
17504
|
-
}
|
|
17505
|
-
const resumeId = ctx.config.runtimeSessionId?.trim() || ctx.config.providerSessionId?.trim();
|
|
17506
|
-
if (resumeId) args.push("--resume", resumeId);
|
|
17507
|
-
const model = ctx.config.selectedModel?.trim();
|
|
17508
|
-
if (model && isGrokCliModelId(model)) args.push("--model", model);
|
|
17509
|
-
return [...args, ...defaultArgs];
|
|
17510
|
-
},
|
|
17511
|
-
augmentPrompt: (ctx) => buildPromptWithImagePathReferences(ctx, imageFiles),
|
|
17512
|
-
parseStructuredLine: parseGrokStructuredLine
|
|
17956
|
+
buildArgs: (ctx) => buildGrokAgentArgs(ctx.config, defaultArgs),
|
|
17957
|
+
keepStdinOpen: true,
|
|
17958
|
+
stdinWriter: (stdin, ctx) => driver.start(stdin, ctx),
|
|
17959
|
+
parseStructuredLine: driver.handleLine
|
|
17513
17960
|
}).run(context);
|
|
17514
17961
|
} finally {
|
|
17515
17962
|
cleanup();
|
|
@@ -17517,10 +17964,20 @@ function createGrokCliBackend(command = "grok", defaultArgs = []) {
|
|
|
17517
17964
|
}
|
|
17518
17965
|
};
|
|
17519
17966
|
}
|
|
17967
|
+
function buildGrokAgentArgs(config, defaultArgs = []) {
|
|
17968
|
+
const args = ["agent"];
|
|
17969
|
+
if (!shouldUseReadOnlyRuntimePermissions(config)) {
|
|
17970
|
+
args.push("--always-approve");
|
|
17971
|
+
}
|
|
17972
|
+
const model = config.selectedModel?.trim();
|
|
17973
|
+
if (model && isGrokCliModelId(model)) args.push("--model", model);
|
|
17974
|
+
args.push(...defaultArgs, "stdio");
|
|
17975
|
+
return args;
|
|
17976
|
+
}
|
|
17520
17977
|
var DEFAULT_SKILL_ROOTS = [
|
|
17521
|
-
(0,
|
|
17522
|
-
(0,
|
|
17523
|
-
(0,
|
|
17978
|
+
(0, import_path5.join)((0, import_os5.homedir)(), ".agents", "skills"),
|
|
17979
|
+
(0, import_path5.join)((0, import_os5.homedir)(), ".claude", "skills"),
|
|
17980
|
+
(0, import_path5.join)((0, import_os5.homedir)(), ".config", "opencode", "skills")
|
|
17524
17981
|
];
|
|
17525
17982
|
function parseFrontmatter(content) {
|
|
17526
17983
|
if (!content.startsWith("---\n")) return {};
|
|
@@ -17536,12 +17993,12 @@ function parseFrontmatter(content) {
|
|
|
17536
17993
|
return result;
|
|
17537
17994
|
}
|
|
17538
17995
|
function listSkillFiles(root) {
|
|
17539
|
-
if (!(0,
|
|
17996
|
+
if (!(0, import_fs5.existsSync)(root)) return [];
|
|
17540
17997
|
const files = [];
|
|
17541
|
-
for (const entry of (0,
|
|
17998
|
+
for (const entry of (0, import_fs5.readdirSync)(root, { withFileTypes: true })) {
|
|
17542
17999
|
if (!entry.isDirectory()) continue;
|
|
17543
|
-
const skillPath = (0,
|
|
17544
|
-
if ((0,
|
|
18000
|
+
const skillPath = (0, import_path5.join)(root, entry.name, "SKILL.md");
|
|
18001
|
+
if ((0, import_fs5.existsSync)(skillPath)) files.push(skillPath);
|
|
17545
18002
|
}
|
|
17546
18003
|
return files;
|
|
17547
18004
|
}
|
|
@@ -17550,7 +18007,7 @@ function loadInstalledSkills(roots = DEFAULT_SKILL_ROOTS) {
|
|
|
17550
18007
|
for (const root of roots) {
|
|
17551
18008
|
for (const skillPath of listSkillFiles(root)) {
|
|
17552
18009
|
try {
|
|
17553
|
-
const frontmatter = parseFrontmatter((0,
|
|
18010
|
+
const frontmatter = parseFrontmatter((0, import_fs5.readFileSync)(skillPath, "utf8"));
|
|
17554
18011
|
const name = frontmatter.name;
|
|
17555
18012
|
const description = frontmatter.description;
|
|
17556
18013
|
if (!name || !description || skills.has(name)) continue;
|
|
@@ -18047,40 +18504,40 @@ function parseSkillInvocation(text) {
|
|
|
18047
18504
|
function candidateRoots(cwd) {
|
|
18048
18505
|
const roots = [];
|
|
18049
18506
|
if (cwd) {
|
|
18050
|
-
roots.push((0,
|
|
18051
|
-
roots.push((0,
|
|
18052
|
-
roots.push((0,
|
|
18053
|
-
if ((0,
|
|
18507
|
+
roots.push((0, import_path6.join)(cwd, ".agents", "skills"));
|
|
18508
|
+
roots.push((0, import_path6.join)(cwd, ".claude", "skills"));
|
|
18509
|
+
roots.push((0, import_path6.join)(cwd, ".codex", "skills"));
|
|
18510
|
+
if ((0, import_fs6.existsSync)(cwd)) {
|
|
18054
18511
|
let entries = [];
|
|
18055
18512
|
try {
|
|
18056
|
-
entries = (0,
|
|
18513
|
+
entries = (0, import_fs6.readdirSync)(cwd, { withFileTypes: true });
|
|
18057
18514
|
} catch {
|
|
18058
18515
|
}
|
|
18059
18516
|
for (const entry of entries) {
|
|
18060
18517
|
if (!entry.isDirectory()) continue;
|
|
18061
18518
|
if (entry.name.startsWith(".")) continue;
|
|
18062
|
-
const child = (0,
|
|
18063
|
-
roots.push((0,
|
|
18064
|
-
roots.push((0,
|
|
18065
|
-
roots.push((0,
|
|
18519
|
+
const child = (0, import_path6.join)(cwd, entry.name);
|
|
18520
|
+
roots.push((0, import_path6.join)(child, ".agents", "skills"));
|
|
18521
|
+
roots.push((0, import_path6.join)(child, ".claude", "skills"));
|
|
18522
|
+
roots.push((0, import_path6.join)(child, ".codex", "skills"));
|
|
18066
18523
|
}
|
|
18067
18524
|
}
|
|
18068
18525
|
}
|
|
18069
|
-
const home = (0,
|
|
18070
|
-
roots.push((0,
|
|
18071
|
-
roots.push((0,
|
|
18072
|
-
roots.push((0,
|
|
18526
|
+
const home = (0, import_os6.homedir)();
|
|
18527
|
+
roots.push((0, import_path6.join)(home, ".agents", "skills"));
|
|
18528
|
+
roots.push((0, import_path6.join)(home, ".claude", "skills"));
|
|
18529
|
+
roots.push((0, import_path6.join)(home, ".codex", "skills"));
|
|
18073
18530
|
return Array.from(new Set(roots));
|
|
18074
18531
|
}
|
|
18075
18532
|
function resolveSkillInvocation(text, cwd) {
|
|
18076
18533
|
const parsed = parseSkillInvocation(text);
|
|
18077
18534
|
if (!parsed) return null;
|
|
18078
18535
|
for (const root of candidateRoots(cwd)) {
|
|
18079
|
-
const skillPath = (0,
|
|
18080
|
-
if (!(0,
|
|
18536
|
+
const skillPath = (0, import_path6.join)(root, parsed.command, "SKILL.md");
|
|
18537
|
+
if (!(0, import_fs6.existsSync)(skillPath)) continue;
|
|
18081
18538
|
let content;
|
|
18082
18539
|
try {
|
|
18083
|
-
content = (0,
|
|
18540
|
+
content = (0, import_fs6.readFileSync)(skillPath, "utf-8");
|
|
18084
18541
|
} catch {
|
|
18085
18542
|
continue;
|
|
18086
18543
|
}
|
|
@@ -18326,8 +18783,14 @@ Prefer relative paths and keep your work scoped to this project.`
|
|
|
18326
18783
|
}
|
|
18327
18784
|
const lifecyclePrompt = buildTaskLifecyclePrompt(config);
|
|
18328
18785
|
if (lifecyclePrompt) systemPromptParts.push(lifecyclePrompt);
|
|
18786
|
+
const teamId = config.teamId;
|
|
18787
|
+
const teamCodeOverlay = teamId ? buildAidenTeamCodeContextOverlay(teamId) : void 0;
|
|
18788
|
+
if (teamCodeOverlay) {
|
|
18789
|
+
systemPromptParts.push(teamCodeOverlay);
|
|
18790
|
+
}
|
|
18329
18791
|
const extra = this.buildExtraSystemPromptParts(config);
|
|
18330
18792
|
systemPromptParts.push(...extra);
|
|
18793
|
+
const mergedAppend = [config.systemPromptAppend?.trim(), teamCodeOverlay].filter((value2) => Boolean(value2 && value2.length > 0)).join("\n\n");
|
|
18331
18794
|
return {
|
|
18332
18795
|
...config,
|
|
18333
18796
|
backendKind,
|
|
@@ -18335,7 +18798,8 @@ Prefer relative paths and keep your work scoped to this project.`
|
|
|
18335
18798
|
runtimeCommand: config.runtimeCommand || this.runtime.runtimeCommand,
|
|
18336
18799
|
runtimeArgs: config.runtimeArgs || this.runtime.runtimeArgs,
|
|
18337
18800
|
selectedModel: config.selectedModel || defaultSelectedModelForBackend(backendKind),
|
|
18338
|
-
systemPrompt: systemPromptParts.join("\n\n") || void 0
|
|
18801
|
+
systemPrompt: systemPromptParts.join("\n\n") || void 0,
|
|
18802
|
+
systemPromptAppend: mergedAppend || void 0
|
|
18339
18803
|
};
|
|
18340
18804
|
}
|
|
18341
18805
|
async runCliBackend(config, safeProjectPath) {
|
|
@@ -18479,6 +18943,21 @@ Prefer relative paths and keep your work scoped to this project.`
|
|
|
18479
18943
|
this.presenter.onComplete(result);
|
|
18480
18944
|
return result;
|
|
18481
18945
|
}
|
|
18946
|
+
if (initialConfig.conversationId) {
|
|
18947
|
+
try {
|
|
18948
|
+
const writtenClis = syncAidenMcpSessionHeaders({
|
|
18949
|
+
conversationId: initialConfig.conversationId,
|
|
18950
|
+
teamId: initialConfig.teamId
|
|
18951
|
+
});
|
|
18952
|
+
if (writtenClis.length > 0) {
|
|
18953
|
+
void this.presenter.onLog(
|
|
18954
|
+
`Synced Aiden MCP session headers to ${writtenClis.join(", ")}`
|
|
18955
|
+
);
|
|
18956
|
+
}
|
|
18957
|
+
} catch (error) {
|
|
18958
|
+
console.warn("[base-machine-agent] Failed to sync MCP session headers", error);
|
|
18959
|
+
}
|
|
18960
|
+
}
|
|
18482
18961
|
try {
|
|
18483
18962
|
return await this.runCliBackend(initialConfig, safeProjectPath);
|
|
18484
18963
|
} catch (error) {
|
|
@@ -18520,8 +18999,8 @@ var MAX_SESSION_VIDEO_BYTES = 100 * 1024 * 1024;
|
|
|
18520
18999
|
function isRecord(value2) {
|
|
18521
19000
|
return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
|
|
18522
19001
|
}
|
|
18523
|
-
function shouldExtractGeneratedImagesFromToolResult(toolName,
|
|
18524
|
-
return isGeneratedImageToolName(toolName)
|
|
19002
|
+
function shouldExtractGeneratedImagesFromToolResult(toolName, _content, _options = {}) {
|
|
19003
|
+
return isGeneratedImageToolName(toolName);
|
|
18525
19004
|
}
|
|
18526
19005
|
function collectStringValues(value2, out) {
|
|
18527
19006
|
if (typeof value2 === "string") {
|
|
@@ -18585,14 +19064,14 @@ function normalizePath(candidate, cwd) {
|
|
|
18585
19064
|
} catch {
|
|
18586
19065
|
}
|
|
18587
19066
|
if (path.startsWith("~/")) return null;
|
|
18588
|
-
if ((0,
|
|
18589
|
-
return cwd ? (0,
|
|
19067
|
+
if ((0, import_path7.isAbsolute)(path)) return path;
|
|
19068
|
+
return cwd ? (0, import_path7.join)(cwd, path) : null;
|
|
18590
19069
|
}
|
|
18591
19070
|
function resolveToolCwd(cwd, toolInput) {
|
|
18592
19071
|
if (!isRecord(toolInput)) return cwd;
|
|
18593
19072
|
const raw = typeof toolInput.cwd === "string" ? toolInput.cwd : typeof toolInput.workdir === "string" ? toolInput.workdir : typeof toolInput.workingDirectory === "string" ? toolInput.workingDirectory : null;
|
|
18594
19073
|
if (!raw) return cwd;
|
|
18595
|
-
return (0,
|
|
19074
|
+
return (0, import_path7.isAbsolute)(raw) || !cwd ? raw : (0, import_path7.join)(cwd, raw);
|
|
18596
19075
|
}
|
|
18597
19076
|
function extractBrowserMediaPathHints(content, cwd, toolName, options = {}, kind = "video") {
|
|
18598
19077
|
if (!isAgentBrowserMediaInvocation(toolName, content, options.toolInput, kind)) return [];
|
|
@@ -18635,19 +19114,19 @@ function extractGeneratedImagesFromToolResult(toolId, content, cwd, toolName, op
|
|
|
18635
19114
|
const effectiveCwd = resolveToolCwd(cwd, options.toolInput);
|
|
18636
19115
|
for (const candidate of extractPathCandidates(content, options)) {
|
|
18637
19116
|
const path = normalizePath(candidate, effectiveCwd);
|
|
18638
|
-
if (!path || seen.has(path) || !(0,
|
|
19117
|
+
if (!path || seen.has(path) || !(0, import_fs7.existsSync)(path)) continue;
|
|
18639
19118
|
seen.add(path);
|
|
18640
|
-
const ext = (0,
|
|
19119
|
+
const ext = (0, import_path7.extname)(path).toLowerCase();
|
|
18641
19120
|
const mimeType = IMAGE_MIME_BY_EXT[ext];
|
|
18642
19121
|
if (!mimeType) continue;
|
|
18643
|
-
const stat = (0,
|
|
19122
|
+
const stat = (0, import_fs7.statSync)(path);
|
|
18644
19123
|
if (!stat.isFile() || stat.size <= 0 || stat.size > MAX_GENERATED_IMAGE_BYTES) continue;
|
|
18645
|
-
const buffer = (0,
|
|
19124
|
+
const buffer = (0, import_fs7.readFileSync)(path);
|
|
18646
19125
|
const { width, height } = readImageDimensions2(buffer, mimeType);
|
|
18647
19126
|
images.push({
|
|
18648
19127
|
type: "generated_image",
|
|
18649
19128
|
id: (0, import_crypto2.randomUUID)(),
|
|
18650
|
-
filename: (0,
|
|
19129
|
+
filename: (0, import_path7.basename)(path),
|
|
18651
19130
|
mimeType,
|
|
18652
19131
|
size: buffer.length,
|
|
18653
19132
|
width,
|
|
@@ -18662,27 +19141,36 @@ function extractGeneratedImagesFromToolResult(toolId, content, cwd, toolName, op
|
|
|
18662
19141
|
return images;
|
|
18663
19142
|
}
|
|
18664
19143
|
function extractSessionMediaFromToolResult(toolId, content, cwd, toolName, options = {}) {
|
|
18665
|
-
|
|
19144
|
+
const isImage = isAgentBrowserMediaInvocation(toolName, content, options.toolInput, "image");
|
|
19145
|
+
const isVideo = isAgentBrowserMediaInvocation(toolName, content, options.toolInput, "video");
|
|
19146
|
+
if (!isImage && !isVideo) return [];
|
|
18666
19147
|
const media = [];
|
|
18667
19148
|
const seen = /* @__PURE__ */ new Set();
|
|
18668
19149
|
const effectiveCwd = resolveToolCwd(cwd, options.toolInput);
|
|
18669
|
-
|
|
19150
|
+
const kind = isVideo ? "video" : "image";
|
|
19151
|
+
const extensionsPattern = kind === "video" ? "mp4|webm|mov" : "png|jpe?g|gif|webp";
|
|
19152
|
+
const maxBytes = kind === "video" ? MAX_SESSION_VIDEO_BYTES : MAX_GENERATED_IMAGE_BYTES;
|
|
19153
|
+
const mimeByExt = kind === "video" ? VIDEO_MIME_BY_EXT : IMAGE_MIME_BY_EXT;
|
|
19154
|
+
for (const candidate of extractPathCandidates(content, options, extensionsPattern)) {
|
|
18670
19155
|
const path = normalizePath(candidate, effectiveCwd);
|
|
18671
|
-
if (!path || seen.has(path) || !(0,
|
|
19156
|
+
if (!path || seen.has(path) || !(0, import_fs7.existsSync)(path)) continue;
|
|
18672
19157
|
seen.add(path);
|
|
18673
|
-
const ext = (0,
|
|
18674
|
-
const mimeType =
|
|
19158
|
+
const ext = (0, import_path7.extname)(path).toLowerCase();
|
|
19159
|
+
const mimeType = mimeByExt[ext];
|
|
18675
19160
|
if (!mimeType) continue;
|
|
18676
|
-
const stat = (0,
|
|
18677
|
-
if (!stat.isFile() || stat.size <= 0 || stat.size >
|
|
18678
|
-
const buffer = (0,
|
|
19161
|
+
const stat = (0, import_fs7.statSync)(path);
|
|
19162
|
+
if (!stat.isFile() || stat.size <= 0 || stat.size > maxBytes) continue;
|
|
19163
|
+
const buffer = (0, import_fs7.readFileSync)(path);
|
|
19164
|
+
const dimensions = kind === "image" ? readImageDimensions2(buffer, mimeType) : null;
|
|
18679
19165
|
media.push({
|
|
18680
19166
|
type: "session_media",
|
|
18681
|
-
kind
|
|
19167
|
+
kind,
|
|
18682
19168
|
id: (0, import_crypto2.randomUUID)(),
|
|
18683
|
-
filename: (0,
|
|
19169
|
+
filename: (0, import_path7.basename)(path),
|
|
18684
19170
|
mimeType,
|
|
18685
19171
|
size: buffer.length,
|
|
19172
|
+
width: dimensions?.width,
|
|
19173
|
+
height: dimensions?.height,
|
|
18686
19174
|
data: buffer.toString("base64"),
|
|
18687
19175
|
sourcePath: path,
|
|
18688
19176
|
sourceHash: (0, import_crypto2.createHash)("sha256").update(buffer).digest("hex"),
|
|
@@ -18932,7 +19420,7 @@ ${meta.description}`);
|
|
|
18932
19420
|
const workflowId = config.workflowId ?? process.env.AIDEN_WORKFLOW_ID;
|
|
18933
19421
|
const workflowExecutionId = config.workflowExecutionId ?? process.env.AIDEN_WORKFLOW_EXECUTION_ID;
|
|
18934
19422
|
const conversationId = config.conversationId ?? process.env.AIDEN_SESSION_ID;
|
|
18935
|
-
const teamId = config.teamId;
|
|
19423
|
+
const teamId = config.teamId ?? process.env.AIDEN_TEAM_ID;
|
|
18936
19424
|
const artifactIds = [];
|
|
18937
19425
|
if (teamId) artifactIds.push(`- teamId: "${teamId}"`);
|
|
18938
19426
|
const isWorkflowSession = !!(workflowId || workflowExecutionId);
|
|
@@ -18970,11 +19458,6 @@ ${meta.description}`);
|
|
|
18970
19458
|
].join("\n")
|
|
18971
19459
|
);
|
|
18972
19460
|
}
|
|
18973
|
-
if (teamId) {
|
|
18974
|
-
parts2.push(
|
|
18975
|
-
`You are operating within team \`${teamId}\`. Always use this as the \`teamId\` for all MCP tool calls that accept it (list_tasks, search, start_task_session, etc.). Do not call list_teams.`
|
|
18976
|
-
);
|
|
18977
|
-
}
|
|
18978
19461
|
return parts2;
|
|
18979
19462
|
}
|
|
18980
19463
|
};
|
|
@@ -19163,20 +19646,40 @@ function extractModelIdsFromJson(value2) {
|
|
|
19163
19646
|
}
|
|
19164
19647
|
return [];
|
|
19165
19648
|
}
|
|
19166
|
-
function
|
|
19649
|
+
function normalizeCodexReasoningEffort(effort) {
|
|
19650
|
+
const normalized = effort.trim().toLowerCase();
|
|
19651
|
+
if (!normalized) return null;
|
|
19652
|
+
if (normalized === "none") return "minimal";
|
|
19653
|
+
if (normalized === "minimal" || normalized === "low" || normalized === "medium" || normalized === "high" || normalized === "xhigh" || normalized === "max" || normalized === "ultra") {
|
|
19654
|
+
return normalized;
|
|
19655
|
+
}
|
|
19656
|
+
return null;
|
|
19657
|
+
}
|
|
19658
|
+
function extractCodexDiscoveredModelIdsFromDebugJson(value2) {
|
|
19167
19659
|
if (!value2 || typeof value2 !== "object") return [];
|
|
19168
19660
|
const models = value2.models;
|
|
19169
19661
|
if (!Array.isArray(models)) return [];
|
|
19170
|
-
const
|
|
19662
|
+
const ids = [];
|
|
19171
19663
|
for (const entry of models) {
|
|
19172
19664
|
if (!entry || typeof entry !== "object") continue;
|
|
19173
19665
|
const record = entry;
|
|
19174
19666
|
const visibility = typeof record.visibility === "string" ? record.visibility.toLowerCase() : "list";
|
|
19175
19667
|
if (visibility === "hidden" || visibility === "hide") continue;
|
|
19176
19668
|
const slug = readModelId(record.slug);
|
|
19177
|
-
if (slug)
|
|
19669
|
+
if (!slug) continue;
|
|
19670
|
+
const reasoningLevels = record.supported_reasoning_levels;
|
|
19671
|
+
if (Array.isArray(reasoningLevels) && reasoningLevels.length > 0) {
|
|
19672
|
+
for (const levelEntry of reasoningLevels) {
|
|
19673
|
+
if (!levelEntry || typeof levelEntry !== "object") continue;
|
|
19674
|
+
const effort = typeof levelEntry.effort === "string" ? levelEntry.effort : null;
|
|
19675
|
+
const normalized = effort ? normalizeCodexReasoningEffort(effort) : null;
|
|
19676
|
+
if (normalized) ids.push(`${slug}-${normalized}`);
|
|
19677
|
+
}
|
|
19678
|
+
continue;
|
|
19679
|
+
}
|
|
19680
|
+
ids.push(slug);
|
|
19178
19681
|
}
|
|
19179
|
-
return [...new Set(
|
|
19682
|
+
return [...new Set(ids)];
|
|
19180
19683
|
}
|
|
19181
19684
|
function extractModelIdsFromText(value2) {
|
|
19182
19685
|
const ansiPattern = new RegExp(`${String.fromCharCode(27)}\\[[0-9;]*m`, "g");
|
|
@@ -19267,8 +19770,8 @@ async function probeJsonOrTextModels(executable, env, argSets, options) {
|
|
|
19267
19770
|
if (!result || result.error || result.status !== 0 || !result.stdout.trim()) continue;
|
|
19268
19771
|
try {
|
|
19269
19772
|
const parsed = JSON.parse(result.stdout);
|
|
19270
|
-
const
|
|
19271
|
-
if (
|
|
19773
|
+
const codexModels = extractCodexDiscoveredModelIdsFromDebugJson(parsed);
|
|
19774
|
+
if (codexModels.length > 0) return codexModels;
|
|
19272
19775
|
const models = extractModelIdsFromJson(parsed);
|
|
19273
19776
|
if (models.length > 0) return models;
|
|
19274
19777
|
} catch {
|
|
@@ -19349,7 +19852,7 @@ async function discoverProviderModels(provider, executable, env) {
|
|
|
19349
19852
|
}
|
|
19350
19853
|
|
|
19351
19854
|
// src/version.ts
|
|
19352
|
-
var AGENT_VERSION = "0.1.
|
|
19855
|
+
var AGENT_VERSION = "0.1.33";
|
|
19353
19856
|
|
|
19354
19857
|
// src/daemon.ts
|
|
19355
19858
|
var STAGING_API_URL = process.env.AIDEN_STAGING_API_URL ?? "https://api.staging.aiden-platform.com";
|
|
@@ -19609,7 +20112,14 @@ function readEndpointDefaults() {
|
|
|
19609
20112
|
function writeConfig(config) {
|
|
19610
20113
|
const configPath = getConfigPath();
|
|
19611
20114
|
(0, import_node_fs7.mkdirSync)((0, import_node_path5.dirname)(configPath), { recursive: true, mode: 448 });
|
|
19612
|
-
(0,
|
|
20115
|
+
const pendingPath = `${configPath}.pending-${process.pid}-${(0, import_node_crypto.randomBytes)(6).toString("hex")}`;
|
|
20116
|
+
try {
|
|
20117
|
+
(0, import_node_fs7.writeFileSync)(pendingPath, JSON.stringify(config, null, 2), { mode: 384 });
|
|
20118
|
+
(0, import_node_fs7.chmodSync)(pendingPath, 384);
|
|
20119
|
+
(0, import_node_fs7.renameSync)(pendingPath, configPath);
|
|
20120
|
+
} finally {
|
|
20121
|
+
(0, import_node_fs7.rmSync)(pendingPath, { force: true });
|
|
20122
|
+
}
|
|
19613
20123
|
}
|
|
19614
20124
|
function removeConfig() {
|
|
19615
20125
|
const configPath = getConfigPath();
|
|
@@ -20329,6 +20839,7 @@ async function startDaemon(args) {
|
|
|
20329
20839
|
}
|
|
20330
20840
|
const activeAgents = /* @__PURE__ */ new Map();
|
|
20331
20841
|
let disconnectedSinceMs = null;
|
|
20842
|
+
let lastConnectError = null;
|
|
20332
20843
|
const pendingDeliveryLost = [];
|
|
20333
20844
|
const currentCapabilities = () => discoverCapabilities();
|
|
20334
20845
|
const currentMetadata = () => collectRuntimeMetadataWithProviderLimits();
|
|
@@ -20397,6 +20908,7 @@ async function startDaemon(args) {
|
|
|
20397
20908
|
}, VERSION_REFRESH_INTERVAL_MS);
|
|
20398
20909
|
socket.on("connect", () => {
|
|
20399
20910
|
disconnectedSinceMs = null;
|
|
20911
|
+
lastConnectError = null;
|
|
20400
20912
|
setConnectedRuntimeSocket(socket);
|
|
20401
20913
|
pushLog(`connected runtime=${runtimeId}`);
|
|
20402
20914
|
console.info("[aiden-agent] Daemon connected", { runtimeId, wsUrl, version: AGENT_VERSION });
|
|
@@ -20434,6 +20946,7 @@ async function startDaemon(args) {
|
|
|
20434
20946
|
let lastConnectErrorLogAt = 0;
|
|
20435
20947
|
socket.on("connect_error", (error) => {
|
|
20436
20948
|
if (!socket.connected && disconnectedSinceMs === null) disconnectedSinceMs = Date.now();
|
|
20949
|
+
lastConnectError = error.message;
|
|
20437
20950
|
pushLog(`connect_error ${error.message}`);
|
|
20438
20951
|
const now = Date.now();
|
|
20439
20952
|
if (now - lastConnectErrorLogAt < 5e3) return;
|
|
@@ -20801,6 +21314,7 @@ async function startDaemon(args) {
|
|
|
20801
21314
|
staleRunCount: runnerSummary.staleRunCount,
|
|
20802
21315
|
lastRunActivityAtMs: runnerSummary.lastRunActivityAtMs,
|
|
20803
21316
|
disconnectedSinceMs: runnerSummary.disconnectedSinceMs,
|
|
21317
|
+
lastConnectError,
|
|
20804
21318
|
daemonSessionId,
|
|
20805
21319
|
heartbeatSeq,
|
|
20806
21320
|
endpointProfile,
|