@aiden-ade/sandbox-agent 0.1.26 → 0.1.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +915 -292
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -4856,11 +4856,11 @@ function resolveCommand(args, env) {
|
|
|
4856
4856
|
|
|
4857
4857
|
// src/daemon.ts
|
|
4858
4858
|
var import_node_child_process3 = require("child_process");
|
|
4859
|
-
var
|
|
4860
|
-
var
|
|
4859
|
+
var import_node_crypto = require("crypto");
|
|
4860
|
+
var import_node_fs3 = require("fs");
|
|
4861
4861
|
var import_node_http = __toESM(require("http"), 1);
|
|
4862
4862
|
var import_node_os4 = require("os");
|
|
4863
|
-
var
|
|
4863
|
+
var import_node_path3 = require("path");
|
|
4864
4864
|
|
|
4865
4865
|
// ../shared/dist/node/provider-limits.js
|
|
4866
4866
|
var import_node_child_process = require("child_process");
|
|
@@ -4974,8 +4974,8 @@ async function withTimeout(promise, timeoutMs, fallback) {
|
|
|
4974
4974
|
try {
|
|
4975
4975
|
return await Promise.race([
|
|
4976
4976
|
promise,
|
|
4977
|
-
new Promise((
|
|
4978
|
-
timer = setTimeout(() =>
|
|
4977
|
+
new Promise((resolve3) => {
|
|
4978
|
+
timer = setTimeout(() => resolve3(fallback), timeoutMs);
|
|
4979
4979
|
})
|
|
4980
4980
|
]);
|
|
4981
4981
|
} finally {
|
|
@@ -4988,7 +4988,7 @@ async function collectCodexLimits(env) {
|
|
|
4988
4988
|
const codexCommand = resolveExecutable("codex", runtimeEnv, "AIDEN_CODEX_PATH");
|
|
4989
4989
|
if (!codexCommand)
|
|
4990
4990
|
return [];
|
|
4991
|
-
return withTimeout(new Promise((
|
|
4991
|
+
return withTimeout(new Promise((resolve3) => {
|
|
4992
4992
|
const child = (0, import_node_child_process.spawn)(codexCommand, ["-s", "read-only", "-a", "untrusted", "app-server"], {
|
|
4993
4993
|
env: runtimeEnv,
|
|
4994
4994
|
stdio: ["pipe", "pipe", "ignore"]
|
|
@@ -5000,7 +5000,7 @@ async function collectCodexLimits(env) {
|
|
|
5000
5000
|
pending.clear();
|
|
5001
5001
|
if (!child.killed)
|
|
5002
5002
|
child.kill();
|
|
5003
|
-
|
|
5003
|
+
resolve3(windows);
|
|
5004
5004
|
};
|
|
5005
5005
|
const request = (method, params = {}) => {
|
|
5006
5006
|
const id = nextId++;
|
|
@@ -7685,9 +7685,9 @@ var Socket2 = class extends Emitter {
|
|
|
7685
7685
|
* @return a Promise that will be fulfilled when the server acknowledges the event
|
|
7686
7686
|
*/
|
|
7687
7687
|
emitWithAck(ev, ...args) {
|
|
7688
|
-
return new Promise((
|
|
7688
|
+
return new Promise((resolve3, reject) => {
|
|
7689
7689
|
const fn = (arg1, arg2) => {
|
|
7690
|
-
return arg1 ? reject(arg1) :
|
|
7690
|
+
return arg1 ? reject(arg1) : resolve3(arg2);
|
|
7691
7691
|
};
|
|
7692
7692
|
fn.withError = true;
|
|
7693
7693
|
args.push(fn);
|
|
@@ -8691,22 +8691,33 @@ var import_node_fs2 = require("fs");
|
|
|
8691
8691
|
var import_node_os2 = require("os");
|
|
8692
8692
|
var import_node_path2 = require("path");
|
|
8693
8693
|
var PROVIDER_CLI_COMMANDS = {
|
|
8694
|
-
claude_cli: { provider: "claude_cli", command: "claude",
|
|
8695
|
-
codex_app_server: {
|
|
8696
|
-
|
|
8694
|
+
claude_cli: { provider: "claude_cli", command: "claude", envVars: ["AIDEN_CLAUDE_PATH"] },
|
|
8695
|
+
codex_app_server: {
|
|
8696
|
+
provider: "codex_app_server",
|
|
8697
|
+
command: "codex",
|
|
8698
|
+
envVars: ["AIDEN_CODEX_PATH"]
|
|
8699
|
+
},
|
|
8700
|
+
copilot_cli: { provider: "copilot_cli", command: "copilot", envVars: ["AIDEN_COPILOT_PATH"] },
|
|
8697
8701
|
cursor_agent_cli: {
|
|
8698
8702
|
provider: "cursor_agent_cli",
|
|
8699
8703
|
command: "cursor-agent",
|
|
8700
|
-
|
|
8704
|
+
envVars: ["AIDEN_CURSOR_AGENT_PATH"]
|
|
8701
8705
|
},
|
|
8702
|
-
gemini_cli: {
|
|
8703
|
-
|
|
8704
|
-
|
|
8705
|
-
|
|
8706
|
-
|
|
8706
|
+
gemini_cli: {
|
|
8707
|
+
provider: "gemini_cli",
|
|
8708
|
+
command: "agy",
|
|
8709
|
+
envVars: ["AIDEN_ANTIGRAVITY_PATH", "AIDEN_GEMINI_PATH"]
|
|
8710
|
+
},
|
|
8711
|
+
kimi_cli: { provider: "kimi_cli", command: "kimi-cli", envVars: ["AIDEN_KIMI_PATH"] },
|
|
8712
|
+
opencode_cli: { provider: "opencode_cli", command: "opencode", envVars: ["AIDEN_OPENCODE_PATH"] },
|
|
8713
|
+
droid_cli: { provider: "droid_cli", command: "droid", envVars: ["AIDEN_DROID_PATH"] },
|
|
8714
|
+
supatest_cli: { provider: "supatest_cli", command: "supatest", envVars: ["AIDEN_SUPATEST_PATH"] }
|
|
8707
8715
|
};
|
|
8708
8716
|
var DISCOVERABLE_PROVIDER_KINDS = Object.keys(PROVIDER_CLI_COMMANDS);
|
|
8709
8717
|
var PROVIDER_ALIASES = {
|
|
8718
|
+
agy: "gemini_cli",
|
|
8719
|
+
antigravity: "gemini_cli",
|
|
8720
|
+
antigravity_cli: "gemini_cli",
|
|
8710
8721
|
codex: "codex_app_server",
|
|
8711
8722
|
gemini: "gemini_cli"
|
|
8712
8723
|
};
|
|
@@ -8716,8 +8727,11 @@ var BACKEND_CLI_COMMANDS = {
|
|
|
8716
8727
|
codex_app_server: "codex",
|
|
8717
8728
|
copilot_cli: "copilot",
|
|
8718
8729
|
cursor_agent_cli: "cursor-agent",
|
|
8719
|
-
|
|
8720
|
-
|
|
8730
|
+
agy: "agy",
|
|
8731
|
+
antigravity: "agy",
|
|
8732
|
+
antigravity_cli: "agy",
|
|
8733
|
+
gemini_cli: "agy",
|
|
8734
|
+
gemini: "agy",
|
|
8721
8735
|
kimi_cli: "kimi-cli",
|
|
8722
8736
|
opencode_cli: "opencode",
|
|
8723
8737
|
droid_cli: "droid",
|
|
@@ -8905,7 +8919,7 @@ function resolveProviderCliCommand(provider, env = getDaemonCliEnvironment()) {
|
|
|
8905
8919
|
const normalized = normalizeDiscoverableProvider(provider);
|
|
8906
8920
|
if (!normalized) return null;
|
|
8907
8921
|
const spec = PROVIDER_CLI_COMMANDS[normalized];
|
|
8908
|
-
const override = process.env[
|
|
8922
|
+
const override = spec.envVars.map((name) => process.env[name]?.trim() || env[name]?.trim()).find(Boolean);
|
|
8909
8923
|
if (override) {
|
|
8910
8924
|
const resolved2 = resolveCliExecutable(override, env) ?? (isRunnableFile(override) ? override : null);
|
|
8911
8925
|
if (resolved2) cacheResolvedCli(spec.command, resolved2);
|
|
@@ -8922,7 +8936,7 @@ function resolveBackendRuntimeCommand(backendKind, env = getDaemonCliEnvironment
|
|
|
8922
8936
|
const cached = getCachedResolvedCli(command);
|
|
8923
8937
|
if (cached && isRunnableFile(cached)) return cached;
|
|
8924
8938
|
const spec = Object.values(PROVIDER_CLI_COMMANDS).find((entry) => entry.command === command);
|
|
8925
|
-
const envOverride = spec ? env[
|
|
8939
|
+
const envOverride = spec ? spec.envVars.map((name) => env[name]?.trim()).find(Boolean) : void 0;
|
|
8926
8940
|
const resolved = resolveCliExecutable(envOverride?.trim() || command, env);
|
|
8927
8941
|
if (resolved) cacheResolvedCli(command, resolved);
|
|
8928
8942
|
return resolved ?? void 0;
|
|
@@ -9321,6 +9335,64 @@ function isReadOnlyAgent(agentId) {
|
|
|
9321
9335
|
return !agent.capabilities.canEditFiles;
|
|
9322
9336
|
}
|
|
9323
9337
|
|
|
9338
|
+
// ../shared/dist/agent/generated-images.js
|
|
9339
|
+
var GENERATED_IMAGE_TOOL_NAMES = [
|
|
9340
|
+
"image_generation",
|
|
9341
|
+
"image_generate",
|
|
9342
|
+
"image_gen",
|
|
9343
|
+
"imagegen",
|
|
9344
|
+
"generate_image",
|
|
9345
|
+
"generate_images",
|
|
9346
|
+
"edit_image",
|
|
9347
|
+
"edit_images",
|
|
9348
|
+
"image_edit",
|
|
9349
|
+
"images_edit",
|
|
9350
|
+
"text_to_image",
|
|
9351
|
+
"images_generate"
|
|
9352
|
+
];
|
|
9353
|
+
var BROWSER_SCREENSHOT_TOOL_NAMES = [
|
|
9354
|
+
"agent_browser_screenshot",
|
|
9355
|
+
"agent_browser_take_screenshot",
|
|
9356
|
+
"agent_browser_capture_screenshot",
|
|
9357
|
+
"browser_screenshot",
|
|
9358
|
+
"browser_take_screenshot",
|
|
9359
|
+
"browser_capture_screenshot",
|
|
9360
|
+
"screenshot"
|
|
9361
|
+
];
|
|
9362
|
+
var BROWSER_RECORDING_TOOL_NAMES = [
|
|
9363
|
+
"agent_browser_record",
|
|
9364
|
+
"agent_browser_recording",
|
|
9365
|
+
"agent_browser_video",
|
|
9366
|
+
"agent_browser_capture_video",
|
|
9367
|
+
"agent_browser_screen_recording",
|
|
9368
|
+
"browser_record",
|
|
9369
|
+
"browser_recording",
|
|
9370
|
+
"browser_video",
|
|
9371
|
+
"browser_capture_video",
|
|
9372
|
+
"browser_screen_recording"
|
|
9373
|
+
];
|
|
9374
|
+
function normalizeToolName(toolName) {
|
|
9375
|
+
return toolName?.toLowerCase().replace(/[^a-z0-9]+/g, "_") ?? "";
|
|
9376
|
+
}
|
|
9377
|
+
function isGeneratedImageToolName(toolName) {
|
|
9378
|
+
const normalized = normalizeToolName(toolName);
|
|
9379
|
+
if (!normalized)
|
|
9380
|
+
return false;
|
|
9381
|
+
return GENERATED_IMAGE_TOOL_NAMES.some((token) => normalized.includes(token));
|
|
9382
|
+
}
|
|
9383
|
+
function isBrowserScreenshotToolName(toolName) {
|
|
9384
|
+
const normalized = normalizeToolName(toolName);
|
|
9385
|
+
if (!normalized)
|
|
9386
|
+
return false;
|
|
9387
|
+
return BROWSER_SCREENSHOT_TOOL_NAMES.some((token) => normalized === token || normalized.endsWith(`_${token}`));
|
|
9388
|
+
}
|
|
9389
|
+
function isBrowserRecordingToolName(toolName) {
|
|
9390
|
+
const normalized = normalizeToolName(toolName);
|
|
9391
|
+
if (!normalized)
|
|
9392
|
+
return false;
|
|
9393
|
+
return BROWSER_RECORDING_TOOL_NAMES.some((token) => normalized === token || normalized.endsWith(`_${token}`));
|
|
9394
|
+
}
|
|
9395
|
+
|
|
9324
9396
|
// ../shared/dist/agent/session-result.js
|
|
9325
9397
|
var SESSION_RESUME_FAILED_MESSAGE = "Session resume failed. The previous session may have expired or is no longer available. Please start a new session.";
|
|
9326
9398
|
|
|
@@ -9403,6 +9475,123 @@ function getAidenAgentPrompt(agentId) {
|
|
|
9403
9475
|
return getAgentSystemPrompt(agentId);
|
|
9404
9476
|
}
|
|
9405
9477
|
|
|
9478
|
+
// ../shared/dist/types/frontend.js
|
|
9479
|
+
var CLAUDE_48_EFFORT_LEVELS = [
|
|
9480
|
+
"low",
|
|
9481
|
+
"medium",
|
|
9482
|
+
"high",
|
|
9483
|
+
"xhigh",
|
|
9484
|
+
"max"
|
|
9485
|
+
];
|
|
9486
|
+
var CLAUDE_5_EFFORT_LEVELS = [
|
|
9487
|
+
"low",
|
|
9488
|
+
"medium",
|
|
9489
|
+
"high",
|
|
9490
|
+
"xhigh",
|
|
9491
|
+
"max"
|
|
9492
|
+
];
|
|
9493
|
+
var CODEX_5X_EFFORT_LEVELS = [
|
|
9494
|
+
"low",
|
|
9495
|
+
"medium",
|
|
9496
|
+
"high",
|
|
9497
|
+
"xhigh"
|
|
9498
|
+
];
|
|
9499
|
+
var AVAILABLE_MODELS = [
|
|
9500
|
+
{
|
|
9501
|
+
id: "",
|
|
9502
|
+
name: "CLI default",
|
|
9503
|
+
capabilities: { contextWindows: [], effortLevels: [] }
|
|
9504
|
+
},
|
|
9505
|
+
{
|
|
9506
|
+
id: "claude-sonnet-5",
|
|
9507
|
+
name: "Sonnet 5",
|
|
9508
|
+
capabilities: { contextWindows: ["200k", "1m"], effortLevels: CLAUDE_5_EFFORT_LEVELS }
|
|
9509
|
+
},
|
|
9510
|
+
{
|
|
9511
|
+
id: "claude-opus-4-8",
|
|
9512
|
+
name: "Opus 4.8",
|
|
9513
|
+
capabilities: { contextWindows: ["200k", "1m"], effortLevels: CLAUDE_48_EFFORT_LEVELS }
|
|
9514
|
+
},
|
|
9515
|
+
{
|
|
9516
|
+
id: "claude-haiku-4-5",
|
|
9517
|
+
name: "Haiku 4.5",
|
|
9518
|
+
capabilities: { contextWindows: ["200k"], effortLevels: [] }
|
|
9519
|
+
}
|
|
9520
|
+
];
|
|
9521
|
+
var CURSOR_AGENT_MODELS = [
|
|
9522
|
+
{ id: "auto", name: "Auto" },
|
|
9523
|
+
{ id: "composer-2.5-fast", name: "Composer 2.5 Fast" },
|
|
9524
|
+
{ id: "composer-2.5", name: "Composer 2.5" },
|
|
9525
|
+
{ id: "composer-2-fast", name: "Composer 2 Fast" },
|
|
9526
|
+
{ id: "composer-2", name: "Composer 2" },
|
|
9527
|
+
{ id: "claude-4.6-sonnet-medium", name: "Sonnet 4.6 1M" },
|
|
9528
|
+
{ id: "claude-4.6-sonnet-medium-thinking", name: "Sonnet 4.6 Thinking" },
|
|
9529
|
+
{ id: "gpt-5.3-codex", name: "Codex 5.3" },
|
|
9530
|
+
{ id: "gpt-5.4-medium", name: "GPT-5.4 1M" },
|
|
9531
|
+
{ id: "gemini-3-flash", name: "Gemini 3 Flash" },
|
|
9532
|
+
{ id: "gpt-5.5", name: "GPT-5.5" }
|
|
9533
|
+
];
|
|
9534
|
+
var COPILOT_CLI_MODELS = [
|
|
9535
|
+
{ id: "claude-sonnet-4.5", name: "Claude Sonnet 4.5" },
|
|
9536
|
+
{ id: "claude-sonnet-4.6", name: "Claude Sonnet 4.6" },
|
|
9537
|
+
{ id: "claude-haiku-4.5", name: "Claude Haiku 4.5" },
|
|
9538
|
+
{ id: "gpt-5.3-codex", name: "GPT-5.3 Codex" },
|
|
9539
|
+
{ id: "gpt-5.4", name: "GPT-5.4" },
|
|
9540
|
+
{ id: "gpt-5.4-mini", name: "GPT-5.4 Mini" },
|
|
9541
|
+
{ id: "auto", name: "Auto" }
|
|
9542
|
+
];
|
|
9543
|
+
var PROVIDER_MODELS = {
|
|
9544
|
+
claude_cli: AVAILABLE_MODELS,
|
|
9545
|
+
codex_app_server: [
|
|
9546
|
+
{
|
|
9547
|
+
id: "gpt-5.5",
|
|
9548
|
+
name: "GPT-5.5",
|
|
9549
|
+
capabilities: { contextWindows: ["1m"], effortLevels: CODEX_5X_EFFORT_LEVELS }
|
|
9550
|
+
},
|
|
9551
|
+
{
|
|
9552
|
+
id: "gpt-5.4-mini",
|
|
9553
|
+
name: "GPT-5.4 Mini",
|
|
9554
|
+
capabilities: { contextWindows: ["1m"], effortLevels: CODEX_5X_EFFORT_LEVELS }
|
|
9555
|
+
}
|
|
9556
|
+
],
|
|
9557
|
+
copilot_cli: COPILOT_CLI_MODELS,
|
|
9558
|
+
cursor_agent_cli: CURSOR_AGENT_MODELS,
|
|
9559
|
+
gemini_cli: [{ id: "", name: "CLI default" }],
|
|
9560
|
+
opencode_cli: [
|
|
9561
|
+
{ id: "opencode/north-mini-code-free", name: "North Mini Code Free" },
|
|
9562
|
+
{ id: "opencode/nemotron-3-ultra-free", name: "Nemotron 3 Ultra Free" },
|
|
9563
|
+
{ id: "opencode/deepseek-v4-flash-free", name: "DeepSeek V4 Flash Free" },
|
|
9564
|
+
{ id: "opencode/mimo-v2.5-free", name: "MiMo V2.5 Free" },
|
|
9565
|
+
{ id: "opencode/big-pickle", name: "Big Pickle" }
|
|
9566
|
+
],
|
|
9567
|
+
droid_cli: [
|
|
9568
|
+
{ id: "claude-opus-4-7", name: "Claude Opus 4.7" },
|
|
9569
|
+
{ id: "claude-opus-4-7-fast", name: "Claude Opus 4.7 Fast" },
|
|
9570
|
+
{ id: "claude-haiku-4-5-20251001", name: "Claude Haiku 4.5" },
|
|
9571
|
+
{ id: "gpt-5.3-codex", name: "GPT-5.3 Codex" },
|
|
9572
|
+
{ id: "gpt-5.2-codex", name: "GPT-5.2 Codex" },
|
|
9573
|
+
{ id: "gemini-3-pro-preview", name: "Gemini 3 Pro" },
|
|
9574
|
+
{ id: "gemini-3-flash-preview", name: "Gemini 3 Flash" },
|
|
9575
|
+
{ id: "glm-4.7", name: "GLM 4.7" },
|
|
9576
|
+
{ id: "kimi-k2.5", name: "Kimi k2.5" }
|
|
9577
|
+
],
|
|
9578
|
+
kimi_cli: [
|
|
9579
|
+
{ id: "kimi-latest", name: "Kimi Latest" },
|
|
9580
|
+
{ id: "kimi-k2.6", name: "Kimi K2.6" },
|
|
9581
|
+
{ id: "kimi-k2.6-thinking", name: "Kimi K2.6 Thinking" },
|
|
9582
|
+
{ id: "kimi-code/kimi-for-coding", name: "Kimi Code" }
|
|
9583
|
+
],
|
|
9584
|
+
supatest_cli: [
|
|
9585
|
+
{ id: "small", name: "Small" },
|
|
9586
|
+
{ id: "medium", name: "Medium" },
|
|
9587
|
+
{ id: "premium", name: "Premium" },
|
|
9588
|
+
{ id: "claude-sonnet-4-5", name: "Sonnet 4.5" },
|
|
9589
|
+
{ id: "claude-opus-4-5", name: "Opus 4.5" },
|
|
9590
|
+
{ id: "claude-haiku-4-5", name: "Haiku 4.5" }
|
|
9591
|
+
],
|
|
9592
|
+
generic_cli: []
|
|
9593
|
+
};
|
|
9594
|
+
|
|
9406
9595
|
// ../agent-core/dist/index.js
|
|
9407
9596
|
var import_readline = require("readline");
|
|
9408
9597
|
var import_child_process = require("child_process");
|
|
@@ -9621,6 +9810,12 @@ var import_path3 = require("path");
|
|
|
9621
9810
|
var import_fs4 = require("fs");
|
|
9622
9811
|
var import_os4 = require("os");
|
|
9623
9812
|
var import_path4 = require("path");
|
|
9813
|
+
var import_fs5 = require("fs");
|
|
9814
|
+
var import_os5 = require("os");
|
|
9815
|
+
var import_path5 = require("path");
|
|
9816
|
+
var import_crypto2 = require("crypto");
|
|
9817
|
+
var import_fs6 = require("fs");
|
|
9818
|
+
var import_path6 = require("path");
|
|
9624
9819
|
function shouldUseReadOnlyRuntimePermissions(config) {
|
|
9625
9820
|
if (isReadOnlyAgent(config.agentId)) return true;
|
|
9626
9821
|
switch (config.mode) {
|
|
@@ -9761,8 +9956,7 @@ function createGenericCliBackend(options) {
|
|
|
9761
9956
|
const state = {
|
|
9762
9957
|
process: null,
|
|
9763
9958
|
iterations: 0,
|
|
9764
|
-
summary: ""
|
|
9765
|
-
allowContinuation: options.allowContinuation ?? false
|
|
9959
|
+
summary: ""
|
|
9766
9960
|
};
|
|
9767
9961
|
const prompt = options.augmentPrompt?.(context) ?? (context.config.mode === "plan" ? buildPlanModePrefix(buildPromptWithSystem(context.config, context.promptText)) : buildPromptWithSystem(context.config, context.promptText));
|
|
9768
9962
|
const args = options.buildArgs?.(context, prompt) ?? options.args.map((arg) => arg === "{{prompt}}" ? prompt : arg);
|
|
@@ -9819,12 +10013,13 @@ function createGenericCliBackend(options) {
|
|
|
9819
10013
|
}
|
|
9820
10014
|
});
|
|
9821
10015
|
let exitCode;
|
|
10016
|
+
let idleTimedOut = false;
|
|
9822
10017
|
try {
|
|
9823
|
-
const exitPromise = new Promise((
|
|
10018
|
+
const exitPromise = new Promise((resolve22, reject) => {
|
|
9824
10019
|
child.on("error", (error) => {
|
|
9825
10020
|
reject(formatCliSpawnError(options.command, error));
|
|
9826
10021
|
});
|
|
9827
|
-
child.on("exit", (code) =>
|
|
10022
|
+
child.on("exit", (code) => resolve22(code ?? 0));
|
|
9828
10023
|
const onAbort = () => {
|
|
9829
10024
|
const pid = child.pid;
|
|
9830
10025
|
if (!pid) return;
|
|
@@ -9840,53 +10035,67 @@ function createGenericCliBackend(options) {
|
|
|
9840
10035
|
context.abortController.signal.addEventListener("abort", onAbort, { once: true });
|
|
9841
10036
|
});
|
|
9842
10037
|
if (options.keepStdinOpen) {
|
|
9843
|
-
|
|
9844
|
-
|
|
9845
|
-
|
|
9846
|
-
|
|
10038
|
+
const resultPromise = new Promise((resolve22) => {
|
|
10039
|
+
state.onResultReceived = () => resolve22("result_received");
|
|
10040
|
+
if (state.resultReceived) resolve22("result_received");
|
|
10041
|
+
});
|
|
10042
|
+
const IDLE_MS = options.resultIdleTimeoutMs ?? 10 * 60 * 1e3;
|
|
10043
|
+
let idleTimer = null;
|
|
10044
|
+
const idlePromise = new Promise((resolve22) => {
|
|
10045
|
+
const armIdleTimer = () => {
|
|
9847
10046
|
if (idleTimer) clearTimeout(idleTimer);
|
|
9848
10047
|
idleTimer = setTimeout(() => {
|
|
9849
|
-
if (
|
|
9850
|
-
|
|
9851
|
-
|
|
9852
|
-
|
|
9853
|
-
);
|
|
10048
|
+
if (presenter.pendingAskUserToolIds?.size) {
|
|
10049
|
+
resolve22("idle_timeout");
|
|
10050
|
+
} else {
|
|
10051
|
+
armIdleTimer();
|
|
9854
10052
|
}
|
|
9855
10053
|
}, IDLE_MS);
|
|
9856
10054
|
};
|
|
9857
|
-
state.onNewOutput =
|
|
9858
|
-
|
|
9859
|
-
|
|
9860
|
-
|
|
9861
|
-
|
|
9862
|
-
|
|
9863
|
-
|
|
9864
|
-
|
|
9865
|
-
|
|
9866
|
-
|
|
9867
|
-
|
|
9868
|
-
|
|
9869
|
-
|
|
9870
|
-
|
|
9871
|
-
|
|
9872
|
-
|
|
9873
|
-
|
|
9874
|
-
|
|
9875
|
-
|
|
9876
|
-
|
|
9877
|
-
|
|
9878
|
-
|
|
9879
|
-
|
|
9880
|
-
|
|
9881
|
-
|
|
9882
|
-
|
|
9883
|
-
|
|
9884
|
-
|
|
10055
|
+
state.onNewOutput = armIdleTimer;
|
|
10056
|
+
armIdleTimer();
|
|
10057
|
+
});
|
|
10058
|
+
const raceResult = await Promise.race([exitPromise, resultPromise, idlePromise]);
|
|
10059
|
+
if (idleTimer) clearTimeout(idleTimer);
|
|
10060
|
+
if (raceResult === "idle_timeout") {
|
|
10061
|
+
idleTimedOut = true;
|
|
10062
|
+
console.warn(
|
|
10063
|
+
`[${options.kind}] Idle timeout (${IDLE_MS}ms) waiting for a pending user answer \u2014 force-killing orphaned process`
|
|
10064
|
+
);
|
|
10065
|
+
try {
|
|
10066
|
+
if (process.platform === "win32") {
|
|
10067
|
+
child.kill("SIGKILL");
|
|
10068
|
+
} else if (child.pid) {
|
|
10069
|
+
process.kill(-child.pid, "SIGKILL");
|
|
10070
|
+
}
|
|
10071
|
+
} catch {
|
|
10072
|
+
}
|
|
10073
|
+
exitCode = await Promise.race([
|
|
10074
|
+
exitPromise,
|
|
10075
|
+
new Promise((resolve22) => setTimeout(() => resolve22(1), 5e3))
|
|
10076
|
+
]);
|
|
10077
|
+
} else if (raceResult === "result_received") {
|
|
10078
|
+
const GRACE_MS = 5e3;
|
|
10079
|
+
const gracedExit = await Promise.race([
|
|
10080
|
+
exitPromise,
|
|
10081
|
+
new Promise((resolve22) => setTimeout(() => resolve22(0), GRACE_MS))
|
|
10082
|
+
]);
|
|
10083
|
+
exitCode = typeof gracedExit === "number" ? gracedExit : 0;
|
|
10084
|
+
if (child.exitCode === null && !child.killed) {
|
|
10085
|
+
console.warn(
|
|
10086
|
+
`[${options.kind}] Process still alive ${GRACE_MS}ms after result event, killing`
|
|
10087
|
+
);
|
|
10088
|
+
try {
|
|
10089
|
+
if (process.platform === "win32") {
|
|
10090
|
+
child.kill("SIGKILL");
|
|
10091
|
+
} else if (child.pid) {
|
|
10092
|
+
process.kill(-child.pid, "SIGKILL");
|
|
9885
10093
|
}
|
|
10094
|
+
} catch {
|
|
9886
10095
|
}
|
|
9887
|
-
} else {
|
|
9888
|
-
exitCode = raceResult;
|
|
9889
10096
|
}
|
|
10097
|
+
} else {
|
|
10098
|
+
exitCode = raceResult;
|
|
9890
10099
|
}
|
|
9891
10100
|
} else {
|
|
9892
10101
|
exitCode = await exitPromise;
|
|
@@ -9910,6 +10119,31 @@ function createGenericCliBackend(options) {
|
|
|
9910
10119
|
usage: state.usage
|
|
9911
10120
|
};
|
|
9912
10121
|
}
|
|
10122
|
+
if (idleTimedOut) {
|
|
10123
|
+
console.error(`[${options.kind}] Process force-killed after idle timeout`, {
|
|
10124
|
+
stderrLines: stderrLines.slice(-10),
|
|
10125
|
+
summaryPreview: state.summary.slice(0, 200),
|
|
10126
|
+
runtimeSessionId: state.runtimeSessionId
|
|
10127
|
+
});
|
|
10128
|
+
await options.afterExit?.(context, state);
|
|
10129
|
+
const hasRenderableTurn2 = state.summary.trim().length > 0 || state.iterations > 0;
|
|
10130
|
+
if (hasRenderableTurn2) {
|
|
10131
|
+
await presenter.onTurnComplete([]);
|
|
10132
|
+
}
|
|
10133
|
+
return {
|
|
10134
|
+
success: false,
|
|
10135
|
+
summary: state.summary.trim() || "Agent execution timed out",
|
|
10136
|
+
filesModified: [],
|
|
10137
|
+
planFilesCreated: [],
|
|
10138
|
+
iterations: Math.max(state.iterations, 1),
|
|
10139
|
+
error: "Agent timed out waiting for your answer to its question \u2014 no response arrived, so the run was stopped. Send your reply as a new message to continue.",
|
|
10140
|
+
providerSessionId: state.runtimeSessionId,
|
|
10141
|
+
runtimeSessionId: state.runtimeSessionId,
|
|
10142
|
+
backendKind: options.kind,
|
|
10143
|
+
supportTier: options.supportTier,
|
|
10144
|
+
usage: state.usage
|
|
10145
|
+
};
|
|
10146
|
+
}
|
|
9913
10147
|
if (exitCode !== 0) {
|
|
9914
10148
|
console.error(`[${options.kind}] Process exited with code ${exitCode}`, {
|
|
9915
10149
|
stderrLines: stderrLines.slice(-10),
|
|
@@ -9982,11 +10216,6 @@ function parseClaudeStructuredLine(line, context, state) {
|
|
|
9982
10216
|
);
|
|
9983
10217
|
break;
|
|
9984
10218
|
}
|
|
9985
|
-
if (state.resultReceived && state.allowContinuation) {
|
|
9986
|
-
console.info("[claude_cli] Continuation turn detected \u2014 restarting presenter");
|
|
9987
|
-
state.resultReceived = false;
|
|
9988
|
-
void presenter.onStart(context.config);
|
|
9989
|
-
}
|
|
9990
10219
|
state.onNewOutput?.();
|
|
9991
10220
|
state.iterations += 1;
|
|
9992
10221
|
const message = typeof parsed.message === "object" && parsed.message !== null ? parsed.message : null;
|
|
@@ -10115,31 +10344,10 @@ function parseClaudeStructuredLine(line, context, state) {
|
|
|
10115
10344
|
break;
|
|
10116
10345
|
}
|
|
10117
10346
|
state.resultReceived = true;
|
|
10118
|
-
|
|
10119
|
-
|
|
10120
|
-
|
|
10121
|
-
|
|
10122
|
-
filesModified: [],
|
|
10123
|
-
planFilesCreated: [],
|
|
10124
|
-
iterations: Math.max(state.iterations, 1),
|
|
10125
|
-
error: state.error ? classifyCliError(state.error, 0) : void 0,
|
|
10126
|
-
providerSessionId: state.runtimeSessionId,
|
|
10127
|
-
runtimeSessionId: state.runtimeSessionId,
|
|
10128
|
-
backendKind: context.config.backendKind,
|
|
10129
|
-
supportTier: context.config.supportTier,
|
|
10130
|
-
usage: state.usage
|
|
10131
|
-
};
|
|
10132
|
-
void presenter.onComplete(continuationResult);
|
|
10133
|
-
state.onNewOutput?.();
|
|
10134
|
-
console.info(
|
|
10135
|
-
"[claude_cli] Result received in continuation mode \u2014 keeping stdin open for background work"
|
|
10136
|
-
);
|
|
10137
|
-
} else {
|
|
10138
|
-
state.onResultReceived?.();
|
|
10139
|
-
if (state.stdin && !state.stdin.destroyed) {
|
|
10140
|
-
state.stdin.end();
|
|
10141
|
-
console.info("[claude_cli] Closed stdin after result event to signal CLI exit");
|
|
10142
|
-
}
|
|
10347
|
+
state.onResultReceived?.();
|
|
10348
|
+
if (state.stdin && !state.stdin.destroyed) {
|
|
10349
|
+
state.stdin.end();
|
|
10350
|
+
console.info("[claude_cli] Closed stdin after result event to signal CLI exit");
|
|
10143
10351
|
}
|
|
10144
10352
|
break;
|
|
10145
10353
|
}
|
|
@@ -11333,10 +11541,36 @@ function parseGeminiStructuredLine(line, context, state) {
|
|
|
11333
11541
|
break;
|
|
11334
11542
|
}
|
|
11335
11543
|
}
|
|
11336
|
-
function
|
|
11544
|
+
function parseAntigravityLine(line, context, state) {
|
|
11545
|
+
try {
|
|
11546
|
+
JSON.parse(line);
|
|
11547
|
+
parseGeminiStructuredLine(line, context, state);
|
|
11548
|
+
return;
|
|
11549
|
+
} catch {
|
|
11550
|
+
}
|
|
11551
|
+
if (!line.trim()) return;
|
|
11552
|
+
state.iterations = Math.max(state.iterations, 1);
|
|
11553
|
+
state.summary += `${line}
|
|
11554
|
+
`;
|
|
11555
|
+
void context.presenter.onAssistantText(`${line}
|
|
11556
|
+
`);
|
|
11557
|
+
}
|
|
11558
|
+
function buildAntigravityCliArgs(context, prompt, defaultArgs = []) {
|
|
11559
|
+
const args = [];
|
|
11560
|
+
const selectedModel = context.config.selectedModel?.trim();
|
|
11561
|
+
const resumeId = context.config.runtimeSessionId?.trim() || context.config.providerSessionId?.trim();
|
|
11562
|
+
if (selectedModel) args.push("--model", selectedModel);
|
|
11563
|
+
if (resumeId) args.push("--conversation", resumeId);
|
|
11564
|
+
if (!shouldUseReadOnlyRuntimePermissions(context.config)) {
|
|
11565
|
+
args.push("--dangerously-skip-permissions");
|
|
11566
|
+
}
|
|
11567
|
+
args.push("--print-timeout", "10m");
|
|
11568
|
+
return [...args, ...defaultArgs, "-p", prompt];
|
|
11569
|
+
}
|
|
11570
|
+
function createAntigravityCliBackend(command = "agy", defaultArgs = []) {
|
|
11337
11571
|
return {
|
|
11338
11572
|
kind: "gemini_cli",
|
|
11339
|
-
supportTier: "
|
|
11573
|
+
supportTier: "text",
|
|
11340
11574
|
async run(context) {
|
|
11341
11575
|
const { files: imageFiles, cleanup } = writeImagesToTempFiles(
|
|
11342
11576
|
context.config.images,
|
|
@@ -11345,22 +11579,12 @@ function createGeminiCliBackend(command = "gemini", defaultArgs = []) {
|
|
|
11345
11579
|
try {
|
|
11346
11580
|
return await createGenericCliBackend({
|
|
11347
11581
|
kind: "gemini_cli",
|
|
11348
|
-
supportTier: "
|
|
11582
|
+
supportTier: "text",
|
|
11349
11583
|
command,
|
|
11350
11584
|
args: [],
|
|
11351
|
-
buildArgs: (ctx) =>
|
|
11352
|
-
const args = ["-p", "", "--output-format", "stream-json"];
|
|
11353
|
-
const resumeId = ctx.config.runtimeSessionId?.trim() || ctx.config.providerSessionId?.trim();
|
|
11354
|
-
const approvalMode = shouldUseReadOnlyRuntimePermissions(ctx.config) ? "plan" : "yolo";
|
|
11355
|
-
args.push("--approval-mode", approvalMode);
|
|
11356
|
-
if (resumeId) args.push("--resume", resumeId);
|
|
11357
|
-
if (ctx.config.selectedModel?.trim())
|
|
11358
|
-
args.push("--model", ctx.config.selectedModel.trim());
|
|
11359
|
-
return [...args, ...defaultArgs];
|
|
11360
|
-
},
|
|
11361
|
-
promptViaStdin: true,
|
|
11585
|
+
buildArgs: (ctx, prompt) => buildAntigravityCliArgs(ctx, prompt, defaultArgs),
|
|
11362
11586
|
augmentPrompt: (ctx) => buildPromptWithImagePathReferences(ctx, imageFiles),
|
|
11363
|
-
parseStructuredLine:
|
|
11587
|
+
parseStructuredLine: parseAntigravityLine
|
|
11364
11588
|
}).run(context);
|
|
11365
11589
|
} finally {
|
|
11366
11590
|
cleanup();
|
|
@@ -11368,6 +11592,72 @@ function createGeminiCliBackend(command = "gemini", defaultArgs = []) {
|
|
|
11368
11592
|
}
|
|
11369
11593
|
};
|
|
11370
11594
|
}
|
|
11595
|
+
function createGeminiCliBackend(command = "agy", defaultArgs = []) {
|
|
11596
|
+
return createAntigravityCliBackend(command, defaultArgs);
|
|
11597
|
+
}
|
|
11598
|
+
var DEFAULT_SKILL_ROOTS = [
|
|
11599
|
+
(0, import_path4.join)((0, import_os4.homedir)(), ".agents", "skills"),
|
|
11600
|
+
(0, import_path4.join)((0, import_os4.homedir)(), ".claude", "skills"),
|
|
11601
|
+
(0, import_path4.join)((0, import_os4.homedir)(), ".config", "opencode", "skills")
|
|
11602
|
+
];
|
|
11603
|
+
function parseFrontmatter(content) {
|
|
11604
|
+
if (!content.startsWith("---\n")) return {};
|
|
11605
|
+
const end = content.indexOf("\n---", 4);
|
|
11606
|
+
if (end === -1) return {};
|
|
11607
|
+
const result = {};
|
|
11608
|
+
for (const line of content.slice(4, end).split("\n")) {
|
|
11609
|
+
const match = /^([A-Za-z0-9_-]+):\s*(.*)$/.exec(line.trim());
|
|
11610
|
+
if (!match) continue;
|
|
11611
|
+
const [, key, rawValue] = match;
|
|
11612
|
+
result[key] = rawValue.replace(/^["']|["']$/g, "").trim();
|
|
11613
|
+
}
|
|
11614
|
+
return result;
|
|
11615
|
+
}
|
|
11616
|
+
function listSkillFiles(root) {
|
|
11617
|
+
if (!(0, import_fs4.existsSync)(root)) return [];
|
|
11618
|
+
const files = [];
|
|
11619
|
+
for (const entry of (0, import_fs4.readdirSync)(root, { withFileTypes: true })) {
|
|
11620
|
+
if (!entry.isDirectory()) continue;
|
|
11621
|
+
const skillPath = (0, import_path4.join)(root, entry.name, "SKILL.md");
|
|
11622
|
+
if ((0, import_fs4.existsSync)(skillPath)) files.push(skillPath);
|
|
11623
|
+
}
|
|
11624
|
+
return files;
|
|
11625
|
+
}
|
|
11626
|
+
function loadInstalledSkills(roots = DEFAULT_SKILL_ROOTS) {
|
|
11627
|
+
const skills = /* @__PURE__ */ new Map();
|
|
11628
|
+
for (const root of roots) {
|
|
11629
|
+
for (const skillPath of listSkillFiles(root)) {
|
|
11630
|
+
try {
|
|
11631
|
+
const frontmatter = parseFrontmatter((0, import_fs4.readFileSync)(skillPath, "utf8"));
|
|
11632
|
+
const name = frontmatter.name;
|
|
11633
|
+
const description = frontmatter.description;
|
|
11634
|
+
if (!name || !description || skills.has(name)) continue;
|
|
11635
|
+
skills.set(name, { name, description, path: skillPath });
|
|
11636
|
+
} catch {
|
|
11637
|
+
}
|
|
11638
|
+
}
|
|
11639
|
+
}
|
|
11640
|
+
return [...skills.values()].sort((a, b) => a.name.localeCompare(b.name));
|
|
11641
|
+
}
|
|
11642
|
+
function buildInstalledSkillsPrompt(roots = DEFAULT_SKILL_ROOTS) {
|
|
11643
|
+
const skills = loadInstalledSkills(roots);
|
|
11644
|
+
if (skills.length === 0) return void 0;
|
|
11645
|
+
return [
|
|
11646
|
+
"## Installed Skills",
|
|
11647
|
+
"",
|
|
11648
|
+
"Use an installed skill before improvising when the task matches a skill description.",
|
|
11649
|
+
"",
|
|
11650
|
+
"Protocol:",
|
|
11651
|
+
"1. Match the request against the skill names and descriptions below.",
|
|
11652
|
+
"2. Before acting on a matching skill, read its SKILL.md file completely.",
|
|
11653
|
+
"3. Resolve any referenced files such as references/, scripts/, or assets/ relative to the skill directory.",
|
|
11654
|
+
"4. Use the smallest set of matching skills for the current turn only.",
|
|
11655
|
+
"5. If a named skill is missing or unreadable, say so briefly and continue with the best fallback.",
|
|
11656
|
+
"",
|
|
11657
|
+
"Available skills:",
|
|
11658
|
+
...skills.map((skill) => `- ${skill.name}: ${skill.description} (file: ${skill.path})`)
|
|
11659
|
+
].join("\n");
|
|
11660
|
+
}
|
|
11371
11661
|
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;
|
|
11372
11662
|
function parseKimiStderrLine(line, state) {
|
|
11373
11663
|
const match = line.match(KIMI_RESUME_SESSION_RE);
|
|
@@ -11470,7 +11760,13 @@ function createKimiCliBackend(command = "kimi-cli", defaultArgs = []) {
|
|
|
11470
11760
|
if (model) args.push("--model", model);
|
|
11471
11761
|
return [...args, ...defaultArgs, "--prompt", prompt];
|
|
11472
11762
|
},
|
|
11473
|
-
augmentPrompt: (ctx) =>
|
|
11763
|
+
augmentPrompt: (ctx) => {
|
|
11764
|
+
const skillPrompt = buildInstalledSkillsPrompt();
|
|
11765
|
+
const promptText = [skillPrompt, ctx.promptText].filter(Boolean).join("\n\n");
|
|
11766
|
+
const basePrompt = buildPromptWithSystem(ctx.config, promptText);
|
|
11767
|
+
const modePrompt = ctx.config.mode === "plan" ? buildPlanModePrefix(basePrompt) : basePrompt;
|
|
11768
|
+
return appendImagePathReferences(modePrompt, imageFiles);
|
|
11769
|
+
},
|
|
11474
11770
|
parseStructuredLine: parseKimiStructuredLine,
|
|
11475
11771
|
parseStderrLine: (line, _ctx, state) => parseKimiStderrLine(line, state)
|
|
11476
11772
|
}).run(context);
|
|
@@ -11813,40 +12109,40 @@ function parseSkillInvocation(text) {
|
|
|
11813
12109
|
function candidateRoots(cwd) {
|
|
11814
12110
|
const roots = [];
|
|
11815
12111
|
if (cwd) {
|
|
11816
|
-
roots.push((0,
|
|
11817
|
-
roots.push((0,
|
|
11818
|
-
roots.push((0,
|
|
11819
|
-
if ((0,
|
|
12112
|
+
roots.push((0, import_path5.join)(cwd, ".agents", "skills"));
|
|
12113
|
+
roots.push((0, import_path5.join)(cwd, ".claude", "skills"));
|
|
12114
|
+
roots.push((0, import_path5.join)(cwd, ".codex", "skills"));
|
|
12115
|
+
if ((0, import_fs5.existsSync)(cwd)) {
|
|
11820
12116
|
let entries = [];
|
|
11821
12117
|
try {
|
|
11822
|
-
entries = (0,
|
|
12118
|
+
entries = (0, import_fs5.readdirSync)(cwd, { withFileTypes: true });
|
|
11823
12119
|
} catch {
|
|
11824
12120
|
}
|
|
11825
12121
|
for (const entry of entries) {
|
|
11826
12122
|
if (!entry.isDirectory()) continue;
|
|
11827
12123
|
if (entry.name.startsWith(".")) continue;
|
|
11828
|
-
const child = (0,
|
|
11829
|
-
roots.push((0,
|
|
11830
|
-
roots.push((0,
|
|
11831
|
-
roots.push((0,
|
|
12124
|
+
const child = (0, import_path5.join)(cwd, entry.name);
|
|
12125
|
+
roots.push((0, import_path5.join)(child, ".agents", "skills"));
|
|
12126
|
+
roots.push((0, import_path5.join)(child, ".claude", "skills"));
|
|
12127
|
+
roots.push((0, import_path5.join)(child, ".codex", "skills"));
|
|
11832
12128
|
}
|
|
11833
12129
|
}
|
|
11834
12130
|
}
|
|
11835
|
-
const home = (0,
|
|
11836
|
-
roots.push((0,
|
|
11837
|
-
roots.push((0,
|
|
11838
|
-
roots.push((0,
|
|
12131
|
+
const home = (0, import_os5.homedir)();
|
|
12132
|
+
roots.push((0, import_path5.join)(home, ".agents", "skills"));
|
|
12133
|
+
roots.push((0, import_path5.join)(home, ".claude", "skills"));
|
|
12134
|
+
roots.push((0, import_path5.join)(home, ".codex", "skills"));
|
|
11839
12135
|
return Array.from(new Set(roots));
|
|
11840
12136
|
}
|
|
11841
12137
|
function resolveSkillInvocation(text, cwd) {
|
|
11842
12138
|
const parsed = parseSkillInvocation(text);
|
|
11843
12139
|
if (!parsed) return null;
|
|
11844
12140
|
for (const root of candidateRoots(cwd)) {
|
|
11845
|
-
const skillPath = (0,
|
|
11846
|
-
if (!(0,
|
|
12141
|
+
const skillPath = (0, import_path5.join)(root, parsed.command, "SKILL.md");
|
|
12142
|
+
if (!(0, import_fs5.existsSync)(skillPath)) continue;
|
|
11847
12143
|
let content;
|
|
11848
12144
|
try {
|
|
11849
|
-
content = (0,
|
|
12145
|
+
content = (0, import_fs5.readFileSync)(skillPath, "utf-8");
|
|
11850
12146
|
} catch {
|
|
11851
12147
|
continue;
|
|
11852
12148
|
}
|
|
@@ -11880,7 +12176,6 @@ function expandSkillInvocationPrompt(text, cwd) {
|
|
|
11880
12176
|
].join("\n")
|
|
11881
12177
|
};
|
|
11882
12178
|
}
|
|
11883
|
-
var DEFAULT_MODEL = "claude-sonnet-4-6";
|
|
11884
12179
|
var DROID_DEFAULT_MODEL = "claude-opus-4-7";
|
|
11885
12180
|
var AGENT_ACTIVITY_HEARTBEAT_MS = 1e4;
|
|
11886
12181
|
function defaultSelectedModelForBackend(backendKind) {
|
|
@@ -11895,10 +12190,18 @@ function defaultSelectedModelForBackend(backendKind) {
|
|
|
11895
12190
|
return void 0;
|
|
11896
12191
|
case "opencode_cli":
|
|
11897
12192
|
return void 0;
|
|
12193
|
+
case "gemini_cli":
|
|
12194
|
+
return void 0;
|
|
11898
12195
|
case "supatest_cli":
|
|
11899
12196
|
return "medium";
|
|
12197
|
+
case "codex_app_server":
|
|
12198
|
+
case "cursor_agent_cli":
|
|
12199
|
+
return PROVIDER_MODELS[backendKind]?.[0]?.id || void 0;
|
|
12200
|
+
case "generic_cli":
|
|
12201
|
+
case "simulation":
|
|
12202
|
+
return void 0;
|
|
11900
12203
|
default:
|
|
11901
|
-
return
|
|
12204
|
+
return void 0;
|
|
11902
12205
|
}
|
|
11903
12206
|
}
|
|
11904
12207
|
function canonicalizePath(inputPath) {
|
|
@@ -12037,12 +12340,13 @@ var BaseMachineAgent = class _BaseMachineAgent {
|
|
|
12037
12340
|
case "codex_app_server":
|
|
12038
12341
|
case "cursor_agent_cli":
|
|
12039
12342
|
case "droid_cli":
|
|
12040
|
-
case "gemini_cli":
|
|
12041
12343
|
case "opencode_cli":
|
|
12042
12344
|
case "copilot_cli":
|
|
12043
12345
|
case "supatest_cli":
|
|
12044
12346
|
case "kimi_cli":
|
|
12045
12347
|
return "structured";
|
|
12348
|
+
case "gemini_cli":
|
|
12349
|
+
return "text";
|
|
12046
12350
|
default:
|
|
12047
12351
|
return "text";
|
|
12048
12352
|
}
|
|
@@ -12096,7 +12400,7 @@ Prefer relative paths and keep your work scoped to this project.`
|
|
|
12096
12400
|
const promptText = this.buildPromptText(runtimeConfig);
|
|
12097
12401
|
const runtimeCommand = runtimeConfig.runtimeCommand || this.runtime.runtimeCommand;
|
|
12098
12402
|
const runtimeArgs = runtimeConfig.runtimeArgs || this.runtime.runtimeArgs || [];
|
|
12099
|
-
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 || "
|
|
12403
|
+
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 || "agy", 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(
|
|
12100
12404
|
runtimeCommand || "generic-cli",
|
|
12101
12405
|
runtimeArgs
|
|
12102
12406
|
);
|
|
@@ -12162,18 +12466,18 @@ Prefer relative paths and keep your work scoped to this project.`
|
|
|
12162
12466
|
`[base-machine-agent] Transient error (attempt ${attempt + 1}/${_BaseMachineAgent.MAX_RETRIES + 1}), retrying in ${delayMs}ms: ${lastResult.error}`
|
|
12163
12467
|
);
|
|
12164
12468
|
void this.presenter.onLog(`Transient error, retrying in ${Math.round(delayMs / 1e3)}s...`);
|
|
12165
|
-
await new Promise((
|
|
12469
|
+
await new Promise((resolve22) => {
|
|
12166
12470
|
const signal = this.abortController?.signal;
|
|
12167
12471
|
if (signal?.aborted) {
|
|
12168
|
-
|
|
12472
|
+
resolve22();
|
|
12169
12473
|
return;
|
|
12170
12474
|
}
|
|
12171
|
-
const timeoutId = setTimeout(
|
|
12475
|
+
const timeoutId = setTimeout(resolve22, delayMs);
|
|
12172
12476
|
signal?.addEventListener(
|
|
12173
12477
|
"abort",
|
|
12174
12478
|
() => {
|
|
12175
12479
|
clearTimeout(timeoutId);
|
|
12176
|
-
|
|
12480
|
+
resolve22();
|
|
12177
12481
|
},
|
|
12178
12482
|
{ once: true }
|
|
12179
12483
|
);
|
|
@@ -12243,6 +12547,195 @@ Prefer relative paths and keep your work scoped to this project.`
|
|
|
12243
12547
|
}
|
|
12244
12548
|
}
|
|
12245
12549
|
};
|
|
12550
|
+
var IMAGE_MIME_BY_EXT = {
|
|
12551
|
+
".gif": "image/gif",
|
|
12552
|
+
".jpeg": "image/jpeg",
|
|
12553
|
+
".jpg": "image/jpeg",
|
|
12554
|
+
".png": "image/png",
|
|
12555
|
+
".webp": "image/webp"
|
|
12556
|
+
};
|
|
12557
|
+
var VIDEO_MIME_BY_EXT = {
|
|
12558
|
+
".mov": "video/quicktime",
|
|
12559
|
+
".mp4": "video/mp4",
|
|
12560
|
+
".webm": "video/webm"
|
|
12561
|
+
};
|
|
12562
|
+
var MAX_GENERATED_IMAGE_BYTES = 20 * 1024 * 1024;
|
|
12563
|
+
var MAX_SESSION_VIDEO_BYTES = 100 * 1024 * 1024;
|
|
12564
|
+
function isRecord(value2) {
|
|
12565
|
+
return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
|
|
12566
|
+
}
|
|
12567
|
+
function shouldExtractGeneratedImagesFromToolResult(toolName, content, options = {}) {
|
|
12568
|
+
return isGeneratedImageToolName(toolName) || isBrowserScreenshotToolName(toolName) || isAgentBrowserMediaInvocation(toolName, content, options.toolInput, "image");
|
|
12569
|
+
}
|
|
12570
|
+
function collectStringValues(value2, out) {
|
|
12571
|
+
if (typeof value2 === "string") {
|
|
12572
|
+
out.push(value2);
|
|
12573
|
+
return;
|
|
12574
|
+
}
|
|
12575
|
+
if (Array.isArray(value2)) {
|
|
12576
|
+
for (const item of value2) collectStringValues(item, out);
|
|
12577
|
+
return;
|
|
12578
|
+
}
|
|
12579
|
+
if (!value2 || typeof value2 !== "object") return;
|
|
12580
|
+
for (const entry of Object.values(value2)) {
|
|
12581
|
+
collectStringValues(entry, out);
|
|
12582
|
+
}
|
|
12583
|
+
}
|
|
12584
|
+
function collectContentStrings(content, toolInput) {
|
|
12585
|
+
const values = [];
|
|
12586
|
+
if (content) {
|
|
12587
|
+
values.push(content);
|
|
12588
|
+
try {
|
|
12589
|
+
collectStringValues(JSON.parse(content), values);
|
|
12590
|
+
} catch {
|
|
12591
|
+
}
|
|
12592
|
+
}
|
|
12593
|
+
collectStringValues(toolInput, values);
|
|
12594
|
+
return values;
|
|
12595
|
+
}
|
|
12596
|
+
function isAgentBrowserMediaInvocation(toolName, content, toolInput, kind) {
|
|
12597
|
+
if (kind === "image" && isBrowserScreenshotToolName(toolName)) return true;
|
|
12598
|
+
if (kind === "video" && isBrowserRecordingToolName(toolName)) return true;
|
|
12599
|
+
const haystack = collectContentStrings(content, toolInput).join("\n").toLowerCase();
|
|
12600
|
+
if (!/(^|[^a-z0-9_-])agent[-_]browser([^a-z0-9_-]|$)/.test(haystack)) return false;
|
|
12601
|
+
return kind === "image" ? /\b(screenshot|capture)\b/.test(haystack) : /\b(record|recording|video)\b/.test(haystack);
|
|
12602
|
+
}
|
|
12603
|
+
function extractPathCandidatesFromValues(values, extensionsPattern = "png|jpe?g|gif|webp") {
|
|
12604
|
+
const paths = /* @__PURE__ */ new Set();
|
|
12605
|
+
const filePathPattern = new RegExp(
|
|
12606
|
+
`(?:file:\\/\\/)?(?:~|\\.{1,2}|\\/)?[^\\s"'\`)\\]}<>]+?\\.(?:${extensionsPattern})\\b`,
|
|
12607
|
+
"gi"
|
|
12608
|
+
);
|
|
12609
|
+
for (const value2 of values) {
|
|
12610
|
+
for (const match of value2.matchAll(filePathPattern)) {
|
|
12611
|
+
paths.add(match[0]);
|
|
12612
|
+
}
|
|
12613
|
+
}
|
|
12614
|
+
return [...paths];
|
|
12615
|
+
}
|
|
12616
|
+
function extractPathCandidates(content, options, extensionsPattern = "png|jpe?g|gif|webp") {
|
|
12617
|
+
return [
|
|
12618
|
+
...extractPathCandidatesFromValues(
|
|
12619
|
+
collectContentStrings(content, options.toolInput),
|
|
12620
|
+
extensionsPattern
|
|
12621
|
+
),
|
|
12622
|
+
...options.pathHints ?? []
|
|
12623
|
+
];
|
|
12624
|
+
}
|
|
12625
|
+
function normalizePath(candidate, cwd) {
|
|
12626
|
+
let path = candidate.trim().replace(/^file:\/\//, "");
|
|
12627
|
+
try {
|
|
12628
|
+
path = decodeURI(path);
|
|
12629
|
+
} catch {
|
|
12630
|
+
}
|
|
12631
|
+
if (path.startsWith("~/")) return null;
|
|
12632
|
+
if ((0, import_path6.isAbsolute)(path)) return path;
|
|
12633
|
+
return cwd ? (0, import_path6.join)(cwd, path) : null;
|
|
12634
|
+
}
|
|
12635
|
+
function resolveToolCwd(cwd, toolInput) {
|
|
12636
|
+
if (!isRecord(toolInput)) return cwd;
|
|
12637
|
+
const raw = typeof toolInput.cwd === "string" ? toolInput.cwd : typeof toolInput.workdir === "string" ? toolInput.workdir : typeof toolInput.workingDirectory === "string" ? toolInput.workingDirectory : null;
|
|
12638
|
+
if (!raw) return cwd;
|
|
12639
|
+
return (0, import_path6.isAbsolute)(raw) || !cwd ? raw : (0, import_path6.join)(cwd, raw);
|
|
12640
|
+
}
|
|
12641
|
+
function extractBrowserMediaPathHints(content, cwd, toolName, options = {}, kind = "video") {
|
|
12642
|
+
if (!isAgentBrowserMediaInvocation(toolName, content, options.toolInput, kind)) return [];
|
|
12643
|
+
const extensionsPattern = kind === "video" ? "mp4|webm|mov" : "png|jpe?g|gif|webp";
|
|
12644
|
+
const effectiveCwd = resolveToolCwd(cwd, options.toolInput);
|
|
12645
|
+
return extractPathCandidatesFromValues(
|
|
12646
|
+
collectContentStrings(content, options.toolInput),
|
|
12647
|
+
extensionsPattern
|
|
12648
|
+
).map((candidate) => normalizePath(candidate, effectiveCwd)).filter((path) => Boolean(path));
|
|
12649
|
+
}
|
|
12650
|
+
function readImageDimensions2(buffer, mimeType) {
|
|
12651
|
+
if (mimeType === "image/png" && buffer.length >= 24 && buffer.toString("ascii", 1, 4) === "PNG") {
|
|
12652
|
+
return { width: buffer.readUInt32BE(16), height: buffer.readUInt32BE(20) };
|
|
12653
|
+
}
|
|
12654
|
+
if (mimeType === "image/gif" && buffer.length >= 10 && buffer.toString("ascii", 0, 3) === "GIF") {
|
|
12655
|
+
return { width: buffer.readUInt16LE(6), height: buffer.readUInt16LE(8) };
|
|
12656
|
+
}
|
|
12657
|
+
if (mimeType === "image/jpeg" && buffer.length > 4) {
|
|
12658
|
+
let offset = 2;
|
|
12659
|
+
while (offset + 9 < buffer.length) {
|
|
12660
|
+
if (buffer[offset] !== 255) break;
|
|
12661
|
+
const marker = buffer[offset + 1];
|
|
12662
|
+
const length = buffer.readUInt16BE(offset + 2);
|
|
12663
|
+
if (length < 2) break;
|
|
12664
|
+
if (marker >= 192 && marker <= 207 && ![196, 200, 204].includes(marker)) {
|
|
12665
|
+
return {
|
|
12666
|
+
width: buffer.readUInt16BE(offset + 7),
|
|
12667
|
+
height: buffer.readUInt16BE(offset + 5)
|
|
12668
|
+
};
|
|
12669
|
+
}
|
|
12670
|
+
offset += 2 + length;
|
|
12671
|
+
}
|
|
12672
|
+
}
|
|
12673
|
+
return { width: null, height: null };
|
|
12674
|
+
}
|
|
12675
|
+
function extractGeneratedImagesFromToolResult(toolId, content, cwd, toolName, options = {}) {
|
|
12676
|
+
if (!shouldExtractGeneratedImagesFromToolResult(toolName, content, options)) return [];
|
|
12677
|
+
const images = [];
|
|
12678
|
+
const seen = /* @__PURE__ */ new Set();
|
|
12679
|
+
const effectiveCwd = resolveToolCwd(cwd, options.toolInput);
|
|
12680
|
+
for (const candidate of extractPathCandidates(content, options)) {
|
|
12681
|
+
const path = normalizePath(candidate, effectiveCwd);
|
|
12682
|
+
if (!path || seen.has(path) || !(0, import_fs6.existsSync)(path)) continue;
|
|
12683
|
+
seen.add(path);
|
|
12684
|
+
const ext = (0, import_path6.extname)(path).toLowerCase();
|
|
12685
|
+
const mimeType = IMAGE_MIME_BY_EXT[ext];
|
|
12686
|
+
if (!mimeType) continue;
|
|
12687
|
+
const stat = (0, import_fs6.statSync)(path);
|
|
12688
|
+
if (!stat.isFile() || stat.size <= 0 || stat.size > MAX_GENERATED_IMAGE_BYTES) continue;
|
|
12689
|
+
const buffer = (0, import_fs6.readFileSync)(path);
|
|
12690
|
+
const { width, height } = readImageDimensions2(buffer, mimeType);
|
|
12691
|
+
images.push({
|
|
12692
|
+
type: "generated_image",
|
|
12693
|
+
id: (0, import_crypto2.randomUUID)(),
|
|
12694
|
+
filename: (0, import_path6.basename)(path),
|
|
12695
|
+
mimeType,
|
|
12696
|
+
size: buffer.length,
|
|
12697
|
+
width,
|
|
12698
|
+
height,
|
|
12699
|
+
data: buffer.toString("base64"),
|
|
12700
|
+
sourcePath: path,
|
|
12701
|
+
sourceHash: (0, import_crypto2.createHash)("sha256").update(buffer).digest("hex"),
|
|
12702
|
+
toolId,
|
|
12703
|
+
ts: Date.now()
|
|
12704
|
+
});
|
|
12705
|
+
}
|
|
12706
|
+
return images;
|
|
12707
|
+
}
|
|
12708
|
+
function extractSessionMediaFromToolResult(toolId, content, cwd, toolName, options = {}) {
|
|
12709
|
+
if (!isAgentBrowserMediaInvocation(toolName, content, options.toolInput, "video")) return [];
|
|
12710
|
+
const media = [];
|
|
12711
|
+
const seen = /* @__PURE__ */ new Set();
|
|
12712
|
+
const effectiveCwd = resolveToolCwd(cwd, options.toolInput);
|
|
12713
|
+
for (const candidate of extractPathCandidates(content, options, "mp4|webm|mov")) {
|
|
12714
|
+
const path = normalizePath(candidate, effectiveCwd);
|
|
12715
|
+
if (!path || seen.has(path) || !(0, import_fs6.existsSync)(path)) continue;
|
|
12716
|
+
seen.add(path);
|
|
12717
|
+
const ext = (0, import_path6.extname)(path).toLowerCase();
|
|
12718
|
+
const mimeType = VIDEO_MIME_BY_EXT[ext];
|
|
12719
|
+
if (!mimeType) continue;
|
|
12720
|
+
const stat = (0, import_fs6.statSync)(path);
|
|
12721
|
+
if (!stat.isFile() || stat.size <= 0 || stat.size > MAX_SESSION_VIDEO_BYTES) continue;
|
|
12722
|
+
const buffer = (0, import_fs6.readFileSync)(path);
|
|
12723
|
+
media.push({
|
|
12724
|
+
type: "session_media",
|
|
12725
|
+
kind: "video",
|
|
12726
|
+
id: (0, import_crypto2.randomUUID)(),
|
|
12727
|
+
filename: (0, import_path6.basename)(path),
|
|
12728
|
+
mimeType,
|
|
12729
|
+
size: buffer.length,
|
|
12730
|
+
data: buffer.toString("base64"),
|
|
12731
|
+
sourcePath: path,
|
|
12732
|
+
sourceHash: (0, import_crypto2.createHash)("sha256").update(buffer).digest("hex"),
|
|
12733
|
+
toolId,
|
|
12734
|
+
ts: Date.now()
|
|
12735
|
+
});
|
|
12736
|
+
}
|
|
12737
|
+
return media;
|
|
12738
|
+
}
|
|
12246
12739
|
|
|
12247
12740
|
// src/core-agent.ts
|
|
12248
12741
|
var CoreAgent = class _CoreAgent extends BaseMachineAgent {
|
|
@@ -12541,149 +13034,162 @@ ${meta.description}`);
|
|
|
12541
13034
|
}
|
|
12542
13035
|
};
|
|
12543
13036
|
|
|
12544
|
-
// src/
|
|
12545
|
-
var
|
|
12546
|
-
|
|
12547
|
-
|
|
12548
|
-
var
|
|
12549
|
-
"
|
|
12550
|
-
"
|
|
12551
|
-
"
|
|
12552
|
-
".
|
|
12553
|
-
"
|
|
12554
|
-
|
|
12555
|
-
var
|
|
12556
|
-
|
|
12557
|
-
|
|
12558
|
-
|
|
12559
|
-
|
|
12560
|
-
|
|
12561
|
-
|
|
12562
|
-
|
|
12563
|
-
|
|
12564
|
-
"edit_image",
|
|
12565
|
-
"text_to_image",
|
|
12566
|
-
"images_generate"
|
|
12567
|
-
].some((token) => normalized.includes(token));
|
|
12568
|
-
}
|
|
12569
|
-
function shouldExtractGeneratedImagesFromToolResult(toolName) {
|
|
12570
|
-
return isGeneratedImageToolName(toolName);
|
|
12571
|
-
}
|
|
12572
|
-
function collectStringValues(value2, out) {
|
|
12573
|
-
if (typeof value2 === "string") {
|
|
12574
|
-
out.push(value2);
|
|
12575
|
-
return;
|
|
12576
|
-
}
|
|
12577
|
-
if (Array.isArray(value2)) {
|
|
12578
|
-
for (const item of value2) collectStringValues(item, out);
|
|
12579
|
-
return;
|
|
13037
|
+
// src/version.ts
|
|
13038
|
+
var AGENT_VERSION = "0.1.28";
|
|
13039
|
+
|
|
13040
|
+
// src/daemon.ts
|
|
13041
|
+
var OPENCODE_FREE_MODEL_IDS = [
|
|
13042
|
+
"opencode/north-mini-code-free",
|
|
13043
|
+
"opencode/nemotron-3-ultra-free",
|
|
13044
|
+
"opencode/deepseek-v4-flash-free",
|
|
13045
|
+
"opencode/mimo-v2.5-free",
|
|
13046
|
+
"opencode/big-pickle"
|
|
13047
|
+
];
|
|
13048
|
+
var MODEL_DISCOVERY_TIMEOUT_MS = 15e3;
|
|
13049
|
+
var PRODUCTION_API_URL = "https://api.aiden-platform.com";
|
|
13050
|
+
var PRODUCTION_WS_URL = "wss://ws.aiden-platform.com";
|
|
13051
|
+
var LOCAL_API_URL = "http://localhost:8400";
|
|
13052
|
+
var LOCAL_WS_URL = "ws://localhost:8401";
|
|
13053
|
+
function requiredString(params, key) {
|
|
13054
|
+
const value2 = params[key];
|
|
13055
|
+
if (typeof value2 !== "string" || value2.trim() === "") {
|
|
13056
|
+
throw new Error(`${key} is required`);
|
|
12580
13057
|
}
|
|
12581
|
-
|
|
12582
|
-
|
|
12583
|
-
|
|
13058
|
+
return value2;
|
|
13059
|
+
}
|
|
13060
|
+
function assertValidGitRef(ref, label) {
|
|
13061
|
+
if (!ref || ref.startsWith("-") || ref.includes("\0")) {
|
|
13062
|
+
throw new Error(`${label} is not a safe git ref`);
|
|
12584
13063
|
}
|
|
13064
|
+
const result = (0, import_node_child_process3.spawnSync)("git", ["check-ref-format", "--branch", ref], {
|
|
13065
|
+
env: getDaemonCliEnvironment(),
|
|
13066
|
+
encoding: "utf8"
|
|
13067
|
+
});
|
|
13068
|
+
if (result.status !== 0) throw new Error(`${label} is not a valid git ref`);
|
|
12585
13069
|
}
|
|
12586
|
-
function
|
|
12587
|
-
const
|
|
12588
|
-
|
|
12589
|
-
|
|
12590
|
-
|
|
13070
|
+
function isPathContained(childPath, parentPath) {
|
|
13071
|
+
const rel = (0, import_node_path3.relative)((0, import_node_path3.resolve)(parentPath), (0, import_node_path3.resolve)(childPath));
|
|
13072
|
+
return rel === "" || !(0, import_node_path3.isAbsolute)(rel) && rel !== ".." && !rel.startsWith(`..${import_node_path3.sep}`);
|
|
13073
|
+
}
|
|
13074
|
+
function assertPathContained(childPath, parentPath, label) {
|
|
13075
|
+
if (!isPathContained(childPath, parentPath)) {
|
|
13076
|
+
throw new Error(`${label} escapes allowed directory`);
|
|
12591
13077
|
}
|
|
12592
|
-
return values;
|
|
12593
13078
|
}
|
|
12594
|
-
function
|
|
12595
|
-
const
|
|
12596
|
-
|
|
12597
|
-
|
|
12598
|
-
|
|
12599
|
-
|
|
12600
|
-
|
|
13079
|
+
function git(cwd, args) {
|
|
13080
|
+
const result = (0, import_node_child_process3.spawnSync)("git", args, {
|
|
13081
|
+
cwd,
|
|
13082
|
+
env: getDaemonCliEnvironment(),
|
|
13083
|
+
encoding: "utf8",
|
|
13084
|
+
maxBuffer: 10 * 1024 * 1024
|
|
13085
|
+
});
|
|
13086
|
+
if (result.status !== 0) {
|
|
13087
|
+
throw new Error((result.stderr || result.stdout || "git command failed").trim());
|
|
12601
13088
|
}
|
|
12602
|
-
return
|
|
13089
|
+
return result.stdout.trim();
|
|
12603
13090
|
}
|
|
12604
|
-
function
|
|
12605
|
-
let path = candidate.trim().replace(/^file:\/\//, "");
|
|
13091
|
+
function gitSafe(cwd, args) {
|
|
12606
13092
|
try {
|
|
12607
|
-
|
|
13093
|
+
return git(cwd, args);
|
|
12608
13094
|
} catch {
|
|
13095
|
+
return "";
|
|
12609
13096
|
}
|
|
12610
|
-
if (path.startsWith("~/")) return null;
|
|
12611
|
-
if ((0, import_node_path3.isAbsolute)(path)) return path;
|
|
12612
|
-
return cwd ? (0, import_node_path3.join)(cwd, path) : null;
|
|
12613
13097
|
}
|
|
12614
|
-
function
|
|
12615
|
-
|
|
12616
|
-
|
|
12617
|
-
|
|
12618
|
-
|
|
12619
|
-
|
|
13098
|
+
function worktreeDir(projectPath) {
|
|
13099
|
+
const resolved = (0, import_node_path3.resolve)(projectPath);
|
|
13100
|
+
return (0, import_node_path3.join)((0, import_node_path3.dirname)(resolved), `${(0, import_node_path3.basename)(resolved)}-aiden-worktrees`);
|
|
13101
|
+
}
|
|
13102
|
+
function pathSegment(value2) {
|
|
13103
|
+
return value2.toLowerCase().replace(/^aiden\//, "").replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 64) || "task";
|
|
13104
|
+
}
|
|
13105
|
+
function repoName(repoUrl, localPath) {
|
|
13106
|
+
return repoUrl.replace(/\.git$/, "").split("/").pop() || (0, import_node_path3.basename)(localPath) || "repo";
|
|
13107
|
+
}
|
|
13108
|
+
function findWorktreeByBranch(repoPath, branchName) {
|
|
13109
|
+
const output = gitSafe(repoPath, ["worktree", "list", "--porcelain"]);
|
|
13110
|
+
const entries = output ? output.split("\n\n") : [];
|
|
13111
|
+
for (const entry of entries) {
|
|
13112
|
+
const lines = entry.split("\n");
|
|
13113
|
+
const path = lines.find((line) => line.startsWith("worktree "))?.slice("worktree ".length);
|
|
13114
|
+
const branch = lines.find((line) => line.startsWith("branch "))?.slice("branch ".length).replace("refs/heads/", "");
|
|
13115
|
+
if (path && branch === branchName) return path;
|
|
12620
13116
|
}
|
|
12621
|
-
|
|
12622
|
-
|
|
12623
|
-
|
|
12624
|
-
|
|
12625
|
-
|
|
12626
|
-
|
|
12627
|
-
|
|
12628
|
-
|
|
13117
|
+
return null;
|
|
13118
|
+
}
|
|
13119
|
+
function ensureGitWorktree(input) {
|
|
13120
|
+
assertValidGitRef(input.branchName, "branchName");
|
|
13121
|
+
assertValidGitRef(input.baseBranch, "baseBranch");
|
|
13122
|
+
const repoPath = (0, import_node_path3.resolve)(input.repoPath);
|
|
13123
|
+
const root = input.allowedRoot ?? worktreeDir(repoPath);
|
|
13124
|
+
const existingPath = findWorktreeByBranch(input.repoPath, input.branchName);
|
|
13125
|
+
if (existingPath) {
|
|
13126
|
+
if ((0, import_node_path3.resolve)(existingPath) === repoPath) {
|
|
13127
|
+
throw new Error(`${input.branchName} is checked out in the shared checkout`);
|
|
13128
|
+
}
|
|
13129
|
+
return existingPath;
|
|
13130
|
+
}
|
|
13131
|
+
assertPathContained(input.worktreePath, root, "worktreePath");
|
|
13132
|
+
(0, import_node_fs3.mkdirSync)((0, import_node_path3.dirname)(input.worktreePath), { recursive: true });
|
|
13133
|
+
if (!gitSafe(input.repoPath, ["branch", "--list", input.branchName])) {
|
|
13134
|
+
git(input.repoPath, ["branch", input.branchName, input.baseBranch]);
|
|
13135
|
+
}
|
|
13136
|
+
if ((0, import_node_fs3.existsSync)(input.worktreePath)) {
|
|
13137
|
+
if (gitSafe(input.worktreePath, ["branch", "--show-current"]) === input.branchName) {
|
|
13138
|
+
return input.worktreePath;
|
|
13139
|
+
}
|
|
13140
|
+
throw new Error("worktree path already exists for a different checkout");
|
|
13141
|
+
}
|
|
13142
|
+
git(input.repoPath, ["worktree", "add", input.worktreePath, input.branchName]);
|
|
13143
|
+
return input.worktreePath;
|
|
13144
|
+
}
|
|
13145
|
+
function ensureWorktree(params) {
|
|
13146
|
+
const input = {
|
|
13147
|
+
projectPath: requiredString(params, "projectPath"),
|
|
13148
|
+
taskId: requiredString(params, "taskId"),
|
|
13149
|
+
branchName: requiredString(params, "branchName"),
|
|
13150
|
+
baseBranch: typeof params.baseBranch === "string" ? params.baseBranch : "main",
|
|
13151
|
+
repoLocalPaths: Array.isArray(params.repoLocalPaths) ? params.repoLocalPaths : []
|
|
13152
|
+
};
|
|
13153
|
+
const taskRoot = (0, import_node_path3.join)(
|
|
13154
|
+
worktreeDir(input.projectPath),
|
|
13155
|
+
`${pathSegment(input.branchName)}-${input.taskId.slice(0, 8)}`
|
|
13156
|
+
);
|
|
13157
|
+
if (input.repoLocalPaths?.length) {
|
|
13158
|
+
return {
|
|
13159
|
+
worktrees: input.repoLocalPaths.map((repo) => {
|
|
13160
|
+
const baseBranch = repo.branch || input.baseBranch || "main";
|
|
13161
|
+
const worktreePath2 = ensureGitWorktree({
|
|
13162
|
+
repoPath: repo.localPath,
|
|
13163
|
+
worktreePath: (0, import_node_path3.join)(taskRoot, pathSegment(repoName(repo.repoUrl, repo.localPath))),
|
|
13164
|
+
branchName: input.branchName,
|
|
13165
|
+
baseBranch,
|
|
13166
|
+
allowedRoot: worktreeDir(input.projectPath)
|
|
13167
|
+
});
|
|
12629
13168
|
return {
|
|
12630
|
-
|
|
12631
|
-
|
|
13169
|
+
repoId: repo.repoId ?? null,
|
|
13170
|
+
repoUrl: repo.repoUrl,
|
|
13171
|
+
worktreePath: worktreePath2,
|
|
13172
|
+
branchName: input.branchName,
|
|
13173
|
+
baseBranch
|
|
12632
13174
|
};
|
|
12633
|
-
}
|
|
12634
|
-
|
|
12635
|
-
}
|
|
13175
|
+
})
|
|
13176
|
+
};
|
|
12636
13177
|
}
|
|
12637
|
-
|
|
13178
|
+
const worktreePath = ensureGitWorktree({
|
|
13179
|
+
repoPath: input.projectPath,
|
|
13180
|
+
worktreePath: taskRoot,
|
|
13181
|
+
branchName: input.branchName,
|
|
13182
|
+
baseBranch: input.baseBranch
|
|
13183
|
+
});
|
|
13184
|
+
return {
|
|
13185
|
+
worktrees: [{ worktreePath, branchName: input.branchName, baseBranch: input.baseBranch }]
|
|
13186
|
+
};
|
|
12638
13187
|
}
|
|
12639
|
-
function
|
|
12640
|
-
|
|
12641
|
-
|
|
12642
|
-
|
|
12643
|
-
for (const candidate of extractPathCandidates(content)) {
|
|
12644
|
-
const path = normalizePath(candidate, cwd);
|
|
12645
|
-
if (!path || seen.has(path) || !(0, import_node_fs3.existsSync)(path)) continue;
|
|
12646
|
-
seen.add(path);
|
|
12647
|
-
const ext = (0, import_node_path3.extname)(path).toLowerCase();
|
|
12648
|
-
const mimeType = IMAGE_MIME_BY_EXT[ext];
|
|
12649
|
-
if (!mimeType) continue;
|
|
12650
|
-
const stat = (0, import_node_fs3.statSync)(path);
|
|
12651
|
-
if (!stat.isFile() || stat.size <= 0 || stat.size > MAX_GENERATED_IMAGE_BYTES) continue;
|
|
12652
|
-
const buffer = (0, import_node_fs3.readFileSync)(path);
|
|
12653
|
-
const { width, height } = readImageDimensions2(buffer, mimeType);
|
|
12654
|
-
images.push({
|
|
12655
|
-
type: "generated_image",
|
|
12656
|
-
id: (0, import_node_crypto.randomUUID)(),
|
|
12657
|
-
filename: (0, import_node_path3.basename)(path),
|
|
12658
|
-
mimeType,
|
|
12659
|
-
size: buffer.length,
|
|
12660
|
-
width,
|
|
12661
|
-
height,
|
|
12662
|
-
data: buffer.toString("base64"),
|
|
12663
|
-
sourcePath: path,
|
|
12664
|
-
sourceHash: (0, import_node_crypto.createHash)("sha256").update(buffer).digest("hex"),
|
|
12665
|
-
toolId,
|
|
12666
|
-
ts: Date.now()
|
|
12667
|
-
});
|
|
12668
|
-
}
|
|
12669
|
-
return images;
|
|
13188
|
+
function resolveRuntimeCwd(payload) {
|
|
13189
|
+
const multiRepoWorktree = payload.worktreeInfo?.allWorktrees?.[0]?.worktreePath;
|
|
13190
|
+
if (multiRepoWorktree) return (0, import_node_path3.dirname)(multiRepoWorktree);
|
|
13191
|
+
return payload.worktreeInfo?.worktreePath ?? payload.projectPath ?? process.cwd();
|
|
12670
13192
|
}
|
|
12671
|
-
|
|
12672
|
-
// src/version.ts
|
|
12673
|
-
var AGENT_VERSION = "0.1.26";
|
|
12674
|
-
|
|
12675
|
-
// src/daemon.ts
|
|
12676
|
-
var OPENCODE_FREE_MODEL_IDS = [
|
|
12677
|
-
"opencode/north-mini-code-free",
|
|
12678
|
-
"opencode/nemotron-3-ultra-free",
|
|
12679
|
-
"opencode/deepseek-v4-flash-free",
|
|
12680
|
-
"opencode/mimo-v2.5-free",
|
|
12681
|
-
"opencode/big-pickle"
|
|
12682
|
-
];
|
|
12683
|
-
var PRODUCTION_API_URL = "https://api.aiden-platform.com";
|
|
12684
|
-
var PRODUCTION_WS_URL = "wss://ws.aiden-platform.com";
|
|
12685
|
-
var LOCAL_API_URL = "http://localhost:8400";
|
|
12686
|
-
var LOCAL_WS_URL = "ws://localhost:8401";
|
|
12687
13193
|
function correlationLogFields(input) {
|
|
12688
13194
|
return Object.fromEntries(
|
|
12689
13195
|
Object.entries({
|
|
@@ -12722,33 +13228,33 @@ function describeOccupiedLocalDaemon(port) {
|
|
|
12722
13228
|
return `local daemon API port ${port} is already in use. If Aiden desktop is open, it manages the daemon automatically. Quit Aiden desktop or stop the existing daemon before starting another.`;
|
|
12723
13229
|
}
|
|
12724
13230
|
function getConfigPath() {
|
|
12725
|
-
return process.env.AIDEN_AGENT_CONFIG_PATH ?? (0,
|
|
13231
|
+
return process.env.AIDEN_AGENT_CONFIG_PATH ?? (0, import_node_path3.join)((0, import_node_os4.homedir)(), ".aiden", "agent", "config.json");
|
|
12726
13232
|
}
|
|
12727
13233
|
function getEndpointDefaultsPath() {
|
|
12728
|
-
return process.env.AIDEN_AGENT_ENDPOINTS_PATH ?? (0,
|
|
13234
|
+
return process.env.AIDEN_AGENT_ENDPOINTS_PATH ?? (0, import_node_path3.join)((0, import_node_path3.dirname)(getConfigPath()), "endpoints.json");
|
|
12729
13235
|
}
|
|
12730
13236
|
function readConfig() {
|
|
12731
13237
|
const configPath = getConfigPath();
|
|
12732
|
-
if (!(0,
|
|
12733
|
-
return JSON.parse((0,
|
|
13238
|
+
if (!(0, import_node_fs3.existsSync)(configPath)) return {};
|
|
13239
|
+
return JSON.parse((0, import_node_fs3.readFileSync)(configPath, "utf8"));
|
|
12734
13240
|
}
|
|
12735
13241
|
function readEndpointDefaults() {
|
|
12736
13242
|
const endpointsPath = getEndpointDefaultsPath();
|
|
12737
|
-
if (!(0,
|
|
13243
|
+
if (!(0, import_node_fs3.existsSync)(endpointsPath)) return {};
|
|
12738
13244
|
try {
|
|
12739
|
-
return JSON.parse((0,
|
|
13245
|
+
return JSON.parse((0, import_node_fs3.readFileSync)(endpointsPath, "utf8"));
|
|
12740
13246
|
} catch {
|
|
12741
13247
|
return {};
|
|
12742
13248
|
}
|
|
12743
13249
|
}
|
|
12744
13250
|
function writeConfig(config) {
|
|
12745
13251
|
const configPath = getConfigPath();
|
|
12746
|
-
(0,
|
|
12747
|
-
(0,
|
|
13252
|
+
(0, import_node_fs3.mkdirSync)((0, import_node_path3.dirname)(configPath), { recursive: true, mode: 448 });
|
|
13253
|
+
(0, import_node_fs3.writeFileSync)(configPath, JSON.stringify(config, null, 2), { mode: 384 });
|
|
12748
13254
|
}
|
|
12749
13255
|
function removeConfig() {
|
|
12750
13256
|
const configPath = getConfigPath();
|
|
12751
|
-
if ((0,
|
|
13257
|
+
if ((0, import_node_fs3.existsSync)(configPath)) (0, import_node_fs3.rmSync)(configPath, { force: true });
|
|
12752
13258
|
}
|
|
12753
13259
|
function argValue(args, name) {
|
|
12754
13260
|
const index = args.indexOf(name);
|
|
@@ -12784,7 +13290,7 @@ function getLocalApiPort(args, stored) {
|
|
|
12784
13290
|
}
|
|
12785
13291
|
function sleep(ms) {
|
|
12786
13292
|
if (ms <= 0) return Promise.resolve();
|
|
12787
|
-
return new Promise((
|
|
13293
|
+
return new Promise((resolve3) => setTimeout(resolve3, ms));
|
|
12788
13294
|
}
|
|
12789
13295
|
function normalizeBackendKind(backendKind) {
|
|
12790
13296
|
if (backendKind === "codex") return "codex_app_server";
|
|
@@ -12816,6 +13322,14 @@ function extractModelIdsFromJson(value2) {
|
|
|
12816
13322
|
}
|
|
12817
13323
|
return [];
|
|
12818
13324
|
}
|
|
13325
|
+
function extractModelIdsFromText(value2) {
|
|
13326
|
+
const ansiPattern = new RegExp(`${String.fromCharCode(27)}\\[[0-9;]*m`, "g");
|
|
13327
|
+
const ignoredLinePattern = /^(available models|models|usage|error|flag provided|try |agy\b)/i;
|
|
13328
|
+
const ids = value2.split(/\r?\n/).map(
|
|
13329
|
+
(line) => line.replace(ansiPattern, "").replace(/^[-*•]\s*/, "").trim()
|
|
13330
|
+
).filter((line) => line.length > 0 && !ignoredLinePattern.test(line));
|
|
13331
|
+
return [...new Set(ids)];
|
|
13332
|
+
}
|
|
12819
13333
|
function discoverOpenCodeModels(executable, env) {
|
|
12820
13334
|
for (const args of [
|
|
12821
13335
|
["models", "--json"],
|
|
@@ -12824,7 +13338,7 @@ function discoverOpenCodeModels(executable, env) {
|
|
|
12824
13338
|
]) {
|
|
12825
13339
|
const result = (0, import_node_child_process3.spawnSync)(executable, args, {
|
|
12826
13340
|
encoding: "utf8",
|
|
12827
|
-
timeout:
|
|
13341
|
+
timeout: MODEL_DISCOVERY_TIMEOUT_MS,
|
|
12828
13342
|
env,
|
|
12829
13343
|
windowsHide: true
|
|
12830
13344
|
});
|
|
@@ -12837,7 +13351,27 @@ function discoverOpenCodeModels(executable, env) {
|
|
|
12837
13351
|
}
|
|
12838
13352
|
return OPENCODE_FREE_MODEL_IDS;
|
|
12839
13353
|
}
|
|
13354
|
+
function discoverAntigravityModels(executable, env) {
|
|
13355
|
+
for (const args of [["models", "--json"], ["models"]]) {
|
|
13356
|
+
const result = (0, import_node_child_process3.spawnSync)(executable, args, {
|
|
13357
|
+
encoding: "utf8",
|
|
13358
|
+
timeout: MODEL_DISCOVERY_TIMEOUT_MS,
|
|
13359
|
+
env,
|
|
13360
|
+
windowsHide: true
|
|
13361
|
+
});
|
|
13362
|
+
if (!result || result.error || result.status !== 0 || !result.stdout.trim()) continue;
|
|
13363
|
+
try {
|
|
13364
|
+
const models = extractModelIdsFromJson(JSON.parse(result.stdout));
|
|
13365
|
+
if (models.length > 0) return models;
|
|
13366
|
+
} catch {
|
|
13367
|
+
const models = extractModelIdsFromText(result.stdout);
|
|
13368
|
+
if (models.length > 0) return models;
|
|
13369
|
+
}
|
|
13370
|
+
}
|
|
13371
|
+
return [];
|
|
13372
|
+
}
|
|
12840
13373
|
function discoverProviderModels(provider, executable, env) {
|
|
13374
|
+
if (provider === "gemini_cli") return discoverAntigravityModels(executable, env);
|
|
12841
13375
|
if (provider === "opencode_cli") return discoverOpenCodeModels(executable, env);
|
|
12842
13376
|
return [];
|
|
12843
13377
|
}
|
|
@@ -12918,7 +13452,7 @@ function collectRuntimeMetadata() {
|
|
|
12918
13452
|
metadata.cpuCores = cpuList.length;
|
|
12919
13453
|
}
|
|
12920
13454
|
try {
|
|
12921
|
-
const disk = (0,
|
|
13455
|
+
const disk = (0, import_node_fs3.statfsSync)((0, import_node_os4.homedir)());
|
|
12922
13456
|
metadata.diskFreeBytes = disk.bavail * disk.bsize;
|
|
12923
13457
|
metadata.diskTotalBytes = disk.blocks * disk.bsize;
|
|
12924
13458
|
} catch {
|
|
@@ -12946,7 +13480,10 @@ var RuntimePresenter = class {
|
|
|
12946
13480
|
this.onRunComplete = onRunComplete;
|
|
12947
13481
|
}
|
|
12948
13482
|
emittedGeneratedImageKeys = /* @__PURE__ */ new Set();
|
|
13483
|
+
emittedSessionMediaKeys = /* @__PURE__ */ new Set();
|
|
12949
13484
|
toolNamesById = /* @__PURE__ */ new Map();
|
|
13485
|
+
toolInputsById = /* @__PURE__ */ new Map();
|
|
13486
|
+
browserRecordingPathHints = /* @__PURE__ */ new Set();
|
|
12950
13487
|
emitEvent(event) {
|
|
12951
13488
|
this.touchRunnerActivity?.();
|
|
12952
13489
|
this.socket.emit("agent.event", {
|
|
@@ -12969,6 +13506,12 @@ var RuntimePresenter = class {
|
|
|
12969
13506
|
}
|
|
12970
13507
|
onToolUse(tool, input, toolId) {
|
|
12971
13508
|
this.toolNamesById.set(toolId, tool);
|
|
13509
|
+
this.toolInputsById.set(toolId, input);
|
|
13510
|
+
for (const path of extractBrowserMediaPathHints(void 0, this.cwd, tool, {
|
|
13511
|
+
toolInput: input
|
|
13512
|
+
})) {
|
|
13513
|
+
this.browserRecordingPathHints.add(path);
|
|
13514
|
+
}
|
|
12972
13515
|
this.emitEvent({ type: "tool_use", id: toolId, name: tool, input, ts: Date.now() });
|
|
12973
13516
|
}
|
|
12974
13517
|
onToolResult(toolId, content, isError) {
|
|
@@ -12981,9 +13524,27 @@ var RuntimePresenter = class {
|
|
|
12981
13524
|
});
|
|
12982
13525
|
if (isError) return;
|
|
12983
13526
|
const toolName = this.toolNamesById.get(toolId);
|
|
12984
|
-
|
|
13527
|
+
const toolInput = this.toolInputsById.get(toolId);
|
|
13528
|
+
const options = { toolInput, pathHints: [...this.browserRecordingPathHints] };
|
|
13529
|
+
for (const image of extractGeneratedImagesFromToolResult(
|
|
13530
|
+
toolId,
|
|
13531
|
+
content,
|
|
13532
|
+
this.cwd,
|
|
13533
|
+
toolName,
|
|
13534
|
+
options
|
|
13535
|
+
)) {
|
|
12985
13536
|
this.emitGeneratedImage(image);
|
|
12986
13537
|
}
|
|
13538
|
+
for (const media of extractSessionMediaFromToolResult(
|
|
13539
|
+
toolId,
|
|
13540
|
+
content,
|
|
13541
|
+
this.cwd,
|
|
13542
|
+
toolName,
|
|
13543
|
+
options
|
|
13544
|
+
)) {
|
|
13545
|
+
this.emitSessionMedia(media);
|
|
13546
|
+
if (media.sourcePath) this.browserRecordingPathHints.delete(media.sourcePath);
|
|
13547
|
+
}
|
|
12987
13548
|
}
|
|
12988
13549
|
onGeneratedImage(image) {
|
|
12989
13550
|
this.emitGeneratedImage(image);
|
|
@@ -12994,6 +13555,15 @@ var RuntimePresenter = class {
|
|
|
12994
13555
|
this.emittedGeneratedImageKeys.add(key);
|
|
12995
13556
|
this.emitEvent(image);
|
|
12996
13557
|
}
|
|
13558
|
+
onSessionMedia(media) {
|
|
13559
|
+
this.emitSessionMedia(media);
|
|
13560
|
+
}
|
|
13561
|
+
emitSessionMedia(media) {
|
|
13562
|
+
const key = media.sourceHash ?? `${media.sourcePath ?? media.id}:${media.size}`;
|
|
13563
|
+
if (this.emittedSessionMediaKeys.has(key)) return;
|
|
13564
|
+
this.emittedSessionMediaKeys.add(key);
|
|
13565
|
+
this.emitEvent(media);
|
|
13566
|
+
}
|
|
12997
13567
|
onTurnComplete(content) {
|
|
12998
13568
|
this.emitEvent({ type: "turn_complete", content, ts: Date.now() });
|
|
12999
13569
|
}
|
|
@@ -13084,7 +13654,7 @@ async function setupDaemon(args) {
|
|
|
13084
13654
|
runtimeId: body.runtime.id,
|
|
13085
13655
|
runtimeToken: body.runtimeToken,
|
|
13086
13656
|
localApiPort: getLocalApiPort(args, {}),
|
|
13087
|
-
localApiToken: (0,
|
|
13657
|
+
localApiToken: (0, import_node_crypto.randomBytes)(24).toString("hex"),
|
|
13088
13658
|
displayName: body.runtime.displayName ?? displayName
|
|
13089
13659
|
});
|
|
13090
13660
|
console.info("[aiden-agent] Runtime registered", {
|
|
@@ -13135,7 +13705,7 @@ async function loginWithDeviceCode(args) {
|
|
|
13135
13705
|
runtimeId: body.runtime.id,
|
|
13136
13706
|
runtimeToken: body.runtimeToken,
|
|
13137
13707
|
localApiPort: getLocalApiPort(args, {}),
|
|
13138
|
-
localApiToken: (0,
|
|
13708
|
+
localApiToken: (0, import_node_crypto.randomBytes)(24).toString("hex"),
|
|
13139
13709
|
displayName: body.runtime.displayName ?? displayName
|
|
13140
13710
|
});
|
|
13141
13711
|
console.info("[aiden-agent] Runtime registered", {
|
|
@@ -13152,7 +13722,7 @@ async function startDaemon(args) {
|
|
|
13152
13722
|
const runtimeToken = argValue(args, "--token") ?? process.env.AIDEN_RUNTIME_TOKEN ?? stored.runtimeToken;
|
|
13153
13723
|
const wsUrl = argValue(args, "--ws-url") ?? process.env.AIDEN_WS_URL ?? stored.wsUrl;
|
|
13154
13724
|
let localApiPort = getLocalApiPort(args, stored);
|
|
13155
|
-
const localApiToken = stored.localApiToken ?? (0,
|
|
13725
|
+
const localApiToken = stored.localApiToken ?? (0, import_node_crypto.randomBytes)(24).toString("hex");
|
|
13156
13726
|
if (!runtimeId || !runtimeToken || !wsUrl) {
|
|
13157
13727
|
throw new Error(
|
|
13158
13728
|
"daemon requires runtimeId, runtime token, and wsUrl. Run setup first or pass --runtime-id/--token/--ws-url."
|
|
@@ -13211,6 +13781,23 @@ async function startDaemon(args) {
|
|
|
13211
13781
|
pushLog(`disconnected ${reason}`);
|
|
13212
13782
|
console.info("[aiden-agent] Daemon disconnected:", reason);
|
|
13213
13783
|
});
|
|
13784
|
+
socket.on("desktop:rpc", (message) => {
|
|
13785
|
+
if (!message?.id || !message.method) return;
|
|
13786
|
+
try {
|
|
13787
|
+
const params = message.params ?? {};
|
|
13788
|
+
if (message.method !== "worktree.ensure") {
|
|
13789
|
+
throw new Error(`Method not found: ${message.method}`);
|
|
13790
|
+
}
|
|
13791
|
+
const result = ensureWorktree(params);
|
|
13792
|
+
socket.emit("desktop:rpc", { jsonrpc: "2.0", id: message.id, result });
|
|
13793
|
+
} catch (error) {
|
|
13794
|
+
socket.emit("desktop:rpc", {
|
|
13795
|
+
jsonrpc: "2.0",
|
|
13796
|
+
id: message.id,
|
|
13797
|
+
error: { code: -32e3, message: error.message }
|
|
13798
|
+
});
|
|
13799
|
+
}
|
|
13800
|
+
});
|
|
13214
13801
|
socket.on("agent.execute", (payload) => {
|
|
13215
13802
|
if (!payload?.runId || !payload.conversationId || typeof payload.content !== "string") {
|
|
13216
13803
|
return;
|
|
@@ -13240,7 +13827,7 @@ async function startDaemon(args) {
|
|
|
13240
13827
|
});
|
|
13241
13828
|
pushLog(`accepted run=${payload.runId}`);
|
|
13242
13829
|
console.info("[aiden-agent] Agent run accepted", correlation);
|
|
13243
|
-
const cwd = payload
|
|
13830
|
+
const cwd = resolveRuntimeCwd(payload);
|
|
13244
13831
|
const nowMs = Date.now();
|
|
13245
13832
|
const touchActivity = () => {
|
|
13246
13833
|
const entry = activeAgents.get(payload.runId);
|
|
@@ -13401,7 +13988,7 @@ async function startDaemon(args) {
|
|
|
13401
13988
|
`${describeOccupiedLocalDaemon(localApiPort)} The token in ${getConfigPath()} no longer matches the running daemon; quit Aiden desktop or run setup again.`
|
|
13402
13989
|
);
|
|
13403
13990
|
}
|
|
13404
|
-
await new Promise((
|
|
13991
|
+
await new Promise((resolve3, reject) => {
|
|
13405
13992
|
const onError = (error) => {
|
|
13406
13993
|
clearInterval(heartbeat);
|
|
13407
13994
|
socket.disconnect();
|
|
@@ -13428,7 +14015,7 @@ async function startDaemon(args) {
|
|
|
13428
14015
|
if (address && typeof address === "object") localApiPort = address.port;
|
|
13429
14016
|
pushLog(`local_api listening port=${localApiPort}`);
|
|
13430
14017
|
console.info("[aiden-agent] Local daemon API listening", { port: localApiPort });
|
|
13431
|
-
|
|
14018
|
+
resolve3();
|
|
13432
14019
|
});
|
|
13433
14020
|
});
|
|
13434
14021
|
let stopped = false;
|
|
@@ -13441,8 +14028,8 @@ async function startDaemon(args) {
|
|
|
13441
14028
|
}
|
|
13442
14029
|
activeAgents.clear();
|
|
13443
14030
|
socket.disconnect();
|
|
13444
|
-
await new Promise((
|
|
13445
|
-
localServer.close(() =>
|
|
14031
|
+
await new Promise((resolve3) => {
|
|
14032
|
+
localServer.close(() => resolve3());
|
|
13446
14033
|
});
|
|
13447
14034
|
};
|
|
13448
14035
|
const controller = {
|
|
@@ -13726,7 +14313,10 @@ var WebPresenter = class {
|
|
|
13726
14313
|
}
|
|
13727
14314
|
wsClient;
|
|
13728
14315
|
emittedGeneratedImageKeys = /* @__PURE__ */ new Set();
|
|
14316
|
+
emittedSessionMediaKeys = /* @__PURE__ */ new Set();
|
|
13729
14317
|
toolNamesById = /* @__PURE__ */ new Map();
|
|
14318
|
+
toolInputsById = /* @__PURE__ */ new Map();
|
|
14319
|
+
browserRecordingPathHints = /* @__PURE__ */ new Set();
|
|
13730
14320
|
suppressSessionLifecycle = false;
|
|
13731
14321
|
setSuppressSessionLifecycle(suppress) {
|
|
13732
14322
|
this.suppressSessionLifecycle = suppress;
|
|
@@ -13745,6 +14335,12 @@ var WebPresenter = class {
|
|
|
13745
14335
|
}
|
|
13746
14336
|
onToolUse(tool, input, toolId) {
|
|
13747
14337
|
this.toolNamesById.set(toolId, tool);
|
|
14338
|
+
this.toolInputsById.set(toolId, input);
|
|
14339
|
+
for (const path of extractBrowserMediaPathHints(void 0, this.cwd, tool, {
|
|
14340
|
+
toolInput: input
|
|
14341
|
+
})) {
|
|
14342
|
+
this.browserRecordingPathHints.add(path);
|
|
14343
|
+
}
|
|
13748
14344
|
this.wsClient.emitEvent({ type: "tool_use", id: toolId, name: tool, input, ts: Date.now() });
|
|
13749
14345
|
}
|
|
13750
14346
|
onToolResult(toolId, content, isError) {
|
|
@@ -13757,9 +14353,27 @@ var WebPresenter = class {
|
|
|
13757
14353
|
});
|
|
13758
14354
|
if (isError) return;
|
|
13759
14355
|
const toolName = this.toolNamesById.get(toolId);
|
|
13760
|
-
|
|
14356
|
+
const toolInput = this.toolInputsById.get(toolId);
|
|
14357
|
+
const options = { toolInput, pathHints: [...this.browserRecordingPathHints] };
|
|
14358
|
+
for (const image of extractGeneratedImagesFromToolResult(
|
|
14359
|
+
toolId,
|
|
14360
|
+
content,
|
|
14361
|
+
this.cwd,
|
|
14362
|
+
toolName,
|
|
14363
|
+
options
|
|
14364
|
+
)) {
|
|
13761
14365
|
this.emitGeneratedImage(image);
|
|
13762
14366
|
}
|
|
14367
|
+
for (const media of extractSessionMediaFromToolResult(
|
|
14368
|
+
toolId,
|
|
14369
|
+
content,
|
|
14370
|
+
this.cwd,
|
|
14371
|
+
toolName,
|
|
14372
|
+
options
|
|
14373
|
+
)) {
|
|
14374
|
+
this.emitSessionMedia(media);
|
|
14375
|
+
if (media.sourcePath) this.browserRecordingPathHints.delete(media.sourcePath);
|
|
14376
|
+
}
|
|
13763
14377
|
}
|
|
13764
14378
|
onGeneratedImage(image) {
|
|
13765
14379
|
this.emitGeneratedImage(image);
|
|
@@ -13770,6 +14384,15 @@ var WebPresenter = class {
|
|
|
13770
14384
|
this.emittedGeneratedImageKeys.add(key);
|
|
13771
14385
|
this.wsClient.emitEvent(image);
|
|
13772
14386
|
}
|
|
14387
|
+
onSessionMedia(media) {
|
|
14388
|
+
this.emitSessionMedia(media);
|
|
14389
|
+
}
|
|
14390
|
+
emitSessionMedia(media) {
|
|
14391
|
+
const key = media.sourceHash ?? `${media.sourcePath ?? media.id}:${media.size}`;
|
|
14392
|
+
if (this.emittedSessionMediaKeys.has(key)) return;
|
|
14393
|
+
this.emittedSessionMediaKeys.add(key);
|
|
14394
|
+
this.wsClient.emitEvent(media);
|
|
14395
|
+
}
|
|
13773
14396
|
onTurnComplete(content) {
|
|
13774
14397
|
this.wsClient.emitEvent({ type: "turn_complete", content, ts: Date.now() });
|
|
13775
14398
|
}
|
|
@@ -13858,9 +14481,9 @@ var WSClient = class {
|
|
|
13858
14481
|
this.socket.emit("agent_event", event);
|
|
13859
14482
|
}
|
|
13860
14483
|
waitForConnection(timeoutMs = 15e3) {
|
|
13861
|
-
return new Promise((
|
|
14484
|
+
return new Promise((resolve3, reject) => {
|
|
13862
14485
|
if (this.socket.connected) {
|
|
13863
|
-
|
|
14486
|
+
resolve3();
|
|
13864
14487
|
return;
|
|
13865
14488
|
}
|
|
13866
14489
|
const timeout = setTimeout(
|
|
@@ -13869,7 +14492,7 @@ var WSClient = class {
|
|
|
13869
14492
|
);
|
|
13870
14493
|
this.socket.once("connect", () => {
|
|
13871
14494
|
clearTimeout(timeout);
|
|
13872
|
-
|
|
14495
|
+
resolve3();
|
|
13873
14496
|
});
|
|
13874
14497
|
this.socket.once("connect_error", (err) => {
|
|
13875
14498
|
clearTimeout(timeout);
|
|
@@ -14010,9 +14633,9 @@ async function runSandbox(config) {
|
|
|
14010
14633
|
onUserMessage: (payload) => {
|
|
14011
14634
|
if (payload === null) {
|
|
14012
14635
|
if (pendingMessageResolve) {
|
|
14013
|
-
const
|
|
14636
|
+
const resolve3 = pendingMessageResolve;
|
|
14014
14637
|
pendingMessageResolve = null;
|
|
14015
|
-
|
|
14638
|
+
resolve3(null);
|
|
14016
14639
|
}
|
|
14017
14640
|
return;
|
|
14018
14641
|
}
|
|
@@ -14034,9 +14657,9 @@ async function runSandbox(config) {
|
|
|
14034
14657
|
fileCount: payload.files?.length ?? 0
|
|
14035
14658
|
});
|
|
14036
14659
|
if (pendingMessageResolve) {
|
|
14037
|
-
const
|
|
14660
|
+
const resolve3 = pendingMessageResolve;
|
|
14038
14661
|
pendingMessageResolve = null;
|
|
14039
|
-
|
|
14662
|
+
resolve3(payload);
|
|
14040
14663
|
} else {
|
|
14041
14664
|
queuedMessages.push(payload);
|
|
14042
14665
|
}
|
|
@@ -14190,8 +14813,8 @@ async function runSandbox(config) {
|
|
|
14190
14813
|
});
|
|
14191
14814
|
if (stopped) break;
|
|
14192
14815
|
}
|
|
14193
|
-
const nextPayload = queuedMessages.shift() ?? await new Promise((
|
|
14194
|
-
pendingMessageResolve =
|
|
14816
|
+
const nextPayload = queuedMessages.shift() ?? await new Promise((resolve3) => {
|
|
14817
|
+
pendingMessageResolve = resolve3;
|
|
14195
14818
|
});
|
|
14196
14819
|
if (nextPayload === null || stopped) {
|
|
14197
14820
|
break;
|