@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.
Files changed (86) hide show
  1. package/dist/__tests__/cli-executable.test.d.ts +2 -0
  2. package/dist/__tests__/cli-executable.test.d.ts.map +1 -0
  3. package/dist/__tests__/cli-executable.test.js +83 -0
  4. package/dist/__tests__/cli-executable.test.js.map +1 -0
  5. package/dist/__tests__/cli-help.test.d.ts +2 -0
  6. package/dist/__tests__/cli-help.test.d.ts.map +1 -0
  7. package/dist/__tests__/cli-help.test.js +33 -0
  8. package/dist/__tests__/cli-help.test.js.map +1 -0
  9. package/dist/__tests__/core-agent-workflow-context.test.d.ts +2 -0
  10. package/dist/__tests__/core-agent-workflow-context.test.d.ts.map +1 -0
  11. package/dist/__tests__/core-agent-workflow-context.test.js +50 -0
  12. package/dist/__tests__/core-agent-workflow-context.test.js.map +1 -0
  13. package/dist/__tests__/daemon-socket.integration.test.d.ts +2 -0
  14. package/dist/__tests__/daemon-socket.integration.test.d.ts.map +1 -0
  15. package/dist/__tests__/daemon-socket.integration.test.js +156 -0
  16. package/dist/__tests__/daemon-socket.integration.test.js.map +1 -0
  17. package/dist/__tests__/daemon.test.d.ts +2 -0
  18. package/dist/__tests__/daemon.test.d.ts.map +1 -0
  19. package/dist/__tests__/daemon.test.js +1014 -0
  20. package/dist/__tests__/daemon.test.js.map +1 -0
  21. package/dist/__tests__/generated-images.test.d.ts +2 -0
  22. package/dist/__tests__/generated-images.test.d.ts.map +1 -0
  23. package/dist/__tests__/generated-images.test.js +50 -0
  24. package/dist/__tests__/generated-images.test.js.map +1 -0
  25. package/dist/__tests__/sandbox-workflow-context.test.d.ts +2 -0
  26. package/dist/__tests__/sandbox-workflow-context.test.d.ts.map +1 -0
  27. package/dist/__tests__/sandbox-workflow-context.test.js +66 -0
  28. package/dist/__tests__/sandbox-workflow-context.test.js.map +1 -0
  29. package/dist/aiden-system-prompt.d.ts +6 -0
  30. package/dist/aiden-system-prompt.d.ts.map +1 -0
  31. package/dist/aiden-system-prompt.js +6 -0
  32. package/dist/aiden-system-prompt.js.map +1 -0
  33. package/dist/cli-executable.d.ts +58 -0
  34. package/dist/cli-executable.d.ts.map +1 -0
  35. package/dist/cli-executable.js +301 -0
  36. package/dist/cli-executable.js.map +1 -0
  37. package/dist/cli-help.d.ts +7 -0
  38. package/dist/cli-help.d.ts.map +1 -0
  39. package/dist/cli-help.js +45 -0
  40. package/dist/cli-help.js.map +1 -0
  41. package/dist/core-agent.d.ts +37 -0
  42. package/dist/core-agent.d.ts.map +1 -0
  43. package/dist/core-agent.js +337 -0
  44. package/dist/core-agent.js.map +1 -0
  45. package/dist/daemon.d.ts +46 -0
  46. package/dist/daemon.d.ts.map +1 -0
  47. package/dist/daemon.js +876 -0
  48. package/dist/daemon.js.map +1 -0
  49. package/dist/generated-images.d.ts +4 -0
  50. package/dist/generated-images.d.ts.map +1 -0
  51. package/dist/generated-images.js +142 -0
  52. package/dist/generated-images.js.map +1 -0
  53. package/dist/index.cjs +770 -256
  54. package/dist/index.d.ts +6 -0
  55. package/dist/index.d.ts.map +1 -0
  56. package/dist/index.js +118 -0
  57. package/dist/index.js.map +1 -0
  58. package/dist/runtime-backends.d.ts +2 -0
  59. package/dist/runtime-backends.d.ts.map +1 -0
  60. package/dist/runtime-backends.js +2 -0
  61. package/dist/runtime-backends.js.map +1 -0
  62. package/dist/sandbox.d.ts +31 -0
  63. package/dist/sandbox.d.ts.map +1 -0
  64. package/dist/sandbox.js +215 -0
  65. package/dist/sandbox.js.map +1 -0
  66. package/dist/types.d.ts +6 -0
  67. package/dist/types.d.ts.map +1 -0
  68. package/dist/types.js +6 -0
  69. package/dist/types.js.map +1 -0
  70. package/dist/updater.d.ts +15 -0
  71. package/dist/updater.d.ts.map +1 -0
  72. package/dist/updater.js +50 -0
  73. package/dist/updater.js.map +1 -0
  74. package/dist/version.d.ts +2 -0
  75. package/dist/version.d.ts.map +1 -0
  76. package/dist/version.js +2 -0
  77. package/dist/version.js.map +1 -0
  78. package/dist/web-presenter.d.ts +36 -0
  79. package/dist/web-presenter.d.ts.map +1 -0
  80. package/dist/web-presenter.js +125 -0
  81. package/dist/web-presenter.js.map +1 -0
  82. package/dist/ws-client.d.ts +114 -0
  83. package/dist/ws-client.d.ts.map +1 -0
  84. package/dist/ws-client.js +97 -0
  85. package/dist/ws-client.js.map +1 -0
  86. 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-dev.json";
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. Clarify only when the request has multiple plausible meanings.
13479
- 3. Keep responses concise, concrete, and tied to the user's next step.
13480
- 4. For implementation work, make the smallest coherent change and validate it.
13481
- 5. For plans, PRDs, reviews, and test reports, use structured Aiden artifacts when task context exists.
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
- - \`Read\`, \`Glob\`, \`Grep\` \u2014 understand the codebase before touching it
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 Array.from(merged);
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, import_path2.join)(cwd, ".aiden-images-") : null,
14965
- (0, import_path2.join)((0, import_os2.tmpdir)(), "aiden-images-")
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, import_fs2.mkdtempSync)(candidate);
15316
+ return (0, import_fs3.mkdtempSync)(candidate);
14970
15317
  } catch {
14971
15318
  }
14972
15319
  }
14973
- return (0, import_fs2.mkdtempSync)((0, import_path2.join)((0, import_os2.tmpdir)(), "aiden-images-"));
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, import_path2.join)(directory, `aiden-img-${img.id}.${ext}`);
14988
- (0, import_fs2.writeFileSync)(filePath, Buffer.from(img.data, "base64"));
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, import_fs2.rmSync)(directory, { recursive: true, force: true });
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, import_path2.join)(directory, `${file.id}-${safeFilename(file.filename)}`);
15030
- (0, import_fs2.writeFileSync)(filePath, Buffer.from(file.data, "base64"));
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, import_fs2.rmSync)(directory, { recursive: true, force: true });
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
- if (context.config.systemPrompt?.trim()) {
16338
- args.push("--system-prompt", context.config.systemPrompt.trim());
16339
- }
16340
- if (context.config.systemPromptAppend?.trim()) {
16341
- args.push("--append-system-prompt", context.config.systemPromptAppend.trim());
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, import_fs3.existsSync)(codexHome)) return null;
16428
- const root = (0, import_path3.join)(codexHome, "sessions");
16429
- if (!(0, import_fs3.existsSync)(root)) return null;
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, import_fs3.readdirSync)(dir, { withFileTypes: true });
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, import_path3.join)(dir, entry.name);
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, import_fs3.statSync)(path).mtimeMs });
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, import_path3.join)((0, import_os3.homedir)(), ".codex");
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, import_fs3.readFileSync)(logPath, "utf8").split(/\r?\n/).filter(Boolean);
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) => buildPromptWithImagePathReferences(ctx, imageFiles),
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 extractToolName2(parsed) {
17312
- for (const key of ["toolName", "name", "tool", "tool_name"]) {
17313
- const value2 = parsed[key];
17314
- if (typeof value2 === "string" && value2.trim()) return value2.trim();
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 toolCall = asRecord(parsed.toolCall) ?? asRecord(parsed.tool_call);
17317
- if (toolCall) {
17318
- for (const key of ["name", "toolName", "tool"]) {
17319
- const value2 = toolCall[key];
17320
- if (typeof value2 === "string" && value2.trim()) return value2.trim();
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
- return "Grok Tool";
17324
- }
17325
- function extractToolId2(parsed, fallback) {
17326
- for (const key of ["toolCallId", "callId", "call_id", "id"]) {
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
- const toolCall = asRecord(parsed.toolCall) ?? asRecord(parsed.tool_call);
17331
- if (toolCall) {
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
- return fallback;
17338
- }
17339
- function extractToolArgs(parsed) {
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
- const toolCall = asRecord(parsed.toolCall) ?? asRecord(parsed.tool_call);
17344
- if (toolCall) {
17345
- for (const key of ["args", "arguments", "input", "params"]) {
17346
- if (toolCall[key] !== void 0) return toolCall[key];
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
- return parsed;
17350
- }
17351
- function extractToolResultText(parsed) {
17352
- for (const key of ["result", "output", "content", "data", "message"]) {
17353
- const value2 = parsed[key];
17354
- if (typeof value2 === "string" && value2.trim()) return value2;
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
- return JSON.stringify(parsed, null, 2);
17357
- }
17358
- function handleGrokStructuredEvent(parsed, context, state) {
17359
- const presenter = context.presenter;
17360
- const type = typeof parsed.type === "string" ? parsed.type : "";
17361
- if (!type) return false;
17362
- for (const key of ["sessionId", "session_id"]) {
17363
- const value2 = parsed[key];
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
- if (typeof parsed.model === "string" && parsed.model.trim()) {
17370
- state.activeModel = parsed.model.trim();
17371
- }
17372
- switch (type) {
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
- case "text":
17383
- case "assistant":
17384
- case "message": {
17385
- const text = typeof parsed.data === "string" ? parsed.data : typeof parsed.text === "string" ? parsed.text : typeof parsed.content === "string" ? parsed.content : "";
17386
- if (!text) return true;
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
- case "tool":
17393
- case "tool_call":
17394
- case "tool_use":
17395
- case "toolCall": {
17396
- const toolId = extractToolId2(parsed, `grok-tool-${Date.now()}`);
17397
- const toolName = extractToolName2(parsed);
17398
- const toolArgs = extractToolArgs(parsed);
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
- case "tool_result":
17410
- case "toolResult": {
17411
- const toolId = extractToolId2(parsed, `grok-tool-${Date.now()}`);
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
- void presenter.onToolResult?.(toolId, extractToolResultText(parsed));
17414
- return true;
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
- case "end":
17425
- case "result": {
17426
- const stopReason = typeof parsed.stopReason === "string" ? parsed.stopReason : "";
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: state.activeModel || (typeof context.config.selectedModel === "string" && context.config.selectedModel.trim() ? context.config.selectedModel : "grok"),
17825
+ model,
17430
17826
  numTurns: Math.max(state.iterations, 1),
17431
- durationMs: typeof parsed.duration_ms === "number" ? parsed.duration_ms : 0,
17432
- inputTokens: 0,
17433
- outputTokens: 0,
17434
- cacheReadTokens: 0,
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: state.usage.model,
17440
- inputTokens: 0,
17441
- outputTokens: 0,
17442
- cacheReadTokens: 0,
17834
+ void context.presenter.onUsageUpdate?.({
17835
+ model,
17836
+ inputTokens,
17837
+ outputTokens,
17838
+ cacheReadTokens,
17443
17839
  cacheCreationTokens: 0
17444
17840
  });
17445
- if ((stopReason.toLowerCase().includes("error") || parsed.is_error === true) && !state.error) {
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.resultReceived = true;
17450
- state.onResultReceived?.();
17451
- return true;
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, prompt) => {
17492
- const args = [
17493
- "-p",
17494
- prompt,
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, import_path4.join)((0, import_os4.homedir)(), ".agents", "skills"),
17522
- (0, import_path4.join)((0, import_os4.homedir)(), ".claude", "skills"),
17523
- (0, import_path4.join)((0, import_os4.homedir)(), ".config", "opencode", "skills")
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, import_fs4.existsSync)(root)) return [];
17996
+ if (!(0, import_fs5.existsSync)(root)) return [];
17540
17997
  const files = [];
17541
- for (const entry of (0, import_fs4.readdirSync)(root, { withFileTypes: true })) {
17998
+ for (const entry of (0, import_fs5.readdirSync)(root, { withFileTypes: true })) {
17542
17999
  if (!entry.isDirectory()) continue;
17543
- const skillPath = (0, import_path4.join)(root, entry.name, "SKILL.md");
17544
- if ((0, import_fs4.existsSync)(skillPath)) files.push(skillPath);
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, import_fs4.readFileSync)(skillPath, "utf8"));
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, import_path5.join)(cwd, ".agents", "skills"));
18051
- roots.push((0, import_path5.join)(cwd, ".claude", "skills"));
18052
- roots.push((0, import_path5.join)(cwd, ".codex", "skills"));
18053
- if ((0, import_fs5.existsSync)(cwd)) {
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, import_fs5.readdirSync)(cwd, { withFileTypes: true });
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, import_path5.join)(cwd, entry.name);
18063
- roots.push((0, import_path5.join)(child, ".agents", "skills"));
18064
- roots.push((0, import_path5.join)(child, ".claude", "skills"));
18065
- roots.push((0, import_path5.join)(child, ".codex", "skills"));
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, import_os5.homedir)();
18070
- roots.push((0, import_path5.join)(home, ".agents", "skills"));
18071
- roots.push((0, import_path5.join)(home, ".claude", "skills"));
18072
- roots.push((0, import_path5.join)(home, ".codex", "skills"));
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, import_path5.join)(root, parsed.command, "SKILL.md");
18080
- if (!(0, import_fs5.existsSync)(skillPath)) continue;
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, import_fs5.readFileSync)(skillPath, "utf-8");
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, content, options = {}) {
18524
- return isGeneratedImageToolName(toolName) || isBrowserScreenshotToolName(toolName) || isAgentBrowserMediaInvocation(toolName, content, options.toolInput, "image");
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, import_path6.isAbsolute)(path)) return path;
18589
- return cwd ? (0, import_path6.join)(cwd, path) : null;
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, import_path6.isAbsolute)(raw) || !cwd ? raw : (0, import_path6.join)(cwd, raw);
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, import_fs6.existsSync)(path)) continue;
19117
+ if (!path || seen.has(path) || !(0, import_fs7.existsSync)(path)) continue;
18639
19118
  seen.add(path);
18640
- const ext = (0, import_path6.extname)(path).toLowerCase();
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, import_fs6.statSync)(path);
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, import_fs6.readFileSync)(path);
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, import_path6.basename)(path),
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
- if (!isAgentBrowserMediaInvocation(toolName, content, options.toolInput, "video")) return [];
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
- for (const candidate of extractPathCandidates(content, options, "mp4|webm|mov")) {
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, import_fs6.existsSync)(path)) continue;
19156
+ if (!path || seen.has(path) || !(0, import_fs7.existsSync)(path)) continue;
18672
19157
  seen.add(path);
18673
- const ext = (0, import_path6.extname)(path).toLowerCase();
18674
- const mimeType = VIDEO_MIME_BY_EXT[ext];
19158
+ const ext = (0, import_path7.extname)(path).toLowerCase();
19159
+ const mimeType = mimeByExt[ext];
18675
19160
  if (!mimeType) continue;
18676
- const stat = (0, import_fs6.statSync)(path);
18677
- if (!stat.isFile() || stat.size <= 0 || stat.size > MAX_SESSION_VIDEO_BYTES) continue;
18678
- const buffer = (0, import_fs6.readFileSync)(path);
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: "video",
19167
+ kind,
18682
19168
  id: (0, import_crypto2.randomUUID)(),
18683
- filename: (0, import_path6.basename)(path),
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 extractCodexModelSlugsFromDebugJson(value2) {
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 slugs = [];
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) slugs.push(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(slugs)];
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 codexSlugs = extractCodexModelSlugsFromDebugJson(parsed);
19271
- if (codexSlugs.length > 0) return codexSlugs;
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.32";
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, import_node_fs7.writeFileSync)(configPath, JSON.stringify(config, null, 2), { mode: 384 });
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,