@aiden-ade/sandbox-agent 0.1.18 → 0.1.19

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 (66) 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__/daemon-socket.integration.test.d.ts +2 -0
  10. package/dist/__tests__/daemon-socket.integration.test.d.ts.map +1 -0
  11. package/dist/__tests__/daemon-socket.integration.test.js +152 -0
  12. package/dist/__tests__/daemon-socket.integration.test.js.map +1 -0
  13. package/dist/__tests__/daemon.test.d.ts +2 -0
  14. package/dist/__tests__/daemon.test.d.ts.map +1 -0
  15. package/dist/__tests__/daemon.test.js +978 -0
  16. package/dist/__tests__/daemon.test.js.map +1 -0
  17. package/dist/__tests__/generated-images.test.d.ts +2 -0
  18. package/dist/__tests__/generated-images.test.d.ts.map +1 -0
  19. package/dist/__tests__/generated-images.test.js +38 -0
  20. package/dist/__tests__/generated-images.test.js.map +1 -0
  21. package/dist/aiden-system-prompt.d.ts +6 -0
  22. package/dist/aiden-system-prompt.d.ts.map +1 -0
  23. package/dist/aiden-system-prompt.js +6 -0
  24. package/dist/aiden-system-prompt.js.map +1 -0
  25. package/dist/cli-executable.d.ts +65 -0
  26. package/dist/cli-executable.d.ts.map +1 -0
  27. package/dist/cli-executable.js +298 -0
  28. package/dist/cli-executable.js.map +1 -0
  29. package/dist/cli-help.d.ts +7 -0
  30. package/dist/cli-help.d.ts.map +1 -0
  31. package/dist/cli-help.js +45 -0
  32. package/dist/cli-help.js.map +1 -0
  33. package/dist/core-agent.d.ts +5 -1
  34. package/dist/core-agent.d.ts.map +1 -1
  35. package/dist/core-agent.js +101 -12
  36. package/dist/core-agent.js.map +1 -1
  37. package/dist/daemon.d.ts +46 -0
  38. package/dist/daemon.d.ts.map +1 -0
  39. package/dist/daemon.js +836 -0
  40. package/dist/daemon.js.map +1 -0
  41. package/dist/generated-images.d.ts +3 -0
  42. package/dist/generated-images.d.ts.map +1 -0
  43. package/dist/generated-images.js +123 -0
  44. package/dist/generated-images.js.map +1 -0
  45. package/dist/index.cjs +80 -243
  46. package/dist/index.js +94 -42
  47. package/dist/index.js.map +1 -1
  48. package/dist/sandbox.d.ts.map +1 -1
  49. package/dist/sandbox.js +18 -3
  50. package/dist/sandbox.js.map +1 -1
  51. package/dist/updater.d.ts.map +1 -1
  52. package/dist/updater.js +0 -4
  53. package/dist/updater.js.map +1 -1
  54. package/dist/version.d.ts +1 -1
  55. package/dist/version.d.ts.map +1 -1
  56. package/dist/version.js +1 -1
  57. package/dist/version.js.map +1 -1
  58. package/dist/web-presenter.d.ts +6 -2
  59. package/dist/web-presenter.d.ts.map +1 -1
  60. package/dist/web-presenter.js +20 -1
  61. package/dist/web-presenter.js.map +1 -1
  62. package/dist/ws-client.d.ts +35 -0
  63. package/dist/ws-client.d.ts.map +1 -1
  64. package/dist/ws-client.js +1 -0
  65. package/dist/ws-client.js.map +1 -1
  66. package/package.json +3 -3
package/dist/index.cjs CHANGED
@@ -4826,13 +4826,16 @@ You may inspect, edit, run commands, create artifacts, and use MCP tools when th
4826
4826
 
4827
4827
  Use these tools, in roughly this order of frequency:
4828
4828
  1. \`delegate_task_session\` \u2014 route work to a specialist, reusing active matching workers by default
4829
- 2. \`get_task_memory\` / \`update_task_memory\` \u2014 keep the task-level working memory current
4830
- 3. \`list_subtasks\` / \`create_subtask\` / \`update_subtask\` \u2014 keep task breakdown current
4831
- 4. \`get_session_context\` \u2014 check what a worker accomplished
4832
- 5. \`update_task\` \u2014 keep status, priority, labels current
4833
- 6. \`send_session_message\` / \`start_task_session\` \u2014 continue a specific session or force a new session only when needed
4834
- 7. \`list_sessions\` / \`search\` / \`Read\` / \`Glob\` / \`Grep\` \u2014 situational awareness
4835
- 8. \`add_task_comment\` / \`create_plan\` \u2014 document decisions and plans
4829
+ 2. \`list_task_events\` / \`add_task_event\` \u2014 use only for high-signal human-visible events: durable decisions, learnings, checkpoints, and outcomes that change future work
4830
+ 3. \`list_agent_memory\` / \`add_agent_memory\` \u2014 use only when synthesized context will help future agents; do not store raw files inspected, commands run, or tool outputs
4831
+ 4. \`list_subtasks\` / \`create_subtask\` / \`update_subtask\` \u2014 keep task breakdown current
4832
+ 5. \`get_session_context\` \u2014 check what a worker accomplished
4833
+ 6. \`update_task\` \u2014 keep status, priority, labels current
4834
+ 7. \`send_session_message\` / \`start_task_session\` \u2014 continue a specific session or force a new session only when needed
4835
+ 8. \`list_sessions\` / \`search\` / \`Read\` / \`Glob\` / \`Grep\` \u2014 situational awareness
4836
+ 9. \`get_task_memory\` / \`update_task_memory\` \u2014 compatibility memory tools for older task summaries and session outcomes
4837
+ 10. \`create_plan\` \u2014 document implementation plans and durable specs as artifacts
4838
+ 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.
4836
4839
 
4837
4840
  ## How to scale work
4838
4841
 
@@ -4867,7 +4870,7 @@ Write it like a senior engineer's handoff note, not a vague request.
4867
4870
  1. Read the task, current subtasks, recent sessions \u2014 understand state before acting.
4868
4871
  2. Decide the next concrete unit of work. Break it down when scope is wide; keep subtasks current.
4869
4872
  3. **Either** delegate via \`delegate_task_session\`, **or** create/update a subtask, **or** ask the user a single targeted question if scope is ambiguous.
4870
- 4. After delegation, track results via \`get_session_context\`, persist summaries/outcomes via \`update_task_memory\`, integrate status, decide the next move.
4873
+ 4. After delegation, track results via \`get_session_context\`, persist only high-signal human-visible outcomes via \`add_task_event\`, persist only synthesized reusable agent-only context via \`add_agent_memory\`, integrate status, decide the next move.
4871
4874
 
4872
4875
  You are coordination-first, not read-only. Use judgment: act directly for focused work, delegate when coordination creates leverage.`;
4873
4876
  var PM_PROMPT = `## You are the PM Agent
@@ -4894,7 +4897,9 @@ Use these tools, in roughly this order of frequency:
4894
4897
  3. \`start_task_session\` \u2014 delegate to a specialist once scope is defined
4895
4898
  4. \`get_session_context\` / \`list_sessions\` \u2014 track progress
4896
4899
  5. \`update_task\` \u2014 keep status and priority current
4897
- 6. \`add_task_comment\` \u2014 surface decisions and risks to the user
4900
+ 6. \`list_task_events\` / \`add_task_event\` \u2014 persist only high-signal human-readable decisions, learnings, checkpoints, and outcomes in the Agent Log
4901
+ 7. \`list_agent_memory\` / \`add_agent_memory\` \u2014 persist only synthesized agent-only context that future agents need
4902
+ 8. \`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.
4898
4903
 
4899
4904
  ## How to think like a PM
4900
4905
 
@@ -5234,11 +5239,12 @@ function getAidenAgentPrompt(agentId) {
5234
5239
  var SESSION_RESUME_FAILED_MESSAGE = "Session resume failed. The previous session may have expired or is no longer available. Please start a new session.";
5235
5240
 
5236
5241
  // ../agent-core/dist/index.js
5237
- var import_crypto = require("crypto");
5238
5242
  var import_fs = require("fs");
5239
5243
  var import_os = require("os");
5240
5244
  var import_path = require("path");
5245
+ var import_crypto = require("crypto");
5241
5246
  var import_fs2 = require("fs");
5247
+ var import_fs3 = require("fs");
5242
5248
  var import_os2 = require("os");
5243
5249
  var import_path2 = require("path");
5244
5250
  var import_readline = require("readline");
@@ -5271,12 +5277,9 @@ var DEFAULT_TEAM_STATUSES = STATUS_OPTIONS.map((o) => ({
5271
5277
  }));
5272
5278
 
5273
5279
  // ../agent-core/dist/index.js
5274
- var import_fs3 = require("fs");
5280
+ var import_fs4 = require("fs");
5275
5281
  var import_os3 = require("os");
5276
5282
  var import_path3 = require("path");
5277
- var import_fs4 = require("fs");
5278
- var import_os4 = require("os");
5279
- var import_path4 = require("path");
5280
5283
  function isLikelyProviderAuthError(stderr) {
5281
5284
  const lower = stderr.toLowerCase();
5282
5285
  return lower.includes("api key") || lower.includes("api_key") || lower.includes("invalid api key") || lower.includes("api key invalid") || lower.includes("unauthorized") || lower.includes("authentication failed") || lower.includes("authentication error") || lower.includes("provider settings") || lower.includes("invalid token") || lower.includes("token expired");
@@ -5410,7 +5413,6 @@ function normalizeCodexMcpToolResult(output) {
5410
5413
  }
5411
5414
  return raw;
5412
5415
  }
5413
- var MAX_INLINE_GENERATED_IMAGE_BYTES = 20 * 1024 * 1024;
5414
5416
  function findCodexSessionLog(runtimeSessionId, codexHome) {
5415
5417
  if (!runtimeSessionId || !(0, import_fs.existsSync)(codexHome)) return null;
5416
5418
  const root = (0, import_path.join)(codexHome, "sessions");
@@ -5441,106 +5443,14 @@ function findCodexSessionLog(runtimeSessionId, codexHome) {
5441
5443
  matches.sort((a, b) => b.mtimeMs - a.mtimeMs);
5442
5444
  return matches[0]?.path ?? null;
5443
5445
  }
5444
- function inferImageMimeType(buffer) {
5445
- if (buffer.length >= 8 && buffer.subarray(0, 8).equals(Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]))) {
5446
- return "image/png";
5447
- }
5448
- if (buffer.length >= 3 && buffer[0] === 255 && buffer[1] === 216 && buffer[2] === 255) {
5449
- return "image/jpeg";
5450
- }
5451
- if (buffer.length >= 6 && (buffer.toString("ascii", 0, 6) === "GIF87a" || buffer.toString("ascii", 0, 6) === "GIF89a")) {
5452
- return "image/gif";
5453
- }
5454
- if (buffer.length >= 12 && buffer.toString("ascii", 0, 4) === "RIFF" && buffer.toString("ascii", 8, 12) === "WEBP") {
5455
- return "image/webp";
5456
- }
5457
- return null;
5458
- }
5459
- function extensionForMimeType(mimeType) {
5460
- switch (mimeType) {
5461
- case "image/jpeg":
5462
- return "jpg";
5463
- case "image/gif":
5464
- return "gif";
5465
- case "image/webp":
5466
- return "webp";
5467
- case "image/png":
5468
- default:
5469
- return "png";
5470
- }
5471
- }
5472
- function readImageDimensions(buffer, mimeType) {
5473
- if (mimeType === "image/png" && buffer.length >= 24) {
5474
- return { width: buffer.readUInt32BE(16), height: buffer.readUInt32BE(20) };
5475
- }
5476
- if (mimeType === "image/gif" && buffer.length >= 10) {
5477
- return { width: buffer.readUInt16LE(6), height: buffer.readUInt16LE(8) };
5478
- }
5479
- if (mimeType === "image/jpeg" && buffer.length > 4) {
5480
- let offset = 2;
5481
- while (offset + 9 < buffer.length) {
5482
- if (buffer[offset] !== 255) break;
5483
- const marker = buffer[offset + 1];
5484
- const length = buffer.readUInt16BE(offset + 2);
5485
- if (length < 2) break;
5486
- if (marker >= 192 && marker <= 207 && ![196, 200, 204].includes(marker)) {
5487
- return {
5488
- width: buffer.readUInt16BE(offset + 7),
5489
- height: buffer.readUInt16BE(offset + 5)
5490
- };
5491
- }
5492
- offset += 2 + length;
5493
- }
5494
- }
5495
- return { width: null, height: null };
5496
- }
5497
- function buildGeneratedImageFromCodexPayload(payload) {
5498
- const data = typeof payload.result === "string" ? payload.result : "";
5499
- if (!data) return null;
5500
- const buffer = Buffer.from(data, "base64");
5501
- if (buffer.length <= 0 || buffer.length > MAX_INLINE_GENERATED_IMAGE_BYTES) return null;
5502
- const mimeType = inferImageMimeType(buffer);
5503
- if (!mimeType) return null;
5504
- const callId = typeof payload.call_id === "string" && payload.call_id ? payload.call_id : void 0;
5505
- const imageId = (0, import_crypto.randomUUID)();
5506
- const { width, height } = readImageDimensions(buffer, mimeType);
5507
- return {
5508
- type: "generated_image",
5509
- id: imageId,
5510
- filename: `${callId ?? imageId}.${extensionForMimeType(mimeType)}`,
5511
- mimeType,
5512
- size: buffer.length,
5513
- width,
5514
- height,
5515
- data: buffer.toString("base64"),
5516
- sourceHash: (0, import_crypto.createHash)("sha256").update(buffer).digest("hex"),
5517
- ...callId ? { toolId: callId } : {},
5518
- ts: Date.now()
5519
- };
5520
- }
5521
- function latestUserMessageLineIndex(lines) {
5522
- let latestIndex = -1;
5523
- for (let index = 0; index < lines.length; index += 1) {
5524
- const line = lines[index];
5525
- if (!line) continue;
5526
- const entry = parseJsonObject(line);
5527
- const payload = entry && typeof entry.payload === "object" && entry.payload !== null ? entry.payload : null;
5528
- if (payload?.type === "message" && payload.role === "user") {
5529
- latestIndex = index;
5530
- }
5531
- }
5532
- return latestIndex;
5533
- }
5534
5446
  async function replayCodexMcpToolEventsFromSessionLog(context, state) {
5535
5447
  const runtimeSessionId = state.runtimeSessionId;
5536
5448
  if (!runtimeSessionId) return;
5537
5449
  const codexHome = context.env.CODEX_HOME || process.env.CODEX_HOME || (0, import_path.join)((0, import_os.homedir)(), ".codex");
5538
5450
  const logPath = findCodexSessionLog(runtimeSessionId, codexHome);
5539
5451
  if (!logPath) return;
5540
- const allLines = (0, import_fs.readFileSync)(logPath, "utf8").split(/\r?\n/).filter(Boolean);
5541
- const latestUserLineIndex = latestUserMessageLineIndex(allLines);
5542
- const lines = latestUserLineIndex >= 0 ? allLines.slice(latestUserLineIndex + 1) : allLines;
5543
5452
  const emittedToolIds = /* @__PURE__ */ new Set();
5453
+ const lines = (0, import_fs.readFileSync)(logPath, "utf8").split(/\r?\n/).filter(Boolean);
5544
5454
  for (const line of lines) {
5545
5455
  const entry = parseJsonObject(line);
5546
5456
  const payload = entry && typeof entry.payload === "object" && entry.payload !== null ? entry.payload : null;
@@ -5560,39 +5470,36 @@ async function replayCodexMcpToolEventsFromSessionLog(context, state) {
5560
5470
  if (!callId) continue;
5561
5471
  context.presenter.onToolUse("tool_search", payload.arguments ?? {}, callId);
5562
5472
  emittedToolIds.add(callId);
5563
- continue;
5564
- }
5565
- if (payload.type === "image_generation_end") {
5566
- const image = buildGeneratedImageFromCodexPayload(payload);
5567
- if (image) await context.presenter.onGeneratedImage?.(image);
5568
5473
  }
5569
5474
  }
5570
- if (emittedToolIds.size > 0) {
5571
- for (const line of lines) {
5572
- const entry = parseJsonObject(line);
5573
- const payload = entry && typeof entry.payload === "object" && entry.payload !== null ? entry.payload : null;
5574
- if (!payload || payload.type !== "function_call_output" && payload.type !== "tool_search_output")
5575
- continue;
5576
- const callId = typeof payload.call_id === "string" ? payload.call_id : "";
5577
- if (!emittedToolIds.has(callId)) continue;
5578
- try {
5579
- const result = payload.type === "tool_search_output" ? JSON.stringify(payload.tools ?? [], null, 2) : normalizeCodexMcpToolResult(payload.output);
5580
- context.presenter.onToolResult?.(callId, result);
5581
- } catch {
5582
- context.presenter.onToolResult?.(callId, String(payload.output ?? ""));
5583
- }
5475
+ if (emittedToolIds.size === 0) return;
5476
+ for (const line of lines) {
5477
+ const entry = parseJsonObject(line);
5478
+ const payload = entry && typeof entry.payload === "object" && entry.payload !== null ? entry.payload : null;
5479
+ if (!payload || payload.type !== "function_call_output" && payload.type !== "tool_search_output") continue;
5480
+ const callId = typeof payload.call_id === "string" ? payload.call_id : "";
5481
+ if (!emittedToolIds.has(callId)) continue;
5482
+ try {
5483
+ const result = payload.type === "tool_search_output" ? JSON.stringify(payload.tools ?? [], null, 2) : normalizeCodexMcpToolResult(payload.output);
5484
+ context.presenter.onToolResult?.(callId, result);
5485
+ } catch {
5486
+ context.presenter.onToolResult?.(callId, String(payload.output ?? ""));
5584
5487
  }
5585
5488
  }
5586
5489
  }
5587
- var KIMI_RESUME_SESSION_RE = /To resume this session:\s*kimi(?:-cli)?\s+(?:-[rS]|--session|--resume)\s+([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})/i;
5588
- function parseKimiStderrLine(line, state) {
5589
- const match = line.match(KIMI_RESUME_SESSION_RE);
5590
- if (match?.[1]) {
5591
- state.runtimeSessionId = match[1];
5490
+ function kimiSessionId(cwd) {
5491
+ let resolved = cwd;
5492
+ try {
5493
+ resolved = (0, import_fs2.realpathSync)(cwd);
5494
+ } catch {
5592
5495
  }
5496
+ return (0, import_crypto.createHash)("md5").update(resolved).digest("hex");
5593
5497
  }
5594
5498
  function parseKimiStructuredLine(line, context, state) {
5595
5499
  const presenter = context.presenter;
5500
+ if (!state.runtimeSessionId) {
5501
+ state.runtimeSessionId = kimiSessionId(context.cwd);
5502
+ }
5596
5503
  let parsed;
5597
5504
  try {
5598
5505
  parsed = JSON.parse(line);
@@ -5677,11 +5584,11 @@ function createImageTempDirectory(cwd) {
5677
5584
  ].filter((value2) => Boolean(value2));
5678
5585
  for (const candidate of candidates) {
5679
5586
  try {
5680
- return (0, import_fs2.mkdtempSync)(candidate);
5587
+ return (0, import_fs3.mkdtempSync)(candidate);
5681
5588
  } catch {
5682
5589
  }
5683
5590
  }
5684
- return (0, import_fs2.mkdtempSync)((0, import_path2.join)((0, import_os2.tmpdir)(), "aiden-images-"));
5591
+ return (0, import_fs3.mkdtempSync)((0, import_path2.join)((0, import_os2.tmpdir)(), "aiden-images-"));
5685
5592
  }
5686
5593
  function writeImagesToTempFiles(images, cwd) {
5687
5594
  if (!images?.length) return { paths: [], files: [], cleanup: () => {
@@ -5692,7 +5599,7 @@ function writeImagesToTempFiles(images, cwd) {
5692
5599
  for (const img of images) {
5693
5600
  const ext = imageFileExtension(img.mimeType);
5694
5601
  const filePath = (0, import_path2.join)(directory, `aiden-img-${img.id}.${ext}`);
5695
- (0, import_fs2.writeFileSync)(filePath, Buffer.from(img.data, "base64"));
5602
+ (0, import_fs3.writeFileSync)(filePath, Buffer.from(img.data, "base64"));
5696
5603
  paths.push(filePath);
5697
5604
  files.push({
5698
5605
  filename: img.filename,
@@ -5707,7 +5614,7 @@ function writeImagesToTempFiles(images, cwd) {
5707
5614
  files,
5708
5615
  cleanup: () => {
5709
5616
  try {
5710
- (0, import_fs2.rmSync)(directory, { recursive: true, force: true });
5617
+ (0, import_fs3.rmSync)(directory, { recursive: true, force: true });
5711
5618
  } catch {
5712
5619
  }
5713
5620
  }
@@ -5796,9 +5703,6 @@ function createGenericCliBackend(options) {
5796
5703
  });
5797
5704
  stderrRl.on("line", (line) => {
5798
5705
  presenter.recordRawTranscript?.("stderr", line);
5799
- if (options.parseStderrLine) {
5800
- options.parseStderrLine(line, context, state);
5801
- }
5802
5706
  if (line.trim().length > 0) {
5803
5707
  stderrLines.push(line);
5804
5708
  void presenter.onLog(`[${options.kind}] ${line}`);
@@ -6271,7 +6175,7 @@ function resolveKimiCliModelArg(model) {
6271
6175
  if (trimmed.startsWith("claude-")) return void 0;
6272
6176
  return trimmed;
6273
6177
  }
6274
- function createKimiCliBackend(command = "kimi-cli", defaultArgs = []) {
6178
+ function createKimiCliBackend(command = "kimi", defaultArgs = []) {
6275
6179
  return {
6276
6180
  kind: "kimi_cli",
6277
6181
  supportTier: "structured",
@@ -6301,8 +6205,7 @@ function createKimiCliBackend(command = "kimi-cli", defaultArgs = []) {
6301
6205
  return [...args, ...defaultArgs, "--prompt", prompt];
6302
6206
  },
6303
6207
  augmentPrompt: (ctx) => buildPromptWithImagePathReferences(ctx, imageFiles),
6304
- parseStructuredLine: parseKimiStructuredLine,
6305
- parseStderrLine: (line, _ctx, state) => parseKimiStderrLine(line, state)
6208
+ parseStructuredLine: parseKimiStructuredLine
6306
6209
  }).run(context);
6307
6210
  } finally {
6308
6211
  cleanup();
@@ -7098,12 +7001,7 @@ function createCodexRuntimeBackend(command = "codex", defaultArgs = []) {
7098
7001
  const resumeId = ctx.config.runtimeSessionId?.trim() || ctx.config.providerSessionId?.trim();
7099
7002
  const modelArgs = ctx.config.selectedModel?.trim() ? ["--model", ctx.config.selectedModel.trim()] : [];
7100
7003
  const effortArgs = buildCodexEffortArgs(ctx.config.selectedEffortLevel);
7101
- const permissionArgs = [
7102
- "--ask-for-approval",
7103
- "never",
7104
- "--sandbox",
7105
- "danger-full-access"
7106
- ];
7004
+ const permissionArgs = ["--dangerously-bypass-approvals-and-sandbox"];
7107
7005
  const imageArgs = imagePaths.flatMap((p) => ["--image", p]);
7108
7006
  const baseArgs = resumeId ? [...permissionArgs, "exec", "resume", "--json", "--skip-git-repo-check", ...modelArgs, ...effortArgs, ...imageArgs, resumeId, "-"] : [...permissionArgs, "exec", "--json", "--skip-git-repo-check", ...modelArgs, ...effortArgs, ...imageArgs, "-"];
7109
7007
  return [...baseArgs, ...defaultArgs];
@@ -7238,85 +7136,6 @@ function createCopilotCliBackend(command = "copilot", defaultArgs = []) {
7238
7136
  }
7239
7137
  };
7240
7138
  }
7241
- var SKILL_COMMAND_RE = /^\s*\/([A-Za-z0-9][A-Za-z0-9._:-]*)(?:\s+([\s\S]*))?$/;
7242
- function parseSkillInvocation(text) {
7243
- const match = text.match(SKILL_COMMAND_RE);
7244
- if (!match) return null;
7245
- return {
7246
- command: match[1],
7247
- userRequest: match[2]?.trim() ?? ""
7248
- };
7249
- }
7250
- function candidateRoots(cwd) {
7251
- const roots = [];
7252
- if (cwd) {
7253
- roots.push((0, import_path4.join)(cwd, ".agents", "skills"));
7254
- roots.push((0, import_path4.join)(cwd, ".claude", "skills"));
7255
- roots.push((0, import_path4.join)(cwd, ".codex", "skills"));
7256
- if ((0, import_fs4.existsSync)(cwd)) {
7257
- let entries = [];
7258
- try {
7259
- entries = (0, import_fs4.readdirSync)(cwd, { withFileTypes: true });
7260
- } catch {
7261
- }
7262
- for (const entry of entries) {
7263
- if (!entry.isDirectory()) continue;
7264
- if (entry.name.startsWith(".")) continue;
7265
- const child = (0, import_path4.join)(cwd, entry.name);
7266
- roots.push((0, import_path4.join)(child, ".agents", "skills"));
7267
- roots.push((0, import_path4.join)(child, ".claude", "skills"));
7268
- roots.push((0, import_path4.join)(child, ".codex", "skills"));
7269
- }
7270
- }
7271
- }
7272
- const home = (0, import_os4.homedir)();
7273
- roots.push((0, import_path4.join)(home, ".agents", "skills"));
7274
- roots.push((0, import_path4.join)(home, ".claude", "skills"));
7275
- roots.push((0, import_path4.join)(home, ".codex", "skills"));
7276
- return Array.from(new Set(roots));
7277
- }
7278
- function resolveSkillInvocation(text, cwd) {
7279
- const parsed = parseSkillInvocation(text);
7280
- if (!parsed) return null;
7281
- for (const root of candidateRoots(cwd)) {
7282
- const skillPath = (0, import_path4.join)(root, parsed.command, "SKILL.md");
7283
- if (!(0, import_fs4.existsSync)(skillPath)) continue;
7284
- let content;
7285
- try {
7286
- content = (0, import_fs4.readFileSync)(skillPath, "utf-8");
7287
- } catch {
7288
- continue;
7289
- }
7290
- return {
7291
- command: parsed.command,
7292
- skillPath,
7293
- content,
7294
- userRequest: parsed.userRequest
7295
- };
7296
- }
7297
- return null;
7298
- }
7299
- function expandSkillInvocationPrompt(text, cwd) {
7300
- const invocation = resolveSkillInvocation(text, cwd);
7301
- if (!invocation) return { text, invocation: null };
7302
- const request = invocation.userRequest || "(No additional request text was provided.)";
7303
- return {
7304
- invocation,
7305
- text: [
7306
- `The user invoked the \`/${invocation.command}\` skill.`,
7307
- `Skill source: ${invocation.skillPath}`,
7308
- "",
7309
- "Follow the skill instructions below for this turn.",
7310
- "",
7311
- `<skill_instructions command="${invocation.command}">`,
7312
- invocation.content.trim(),
7313
- "</skill_instructions>",
7314
- "",
7315
- "User request after the slash command:",
7316
- request
7317
- ].join("\n")
7318
- };
7319
- }
7320
7139
  var DEFAULT_MODEL = "claude-sonnet-4-6";
7321
7140
  var DROID_DEFAULT_MODEL = "claude-opus-4-7";
7322
7141
  function defaultSelectedModelForBackend(backendKind) {
@@ -7338,7 +7157,7 @@ function defaultSelectedModelForBackend(backendKind) {
7338
7157
  function canonicalizePath(inputPath) {
7339
7158
  try {
7340
7159
  const resolved = (0, import_path3.resolve)(inputPath);
7341
- return (0, import_fs3.existsSync)(resolved) ? (0, import_fs3.realpathSync)(resolved) : resolved;
7160
+ return (0, import_fs4.existsSync)(resolved) ? (0, import_fs4.realpathSync)(resolved) : resolved;
7342
7161
  } catch {
7343
7162
  return null;
7344
7163
  }
@@ -7496,21 +7315,16 @@ Prefer relative paths and keep your work scoped to this project.`
7496
7315
  async runCliBackend(config, safeProjectPath) {
7497
7316
  const backendKind = this.resolveBackendKind(config);
7498
7317
  const defaultCwd = (0, import_path3.join)((0, import_os3.homedir)(), "Documents", "aiden");
7499
- if (!(0, import_fs3.existsSync)(defaultCwd)) {
7500
- (0, import_fs3.mkdirSync)(defaultCwd, { recursive: true });
7318
+ if (!(0, import_fs4.existsSync)(defaultCwd)) {
7319
+ (0, import_fs4.mkdirSync)(defaultCwd, { recursive: true });
7501
7320
  }
7502
7321
  let runtimeConfig = this.buildRuntimeConfig(config, safeProjectPath);
7503
7322
  const cwd = runtimeConfig.worktreePath || safeProjectPath || runtimeConfig.cwd || defaultCwd;
7504
- const skillExpansion = expandSkillInvocationPrompt(runtimeConfig.task, cwd);
7505
- if (skillExpansion.invocation) {
7506
- runtimeConfig = { ...runtimeConfig, task: skillExpansion.text };
7507
- void this.presenter.onLog(`Using /${skillExpansion.invocation.command} skill`);
7508
- }
7509
7323
  const env = await this.buildCliEnvironment();
7510
7324
  const promptText = this.buildPromptText(runtimeConfig);
7511
7325
  const runtimeCommand = runtimeConfig.runtimeCommand || this.runtime.runtimeCommand;
7512
7326
  const runtimeArgs = runtimeConfig.runtimeArgs || this.runtime.runtimeArgs || [];
7513
- const backend = backendKind === "claude_cli" ? createClaudeCliBackend(runtimeCommand || "claude", runtimeArgs) : backendKind === "codex_app_server" ? createCodexRuntimeBackend(runtimeCommand || "codex", runtimeArgs) : backendKind === "copilot_cli" ? createCopilotCliBackend(runtimeCommand || "copilot", runtimeArgs) : backendKind === "cursor_agent_cli" ? createCursorAgentCliBackend(runtimeCommand || "cursor-agent", runtimeArgs) : backendKind === "gemini_cli" ? createGeminiCliBackend(runtimeCommand || "gemini", runtimeArgs) : backendKind === "droid_cli" ? createDroidCliBackend(runtimeCommand || "droid", runtimeArgs) : backendKind === "opencode_cli" ? createOpencodeCliBackend(runtimeCommand || "opencode", runtimeArgs) : backendKind === "kimi_cli" ? createKimiCliBackend(runtimeCommand || "kimi-cli", runtimeArgs) : backendKind === "supatest_cli" ? createSupatestCliBackend(runtimeCommand || "supatest", runtimeArgs) : createGenericCliPassthroughBackend(runtimeCommand || "generic-cli", runtimeArgs);
7327
+ const backend = backendKind === "claude_cli" ? createClaudeCliBackend(runtimeCommand || "claude", runtimeArgs) : backendKind === "codex_app_server" ? createCodexRuntimeBackend(runtimeCommand || "codex", runtimeArgs) : backendKind === "copilot_cli" ? createCopilotCliBackend(runtimeCommand || "copilot", runtimeArgs) : backendKind === "cursor_agent_cli" ? createCursorAgentCliBackend(runtimeCommand || "cursor-agent", runtimeArgs) : backendKind === "gemini_cli" ? createGeminiCliBackend(runtimeCommand || "gemini", runtimeArgs) : backendKind === "droid_cli" ? createDroidCliBackend(runtimeCommand || "droid", runtimeArgs) : backendKind === "opencode_cli" ? createOpencodeCliBackend(runtimeCommand || "opencode", runtimeArgs) : backendKind === "kimi_cli" ? createKimiCliBackend(runtimeCommand || "kimi", runtimeArgs) : backendKind === "supatest_cli" ? createSupatestCliBackend(runtimeCommand || "supatest", runtimeArgs) : createGenericCliPassthroughBackend(runtimeCommand || "generic-cli", runtimeArgs);
7514
7328
  let lastResult = null;
7515
7329
  for (let attempt = 0; attempt <= _BaseMachineAgent.MAX_RETRIES; attempt++) {
7516
7330
  if (this.abortController?.signal.aborted) break;
@@ -7606,7 +7420,7 @@ Prefer relative paths and keep your work scoped to this project.`
7606
7420
  const canonicalized = canonicalizePath(initialConfig.teamPath);
7607
7421
  if (canonicalized) safeProjectPath = canonicalized;
7608
7422
  }
7609
- if (safeProjectPath && !(0, import_fs3.existsSync)(safeProjectPath)) {
7423
+ if (safeProjectPath && !(0, import_fs4.existsSync)(safeProjectPath)) {
7610
7424
  const message = `Local path no longer exists: "${safeProjectPath}". Please update the team's local path in team settings before running the agent.`;
7611
7425
  this.presenter.onError(message, true);
7612
7426
  const result = {
@@ -8173,6 +7987,22 @@ var IMAGE_MIME_BY_EXT = {
8173
7987
  ".webp": "image/webp"
8174
7988
  };
8175
7989
  var MAX_GENERATED_IMAGE_BYTES = 20 * 1024 * 1024;
7990
+ function isGeneratedImageToolName(toolName) {
7991
+ if (!toolName) return false;
7992
+ const normalized = toolName.toLowerCase().replace(/[^a-z0-9]+/g, "_");
7993
+ return [
7994
+ "image_generation",
7995
+ "image_gen",
7996
+ "imagegen",
7997
+ "generate_image",
7998
+ "edit_image",
7999
+ "text_to_image",
8000
+ "images_generate"
8001
+ ].some((token) => normalized.includes(token));
8002
+ }
8003
+ function shouldExtractGeneratedImagesFromToolResult(toolName) {
8004
+ return isGeneratedImageToolName(toolName);
8005
+ }
8176
8006
  function collectStringValues(value2, out) {
8177
8007
  if (typeof value2 === "string") {
8178
8008
  out.push(value2);
@@ -8215,7 +8045,7 @@ function normalizePath(candidate, cwd) {
8215
8045
  if ((0, import_node_path2.isAbsolute)(path)) return path;
8216
8046
  return cwd ? (0, import_node_path2.join)(cwd, path) : null;
8217
8047
  }
8218
- function readImageDimensions2(buffer, mimeType) {
8048
+ function readImageDimensions(buffer, mimeType) {
8219
8049
  if (mimeType === "image/png" && buffer.length >= 24 && buffer.toString("ascii", 1, 4) === "PNG") {
8220
8050
  return { width: buffer.readUInt32BE(16), height: buffer.readUInt32BE(20) };
8221
8051
  }
@@ -8240,7 +8070,8 @@ function readImageDimensions2(buffer, mimeType) {
8240
8070
  }
8241
8071
  return { width: null, height: null };
8242
8072
  }
8243
- function extractGeneratedImagesFromToolResult(toolId, content, cwd) {
8073
+ function extractGeneratedImagesFromToolResult(toolId, content, cwd, toolName) {
8074
+ if (!shouldExtractGeneratedImagesFromToolResult(toolName)) return [];
8244
8075
  const images = [];
8245
8076
  const seen = /* @__PURE__ */ new Set();
8246
8077
  for (const candidate of extractPathCandidates(content)) {
@@ -8253,7 +8084,7 @@ function extractGeneratedImagesFromToolResult(toolId, content, cwd) {
8253
8084
  const stat = (0, import_node_fs2.statSync)(path);
8254
8085
  if (!stat.isFile() || stat.size <= 0 || stat.size > MAX_GENERATED_IMAGE_BYTES) continue;
8255
8086
  const buffer = (0, import_node_fs2.readFileSync)(path);
8256
- const { width, height } = readImageDimensions2(buffer, mimeType);
8087
+ const { width, height } = readImageDimensions(buffer, mimeType);
8257
8088
  images.push({
8258
8089
  type: "generated_image",
8259
8090
  id: (0, import_node_crypto.randomUUID)(),
@@ -8282,6 +8113,7 @@ var WebPresenter = class {
8282
8113
  wsClient;
8283
8114
  conversationId;
8284
8115
  emittedGeneratedImageKeys = /* @__PURE__ */ new Set();
8116
+ toolNamesById = /* @__PURE__ */ new Map();
8285
8117
  suppressSessionLifecycle = false;
8286
8118
  setSuppressSessionLifecycle(suppress) {
8287
8119
  this.suppressSessionLifecycle = suppress;
@@ -8299,6 +8131,7 @@ var WebPresenter = class {
8299
8131
  this.wsClient.emitEvent({ type: "thinking", text, ts: Date.now() });
8300
8132
  }
8301
8133
  onToolUse(tool, input, toolId) {
8134
+ this.toolNamesById.set(toolId, tool);
8302
8135
  this.wsClient.emitEvent({ type: "tool_use", id: toolId, name: tool, input, ts: Date.now() });
8303
8136
  }
8304
8137
  onToolResult(toolId, content, isError) {
@@ -8310,7 +8143,8 @@ var WebPresenter = class {
8310
8143
  ...isError ? { is_error: true } : {}
8311
8144
  });
8312
8145
  if (isError) return;
8313
- for (const image of extractGeneratedImagesFromToolResult(toolId, content, this.cwd)) {
8146
+ const toolName = this.toolNamesById.get(toolId);
8147
+ for (const image of extractGeneratedImagesFromToolResult(toolId, content, this.cwd, toolName)) {
8314
8148
  this.emitGeneratedImage(image);
8315
8149
  }
8316
8150
  }
@@ -12025,7 +11859,7 @@ var WSClient = class {
12025
11859
  };
12026
11860
 
12027
11861
  // src/version.ts
12028
- var AGENT_VERSION = "0.1.18";
11862
+ var AGENT_VERSION = "0.1.19";
12029
11863
 
12030
11864
  // src/sandbox.ts
12031
11865
  async function runSandbox(config) {
@@ -12659,6 +12493,7 @@ var RuntimePresenter = class {
12659
12493
  this.cwd = cwd;
12660
12494
  }
12661
12495
  emittedGeneratedImageKeys = /* @__PURE__ */ new Set();
12496
+ toolNamesById = /* @__PURE__ */ new Map();
12662
12497
  emitEvent(event) {
12663
12498
  this.socket.emit("agent.event", {
12664
12499
  conversationId: this.conversationId,
@@ -12679,6 +12514,7 @@ var RuntimePresenter = class {
12679
12514
  this.emitEvent({ type: "thinking", text, ts: Date.now() });
12680
12515
  }
12681
12516
  onToolUse(tool, input, toolId) {
12517
+ this.toolNamesById.set(toolId, tool);
12682
12518
  this.emitEvent({ type: "tool_use", id: toolId, name: tool, input, ts: Date.now() });
12683
12519
  }
12684
12520
  onToolResult(toolId, content, isError) {
@@ -12690,7 +12526,8 @@ var RuntimePresenter = class {
12690
12526
  ...isError ? { is_error: true } : {}
12691
12527
  });
12692
12528
  if (isError) return;
12693
- for (const image of extractGeneratedImagesFromToolResult(toolId, content, this.cwd)) {
12529
+ const toolName = this.toolNamesById.get(toolId);
12530
+ for (const image of extractGeneratedImagesFromToolResult(toolId, content, this.cwd, toolName)) {
12694
12531
  this.emitGeneratedImage(image);
12695
12532
  }
12696
12533
  }