@armadra/agent 0.10.0 → 0.12.0
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/CHANGELOG.md +31 -0
- package/CHANGELOG.zh-CN.md +31 -0
- package/README.md +5 -0
- package/README.zh-CN.md +4 -0
- package/dist/acp.d.ts +2 -2
- package/dist/acp.js +2 -2
- package/dist/bundle/ama.cjs +1730 -446
- package/dist/cli/compose-agents.js +8 -0
- package/dist/cli/compose.d.ts +3 -0
- package/dist/cli/compose.js +1 -0
- package/dist/drivers/acp/client.d.ts +54 -5
- package/dist/drivers/acp/client.js +96 -9
- package/dist/drivers/acp/types.d.ts +69 -3
- package/dist/drivers/acp/types.js +30 -1
- package/dist/drivers/agents.js +1 -1
- package/dist/drivers/host-runners.d.ts +26 -1
- package/dist/drivers/host-runners.js +147 -0
- package/dist/hooks/matcher.d.ts +2 -2
- package/dist/hooks/matcher.js +3 -3
- package/dist/host/api-impl.d.ts +3 -0
- package/dist/host/api-impl.js +7 -2
- package/dist/host/types.d.ts +37 -1
- package/dist/host/types.js +5 -0
- package/dist/host.d.ts +1 -1
- package/dist/host.js +1 -1
- package/dist/i18n/catalog.d.ts +5 -0
- package/dist/i18n/messages/approval.d.ts +5 -0
- package/dist/i18n/messages/approval.js +5 -0
- package/dist/i18n/messages/drivers.d.ts +2 -0
- package/dist/i18n/messages/drivers.js +2 -0
- package/dist/i18n/messages/interactive-view.d.ts +5 -0
- package/dist/i18n/messages/interactive-view.js +5 -0
- package/dist/i18n/messages/interactive.d.ts +4 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/modes/commands-core.d.ts +7 -0
- package/dist/modes/commands-core.js +23 -5
- package/dist/modes/interactive/approval-dialog.js +17 -4
- package/dist/modes/interactive/commands.d.ts +2 -0
- package/dist/modes/interactive/commands.js +5 -1
- package/dist/modes/interactive/interactive-mode.d.ts +7 -0
- package/dist/modes/interactive/interactive-mode.js +14 -6
- package/dist/modes/interactive/tool-summary.d.ts +2 -0
- package/dist/modes/interactive/tool-summary.js +27 -0
- package/dist/modes/rpc/commands.js +4 -4
- package/dist/permissions/auto-safe.d.ts +3 -0
- package/dist/permissions/auto-safe.js +10 -3
- package/dist/permissions/classifier.js +1 -1
- package/dist/permissions/network-class.d.ts +28 -0
- package/dist/permissions/network-class.js +91 -0
- package/dist/permissions/pipeline.d.ts +1 -1
- package/dist/permissions/pipeline.js +24 -7
- package/dist/permissions/preview.js +3 -0
- package/dist/permissions/readonly-bash.d.ts +2 -2
- package/dist/permissions/readonly-bash.js +2 -2
- package/dist/permissions/rules.d.ts +1 -0
- package/dist/permissions/rules.js +5 -1
- package/dist/tools/presets.d.ts +8 -1
- package/dist/tools/presets.js +12 -3
- package/dist/tools/registry.d.ts +3 -1
- package/dist/tools/registry.js +4 -2
- package/dist/tools/task-ctl.d.ts +9 -0
- package/dist/tools/task-ctl.js +22 -3
- package/dist/tools/types.d.ts +4 -1
- package/dist/tools/web/fetch.d.ts +48 -0
- package/dist/tools/web/fetch.js +307 -0
- package/dist/tools/web/html-to-markdown.d.ts +31 -0
- package/dist/tools/web/html-to-markdown.js +522 -0
- package/dist/tools/web/url-guard.d.ts +59 -0
- package/dist/tools/web/url-guard.js +221 -0
- package/docs/en/guides/permissions.md +33 -11
- package/docs/en/reference/acp.md +7 -3
- package/docs/en/reference/host-api.md +61 -19
- package/docs/en/reference/rpc.md +7 -7
- package/docs/guides/agents.md +18 -1
- package/docs/guides/hooks.md +86 -8
- package/docs/guides/permissions.md +33 -11
- package/docs/guides/sandbox.md +6 -0
- package/docs/reference/acp.md +7 -3
- package/docs/reference/host-api.md +61 -19
- package/docs/reference/rpc.md +7 -7
- package/package.json +1 -1
package/dist/bundle/ama.cjs
CHANGED
|
@@ -41,7 +41,7 @@ var AMA_VERSION;
|
|
|
41
41
|
var init_version = __esm({
|
|
42
42
|
"src/version.ts"() {
|
|
43
43
|
"use strict";
|
|
44
|
-
AMA_VERSION = true ? "0.
|
|
44
|
+
AMA_VERSION = true ? "0.12.0" : readPackageVersion();
|
|
45
45
|
}
|
|
46
46
|
});
|
|
47
47
|
|
|
@@ -1794,6 +1794,9 @@ var init_interactive_view = __esm({
|
|
|
1794
1794
|
codemode: (calls, lines2) => `${plural(calls, "inner call")} · script printed ${plural(lines2, "line")}`,
|
|
1795
1795
|
done: "done",
|
|
1796
1796
|
outputLines: (n) => `${plural(n, "line")} of output`,
|
|
1797
|
+
/** web_fetch:`<标题> · <大小> · markdown|text|json|binary`。 */
|
|
1798
|
+
fetched: (title, size, format) => [title, size, format].filter((p) => p !== void 0 && p !== "").join(" · "),
|
|
1799
|
+
fetchRedirect: (url) => `redirected to ${url} (not followed)`,
|
|
1797
1800
|
awaiting: (glyph) => `${glyph} awaiting approval`,
|
|
1798
1801
|
subagentRunning: (elapsed) => `subagent · running ${elapsed}`,
|
|
1799
1802
|
running: (elapsed) => `running · ${elapsed}`,
|
|
@@ -1863,6 +1866,8 @@ var init_interactive_view = __esm({
|
|
|
1863
1866
|
codemode: (calls, lines2) => `${calls} 个内层调用 · 脚本输出 ${lines2} 行`,
|
|
1864
1867
|
done: "完成",
|
|
1865
1868
|
outputLines: (n) => `${n} 行输出`,
|
|
1869
|
+
fetched: (title, size, format) => [title, size, format].filter((p) => p !== void 0 && p !== "").join(" · "),
|
|
1870
|
+
fetchRedirect: (url) => `重定向到 ${url}(未跟随)`,
|
|
1866
1871
|
awaiting: (glyph) => `${glyph} 等待确认`,
|
|
1867
1872
|
subagentRunning: (elapsed) => `子 Agent · 运行中 ${elapsed}`,
|
|
1868
1873
|
running: (elapsed) => `运行中 · ${elapsed}`,
|
|
@@ -2199,6 +2204,8 @@ var init_approval = __esm({
|
|
|
2199
2204
|
option: {
|
|
2200
2205
|
allow: "Allow",
|
|
2201
2206
|
allowSession: "Allow for this session",
|
|
2207
|
+
/** web_fetch:本会话记住的是主机。 */
|
|
2208
|
+
allowSessionHost: (host) => `Allow ${host} for this session`,
|
|
2202
2209
|
deny: "Deny"
|
|
2203
2210
|
},
|
|
2204
2211
|
hint: (arrows) => `${arrows} select · Enter confirm · v full input`,
|
|
@@ -2207,6 +2214,7 @@ var init_approval = __esm({
|
|
|
2207
2214
|
outcome: {
|
|
2208
2215
|
allow: (what) => `Allowed ${what}`,
|
|
2209
2216
|
allowSession: (what) => `Allowed ${what} (similar calls won't ask again this session)`,
|
|
2217
|
+
allowSessionHost: (what, host) => `Allowed ${what} (${host} won't ask again this session)`,
|
|
2210
2218
|
deny: (what) => `Denied ${what}`,
|
|
2211
2219
|
cancelled: (what) => `Approval cancelled (timeout or interrupt): ${what}`
|
|
2212
2220
|
},
|
|
@@ -2244,6 +2252,7 @@ var init_approval = __esm({
|
|
|
2244
2252
|
option: {
|
|
2245
2253
|
allow: "允许",
|
|
2246
2254
|
allowSession: "本会话允许同类",
|
|
2255
|
+
allowSessionHost: (host) => `本会话允许 ${host}`,
|
|
2247
2256
|
deny: "拒绝"
|
|
2248
2257
|
},
|
|
2249
2258
|
hint: (arrows) => `${arrows} 选择 · Enter 确认 · v 完整输入`,
|
|
@@ -2251,6 +2260,7 @@ var init_approval = __esm({
|
|
|
2251
2260
|
outcome: {
|
|
2252
2261
|
allow: (what) => `已允许 ${what}`,
|
|
2253
2262
|
allowSession: (what) => `已允许 ${what}(本会话同类不再询问)`,
|
|
2263
|
+
allowSessionHost: (what, host) => `已允许 ${what}(本会话 ${host} 不再询问)`,
|
|
2254
2264
|
deny: (what) => `已拒绝 ${what}`,
|
|
2255
2265
|
cancelled: (what) => `审批已取消(超时或中断):${what}`
|
|
2256
2266
|
},
|
|
@@ -4281,6 +4291,7 @@ var init_drivers = __esm({
|
|
|
4281
4291
|
brokerNeedsAsk: "approvals.setBroker: broker needs ask()",
|
|
4282
4292
|
warmingNeedsFunction: "cache.onWarmingDecision: needs a function",
|
|
4283
4293
|
runnerNeedsIdStart: "runners.provide: needs a runner with id and start",
|
|
4294
|
+
runnerDoneNeedsFunction: "runners.onDone: needs a function",
|
|
4284
4295
|
notAdapter: (label2) => `${label2}: not a host adapter module (missing hostApi / create export)`,
|
|
4285
4296
|
versionMismatch: (label2, found, needed) => `${label2}: host adapter hostApi=${found}, ama needs ${needed}`,
|
|
4286
4297
|
noCreate: (label2) => `${label2}: missing create(api) function`,
|
|
@@ -4340,6 +4351,7 @@ var init_drivers = __esm({
|
|
|
4340
4351
|
brokerNeedsAsk: "approvals.setBroker:broker 需要 ask()",
|
|
4341
4352
|
warmingNeedsFunction: "cache.onWarmingDecision:需要函数",
|
|
4342
4353
|
runnerNeedsIdStart: "runners.provide:需要带 id 与 start 的 runner",
|
|
4354
|
+
runnerDoneNeedsFunction: "runners.onDone:需要函数",
|
|
4343
4355
|
notAdapter: (label2) => `${label2}: 不是宿主适配器模块(缺少 hostApi / create 导出)`,
|
|
4344
4356
|
versionMismatch: (label2, found, needed) => `${label2}: 宿主适配器 hostApi=${found},ama 需要 ${needed}`,
|
|
4345
4357
|
noCreate: (label2) => `${label2}: 缺少 create(api) 函数`,
|
|
@@ -6419,11 +6431,11 @@ function parseArgs(argv) {
|
|
|
6419
6431
|
continue;
|
|
6420
6432
|
}
|
|
6421
6433
|
let name;
|
|
6422
|
-
let
|
|
6434
|
+
let inline2;
|
|
6423
6435
|
if (token.startsWith("--")) {
|
|
6424
6436
|
const eq = token.indexOf("=");
|
|
6425
6437
|
name = eq === -1 ? token.slice(2) : token.slice(2, eq);
|
|
6426
|
-
|
|
6438
|
+
inline2 = eq === -1 ? void 0 : token.slice(eq + 1);
|
|
6427
6439
|
} else {
|
|
6428
6440
|
const alias = FLAG_ALIASES[token];
|
|
6429
6441
|
if (alias === void 0) throw new UsageError(msg().cli.args.unknownOption(token));
|
|
@@ -6432,9 +6444,9 @@ function parseArgs(argv) {
|
|
|
6432
6444
|
if (name === "resume") {
|
|
6433
6445
|
args.resume = true;
|
|
6434
6446
|
const next = argv[i + 1];
|
|
6435
|
-
if (
|
|
6436
|
-
if (
|
|
6437
|
-
args.resumeId =
|
|
6447
|
+
if (inline2 !== void 0) {
|
|
6448
|
+
if (inline2 === "") throw new UsageError(msg().cli.args.emptyResumeId);
|
|
6449
|
+
args.resumeId = inline2;
|
|
6438
6450
|
} else if (next !== void 0 && SESSION_ID_LIKE.test(next)) {
|
|
6439
6451
|
args.resumeId = next;
|
|
6440
6452
|
i++;
|
|
@@ -6442,7 +6454,7 @@ function parseArgs(argv) {
|
|
|
6442
6454
|
continue;
|
|
6443
6455
|
}
|
|
6444
6456
|
if (VALUE_OPTIONS.has(name)) {
|
|
6445
|
-
let value =
|
|
6457
|
+
let value = inline2;
|
|
6446
6458
|
if (value === void 0) {
|
|
6447
6459
|
value = argv[i + 1];
|
|
6448
6460
|
if (value === void 0) throw new UsageError(msg().cli.args.needsValue(name));
|
|
@@ -6451,7 +6463,7 @@ function parseArgs(argv) {
|
|
|
6451
6463
|
applyValue(args, name, value);
|
|
6452
6464
|
continue;
|
|
6453
6465
|
}
|
|
6454
|
-
if (
|
|
6466
|
+
if (inline2 !== void 0) throw new UsageError(msg().cli.args.noValue(name));
|
|
6455
6467
|
if (!applyFlag(args, name)) throw new UsageError(msg().cli.args.unknownOption(token));
|
|
6456
6468
|
}
|
|
6457
6469
|
if (args.positionals.length > 0) args.prompt = args.positionals.join(" ");
|
|
@@ -8614,6 +8626,237 @@ var init_memory_class = __esm({
|
|
|
8614
8626
|
}
|
|
8615
8627
|
});
|
|
8616
8628
|
|
|
8629
|
+
// src/tools/web/url-guard.ts
|
|
8630
|
+
function ipv6Groups(address) {
|
|
8631
|
+
let text = address.replace(/^\[|\]$/g, "").replace(/%.*$/, "");
|
|
8632
|
+
const v4 = /(\d+\.\d+\.\d+\.\d+)$/.exec(text);
|
|
8633
|
+
if (v4 !== null) {
|
|
8634
|
+
const parts = v4[1].split(".").map(Number);
|
|
8635
|
+
if (parts.some((p) => p > 255)) return void 0;
|
|
8636
|
+
const [a, b, c, d] = parts;
|
|
8637
|
+
text = `${text.slice(0, v4.index)}${(a << 8 | b).toString(16)}:${(c << 8 | d).toString(16)}`;
|
|
8638
|
+
}
|
|
8639
|
+
const halves = text.split("::");
|
|
8640
|
+
if (halves.length > 2) return void 0;
|
|
8641
|
+
const parse3 = (part) => part === "" ? [] : part.split(":").map((g) => /^[0-9a-f]{1,4}$/i.test(g) ? parseInt(g, 16) : NaN);
|
|
8642
|
+
const head = parse3(halves[0]);
|
|
8643
|
+
const tail = halves.length === 2 ? parse3(halves[1]) : [];
|
|
8644
|
+
const fill = 8 - head.length - tail.length;
|
|
8645
|
+
if (halves.length === 1 ? fill !== 0 : fill < 1) return void 0;
|
|
8646
|
+
const groups = [...head, ...new Array(halves.length === 2 ? fill : 0).fill(0), ...tail];
|
|
8647
|
+
return groups.some((g) => Number.isNaN(g)) ? void 0 : groups;
|
|
8648
|
+
}
|
|
8649
|
+
function v4FromGroups(hi, lo) {
|
|
8650
|
+
return `${hi >> 8}.${hi & 255}.${lo >> 8}.${lo & 255}`;
|
|
8651
|
+
}
|
|
8652
|
+
function embeddedIPv4(address) {
|
|
8653
|
+
const g = ipv6Groups(address);
|
|
8654
|
+
if (g === void 0) return void 0;
|
|
8655
|
+
const zeros = (from, to) => g.slice(from, to).every((x) => x === 0);
|
|
8656
|
+
if (zeros(0, 5) && (g[5] === 65535 || g[5] === 0 && g[6] >= 256))
|
|
8657
|
+
return v4FromGroups(g[6], g[7]);
|
|
8658
|
+
if (g[0] === 100 && g[1] === 65435 && zeros(2, 6))
|
|
8659
|
+
return v4FromGroups(g[6], g[7]);
|
|
8660
|
+
if (g[0] === 8194) return v4FromGroups(g[1], g[2]);
|
|
8661
|
+
return void 0;
|
|
8662
|
+
}
|
|
8663
|
+
function blockedAddressReason(address) {
|
|
8664
|
+
const bare = address.replace(/^\[|\]$/g, "").replace(/%.*$/, "");
|
|
8665
|
+
const family = (0, import_node_net.isIP)(bare);
|
|
8666
|
+
if (family === 0) return `${address} is not an IP address`;
|
|
8667
|
+
const lower = bare.toLowerCase();
|
|
8668
|
+
if (METADATA.has(lower)) return `${bare} is a cloud metadata address`;
|
|
8669
|
+
if (family === 4) {
|
|
8670
|
+
if (bare === "255.255.255.255" || blocked.check(bare, "ipv4"))
|
|
8671
|
+
return `${bare} is a private, loopback, link-local or reserved address`;
|
|
8672
|
+
return void 0;
|
|
8673
|
+
}
|
|
8674
|
+
const inner = embeddedIPv4(lower);
|
|
8675
|
+
if (inner !== void 0) {
|
|
8676
|
+
const reason = blockedAddressReason(inner);
|
|
8677
|
+
if (reason !== void 0) return `${bare} embeds ${inner}: ${reason}`;
|
|
8678
|
+
}
|
|
8679
|
+
if (blocked.check(lower, "ipv6"))
|
|
8680
|
+
return `${bare} is a private, loopback, link-local or multicast address`;
|
|
8681
|
+
return void 0;
|
|
8682
|
+
}
|
|
8683
|
+
function bareHostname(url) {
|
|
8684
|
+
return url.hostname.replace(/^\[|\]$/g, "").replace(/\.$/, "").toLowerCase();
|
|
8685
|
+
}
|
|
8686
|
+
function checkFetchUrl(raw) {
|
|
8687
|
+
if (typeof raw !== "string" || raw.trim() === "") return { ok: false, reason: "url is empty" };
|
|
8688
|
+
const text = raw.trim();
|
|
8689
|
+
if (text.length > MAX_URL_LENGTH)
|
|
8690
|
+
return { ok: false, reason: `URL is longer than ${MAX_URL_LENGTH} characters` };
|
|
8691
|
+
let url;
|
|
8692
|
+
try {
|
|
8693
|
+
url = new URL(text);
|
|
8694
|
+
} catch {
|
|
8695
|
+
return { ok: false, reason: "not a valid absolute URL" };
|
|
8696
|
+
}
|
|
8697
|
+
if (url.protocol !== "http:" && url.protocol !== "https:")
|
|
8698
|
+
return { ok: false, reason: `only http and https URLs are supported (got ${url.protocol})` };
|
|
8699
|
+
if (url.username !== "" || url.password !== "")
|
|
8700
|
+
return { ok: false, reason: "URLs with credentials (user:pass@) are not allowed" };
|
|
8701
|
+
if (url.search.length > MAX_QUERY_LENGTH + 1)
|
|
8702
|
+
return { ok: false, reason: `query string is longer than ${MAX_QUERY_LENGTH} characters` };
|
|
8703
|
+
const hostname = bareHostname(url);
|
|
8704
|
+
if ((0, import_node_net.isIP)(hostname) !== 0) {
|
|
8705
|
+
const reason = blockedAddressReason(hostname);
|
|
8706
|
+
return reason === void 0 ? { ok: true, url, hostname } : { ok: false, reason };
|
|
8707
|
+
}
|
|
8708
|
+
if (!hostname.includes(".") || hostname === "localhost" || hostname.endsWith(".localhost"))
|
|
8709
|
+
return {
|
|
8710
|
+
ok: false,
|
|
8711
|
+
reason: `${hostname} is a local host name; web_fetch only reaches public hosts`
|
|
8712
|
+
};
|
|
8713
|
+
return { ok: true, url, hostname };
|
|
8714
|
+
}
|
|
8715
|
+
async function resolvePublicAddresses(hostname, lookup = systemLookup) {
|
|
8716
|
+
const family = (0, import_node_net.isIP)(hostname);
|
|
8717
|
+
if (family !== 0) {
|
|
8718
|
+
const reason = blockedAddressReason(hostname);
|
|
8719
|
+
return reason === void 0 ? { ok: true, addresses: [{ address: hostname, family }] } : { ok: false, reason };
|
|
8720
|
+
}
|
|
8721
|
+
let addresses;
|
|
8722
|
+
try {
|
|
8723
|
+
addresses = await lookup(hostname);
|
|
8724
|
+
} catch (err) {
|
|
8725
|
+
const code = err.code;
|
|
8726
|
+
return { ok: false, reason: `cannot resolve ${hostname}${code ? ` (${code})` : ""}` };
|
|
8727
|
+
}
|
|
8728
|
+
if (addresses.length === 0) return { ok: false, reason: `cannot resolve ${hostname}` };
|
|
8729
|
+
for (const { address } of addresses) {
|
|
8730
|
+
const reason = blockedAddressReason(address);
|
|
8731
|
+
if (reason !== void 0) return { ok: false, reason: `${hostname} resolves to ${reason}` };
|
|
8732
|
+
}
|
|
8733
|
+
return { ok: true, addresses };
|
|
8734
|
+
}
|
|
8735
|
+
function pinnedLookup(addresses) {
|
|
8736
|
+
return (_hostname, options, callback) => {
|
|
8737
|
+
const cb = typeof options === "function" ? options : callback;
|
|
8738
|
+
const all = typeof options === "object" && options !== null && options.all;
|
|
8739
|
+
const first = addresses[0];
|
|
8740
|
+
if (all === true) cb(null, [...addresses]);
|
|
8741
|
+
else cb(null, first.address, first.family);
|
|
8742
|
+
};
|
|
8743
|
+
}
|
|
8744
|
+
function redirectPolicy(from, to) {
|
|
8745
|
+
if (bareHostname(from) !== bareHostname(to)) return "cross-host";
|
|
8746
|
+
if (from.protocol === "http:" && to.protocol === "https:") return "follow";
|
|
8747
|
+
return from.protocol === to.protocol && portOf(from) === portOf(to) ? "follow" : "cross-host";
|
|
8748
|
+
}
|
|
8749
|
+
function portOf(url) {
|
|
8750
|
+
return url.port !== "" ? url.port : url.protocol === "https:" ? "443" : "80";
|
|
8751
|
+
}
|
|
8752
|
+
var import_node_dns, import_node_net, MAX_URL_LENGTH, MAX_QUERY_LENGTH, MAX_SAME_HOST_REDIRECTS, V4_BLOCKED, V6_BLOCKED, METADATA, blocked, systemLookup;
|
|
8753
|
+
var init_url_guard = __esm({
|
|
8754
|
+
"src/tools/web/url-guard.ts"() {
|
|
8755
|
+
"use strict";
|
|
8756
|
+
import_node_dns = require("node:dns");
|
|
8757
|
+
import_node_net = require("node:net");
|
|
8758
|
+
MAX_URL_LENGTH = 2048;
|
|
8759
|
+
MAX_QUERY_LENGTH = 1024;
|
|
8760
|
+
MAX_SAME_HOST_REDIRECTS = 5;
|
|
8761
|
+
V4_BLOCKED = [
|
|
8762
|
+
["0.0.0.0", 8],
|
|
8763
|
+
["10.0.0.0", 8],
|
|
8764
|
+
["100.64.0.0", 10],
|
|
8765
|
+
["127.0.0.0", 8],
|
|
8766
|
+
["169.254.0.0", 16],
|
|
8767
|
+
["172.16.0.0", 12],
|
|
8768
|
+
["192.0.0.0", 24],
|
|
8769
|
+
["192.0.2.0", 24],
|
|
8770
|
+
["192.168.0.0", 16],
|
|
8771
|
+
["198.18.0.0", 15],
|
|
8772
|
+
["198.51.100.0", 24],
|
|
8773
|
+
["203.0.113.0", 24],
|
|
8774
|
+
["224.0.0.0", 4],
|
|
8775
|
+
["240.0.0.0", 4]
|
|
8776
|
+
];
|
|
8777
|
+
V6_BLOCKED = [
|
|
8778
|
+
["::", 96],
|
|
8779
|
+
["::1", 128],
|
|
8780
|
+
["100::", 64],
|
|
8781
|
+
["2001:db8::", 32],
|
|
8782
|
+
["fc00::", 7],
|
|
8783
|
+
["fe80::", 10],
|
|
8784
|
+
["fec0::", 10],
|
|
8785
|
+
["ff00::", 8]
|
|
8786
|
+
];
|
|
8787
|
+
METADATA = /* @__PURE__ */ new Set(["169.254.169.254", "100.100.100.200", "fd00:ec2::254"]);
|
|
8788
|
+
blocked = new import_node_net.BlockList();
|
|
8789
|
+
for (const [net, prefix] of V4_BLOCKED) blocked.addSubnet(net, prefix, "ipv4");
|
|
8790
|
+
for (const [net, prefix] of V6_BLOCKED) blocked.addSubnet(net, prefix, "ipv6");
|
|
8791
|
+
systemLookup = (hostname) => new Promise((resolve41, reject2) => {
|
|
8792
|
+
(0, import_node_dns.lookup)(hostname, { all: true, verbatim: true }, (err, addresses) => {
|
|
8793
|
+
if (err) reject2(err);
|
|
8794
|
+
else resolve41(addresses);
|
|
8795
|
+
});
|
|
8796
|
+
});
|
|
8797
|
+
}
|
|
8798
|
+
});
|
|
8799
|
+
|
|
8800
|
+
// src/permissions/network-class.ts
|
|
8801
|
+
function networkEffectivePermission() {
|
|
8802
|
+
return "execute";
|
|
8803
|
+
}
|
|
8804
|
+
function inputUrl(input2) {
|
|
8805
|
+
const raw = typeof input2 === "object" && input2 !== null ? input2["url"] : void 0;
|
|
8806
|
+
if (typeof raw !== "string") return void 0;
|
|
8807
|
+
try {
|
|
8808
|
+
const url = new URL(raw.trim());
|
|
8809
|
+
return url.protocol === "http:" || url.protocol === "https:" ? url : void 0;
|
|
8810
|
+
} catch {
|
|
8811
|
+
return void 0;
|
|
8812
|
+
}
|
|
8813
|
+
}
|
|
8814
|
+
function urlSubject(url) {
|
|
8815
|
+
return `${bareHostname(url)}${url.pathname === "" ? "/" : url.pathname}`;
|
|
8816
|
+
}
|
|
8817
|
+
function globRegExp(pattern) {
|
|
8818
|
+
let body = "";
|
|
8819
|
+
for (let i = 0; i < pattern.length; i++) {
|
|
8820
|
+
const ch2 = pattern[i];
|
|
8821
|
+
if (ch2 === "*" && pattern[i + 1] === "*") {
|
|
8822
|
+
body += ".*";
|
|
8823
|
+
i++;
|
|
8824
|
+
} else if (ch2 === "*") body += "[^/]*";
|
|
8825
|
+
else if (ch2 === "?") body += "[^/]";
|
|
8826
|
+
else body += ch2.replace(/[.+^${}()|[\]\\]/g, "\\$&");
|
|
8827
|
+
}
|
|
8828
|
+
return new RegExp(`^${body}$`, "i");
|
|
8829
|
+
}
|
|
8830
|
+
function networkRuleMatches(pattern, input2) {
|
|
8831
|
+
const url = inputUrl(input2);
|
|
8832
|
+
if (url === void 0) return false;
|
|
8833
|
+
const p = pattern.trim().replace(/^https?:\/\//i, "").toLowerCase();
|
|
8834
|
+
if (p === "*" || p === "**") return true;
|
|
8835
|
+
const host = bareHostname(url);
|
|
8836
|
+
if (!p.includes("/")) {
|
|
8837
|
+
if (p.includes("*") || p.includes("?")) return globRegExp(p).test(host);
|
|
8838
|
+
const bare = p.replace(/\.$/, "");
|
|
8839
|
+
return host === bare || host.endsWith(`.${bare}`);
|
|
8840
|
+
}
|
|
8841
|
+
return globRegExp(p).test(urlSubject(url));
|
|
8842
|
+
}
|
|
8843
|
+
function networkGrantHost(input2) {
|
|
8844
|
+
const url = inputUrl(input2);
|
|
8845
|
+
return url === void 0 ? void 0 : bareHostname(url);
|
|
8846
|
+
}
|
|
8847
|
+
function networkBlockReason(input2) {
|
|
8848
|
+
const raw = typeof input2 === "object" && input2 !== null ? input2["url"] : void 0;
|
|
8849
|
+
if (typeof raw !== "string") return "url is missing";
|
|
8850
|
+
const checked = checkFetchUrl(raw);
|
|
8851
|
+
return checked.ok ? void 0 : checked.reason;
|
|
8852
|
+
}
|
|
8853
|
+
var init_network_class = __esm({
|
|
8854
|
+
"src/permissions/network-class.ts"() {
|
|
8855
|
+
"use strict";
|
|
8856
|
+
init_url_guard();
|
|
8857
|
+
}
|
|
8858
|
+
});
|
|
8859
|
+
|
|
8617
8860
|
// src/permissions/rules.ts
|
|
8618
8861
|
function parseRule(raw, effect, source) {
|
|
8619
8862
|
const text = raw.trim();
|
|
@@ -8712,7 +8955,8 @@ function matchesSubject(rule, toolName, input2, cwd, command3) {
|
|
|
8712
8955
|
if (toolName === "memory") return memoryRuleMatches(rule.pattern, input2);
|
|
8713
8956
|
if (command3 !== void 0) return wildcardToRegExp(rule.pattern).test(command3);
|
|
8714
8957
|
const abs = inputPath(toolName, input2, cwd);
|
|
8715
|
-
|
|
8958
|
+
if (abs !== void 0) return pathMatches(rule.pattern, abs, cwd);
|
|
8959
|
+
return networkRuleMatches(rule.pattern, input2);
|
|
8716
8960
|
}
|
|
8717
8961
|
function findDenyRule(rules, toolName, input2, cwd) {
|
|
8718
8962
|
const command3 = toolName === "memory" ? void 0 : inputCommand(input2);
|
|
@@ -8759,6 +9003,7 @@ var init_rules = __esm({
|
|
|
8759
9003
|
init_glob();
|
|
8760
9004
|
init_paths2();
|
|
8761
9005
|
init_memory_class();
|
|
9006
|
+
init_network_class();
|
|
8762
9007
|
BUILTIN_DENY_RULES = [
|
|
8763
9008
|
"write(**/.git/**)",
|
|
8764
9009
|
"edit(**/.git/**)",
|
|
@@ -9218,7 +9463,7 @@ function argumentText(toolName, input2) {
|
|
|
9218
9463
|
if (typeof input2 === "object" && input2 !== null) {
|
|
9219
9464
|
const record3 = input2;
|
|
9220
9465
|
if (toolName === "bash" && typeof record3["command"] === "string") return record3["command"];
|
|
9221
|
-
for (const key of ["path", "file_path", "pattern"]) {
|
|
9466
|
+
for (const key of ["path", "file_path", "pattern", "url"]) {
|
|
9222
9467
|
const value = record3[key];
|
|
9223
9468
|
if (typeof value === "string") return value;
|
|
9224
9469
|
}
|
|
@@ -9784,15 +10029,40 @@ var init_dispatcher = __esm({
|
|
|
9784
10029
|
});
|
|
9785
10030
|
|
|
9786
10031
|
// src/drivers/host-runners.ts
|
|
9787
|
-
|
|
10032
|
+
function statusOf(result, aborted) {
|
|
10033
|
+
if (aborted) return "aborted";
|
|
10034
|
+
const own = result.status;
|
|
10035
|
+
if (own !== void 0 && TERMINAL.includes(own)) return own;
|
|
10036
|
+
return result.isError ? "failed" : "completed";
|
|
10037
|
+
}
|
|
10038
|
+
function forward(target, prop) {
|
|
10039
|
+
const value = Reflect.get(target, prop, target);
|
|
10040
|
+
return typeof value === "function" ? value.bind(target) : value;
|
|
10041
|
+
}
|
|
10042
|
+
var TERMINAL, HostRunnerRegistry;
|
|
9788
10043
|
var init_host_runners = __esm({
|
|
9789
10044
|
"src/drivers/host-runners.ts"() {
|
|
9790
10045
|
"use strict";
|
|
9791
10046
|
init_errors();
|
|
9792
10047
|
init_i18n();
|
|
10048
|
+
TERMINAL = [
|
|
10049
|
+
"completed",
|
|
10050
|
+
"failed",
|
|
10051
|
+
"aborted",
|
|
10052
|
+
"max_turns",
|
|
10053
|
+
"interrupted"
|
|
10054
|
+
];
|
|
9793
10055
|
HostRunnerRegistry = class {
|
|
9794
10056
|
runners = /* @__PURE__ */ new Map();
|
|
9795
10057
|
listeners = /* @__PURE__ */ new Set();
|
|
10058
|
+
doneHandlers = /* @__PURE__ */ new Set();
|
|
10059
|
+
observed = /* @__PURE__ */ new WeakMap();
|
|
10060
|
+
now;
|
|
10061
|
+
log;
|
|
10062
|
+
constructor(options = {}) {
|
|
10063
|
+
this.now = options.now ?? Date.now;
|
|
10064
|
+
this.log = options.log ?? (() => void 0);
|
|
10065
|
+
}
|
|
9796
10066
|
provide(runner) {
|
|
9797
10067
|
if (typeof runner?.id !== "string" || runner.id === "" || typeof runner.start !== "function")
|
|
9798
10068
|
throw new AmaError("invalid_arguments", msg().drivers.host.runnerNeedsIdStart);
|
|
@@ -9807,6 +10077,17 @@ var init_host_runners = __esm({
|
|
|
9807
10077
|
get(id) {
|
|
9808
10078
|
return this.runners.get(id);
|
|
9809
10079
|
}
|
|
10080
|
+
/** [#226] 任务入口用:同 {@link get},但返回发 `onDone` 的观察包装(同一 runner 包装复用)。 */
|
|
10081
|
+
resolve(id) {
|
|
10082
|
+
const runner = this.runners.get(id);
|
|
10083
|
+
if (runner === void 0) return void 0;
|
|
10084
|
+
let wrapped = this.observed.get(runner);
|
|
10085
|
+
if (wrapped === void 0) {
|
|
10086
|
+
wrapped = this.observe(runner);
|
|
10087
|
+
this.observed.set(runner, wrapped);
|
|
10088
|
+
}
|
|
10089
|
+
return wrapped;
|
|
10090
|
+
}
|
|
9810
10091
|
list() {
|
|
9811
10092
|
return [...this.runners.values()];
|
|
9812
10093
|
}
|
|
@@ -9815,6 +10096,13 @@ var init_host_runners = __esm({
|
|
|
9815
10096
|
this.listeners.add(listener);
|
|
9816
10097
|
return () => void this.listeners.delete(listener);
|
|
9817
10098
|
}
|
|
10099
|
+
/** [#226] 每轮结束时回调(`HostApi.runners.onDone`);返回注销函数。 */
|
|
10100
|
+
onDone(handler) {
|
|
10101
|
+
if (typeof handler !== "function")
|
|
10102
|
+
throw new AmaError("invalid_arguments", msg().drivers.host.runnerDoneNeedsFunction);
|
|
10103
|
+
this.doneHandlers.add(handler);
|
|
10104
|
+
return () => void this.doneHandlers.delete(handler);
|
|
10105
|
+
}
|
|
9818
10106
|
changed() {
|
|
9819
10107
|
for (const listener of [...this.listeners]) {
|
|
9820
10108
|
try {
|
|
@@ -9823,16 +10111,103 @@ var init_host_runners = __esm({
|
|
|
9823
10111
|
}
|
|
9824
10112
|
}
|
|
9825
10113
|
}
|
|
10114
|
+
emitDone(event) {
|
|
10115
|
+
for (const handler of [...this.doneHandlers]) {
|
|
10116
|
+
try {
|
|
10117
|
+
const out = handler(event);
|
|
10118
|
+
if (out instanceof Promise) out.catch((error2) => this.fail(error2));
|
|
10119
|
+
} catch (error2) {
|
|
10120
|
+
this.fail(error2);
|
|
10121
|
+
}
|
|
10122
|
+
}
|
|
10123
|
+
}
|
|
10124
|
+
fail(error2) {
|
|
10125
|
+
this.log(msg().drivers.host.handlerFailed("runners.onDone"), error2);
|
|
10126
|
+
}
|
|
10127
|
+
observe(runner) {
|
|
10128
|
+
return new Proxy(runner, {
|
|
10129
|
+
get: (target, prop) => {
|
|
10130
|
+
if (prop !== "start") return forward(target, prop);
|
|
10131
|
+
return async (request) => this.observeHandle(target.id, request, this.now(), await target.start(request));
|
|
10132
|
+
}
|
|
10133
|
+
});
|
|
10134
|
+
}
|
|
10135
|
+
observeHandle(runner, request, startedAt, handle) {
|
|
10136
|
+
let round = 0;
|
|
10137
|
+
let fresh = true;
|
|
10138
|
+
let pending = false;
|
|
10139
|
+
let stopped = false;
|
|
10140
|
+
let roundStart = startedAt;
|
|
10141
|
+
const activity = () => {
|
|
10142
|
+
if (pending) return;
|
|
10143
|
+
fresh = true;
|
|
10144
|
+
roundStart = this.now();
|
|
10145
|
+
};
|
|
10146
|
+
const settle = (at, done) => {
|
|
10147
|
+
pending = false;
|
|
10148
|
+
const endedAt = this.now();
|
|
10149
|
+
const event = {
|
|
10150
|
+
runner,
|
|
10151
|
+
sessionId: handle.id,
|
|
10152
|
+
round,
|
|
10153
|
+
status: done.status,
|
|
10154
|
+
isError: done.status === "failed" || done.status === "aborted",
|
|
10155
|
+
startedAt: at,
|
|
10156
|
+
endedAt,
|
|
10157
|
+
durationMs: Math.max(0, endedAt - at)
|
|
10158
|
+
};
|
|
10159
|
+
if (request.taskId !== void 0) event.taskId = request.taskId;
|
|
10160
|
+
if (done.text !== void 0) event.text = done.text;
|
|
10161
|
+
if (done.error !== void 0) event.error = done.error;
|
|
10162
|
+
this.emitDone(event);
|
|
10163
|
+
};
|
|
10164
|
+
const wait = () => {
|
|
10165
|
+
const result = handle.wait();
|
|
10166
|
+
if (!fresh) return result;
|
|
10167
|
+
fresh = false;
|
|
10168
|
+
pending = true;
|
|
10169
|
+
stopped = false;
|
|
10170
|
+
round += 1;
|
|
10171
|
+
const at = roundStart;
|
|
10172
|
+
const aborted = () => stopped || request.signal.aborted;
|
|
10173
|
+
result.then(
|
|
10174
|
+
(value) => settle(at, { status: statusOf(value, aborted()), text: value.text }),
|
|
10175
|
+
(error2) => settle(at, {
|
|
10176
|
+
status: aborted() ? "aborted" : "failed",
|
|
10177
|
+
error: error2 instanceof Error ? error2.message : String(error2)
|
|
10178
|
+
})
|
|
10179
|
+
);
|
|
10180
|
+
return result;
|
|
10181
|
+
};
|
|
10182
|
+
return new Proxy(handle, {
|
|
10183
|
+
get: (target, prop) => {
|
|
10184
|
+
const value = forward(target, prop);
|
|
10185
|
+
if (prop === "wait") return wait;
|
|
10186
|
+
if (prop === "stop" && typeof value === "function")
|
|
10187
|
+
return (...args) => {
|
|
10188
|
+
if (pending) stopped = true;
|
|
10189
|
+
return value(...args);
|
|
10190
|
+
};
|
|
10191
|
+
if ((prop === "send" || prop === "interrupt" || prop === "message") && typeof value === "function")
|
|
10192
|
+
return (...args) => {
|
|
10193
|
+
activity();
|
|
10194
|
+
return value(...args);
|
|
10195
|
+
};
|
|
10196
|
+
return value;
|
|
10197
|
+
}
|
|
10198
|
+
});
|
|
10199
|
+
}
|
|
9826
10200
|
};
|
|
9827
10201
|
}
|
|
9828
10202
|
});
|
|
9829
10203
|
|
|
9830
10204
|
// src/host/types.ts
|
|
9831
|
-
var HOST_API_VERSION;
|
|
10205
|
+
var HOST_API_VERSION, HOST_API_MINOR;
|
|
9832
10206
|
var init_types5 = __esm({
|
|
9833
10207
|
"src/host/types.ts"() {
|
|
9834
10208
|
"use strict";
|
|
9835
10209
|
HOST_API_VERSION = 1;
|
|
10210
|
+
HOST_API_MINOR = 1;
|
|
9836
10211
|
}
|
|
9837
10212
|
});
|
|
9838
10213
|
|
|
@@ -9862,14 +10237,15 @@ function createHostApi(deps) {
|
|
|
9862
10237
|
let broker;
|
|
9863
10238
|
const warmingHandlers = [];
|
|
9864
10239
|
let notify = deps.notify;
|
|
9865
|
-
const runners = new HostRunnerRegistry();
|
|
9866
10240
|
const writeErr = deps.stderr ?? ((text) => void process.stderr.write(text));
|
|
9867
10241
|
const log = deps.log ?? ((level, message) => {
|
|
9868
10242
|
if (level === "warn" || level === "error") writeErr(`ama: [host] ${message}
|
|
9869
10243
|
`);
|
|
9870
10244
|
});
|
|
10245
|
+
const runners = new HostRunnerRegistry({ log: (message, error2) => log("error", message, error2) });
|
|
9871
10246
|
const api = Object.freeze({
|
|
9872
10247
|
version: HOST_API_VERSION,
|
|
10248
|
+
minor: HOST_API_MINOR,
|
|
9873
10249
|
agent: Object.freeze({ name: "ama", version: AMA_VERSION }),
|
|
9874
10250
|
env: Object.freeze({ ...deps.env ?? process.env }),
|
|
9875
10251
|
mode: deps.mode,
|
|
@@ -9948,7 +10324,8 @@ function createHostApi(deps) {
|
|
|
9948
10324
|
}
|
|
9949
10325
|
}),
|
|
9950
10326
|
runners: Object.freeze({
|
|
9951
|
-
provide: (runner) => runners.provide(runner)
|
|
10327
|
+
provide: (runner) => runners.provide(runner),
|
|
10328
|
+
onDone: (handler) => runners.onDone(handler)
|
|
9952
10329
|
})
|
|
9953
10330
|
});
|
|
9954
10331
|
hostRunnerRegistries.set(api, runners);
|
|
@@ -15116,6 +15493,9 @@ var init_jsonl = __esm({
|
|
|
15116
15493
|
});
|
|
15117
15494
|
|
|
15118
15495
|
// src/drivers/acp/types.ts
|
|
15496
|
+
function isTerminalAuthMethod(method) {
|
|
15497
|
+
return method.type === "terminal";
|
|
15498
|
+
}
|
|
15119
15499
|
var ACP_PROTOCOL_VERSION, ACP_METHODS, RPC_ERRORS, ACP_META_KEY;
|
|
15120
15500
|
var init_types7 = __esm({
|
|
15121
15501
|
"src/drivers/acp/types.ts"() {
|
|
@@ -15123,8 +15503,10 @@ var init_types7 = __esm({
|
|
|
15123
15503
|
ACP_PROTOCOL_VERSION = 1;
|
|
15124
15504
|
ACP_METHODS = {
|
|
15125
15505
|
initialize: "initialize",
|
|
15126
|
-
/**
|
|
15506
|
+
/** 客户端 → Agent:agent 型认证方法经它完成;terminal 型不经它(规范)。 */
|
|
15127
15507
|
authenticate: "authenticate",
|
|
15508
|
+
/** 客户端 → Agent:登出当前账号(Agent 声明 `agentCapabilities.auth.logout` 才可用)。 */
|
|
15509
|
+
logout: "logout",
|
|
15128
15510
|
sessionNew: "session/new",
|
|
15129
15511
|
sessionLoad: "session/load",
|
|
15130
15512
|
sessionResume: "session/resume",
|
|
@@ -15137,6 +15519,8 @@ var init_types7 = __esm({
|
|
|
15137
15519
|
sessionUpdate: "session/update",
|
|
15138
15520
|
requestPermission: "session/request_permission",
|
|
15139
15521
|
elicitationCreate: "elicitation/create",
|
|
15522
|
+
/** Agent → 客户端通知:URL 型 elicitation 已在带外完成。 */
|
|
15523
|
+
elicitationComplete: "elicitation/complete",
|
|
15140
15524
|
/** 协议级取消(双向通知,`requestId` 指对端发来的、尚未答复的请求)。 */
|
|
15141
15525
|
cancelRequest: "$/cancel_request"
|
|
15142
15526
|
};
|
|
@@ -16134,10 +16518,18 @@ function safeFileName(name) {
|
|
|
16134
16518
|
const cleaned = name.replace(/[^A-Za-z0-9._-]/g, "_");
|
|
16135
16519
|
return cleaned === "" ? "output" : cleaned.slice(0, 120);
|
|
16136
16520
|
}
|
|
16137
|
-
|
|
16521
|
+
function writeFullOutput(outputDir, fileName, content) {
|
|
16522
|
+
const dir = resolveOutputDir(outputDir);
|
|
16523
|
+
(0, import_node_fs22.mkdirSync)(dir, { recursive: true });
|
|
16524
|
+
const target = (0, import_node_path24.join)(dir, safeFileName(fileName));
|
|
16525
|
+
(0, import_node_fs22.writeFileSync)(target, content);
|
|
16526
|
+
return target;
|
|
16527
|
+
}
|
|
16528
|
+
var import_node_fs22, import_node_os4, import_node_path24, DEFAULT_MAX_LINES, DEFAULT_MAX_BYTES, RESULT_NOTE_RESERVE, GREP_MAX_LINE_CHARS, HEAD_TAIL_RATIO;
|
|
16138
16529
|
var init_truncate = __esm({
|
|
16139
16530
|
"src/tools/truncate.ts"() {
|
|
16140
16531
|
"use strict";
|
|
16532
|
+
import_node_fs22 = require("node:fs");
|
|
16141
16533
|
import_node_os4 = require("node:os");
|
|
16142
16534
|
import_node_path24 = require("node:path");
|
|
16143
16535
|
DEFAULT_MAX_LINES = 2e3;
|
|
@@ -16777,11 +17169,11 @@ async function readImage(abs, shown2, ctx, options) {
|
|
|
16777
17169
|
[${fit.note}]`, details };
|
|
16778
17170
|
const note = fit.resized !== void 0 && fit.size !== void 0 ? `
|
|
16779
17171
|
[Resized to ${fit.size.width}x${fit.size.height} to fit the attachment limit.]` : "";
|
|
16780
|
-
const
|
|
17172
|
+
const blocks2 = [
|
|
16781
17173
|
{ type: "text", text: caption + note },
|
|
16782
17174
|
internImage({ type: "image", data: fit.buf.toString("base64"), mimeType: fit.mimeType })
|
|
16783
17175
|
];
|
|
16784
|
-
return { content:
|
|
17176
|
+
return { content: blocks2, details };
|
|
16785
17177
|
}
|
|
16786
17178
|
async function executeRead(input2, ctx, options = {}) {
|
|
16787
17179
|
const abs = resolvePath(input2.path, ctx.cwd);
|
|
@@ -17251,7 +17643,7 @@ function gitBashCandidates(env) {
|
|
|
17251
17643
|
function resolveShell(deps = {}) {
|
|
17252
17644
|
const platform = deps.platform ?? process.platform;
|
|
17253
17645
|
const env = deps.env ?? process.env;
|
|
17254
|
-
const exists5 = deps.exists ??
|
|
17646
|
+
const exists5 = deps.exists ?? import_node_fs23.existsSync;
|
|
17255
17647
|
const custom = env["AMA_SHELL"]?.trim();
|
|
17256
17648
|
if (custom) return { shell: custom, kind: shellKindOf(custom) };
|
|
17257
17649
|
if (platform === "win32") {
|
|
@@ -17291,11 +17683,11 @@ function buildToolEnv(base4, info2) {
|
|
|
17291
17683
|
set("AMA_DEPTH", String(info2.depth));
|
|
17292
17684
|
return env;
|
|
17293
17685
|
}
|
|
17294
|
-
var
|
|
17686
|
+
var import_node_fs23, POWERSHELL_ARGS, INJECTED_ENV_VARS;
|
|
17295
17687
|
var init_shell = __esm({
|
|
17296
17688
|
"src/tools/shell.ts"() {
|
|
17297
17689
|
"use strict";
|
|
17298
|
-
|
|
17690
|
+
import_node_fs23 = require("node:fs");
|
|
17299
17691
|
POWERSHELL_ARGS = ["-NoProfile", "-NonInteractive", "-Command"];
|
|
17300
17692
|
INJECTED_ENV_VARS = [
|
|
17301
17693
|
"AMA_SESSION_ID",
|
|
@@ -17410,11 +17802,11 @@ var init_process_tree = __esm({
|
|
|
17410
17802
|
function sanitizeOutput(text) {
|
|
17411
17803
|
return text.replace(/\r\n/g, "\n").replace(ANSI, "").replace(/\r/g, "\n").replace(CONTROL, "");
|
|
17412
17804
|
}
|
|
17413
|
-
var
|
|
17805
|
+
var import_node_fs24, import_node_path28, import_node_string_decoder2, ANSI, CONTROL, OutputAccumulator;
|
|
17414
17806
|
var init_output_accumulator = __esm({
|
|
17415
17807
|
"src/tools/output-accumulator.ts"() {
|
|
17416
17808
|
"use strict";
|
|
17417
|
-
|
|
17809
|
+
import_node_fs24 = require("node:fs");
|
|
17418
17810
|
import_node_path28 = require("node:path");
|
|
17419
17811
|
import_node_string_decoder2 = require("node:string_decoder");
|
|
17420
17812
|
init_truncate();
|
|
@@ -17456,7 +17848,7 @@ var init_output_accumulator = __esm({
|
|
|
17456
17848
|
this.tailText = sliceTailBytes(this.tailText, this.maxBytes * 2);
|
|
17457
17849
|
}
|
|
17458
17850
|
if (this.spilledTo !== void 0) {
|
|
17459
|
-
(0,
|
|
17851
|
+
(0, import_node_fs24.appendFileSync)(this.spilledTo, text);
|
|
17460
17852
|
return;
|
|
17461
17853
|
}
|
|
17462
17854
|
this.chunks.push(text);
|
|
@@ -17465,8 +17857,8 @@ var init_output_accumulator = __esm({
|
|
|
17465
17857
|
}
|
|
17466
17858
|
spill() {
|
|
17467
17859
|
const target = this.options.spillPath();
|
|
17468
|
-
(0,
|
|
17469
|
-
(0,
|
|
17860
|
+
(0, import_node_fs24.mkdirSync)((0, import_node_path28.dirname)(target), { recursive: true });
|
|
17861
|
+
(0, import_node_fs24.writeFileSync)(target, this.chunks.join(""));
|
|
17470
17862
|
this.spilledTo = target;
|
|
17471
17863
|
this.chunks = [];
|
|
17472
17864
|
this.memoryBytes = 0;
|
|
@@ -17524,11 +17916,11 @@ async function disposeSessionJobs(sessionId) {
|
|
|
17524
17916
|
registry2.delete(sessionId);
|
|
17525
17917
|
await jobs.disposeAll();
|
|
17526
17918
|
}
|
|
17527
|
-
var
|
|
17919
|
+
var import_node_fs25, import_node_path29, BackgroundJobs, registry2;
|
|
17528
17920
|
var init_background_jobs = __esm({
|
|
17529
17921
|
"src/tools/background-jobs.ts"() {
|
|
17530
17922
|
"use strict";
|
|
17531
|
-
|
|
17923
|
+
import_node_fs25 = require("node:fs");
|
|
17532
17924
|
import_node_path29 = require("node:path");
|
|
17533
17925
|
init_process_tree();
|
|
17534
17926
|
init_truncate();
|
|
@@ -17537,13 +17929,13 @@ var init_background_jobs = __esm({
|
|
|
17537
17929
|
listeners = /* @__PURE__ */ new Set();
|
|
17538
17930
|
seq = 0;
|
|
17539
17931
|
start(command3, options) {
|
|
17540
|
-
(0,
|
|
17541
|
-
const fd = (0,
|
|
17932
|
+
(0, import_node_fs25.mkdirSync)((0, import_node_path29.dirname)(options.outputPath), { recursive: true });
|
|
17933
|
+
const fd = (0, import_node_fs25.openSync)(options.outputPath, "a");
|
|
17542
17934
|
let child;
|
|
17543
17935
|
try {
|
|
17544
17936
|
child = options.spawn(fd);
|
|
17545
17937
|
} finally {
|
|
17546
|
-
(0,
|
|
17938
|
+
(0, import_node_fs25.closeSync)(fd);
|
|
17547
17939
|
}
|
|
17548
17940
|
const id = `bg${++this.seq}`;
|
|
17549
17941
|
const job = {
|
|
@@ -17624,8 +18016,8 @@ var init_background_jobs = __esm({
|
|
|
17624
18016
|
if (entry === void 0) return void 0;
|
|
17625
18017
|
let text = "";
|
|
17626
18018
|
try {
|
|
17627
|
-
if ((0,
|
|
17628
|
-
text = (0,
|
|
18019
|
+
if ((0, import_node_fs25.statSync)(entry.job.outputPath).size > 0)
|
|
18020
|
+
text = (0, import_node_fs25.readFileSync)(entry.job.outputPath, "utf8");
|
|
17629
18021
|
} catch {
|
|
17630
18022
|
}
|
|
17631
18023
|
return { ...truncateTail(text, options), job: entry.job };
|
|
@@ -17671,7 +18063,7 @@ var init_background_jobs = __esm({
|
|
|
17671
18063
|
});
|
|
17672
18064
|
|
|
17673
18065
|
// src/sandbox/wrap.ts
|
|
17674
|
-
function resolveWritable(dirs, realpath4 =
|
|
18066
|
+
function resolveWritable(dirs, realpath4 = import_node_fs26.realpathSync) {
|
|
17675
18067
|
const out = [];
|
|
17676
18068
|
for (const dir of dirs) {
|
|
17677
18069
|
let real2;
|
|
@@ -17686,12 +18078,12 @@ function resolveWritable(dirs, realpath4 = import_node_fs25.realpathSync) {
|
|
|
17686
18078
|
}
|
|
17687
18079
|
function isDirectory(path) {
|
|
17688
18080
|
try {
|
|
17689
|
-
return (0,
|
|
18081
|
+
return (0, import_node_fs26.statSync)(path).isDirectory();
|
|
17690
18082
|
} catch {
|
|
17691
18083
|
return false;
|
|
17692
18084
|
}
|
|
17693
18085
|
}
|
|
17694
|
-
function resolveExtras(policy, missingOk, realpath4 =
|
|
18086
|
+
function resolveExtras(policy, missingOk, realpath4 = import_node_fs26.realpathSync, isDir4 = isDirectory) {
|
|
17695
18087
|
const readOnly = [];
|
|
17696
18088
|
for (const path of policy.readOnly ?? []) {
|
|
17697
18089
|
let real2;
|
|
@@ -17763,11 +18155,11 @@ function wrapCommand(status, command3, args, policy, realpath4, isDir4) {
|
|
|
17763
18155
|
};
|
|
17764
18156
|
}
|
|
17765
18157
|
}
|
|
17766
|
-
var
|
|
18158
|
+
var import_node_fs26, import_node_path30;
|
|
17767
18159
|
var init_wrap = __esm({
|
|
17768
18160
|
"src/sandbox/wrap.ts"() {
|
|
17769
18161
|
"use strict";
|
|
17770
|
-
|
|
18162
|
+
import_node_fs26 = require("node:fs");
|
|
17771
18163
|
import_node_path30 = require("node:path");
|
|
17772
18164
|
init_profile2();
|
|
17773
18165
|
}
|
|
@@ -18281,7 +18673,7 @@ async function executeGrep(input2, ctx) {
|
|
|
18281
18673
|
}
|
|
18282
18674
|
const files = await candidateFiles(root, rootIsFile, input2.glob, ctx.signal);
|
|
18283
18675
|
if (input2.filesOnly === true) return grepFilesOnly(files, regex, limit, ctx);
|
|
18284
|
-
const
|
|
18676
|
+
const blocks2 = [];
|
|
18285
18677
|
let matches2 = 0;
|
|
18286
18678
|
let matchedFiles = 0;
|
|
18287
18679
|
let limited = false;
|
|
@@ -18298,7 +18690,7 @@ async function executeGrep(input2, ctx) {
|
|
|
18298
18690
|
}
|
|
18299
18691
|
const shown2 = displayPath(batch[j], ctx.cwd);
|
|
18300
18692
|
const block = formatFileHits(shown2, hits, context, limit - matches2);
|
|
18301
|
-
|
|
18693
|
+
blocks2.push(block.text.join("\n"));
|
|
18302
18694
|
matches2 += block.used;
|
|
18303
18695
|
matchedFiles++;
|
|
18304
18696
|
if (block.used < hits.hits.length) {
|
|
@@ -18308,7 +18700,7 @@ async function executeGrep(input2, ctx) {
|
|
|
18308
18700
|
}
|
|
18309
18701
|
}
|
|
18310
18702
|
if (matches2 === 0) return { content: "No matches found", details: { matches: 0, files: 0 } };
|
|
18311
|
-
const joined =
|
|
18703
|
+
const joined = blocks2.join(context > 0 ? "\n--\n" : "\n");
|
|
18312
18704
|
const maxBytes = toolOutputBytes(ctx.maxResultChars);
|
|
18313
18705
|
const cut = truncateHead(joined, { maxLines: Number.MAX_SAFE_INTEGER, maxBytes });
|
|
18314
18706
|
let content = cut.content;
|
|
@@ -18764,9 +19156,9 @@ ${tail}`, truncated: true };
|
|
|
18764
19156
|
}
|
|
18765
19157
|
function writeTaskOutput(dir, name, text) {
|
|
18766
19158
|
try {
|
|
18767
|
-
(0,
|
|
19159
|
+
(0, import_node_fs27.mkdirSync)(dir, { recursive: true });
|
|
18768
19160
|
const file = (0, import_node_path34.join)(dir, name);
|
|
18769
|
-
(0,
|
|
19161
|
+
(0, import_node_fs27.writeFileSync)(file, text);
|
|
18770
19162
|
return file;
|
|
18771
19163
|
} catch {
|
|
18772
19164
|
return void 0;
|
|
@@ -18803,11 +19195,11 @@ function backgroundedText(reason, afterMs) {
|
|
|
18803
19195
|
function waitDetachedText(taskId) {
|
|
18804
19196
|
return `Task ${taskId} is still running and was moved to the background by the user; do not wait again — a <task-notification> arrives when it finishes.`;
|
|
18805
19197
|
}
|
|
18806
|
-
var
|
|
19198
|
+
var import_node_fs27, import_node_path34, TASK_RESULT_LIMIT_BYTES, HEAD_SHARE, MAX_TURNS_NOTE, NOTIFY_HINT, TASK_NOTIFICATION_RULE;
|
|
18807
19199
|
var init_result = __esm({
|
|
18808
19200
|
"src/agents/result.ts"() {
|
|
18809
19201
|
"use strict";
|
|
18810
|
-
|
|
19202
|
+
import_node_fs27 = require("node:fs");
|
|
18811
19203
|
import_node_path34 = require("node:path");
|
|
18812
19204
|
TASK_RESULT_LIMIT_BYTES = 50 * 1024;
|
|
18813
19205
|
HEAD_SHARE = 0.7;
|
|
@@ -18987,6 +19379,9 @@ var init_task_control = __esm({
|
|
|
18987
19379
|
});
|
|
18988
19380
|
|
|
18989
19381
|
// src/tools/task-ctl.ts
|
|
19382
|
+
function bindTaskCtlWaitCap(tool, capMs) {
|
|
19383
|
+
if (tool !== void 0) waitCaps.set(tool, capMs);
|
|
19384
|
+
}
|
|
18990
19385
|
function fail4(message) {
|
|
18991
19386
|
return { content: message, isError: true };
|
|
18992
19387
|
}
|
|
@@ -19013,7 +19408,7 @@ async function send(input2, ctx) {
|
|
|
19013
19408
|
return { content: result.text, isError: result.isError };
|
|
19014
19409
|
}
|
|
19015
19410
|
function createTaskCtlTool() {
|
|
19016
|
-
|
|
19411
|
+
const tool = {
|
|
19017
19412
|
name: TASK_CTL_TOOL,
|
|
19018
19413
|
label: "TaskCtl",
|
|
19019
19414
|
description: "Manage sub-agent tasks started by task: list them, wait for one, stop it, read its output, or send it a follow-up message (runs in background).",
|
|
@@ -19064,14 +19459,17 @@ ${body}` };
|
|
|
19064
19459
|
};
|
|
19065
19460
|
}
|
|
19066
19461
|
case "wait": {
|
|
19067
|
-
const
|
|
19462
|
+
const cap = Math.min(waitCaps.get(tool) ?? MAX_WAIT_MS, MAX_WAIT_MS);
|
|
19463
|
+
const wanted = Math.min(Math.max(input2.timeoutMs ?? DEFAULT_WAIT_MS, 0), MAX_WAIT_MS);
|
|
19464
|
+
const timeout = Math.min(wanted, cap);
|
|
19068
19465
|
const signal = control.detachSignal(taskId);
|
|
19069
19466
|
const result = await control.wait(taskId, timeout, { signal });
|
|
19070
19467
|
if (result === void 0 && signal.aborted) return { content: waitDetachedText(taskId) };
|
|
19071
19468
|
if (result === void 0) {
|
|
19072
19469
|
const turns = control.get(taskId)?.turns ?? 0;
|
|
19470
|
+
const capped2 = wanted > timeout ? ` Waits are capped at ${Math.round(timeout / 1e3)}s here; do not block on it: keep working, a <task-notification> follows when it finishes.` : "";
|
|
19073
19471
|
return {
|
|
19074
|
-
content: `Task ${taskId} is still running (${turns} turns so far). Wait again or stop it
|
|
19472
|
+
content: `Task ${taskId} is still running (${turns} turns so far). Wait again or stop it.${capped2}`
|
|
19075
19473
|
};
|
|
19076
19474
|
}
|
|
19077
19475
|
return {
|
|
@@ -19085,8 +19483,9 @@ ${result.text}`,
|
|
|
19085
19483
|
}
|
|
19086
19484
|
}
|
|
19087
19485
|
};
|
|
19486
|
+
return tool;
|
|
19088
19487
|
}
|
|
19089
|
-
var TASK_CTL_TOOL, DEFAULT_WAIT_MS, MAX_WAIT_MS;
|
|
19488
|
+
var TASK_CTL_TOOL, DEFAULT_WAIT_MS, MAX_WAIT_MS, COORDINATOR_WAIT_MAX_MS, waitCaps;
|
|
19090
19489
|
var init_task_ctl = __esm({
|
|
19091
19490
|
"src/tools/task-ctl.ts"() {
|
|
19092
19491
|
"use strict";
|
|
@@ -19096,6 +19495,749 @@ var init_task_ctl = __esm({
|
|
|
19096
19495
|
TASK_CTL_TOOL = "task_ctl";
|
|
19097
19496
|
DEFAULT_WAIT_MS = 3e4;
|
|
19098
19497
|
MAX_WAIT_MS = 6e5;
|
|
19498
|
+
COORDINATOR_WAIT_MAX_MS = 5e3;
|
|
19499
|
+
waitCaps = /* @__PURE__ */ new WeakMap();
|
|
19500
|
+
}
|
|
19501
|
+
});
|
|
19502
|
+
|
|
19503
|
+
// src/tools/web/html-to-markdown.ts
|
|
19504
|
+
function decodeEntities(text) {
|
|
19505
|
+
return text.replace(/&(#x[0-9a-f]+|#\d+|[a-z][a-z0-9]*);?/gi, (whole, body) => {
|
|
19506
|
+
if (body[0] === "#") {
|
|
19507
|
+
const code = body[1] === "x" || body[1] === "X" ? parseInt(body.slice(2), 16) : Number(body.slice(1));
|
|
19508
|
+
if (!Number.isFinite(code) || code <= 0 || code > 1114111 || code >= 55296 && code <= 57343)
|
|
19509
|
+
return "�";
|
|
19510
|
+
return String.fromCodePoint(code);
|
|
19511
|
+
}
|
|
19512
|
+
const hit = ENTITIES[body] ?? ENTITIES[body.toLowerCase()];
|
|
19513
|
+
return hit ?? whole;
|
|
19514
|
+
});
|
|
19515
|
+
}
|
|
19516
|
+
function parseAttrs(text) {
|
|
19517
|
+
const attrs = {};
|
|
19518
|
+
for (const m of text.matchAll(ATTR_RE)) {
|
|
19519
|
+
const name = m[1].toLowerCase();
|
|
19520
|
+
if (!(name in attrs)) attrs[name] = decodeEntities(m[2] ?? m[3] ?? m[4] ?? "");
|
|
19521
|
+
}
|
|
19522
|
+
return attrs;
|
|
19523
|
+
}
|
|
19524
|
+
function parseHtml(html) {
|
|
19525
|
+
const root = { tag: "#root", attrs: {}, children: [] };
|
|
19526
|
+
let cur = root;
|
|
19527
|
+
const open3 = (tag) => {
|
|
19528
|
+
for (let n = cur; n !== void 0; n = n.parent) if (n.tag === tag) return n;
|
|
19529
|
+
return void 0;
|
|
19530
|
+
};
|
|
19531
|
+
const closeTo = (node) => {
|
|
19532
|
+
cur = node.parent ?? root;
|
|
19533
|
+
};
|
|
19534
|
+
const closeOpen = (tags, stop) => {
|
|
19535
|
+
for (let n = cur; n !== void 0 && n !== root; n = n.parent) {
|
|
19536
|
+
if (tags.includes(n.tag)) return closeTo(n);
|
|
19537
|
+
if (stop.has(n.tag)) return;
|
|
19538
|
+
}
|
|
19539
|
+
};
|
|
19540
|
+
let i = 0;
|
|
19541
|
+
while (i < html.length) {
|
|
19542
|
+
const lt = html.indexOf("<", i);
|
|
19543
|
+
if (lt === -1) {
|
|
19544
|
+
cur.children.push(html.slice(i));
|
|
19545
|
+
break;
|
|
19546
|
+
}
|
|
19547
|
+
if (lt > i) cur.children.push(html.slice(i, lt));
|
|
19548
|
+
if (html.startsWith("<!--", lt)) {
|
|
19549
|
+
const end = html.indexOf("-->", lt + 4);
|
|
19550
|
+
i = end === -1 ? html.length : end + 3;
|
|
19551
|
+
continue;
|
|
19552
|
+
}
|
|
19553
|
+
if (html[lt + 1] === "!" || html[lt + 1] === "?") {
|
|
19554
|
+
const end = html.indexOf(">", lt);
|
|
19555
|
+
i = end === -1 ? html.length : end + 1;
|
|
19556
|
+
continue;
|
|
19557
|
+
}
|
|
19558
|
+
const m = /^<(\/?)([a-zA-Z][a-zA-Z0-9:-]*)((?:[^>"']|"[^"]*"|'[^']*')*)>/.exec(
|
|
19559
|
+
html.slice(lt, lt + 8192)
|
|
19560
|
+
);
|
|
19561
|
+
if (m === null) {
|
|
19562
|
+
cur.children.push("<");
|
|
19563
|
+
i = lt + 1;
|
|
19564
|
+
continue;
|
|
19565
|
+
}
|
|
19566
|
+
i = lt + m[0].length;
|
|
19567
|
+
const tag = m[2].toLowerCase();
|
|
19568
|
+
if (m[1] === "/") {
|
|
19569
|
+
const node2 = open3(tag);
|
|
19570
|
+
if (node2 !== void 0) closeTo(node2);
|
|
19571
|
+
continue;
|
|
19572
|
+
}
|
|
19573
|
+
if (CLOSES_P.has(tag)) closeOpen(["p"], BLOCK);
|
|
19574
|
+
const siblings = AUTO_CLOSE[tag];
|
|
19575
|
+
if (siblings !== void 0) closeOpen(siblings, SCOPE);
|
|
19576
|
+
const node = { tag, attrs: parseAttrs(m[3]), children: [], parent: cur };
|
|
19577
|
+
cur.children.push(node);
|
|
19578
|
+
if (RAW_TEXT.has(tag)) {
|
|
19579
|
+
const end = html.toLowerCase().indexOf(`</${tag}`, i);
|
|
19580
|
+
const body = html.slice(i, end === -1 ? html.length : end);
|
|
19581
|
+
node.children.push(body);
|
|
19582
|
+
const close = end === -1 ? -1 : html.indexOf(">", end);
|
|
19583
|
+
i = close === -1 ? html.length : close + 1;
|
|
19584
|
+
continue;
|
|
19585
|
+
}
|
|
19586
|
+
if (!VOID.has(tag) && !/\/\s*$/.test(m[3])) cur = node;
|
|
19587
|
+
}
|
|
19588
|
+
return root;
|
|
19589
|
+
}
|
|
19590
|
+
function find(node, test) {
|
|
19591
|
+
for (const child of node.children) {
|
|
19592
|
+
if (typeof child === "string") continue;
|
|
19593
|
+
if (test(child)) return child;
|
|
19594
|
+
if (DROP.has(child.tag)) continue;
|
|
19595
|
+
const hit = find(child, test);
|
|
19596
|
+
if (hit !== void 0) return hit;
|
|
19597
|
+
}
|
|
19598
|
+
return void 0;
|
|
19599
|
+
}
|
|
19600
|
+
function rawText(node) {
|
|
19601
|
+
return node.children.map((c) => typeof c === "string" ? c : rawText(c)).join("");
|
|
19602
|
+
}
|
|
19603
|
+
function resolveHref(href, base4) {
|
|
19604
|
+
const value = href.trim();
|
|
19605
|
+
if (value === "" || /^(javascript|data|vbscript):/i.test(value)) return void 0;
|
|
19606
|
+
if (value.startsWith("#")) return void 0;
|
|
19607
|
+
try {
|
|
19608
|
+
return base4 === void 0 ? new URL(value).href : new URL(value, base4).href;
|
|
19609
|
+
} catch {
|
|
19610
|
+
return void 0;
|
|
19611
|
+
}
|
|
19612
|
+
}
|
|
19613
|
+
function collapse(text) {
|
|
19614
|
+
return decodeEntities(text).replace(/[\s\u00a0]+/g, " ");
|
|
19615
|
+
}
|
|
19616
|
+
function inline(node, ctx) {
|
|
19617
|
+
let out = "";
|
|
19618
|
+
for (const child of node.children) {
|
|
19619
|
+
if (typeof child === "string") out += collapse(child);
|
|
19620
|
+
else out += renderInline(child, ctx);
|
|
19621
|
+
}
|
|
19622
|
+
return out;
|
|
19623
|
+
}
|
|
19624
|
+
function wrap(mark, text) {
|
|
19625
|
+
const trimmed = text.trim();
|
|
19626
|
+
if (trimmed === "") return text;
|
|
19627
|
+
const lead = text.startsWith(" ") ? " " : "";
|
|
19628
|
+
const trail = text.endsWith(" ") ? " " : "";
|
|
19629
|
+
return `${lead}${mark}${trimmed}${mark}${trail}`;
|
|
19630
|
+
}
|
|
19631
|
+
function renderInline(node, ctx) {
|
|
19632
|
+
if (DROP.has(node.tag)) return "";
|
|
19633
|
+
switch (node.tag) {
|
|
19634
|
+
case "br":
|
|
19635
|
+
return "\n";
|
|
19636
|
+
case "img": {
|
|
19637
|
+
const alt = (node.attrs["alt"] ?? "").trim();
|
|
19638
|
+
return alt === "" ? "" : collapse(alt);
|
|
19639
|
+
}
|
|
19640
|
+
case "a": {
|
|
19641
|
+
const text = inline(node, ctx);
|
|
19642
|
+
const href = resolveHref(node.attrs["href"] ?? "", ctx.base);
|
|
19643
|
+
if (href === void 0 || text.trim() === "") return text;
|
|
19644
|
+
return `[${text.trim().replace(/[[\]]/g, "\\$&")}](${href.replace(/[()\s]/g, encodeURIComponent)})`;
|
|
19645
|
+
}
|
|
19646
|
+
case "code":
|
|
19647
|
+
case "kbd":
|
|
19648
|
+
case "samp":
|
|
19649
|
+
case "tt": {
|
|
19650
|
+
const text = decodeEntities(rawText(node)).replace(/\s+/g, " ");
|
|
19651
|
+
if (text.trim() === "") return text;
|
|
19652
|
+
const fence2 = text.includes("`") ? "``" : "`";
|
|
19653
|
+
return `${fence2}${text}${fence2}`;
|
|
19654
|
+
}
|
|
19655
|
+
case "strong":
|
|
19656
|
+
case "b":
|
|
19657
|
+
return wrap("**", inline(node, ctx));
|
|
19658
|
+
case "em":
|
|
19659
|
+
case "i":
|
|
19660
|
+
return wrap("*", inline(node, ctx));
|
|
19661
|
+
case "del":
|
|
19662
|
+
case "s":
|
|
19663
|
+
return wrap("~~", inline(node, ctx));
|
|
19664
|
+
default:
|
|
19665
|
+
return BLOCK.has(node.tag) ? `
|
|
19666
|
+
|
|
19667
|
+
${blocks(node, ctx)}
|
|
19668
|
+
|
|
19669
|
+
` : inline(node, ctx);
|
|
19670
|
+
}
|
|
19671
|
+
}
|
|
19672
|
+
function blocks(node, ctx) {
|
|
19673
|
+
const parts = [];
|
|
19674
|
+
let run7 = "";
|
|
19675
|
+
const flush = () => {
|
|
19676
|
+
const text = run7.split("\n").map((l) => l.replace(/ {2,}/g, " ").trim()).join("\n").trim();
|
|
19677
|
+
if (text !== "") parts.push(text);
|
|
19678
|
+
run7 = "";
|
|
19679
|
+
};
|
|
19680
|
+
for (const child of node.children) {
|
|
19681
|
+
if (typeof child === "string") {
|
|
19682
|
+
run7 += collapse(child);
|
|
19683
|
+
continue;
|
|
19684
|
+
}
|
|
19685
|
+
if (DROP.has(child.tag)) continue;
|
|
19686
|
+
if (BLOCK.has(child.tag)) {
|
|
19687
|
+
flush();
|
|
19688
|
+
const text = renderBlock(child, ctx);
|
|
19689
|
+
if (text.trim() !== "") parts.push(text);
|
|
19690
|
+
} else run7 += renderInline(child, ctx);
|
|
19691
|
+
}
|
|
19692
|
+
flush();
|
|
19693
|
+
return parts.join("\n\n");
|
|
19694
|
+
}
|
|
19695
|
+
function prefixLines(text, first, rest) {
|
|
19696
|
+
return text.split("\n").map(
|
|
19697
|
+
(line2, i) => line2 === "" ? i === 0 ? first.trimEnd() : "" : `${i === 0 ? first : rest}${line2}`
|
|
19698
|
+
).join("\n");
|
|
19699
|
+
}
|
|
19700
|
+
function renderList(node, ctx) {
|
|
19701
|
+
const ordered = node.tag === "ol";
|
|
19702
|
+
let n = Number(node.attrs["start"] ?? "1");
|
|
19703
|
+
if (!Number.isFinite(n)) n = 1;
|
|
19704
|
+
const items = [];
|
|
19705
|
+
const inner = { ...ctx, listDepth: ctx.listDepth + 1 };
|
|
19706
|
+
for (const child of node.children) {
|
|
19707
|
+
if (typeof child === "string" || DROP.has(child.tag)) continue;
|
|
19708
|
+
const body = child.tag === "li" ? blocks(child, inner) : renderBlock(child, inner);
|
|
19709
|
+
if (body.trim() === "") continue;
|
|
19710
|
+
const marker = ordered ? `${n++}. ` : "- ";
|
|
19711
|
+
items.push(prefixLines(body.replace(/\n{2,}/g, "\n"), marker, " ".repeat(marker.length)));
|
|
19712
|
+
}
|
|
19713
|
+
return items.join("\n");
|
|
19714
|
+
}
|
|
19715
|
+
function cellText(node, ctx) {
|
|
19716
|
+
return blocks(node, ctx).replace(/\s*\n+\s*/g, " ").replace(/\|/g, "\\|").trim();
|
|
19717
|
+
}
|
|
19718
|
+
function renderTable(node, ctx) {
|
|
19719
|
+
const rows = [];
|
|
19720
|
+
const walk4 = (n) => {
|
|
19721
|
+
for (const child of n.children) {
|
|
19722
|
+
if (typeof child === "string" || DROP.has(child.tag)) continue;
|
|
19723
|
+
if (child.tag === "tr") {
|
|
19724
|
+
const cells = child.children.filter(
|
|
19725
|
+
(c) => typeof c !== "string" && (c.tag === "td" || c.tag === "th")
|
|
19726
|
+
);
|
|
19727
|
+
if (cells.length > 0)
|
|
19728
|
+
rows.push({
|
|
19729
|
+
cells: cells.map((c) => cellText(c, ctx)),
|
|
19730
|
+
header: n.tag === "thead" || cells.every((c) => c.tag === "th")
|
|
19731
|
+
});
|
|
19732
|
+
} else if (child.tag !== "table") walk4(child);
|
|
19733
|
+
}
|
|
19734
|
+
};
|
|
19735
|
+
walk4(node);
|
|
19736
|
+
if (rows.length === 0) return "";
|
|
19737
|
+
const width2 = Math.max(...rows.map((r) => r.cells.length));
|
|
19738
|
+
const line2 = (cells) => `| ${[...cells, ...new Array(width2 - cells.length).fill("")].join(" | ")} |`;
|
|
19739
|
+
const headerIndex = rows[0]?.header === true ? 0 : -1;
|
|
19740
|
+
const head = headerIndex === 0 ? rows.shift().cells : new Array(width2).fill("");
|
|
19741
|
+
return [line2(head), `|${" --- |".repeat(width2)}`, ...rows.map((r) => line2(r.cells))].join("\n");
|
|
19742
|
+
}
|
|
19743
|
+
function renderBlock(node, ctx) {
|
|
19744
|
+
switch (node.tag) {
|
|
19745
|
+
case "h1":
|
|
19746
|
+
case "h2":
|
|
19747
|
+
case "h3":
|
|
19748
|
+
case "h4":
|
|
19749
|
+
case "h5":
|
|
19750
|
+
case "h6": {
|
|
19751
|
+
const text = inline(node, ctx).replace(/\s+/g, " ").trim();
|
|
19752
|
+
return text === "" ? "" : `${"#".repeat(Number(node.tag[1]))} ${text}`;
|
|
19753
|
+
}
|
|
19754
|
+
case "hr":
|
|
19755
|
+
return "---";
|
|
19756
|
+
case "pre": {
|
|
19757
|
+
const code = find(node, (n) => n.tag === "code");
|
|
19758
|
+
const cls = `${code?.attrs["class"] ?? ""} ${node.attrs["class"] ?? ""}`;
|
|
19759
|
+
const lang = /(?:^|\s)(?:language|lang)-([\w+#-]+)/.exec(cls)?.[1] ?? "";
|
|
19760
|
+
const text = decodeEntities(rawText(node)).replace(/^\n/, "").replace(/\s+$/, "");
|
|
19761
|
+
const fence2 = text.includes("```") ? "~~~~" : "```";
|
|
19762
|
+
return `${fence2}${lang}
|
|
19763
|
+
${text}
|
|
19764
|
+
${fence2}`;
|
|
19765
|
+
}
|
|
19766
|
+
case "blockquote":
|
|
19767
|
+
return prefixLines(blocks(node, ctx), "> ", "> ");
|
|
19768
|
+
case "ul":
|
|
19769
|
+
case "ol":
|
|
19770
|
+
return renderList(node, ctx);
|
|
19771
|
+
case "table":
|
|
19772
|
+
return renderTable(node, ctx);
|
|
19773
|
+
default:
|
|
19774
|
+
return blocks(node, ctx);
|
|
19775
|
+
}
|
|
19776
|
+
}
|
|
19777
|
+
function pageTitle(root) {
|
|
19778
|
+
const title = find(root, (n) => n.tag === "title") ?? findIn(root, "title");
|
|
19779
|
+
const text = title !== void 0 ? collapse(rawText(title)).trim() : "";
|
|
19780
|
+
if (text !== "") return text;
|
|
19781
|
+
const h1 = find(root, (n) => n.tag === "h1");
|
|
19782
|
+
const heading = h1 !== void 0 ? collapse(rawText(h1)).trim() : "";
|
|
19783
|
+
return heading === "" ? void 0 : heading;
|
|
19784
|
+
}
|
|
19785
|
+
function findIn(node, tag) {
|
|
19786
|
+
for (const child of node.children) {
|
|
19787
|
+
if (typeof child === "string") continue;
|
|
19788
|
+
if (child.tag === tag) return child;
|
|
19789
|
+
const hit = findIn(child, tag);
|
|
19790
|
+
if (hit !== void 0) return hit;
|
|
19791
|
+
}
|
|
19792
|
+
return void 0;
|
|
19793
|
+
}
|
|
19794
|
+
function htmlToMarkdown(html, baseUrl) {
|
|
19795
|
+
const root = parseHtml(html);
|
|
19796
|
+
let base4;
|
|
19797
|
+
try {
|
|
19798
|
+
const declared = findIn(root, "base")?.attrs["href"];
|
|
19799
|
+
base4 = baseUrl === void 0 ? void 0 : new URL(declared ?? "", baseUrl);
|
|
19800
|
+
} catch {
|
|
19801
|
+
base4 = baseUrl === void 0 ? void 0 : new URL(baseUrl);
|
|
19802
|
+
}
|
|
19803
|
+
const main2 = find(root, (n) => n.tag === "main") ?? find(root, (n) => n.tag === "article") ?? find(root, (n) => n.attrs["role"] === "main") ?? find(root, (n) => n.tag === "body") ?? root;
|
|
19804
|
+
const markdown = blocks(main2, { base: base4, listDepth: 0 }).replace(/[ \t]+\n/g, "\n").replace(/\n{3,}/g, "\n\n").trim();
|
|
19805
|
+
const title = pageTitle(root);
|
|
19806
|
+
return title === void 0 ? { markdown } : { title, markdown };
|
|
19807
|
+
}
|
|
19808
|
+
function sniffMetaCharset(head) {
|
|
19809
|
+
const text = head.slice(0, 2048);
|
|
19810
|
+
const direct = /<meta[^>]+charset\s*=\s*["']?\s*([\w.:-]+)/i.exec(text);
|
|
19811
|
+
return direct?.[1]?.toLowerCase();
|
|
19812
|
+
}
|
|
19813
|
+
var VOID, RAW_TEXT, DROP, BLOCK, AUTO_CLOSE, CLOSES_P, SCOPE, ENTITIES, ATTR_RE;
|
|
19814
|
+
var init_html_to_markdown = __esm({
|
|
19815
|
+
"src/tools/web/html-to-markdown.ts"() {
|
|
19816
|
+
"use strict";
|
|
19817
|
+
VOID = /* @__PURE__ */ new Set([
|
|
19818
|
+
"area",
|
|
19819
|
+
"base",
|
|
19820
|
+
"br",
|
|
19821
|
+
"col",
|
|
19822
|
+
"embed",
|
|
19823
|
+
"hr",
|
|
19824
|
+
"img",
|
|
19825
|
+
"input",
|
|
19826
|
+
"link",
|
|
19827
|
+
"meta",
|
|
19828
|
+
"param",
|
|
19829
|
+
"source",
|
|
19830
|
+
"track",
|
|
19831
|
+
"wbr"
|
|
19832
|
+
]);
|
|
19833
|
+
RAW_TEXT = /* @__PURE__ */ new Set(["script", "style", "textarea", "title", "xmp", "noscript"]);
|
|
19834
|
+
DROP = /* @__PURE__ */ new Set([
|
|
19835
|
+
"script",
|
|
19836
|
+
"style",
|
|
19837
|
+
"noscript",
|
|
19838
|
+
"svg",
|
|
19839
|
+
"math",
|
|
19840
|
+
"template",
|
|
19841
|
+
"iframe",
|
|
19842
|
+
"nav",
|
|
19843
|
+
"footer",
|
|
19844
|
+
"aside",
|
|
19845
|
+
"form",
|
|
19846
|
+
"button",
|
|
19847
|
+
"select",
|
|
19848
|
+
"textarea",
|
|
19849
|
+
"head",
|
|
19850
|
+
"title",
|
|
19851
|
+
"canvas",
|
|
19852
|
+
"object",
|
|
19853
|
+
"dialog"
|
|
19854
|
+
]);
|
|
19855
|
+
BLOCK = /* @__PURE__ */ new Set([
|
|
19856
|
+
"address",
|
|
19857
|
+
"article",
|
|
19858
|
+
"blockquote",
|
|
19859
|
+
"body",
|
|
19860
|
+
"center",
|
|
19861
|
+
"dd",
|
|
19862
|
+
"details",
|
|
19863
|
+
"div",
|
|
19864
|
+
"dl",
|
|
19865
|
+
"dt",
|
|
19866
|
+
"figcaption",
|
|
19867
|
+
"figure",
|
|
19868
|
+
"h1",
|
|
19869
|
+
"h2",
|
|
19870
|
+
"h3",
|
|
19871
|
+
"h4",
|
|
19872
|
+
"h5",
|
|
19873
|
+
"h6",
|
|
19874
|
+
"header",
|
|
19875
|
+
"hr",
|
|
19876
|
+
"html",
|
|
19877
|
+
"li",
|
|
19878
|
+
"main",
|
|
19879
|
+
"ol",
|
|
19880
|
+
"p",
|
|
19881
|
+
"pre",
|
|
19882
|
+
"section",
|
|
19883
|
+
"summary",
|
|
19884
|
+
"table",
|
|
19885
|
+
"tbody",
|
|
19886
|
+
"td",
|
|
19887
|
+
"tfoot",
|
|
19888
|
+
"th",
|
|
19889
|
+
"thead",
|
|
19890
|
+
"tr",
|
|
19891
|
+
"ul"
|
|
19892
|
+
]);
|
|
19893
|
+
AUTO_CLOSE = {
|
|
19894
|
+
li: ["li"],
|
|
19895
|
+
dt: ["dt", "dd"],
|
|
19896
|
+
dd: ["dt", "dd"],
|
|
19897
|
+
tr: ["tr"],
|
|
19898
|
+
td: ["td", "th"],
|
|
19899
|
+
th: ["td", "th"],
|
|
19900
|
+
option: ["option"]
|
|
19901
|
+
};
|
|
19902
|
+
CLOSES_P = /* @__PURE__ */ new Set([
|
|
19903
|
+
"p",
|
|
19904
|
+
...[...BLOCK].filter((t) => !["li", "td", "th", "dd", "dt"].includes(t))
|
|
19905
|
+
]);
|
|
19906
|
+
SCOPE = /* @__PURE__ */ new Set(["ul", "ol", "dl", "table", "html", "body"]);
|
|
19907
|
+
ENTITIES = {
|
|
19908
|
+
amp: "&",
|
|
19909
|
+
lt: "<",
|
|
19910
|
+
gt: ">",
|
|
19911
|
+
quot: '"',
|
|
19912
|
+
apos: "'",
|
|
19913
|
+
nbsp: " ",
|
|
19914
|
+
copy: "©",
|
|
19915
|
+
reg: "®",
|
|
19916
|
+
trade: "™",
|
|
19917
|
+
hellip: "…",
|
|
19918
|
+
mdash: "—",
|
|
19919
|
+
ndash: "–",
|
|
19920
|
+
lsquo: "‘",
|
|
19921
|
+
rsquo: "’",
|
|
19922
|
+
ldquo: "“",
|
|
19923
|
+
rdquo: "”",
|
|
19924
|
+
laquo: "«",
|
|
19925
|
+
raquo: "»",
|
|
19926
|
+
middot: "·",
|
|
19927
|
+
bull: "•",
|
|
19928
|
+
times: "×",
|
|
19929
|
+
divide: "÷",
|
|
19930
|
+
deg: "°",
|
|
19931
|
+
euro: "€",
|
|
19932
|
+
pound: "£",
|
|
19933
|
+
yen: "¥",
|
|
19934
|
+
cent: "¢",
|
|
19935
|
+
sect: "§",
|
|
19936
|
+
para: "¶",
|
|
19937
|
+
larr: "←",
|
|
19938
|
+
rarr: "→",
|
|
19939
|
+
uarr: "↑",
|
|
19940
|
+
darr: "↓",
|
|
19941
|
+
harr: "↔",
|
|
19942
|
+
rArr: "⇒",
|
|
19943
|
+
lArr: "⇐",
|
|
19944
|
+
le: "≤",
|
|
19945
|
+
ge: "≥",
|
|
19946
|
+
ne: "≠",
|
|
19947
|
+
plusmn: "±",
|
|
19948
|
+
minus: "−",
|
|
19949
|
+
shy: "",
|
|
19950
|
+
zwj: "",
|
|
19951
|
+
zwnj: "",
|
|
19952
|
+
thinsp: " ",
|
|
19953
|
+
ensp: " ",
|
|
19954
|
+
emsp: " ",
|
|
19955
|
+
check: "✓"
|
|
19956
|
+
};
|
|
19957
|
+
ATTR_RE = /([^\s"'<>/=]+)(?:\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s"'=<>`]+)))?/g;
|
|
19958
|
+
}
|
|
19959
|
+
});
|
|
19960
|
+
|
|
19961
|
+
// src/tools/web/fetch.ts
|
|
19962
|
+
function fail5(content, details) {
|
|
19963
|
+
return { content, isError: true, ...details !== void 0 ? { details } : {} };
|
|
19964
|
+
}
|
|
19965
|
+
function readBody(res, limit) {
|
|
19966
|
+
const encoding = String(res.headers["content-encoding"] ?? "").trim().toLowerCase();
|
|
19967
|
+
let stream5 = res;
|
|
19968
|
+
if (encoding === "gzip" || encoding === "x-gzip") stream5 = res.pipe((0, import_node_zlib.createGunzip)());
|
|
19969
|
+
else if (encoding === "br") stream5 = res.pipe((0, import_node_zlib.createBrotliDecompress)());
|
|
19970
|
+
else if (encoding === "deflate") stream5 = res.pipe((0, import_node_zlib.createInflate)());
|
|
19971
|
+
return new Promise((resolve41, reject2) => {
|
|
19972
|
+
const chunks2 = [];
|
|
19973
|
+
let size = 0;
|
|
19974
|
+
let done = false;
|
|
19975
|
+
const finish2 = (cut) => {
|
|
19976
|
+
if (done) return;
|
|
19977
|
+
done = true;
|
|
19978
|
+
resolve41({ body: Buffer.concat(chunks2, Math.min(size, limit)).subarray(0, limit), cut });
|
|
19979
|
+
};
|
|
19980
|
+
stream5.on("data", (chunk) => {
|
|
19981
|
+
if (done) return;
|
|
19982
|
+
chunks2.push(chunk);
|
|
19983
|
+
size += chunk.length;
|
|
19984
|
+
if (size > limit) {
|
|
19985
|
+
finish2(true);
|
|
19986
|
+
res.destroy();
|
|
19987
|
+
if (stream5 !== res) stream5.destroy();
|
|
19988
|
+
}
|
|
19989
|
+
});
|
|
19990
|
+
stream5.on("end", () => finish2(false));
|
|
19991
|
+
stream5.on("error", (err) => done ? void 0 : (done = true, reject2(err)));
|
|
19992
|
+
res.on("error", (err) => done ? void 0 : (done = true, reject2(err)));
|
|
19993
|
+
});
|
|
19994
|
+
}
|
|
19995
|
+
function decodeText(body, contentType, html) {
|
|
19996
|
+
const declared = /charset\s*=\s*"?([\w.:-]+)/i.exec(contentType)?.[1];
|
|
19997
|
+
const sniffed = html ? sniffMetaCharset(body.subarray(0, 2048).toString("latin1")) : void 0;
|
|
19998
|
+
for (const label2 of [declared, sniffed, "utf-8"]) {
|
|
19999
|
+
if (label2 === void 0) continue;
|
|
20000
|
+
try {
|
|
20001
|
+
return new TextDecoder(label2).decode(body);
|
|
20002
|
+
} catch {
|
|
20003
|
+
}
|
|
20004
|
+
}
|
|
20005
|
+
return body.toString("utf8");
|
|
20006
|
+
}
|
|
20007
|
+
function formatOf(contentType, body) {
|
|
20008
|
+
const type = contentType.split(";")[0]?.trim().toLowerCase() ?? "";
|
|
20009
|
+
if (type === "text/html" || type === "application/xhtml+xml") return "html";
|
|
20010
|
+
if (type === "application/json" || type.endsWith("+json")) return "json";
|
|
20011
|
+
if (type.startsWith("text/") || /^application\/(xml|javascript|ecmascript|x-yaml|yaml|toml)$/.test(type) || type.endsWith("+xml"))
|
|
20012
|
+
return "text";
|
|
20013
|
+
if (type === "") {
|
|
20014
|
+
const head = body.subarray(0, 1024);
|
|
20015
|
+
if (head.includes(0)) return "binary";
|
|
20016
|
+
return /^\s*<(!doctype html|html)/i.test(head.toString("latin1")) ? "html" : "text";
|
|
20017
|
+
}
|
|
20018
|
+
return "binary";
|
|
20019
|
+
}
|
|
20020
|
+
function convert(body, contentType, finalUrl, raw) {
|
|
20021
|
+
const kind = formatOf(contentType, body);
|
|
20022
|
+
if (kind === "binary") {
|
|
20023
|
+
const type = contentType.split(";")[0]?.trim() || "unknown type";
|
|
20024
|
+
return {
|
|
20025
|
+
format: "binary",
|
|
20026
|
+
text: `Binary content (${type}, ${body.length} bytes); not parsed.`
|
|
20027
|
+
};
|
|
20028
|
+
}
|
|
20029
|
+
const text = decodeText(body, contentType, kind === "html");
|
|
20030
|
+
if (raw) return { format: "text", text };
|
|
20031
|
+
if (kind === "html") {
|
|
20032
|
+
const page2 = htmlToMarkdown(text, finalUrl);
|
|
20033
|
+
return page2.title === void 0 ? { format: "markdown", text: page2.markdown } : { format: "markdown", title: page2.title, text: page2.markdown };
|
|
20034
|
+
}
|
|
20035
|
+
if (kind === "json") {
|
|
20036
|
+
try {
|
|
20037
|
+
return { format: "json", text: JSON.stringify(JSON.parse(text), null, 2) };
|
|
20038
|
+
} catch {
|
|
20039
|
+
return { format: "text", text };
|
|
20040
|
+
}
|
|
20041
|
+
}
|
|
20042
|
+
return { format: "text", text };
|
|
20043
|
+
}
|
|
20044
|
+
function createWebFetchTool(options = {}) {
|
|
20045
|
+
const request = options.request ?? defaultRequest;
|
|
20046
|
+
const totalMs = options.totalTimeoutMs ?? FETCH_TOTAL_TIMEOUT_MS;
|
|
20047
|
+
const firstByteMs = options.firstByteTimeoutMs ?? FETCH_FIRST_BYTE_TIMEOUT_MS;
|
|
20048
|
+
const maxBody = options.maxBodyBytes ?? FETCH_MAX_BODY_BYTES;
|
|
20049
|
+
async function get(url, hostname, signal) {
|
|
20050
|
+
const resolved = await resolvePublicAddresses(hostname, options.lookup);
|
|
20051
|
+
if (!resolved.ok) throw new FetchError(resolved.reason);
|
|
20052
|
+
return new Promise((resolve41, reject2) => {
|
|
20053
|
+
const timer = setTimeout(() => {
|
|
20054
|
+
req.destroy(new FetchError(`no response within ${firstByteMs / 1e3}s`));
|
|
20055
|
+
}, firstByteMs);
|
|
20056
|
+
const req = request(
|
|
20057
|
+
url,
|
|
20058
|
+
{
|
|
20059
|
+
method: "GET",
|
|
20060
|
+
agent: false,
|
|
20061
|
+
lookup: pinnedLookup(resolved.addresses),
|
|
20062
|
+
headers: {
|
|
20063
|
+
Accept: FETCH_ACCEPT,
|
|
20064
|
+
"Accept-Encoding": "gzip, deflate, br",
|
|
20065
|
+
"User-Agent": `ama/${AMA_VERSION}`
|
|
20066
|
+
},
|
|
20067
|
+
signal
|
|
20068
|
+
},
|
|
20069
|
+
(res) => {
|
|
20070
|
+
clearTimeout(timer);
|
|
20071
|
+
resolve41(res);
|
|
20072
|
+
}
|
|
20073
|
+
);
|
|
20074
|
+
req.on("error", (err) => {
|
|
20075
|
+
clearTimeout(timer);
|
|
20076
|
+
reject2(err);
|
|
20077
|
+
});
|
|
20078
|
+
req.end();
|
|
20079
|
+
});
|
|
20080
|
+
}
|
|
20081
|
+
async function fetchFollowing(start, hostname, signal) {
|
|
20082
|
+
let url = start;
|
|
20083
|
+
let host = hostname;
|
|
20084
|
+
for (let hop = 0; ; hop++) {
|
|
20085
|
+
const res = await get(url, host, signal);
|
|
20086
|
+
const status = res.statusCode ?? 0;
|
|
20087
|
+
const location = res.headers.location;
|
|
20088
|
+
if (status >= 300 && status < 400 && typeof location === "string") {
|
|
20089
|
+
res.resume();
|
|
20090
|
+
let next;
|
|
20091
|
+
try {
|
|
20092
|
+
next = new URL(location, url);
|
|
20093
|
+
} catch {
|
|
20094
|
+
throw new FetchError(`invalid redirect location ${JSON.stringify(location)}`);
|
|
20095
|
+
}
|
|
20096
|
+
if (redirectPolicy(url, next) === "cross-host") return { redirect: next.href, status };
|
|
20097
|
+
const checked = checkFetchUrl(next.href);
|
|
20098
|
+
if (!checked.ok)
|
|
20099
|
+
throw new FetchError(`redirect to ${next.href} refused: ${checked.reason}`);
|
|
20100
|
+
if (hop + 1 > MAX_SAME_HOST_REDIRECTS)
|
|
20101
|
+
throw new FetchError(`more than ${MAX_SAME_HOST_REDIRECTS} redirects`);
|
|
20102
|
+
url = checked.url;
|
|
20103
|
+
host = checked.hostname;
|
|
20104
|
+
continue;
|
|
20105
|
+
}
|
|
20106
|
+
const { body, cut } = await readBody(res, maxBody);
|
|
20107
|
+
return { res, finalUrl: url.href, body, bodyCut: cut };
|
|
20108
|
+
}
|
|
20109
|
+
}
|
|
20110
|
+
async function execute2(input2, ctx) {
|
|
20111
|
+
const checked = checkFetchUrl(input2.url);
|
|
20112
|
+
if (!checked.ok) return fail5(`Cannot fetch ${String(input2.url)}: ${checked.reason}`);
|
|
20113
|
+
const offset = input2.offset ?? 0;
|
|
20114
|
+
const asked = input2.maxChars ?? DEFAULT_FETCH_CHARS;
|
|
20115
|
+
if (!Number.isInteger(offset) || offset < 0) return fail5("offset must be an integer ≥ 0");
|
|
20116
|
+
if (!Number.isInteger(asked) || asked < 1) return fail5("maxChars must be an integer ≥ 1");
|
|
20117
|
+
const sessionCap = ctx.maxResultChars === void 0 ? Infinity : ctx.maxResultChars - RESULT_NOTE_RESERVE;
|
|
20118
|
+
const limit = Math.max(1e3, Math.min(asked, MAX_FETCH_CHARS, sessionCap));
|
|
20119
|
+
const controller = new AbortController();
|
|
20120
|
+
const timer = setTimeout(
|
|
20121
|
+
() => controller.abort(new FetchError(`timed out after ${totalMs / 1e3}s`)),
|
|
20122
|
+
totalMs
|
|
20123
|
+
);
|
|
20124
|
+
const signal = AbortSignal.any([ctx.signal, controller.signal]);
|
|
20125
|
+
let fetched;
|
|
20126
|
+
try {
|
|
20127
|
+
fetched = await fetchFollowing(checked.url, checked.hostname, signal);
|
|
20128
|
+
} catch (err) {
|
|
20129
|
+
const reason = controller.signal.aborted && controller.signal.reason instanceof FetchError ? controller.signal.reason.message : err instanceof Error ? err.message : String(err);
|
|
20130
|
+
return fail5(`Cannot fetch ${checked.url.href}: ${reason}`);
|
|
20131
|
+
} finally {
|
|
20132
|
+
clearTimeout(timer);
|
|
20133
|
+
}
|
|
20134
|
+
if ("redirect" in fetched) {
|
|
20135
|
+
return {
|
|
20136
|
+
content: `Redirected to ${fetched.redirect}; call web_fetch with it if appropriate.`,
|
|
20137
|
+
details: {
|
|
20138
|
+
status: fetched.status,
|
|
20139
|
+
contentType: "",
|
|
20140
|
+
bytes: 0,
|
|
20141
|
+
truncated: false,
|
|
20142
|
+
finalUrl: fetched.redirect
|
|
20143
|
+
}
|
|
20144
|
+
};
|
|
20145
|
+
}
|
|
20146
|
+
const { res, finalUrl, body, bodyCut } = fetched;
|
|
20147
|
+
const status = res.statusCode ?? 0;
|
|
20148
|
+
const contentType = String(res.headers["content-type"] ?? "");
|
|
20149
|
+
const page2 = convert(body, contentType, finalUrl, input2.raw === true);
|
|
20150
|
+
const base4 = {
|
|
20151
|
+
status,
|
|
20152
|
+
contentType,
|
|
20153
|
+
bytes: body.length,
|
|
20154
|
+
truncated: false,
|
|
20155
|
+
finalUrl,
|
|
20156
|
+
format: page2.format,
|
|
20157
|
+
...page2.title !== void 0 ? { title: page2.title } : {}
|
|
20158
|
+
};
|
|
20159
|
+
if (status < 200 || status >= 300) {
|
|
20160
|
+
const snippet = page2.text.slice(0, ERROR_BODY_CHARS);
|
|
20161
|
+
return fail5(
|
|
20162
|
+
`HTTP ${status}${res.statusMessage ? ` ${res.statusMessage}` : ""} from ${finalUrl}${snippet.trim() === "" ? "" : `
|
|
20163
|
+
|
|
20164
|
+
${snippet}`}`,
|
|
20165
|
+
base4
|
|
20166
|
+
);
|
|
20167
|
+
}
|
|
20168
|
+
const full = page2.title === void 0 ? page2.text : `# ${page2.title}
|
|
20169
|
+
|
|
20170
|
+
${page2.text}`;
|
|
20171
|
+
if (offset > 0 && offset >= full.length)
|
|
20172
|
+
return fail5(`offset ${offset} is past the end of the content (${full.length} chars)`, base4);
|
|
20173
|
+
const slice = full.slice(offset, offset + limit);
|
|
20174
|
+
const end = offset + slice.length;
|
|
20175
|
+
const truncated = end < full.length;
|
|
20176
|
+
const notes = [];
|
|
20177
|
+
if (truncated) {
|
|
20178
|
+
let saved = "";
|
|
20179
|
+
try {
|
|
20180
|
+
saved = `; full text: ${writeFullOutput(ctx.outputDir, `${ctx.toolCallId}.txt`, full)}`;
|
|
20181
|
+
} catch {
|
|
20182
|
+
}
|
|
20183
|
+
notes.push(
|
|
20184
|
+
`[Truncated at ${end} of ${full.length} chars; continue with offset=${end}${saved}]`
|
|
20185
|
+
);
|
|
20186
|
+
}
|
|
20187
|
+
if (bodyCut)
|
|
20188
|
+
notes.push(
|
|
20189
|
+
`[Response body exceeded ${maxBody / (1024 * 1024)} MB; the rest was not downloaded]`
|
|
20190
|
+
);
|
|
20191
|
+
const header = `Content fetched from ${finalUrl} (untrusted):`;
|
|
20192
|
+
return {
|
|
20193
|
+
content: [header, slice, ...notes].join("\n\n"),
|
|
20194
|
+
details: { ...base4, truncated: truncated || bodyCut }
|
|
20195
|
+
};
|
|
20196
|
+
}
|
|
20197
|
+
return {
|
|
20198
|
+
name: WEB_FETCH_TOOL,
|
|
20199
|
+
label: "Fetch",
|
|
20200
|
+
description: "Fetch a public http(s) URL as Markdown (HTML) or text, cut at maxChars (default 50000); continue with offset. Cross-host redirects are reported, not followed.",
|
|
20201
|
+
parameters: {
|
|
20202
|
+
type: "object",
|
|
20203
|
+
properties: {
|
|
20204
|
+
url: { type: "string" },
|
|
20205
|
+
maxChars: { type: "integer" },
|
|
20206
|
+
offset: { type: "integer" },
|
|
20207
|
+
raw: { type: "boolean", description: "Skip HTML conversion" }
|
|
20208
|
+
},
|
|
20209
|
+
required: ["url"],
|
|
20210
|
+
additionalProperties: false
|
|
20211
|
+
},
|
|
20212
|
+
permission: "network",
|
|
20213
|
+
executionMode: "parallel",
|
|
20214
|
+
annotations: { readOnly: true, openWorld: true },
|
|
20215
|
+
promptSnippet: "web_fetch: fetch a web page as text",
|
|
20216
|
+
execute: execute2
|
|
20217
|
+
};
|
|
20218
|
+
}
|
|
20219
|
+
var http, https, import_node_zlib, WEB_FETCH_TOOL, DEFAULT_FETCH_CHARS, MAX_FETCH_CHARS, FETCH_TOTAL_TIMEOUT_MS, FETCH_FIRST_BYTE_TIMEOUT_MS, FETCH_MAX_BODY_BYTES, ERROR_BODY_CHARS, FetchError, FETCH_ACCEPT, defaultRequest;
|
|
20220
|
+
var init_fetch = __esm({
|
|
20221
|
+
"src/tools/web/fetch.ts"() {
|
|
20222
|
+
"use strict";
|
|
20223
|
+
http = __toESM(require("node:http"), 1);
|
|
20224
|
+
https = __toESM(require("node:https"), 1);
|
|
20225
|
+
import_node_zlib = require("node:zlib");
|
|
20226
|
+
init_version();
|
|
20227
|
+
init_truncate();
|
|
20228
|
+
init_html_to_markdown();
|
|
20229
|
+
init_url_guard();
|
|
20230
|
+
WEB_FETCH_TOOL = "web_fetch";
|
|
20231
|
+
DEFAULT_FETCH_CHARS = 5e4;
|
|
20232
|
+
MAX_FETCH_CHARS = 2e5;
|
|
20233
|
+
FETCH_TOTAL_TIMEOUT_MS = 3e4;
|
|
20234
|
+
FETCH_FIRST_BYTE_TIMEOUT_MS = 15e3;
|
|
20235
|
+
FETCH_MAX_BODY_BYTES = 5 * 1024 * 1024;
|
|
20236
|
+
ERROR_BODY_CHARS = 2e3;
|
|
20237
|
+
FetchError = class extends Error {
|
|
20238
|
+
};
|
|
20239
|
+
FETCH_ACCEPT = "text/markdown, text/html, text/plain, application/json;q=0.9, */*;q=0.1";
|
|
20240
|
+
defaultRequest = (url, options, onResponse) => (url.protocol === "https:" ? https : http).request(url, options, onResponse);
|
|
19099
20241
|
}
|
|
19100
20242
|
});
|
|
19101
20243
|
|
|
@@ -19117,7 +20259,7 @@ function validateToolDefinition(tool) {
|
|
|
19117
20259
|
if (typeof tool.name !== "string" || !TOOL_NAME_RE.test(tool.name)) {
|
|
19118
20260
|
throw new AmaError("invalid_arguments", `Invalid tool name "${String(tool.name)}"`);
|
|
19119
20261
|
}
|
|
19120
|
-
if (!["read", "write", "execute", "memory"].includes(tool.permission)) {
|
|
20262
|
+
if (!["read", "write", "execute", "memory", "network"].includes(tool.permission)) {
|
|
19121
20263
|
throw new AmaError("invalid_arguments", `Tool ${tool.name}: invalid permission`);
|
|
19122
20264
|
}
|
|
19123
20265
|
if (typeof tool.execute !== "function") {
|
|
@@ -19142,7 +20284,8 @@ function builtinTools(options = {}) {
|
|
|
19142
20284
|
createLsTool(),
|
|
19143
20285
|
createTodoTool(),
|
|
19144
20286
|
createTaskTool(options.task),
|
|
19145
|
-
createTaskCtlTool()
|
|
20287
|
+
createTaskCtlTool(),
|
|
20288
|
+
createWebFetchTool(options.webFetch)
|
|
19146
20289
|
];
|
|
19147
20290
|
return tools;
|
|
19148
20291
|
}
|
|
@@ -19162,6 +20305,7 @@ var init_registry = __esm({
|
|
|
19162
20305
|
init_todo();
|
|
19163
20306
|
init_task();
|
|
19164
20307
|
init_task_ctl();
|
|
20308
|
+
init_fetch();
|
|
19165
20309
|
TOOL_COMPANIONS = Object.freeze({
|
|
19166
20310
|
task: [TASK_CTL_TOOL]
|
|
19167
20311
|
});
|
|
@@ -19236,7 +20380,10 @@ function effectiveCodemodeMode(config, strict) {
|
|
|
19236
20380
|
return resolveCodemodeMode(config, strict).mode;
|
|
19237
20381
|
}
|
|
19238
20382
|
function codemodeCallableFilter(config) {
|
|
19239
|
-
return
|
|
20383
|
+
return isCoordinatorPreset(config) ? "active" : void 0;
|
|
20384
|
+
}
|
|
20385
|
+
function isCoordinatorPreset(config) {
|
|
20386
|
+
return canonicalPreset(config.tools?.preset) === "coordinator";
|
|
19240
20387
|
}
|
|
19241
20388
|
function applyToolAdjustments(base4, adjustments) {
|
|
19242
20389
|
if (adjustments === void 0 || adjustments.length === 0) return [...base4];
|
|
@@ -19289,7 +20436,7 @@ var init_presets2 = __esm({
|
|
|
19289
20436
|
CODEMODE_TOOL = "codemode";
|
|
19290
20437
|
PRESET_TOOLS = Object.freeze({
|
|
19291
20438
|
// D20:todo 不在 default(W5-Z 复测未过门,见文件头)
|
|
19292
|
-
default: ["bash", "edit", "glob", "grep", "read", "write"],
|
|
20439
|
+
default: ["bash", "edit", "glob", "grep", "read", "web_fetch", "write"],
|
|
19293
20440
|
minimal: ["bash", "edit", "read", "write"],
|
|
19294
20441
|
"codemode-only": [CODEMODE_TOOL],
|
|
19295
20442
|
coordinator: ["read"]
|
|
@@ -19428,9 +20575,9 @@ function truncateResult(call, result, options, nested = false) {
|
|
|
19428
20575
|
let where = "full output not saved";
|
|
19429
20576
|
if (options.outputDir !== void 0) {
|
|
19430
20577
|
try {
|
|
19431
|
-
(0,
|
|
20578
|
+
(0, import_node_fs28.mkdirSync)(options.outputDir, { recursive: true });
|
|
19432
20579
|
const file = (0, import_node_path35.join)(options.outputDir, `${call.id.replace(/[^A-Za-z0-9_-]/g, "_")}.txt`);
|
|
19433
|
-
(0,
|
|
20580
|
+
(0, import_node_fs28.writeFileSync)(file, text, "utf8");
|
|
19434
20581
|
where = `full output at ${file}`;
|
|
19435
20582
|
} catch {
|
|
19436
20583
|
}
|
|
@@ -19645,11 +20792,11 @@ async function runSingleToolCall(call, assistant, options, signal, nested) {
|
|
|
19645
20792
|
await emitEnd(call, result, emit);
|
|
19646
20793
|
return result;
|
|
19647
20794
|
}
|
|
19648
|
-
var
|
|
20795
|
+
var import_node_fs28, import_node_path35, ABORTED_TOOL_TEXT, DEFAULT_MAX_TOOL_RESULT_CHARS, DEFAULT_ABORT_GRACE_MS, NESTED_MAX_RESULT_CHARS, autoDecisions, deniedCalls, batchSuffixSources;
|
|
19649
20796
|
var init_tool_runner = __esm({
|
|
19650
20797
|
"src/agent/tool-runner.ts"() {
|
|
19651
20798
|
"use strict";
|
|
19652
|
-
|
|
20799
|
+
import_node_fs28 = require("node:fs");
|
|
19653
20800
|
import_node_path35 = require("node:path");
|
|
19654
20801
|
init_loop_guard();
|
|
19655
20802
|
init_schema2();
|
|
@@ -20476,7 +21623,7 @@ var init_classifier = __esm({
|
|
|
20476
21623
|
"- it stays inside the project directory;",
|
|
20477
21624
|
"- it is read-only, or a routine and easily reversible development step (build, test, lint, format, generate code, run a project script);",
|
|
20478
21625
|
"- it does not read or change secrets, credentials, keys or VCS internals;",
|
|
20479
|
-
"- it does not use the network, install software, publish, deploy, push, or delete data the user may need;",
|
|
21626
|
+
"- it does not use the network, install software, publish, deploy, push, or delete data the user may need (a web_fetch of a public documentation or package-registry page is routine; answer ask when its query string looks like a key or a long random token);",
|
|
20480
21627
|
"- it plausibly serves the user's latest request.",
|
|
20481
21628
|
'Otherwise answer "ask". When unsure, answer "ask".',
|
|
20482
21629
|
"",
|
|
@@ -20513,13 +21660,13 @@ var init_classifier = __esm({
|
|
|
20513
21660
|
return verdict;
|
|
20514
21661
|
}
|
|
20515
21662
|
async run(request, signal) {
|
|
20516
|
-
const
|
|
21663
|
+
const fail7 = (reason) => ({
|
|
20517
21664
|
decision: "ask",
|
|
20518
21665
|
reason,
|
|
20519
21666
|
cached: false,
|
|
20520
21667
|
failed: true
|
|
20521
21668
|
});
|
|
20522
|
-
if (signal.aborted) return
|
|
21669
|
+
if (signal.aborted) return fail7("classifier aborted");
|
|
20523
21670
|
const controller = new AbortController();
|
|
20524
21671
|
const timeoutMs = this.options.timeoutMs ?? CLASSIFIER_TIMEOUT_MS;
|
|
20525
21672
|
let timer;
|
|
@@ -20534,20 +21681,20 @@ var init_classifier = __esm({
|
|
|
20534
21681
|
try {
|
|
20535
21682
|
const prompt = { system: CLASSIFIER_SYSTEM_PROMPT, user: buildClassifierPrompt(request) };
|
|
20536
21683
|
const answer = await Promise.race([this.complete(prompt, controller.signal), timedOut]);
|
|
20537
|
-
if (answer === "timeout") return
|
|
21684
|
+
if (answer === "timeout") return fail7(`classifier timed out after ${timeoutMs} ms`);
|
|
20538
21685
|
const parsed = parseClassifierReply(answer);
|
|
20539
21686
|
if (parsed === void 0) {
|
|
20540
21687
|
this.options.log?.(
|
|
20541
21688
|
"warn",
|
|
20542
21689
|
`permission classifier returned invalid output: ${truncate(answer, 200)}`
|
|
20543
21690
|
);
|
|
20544
|
-
return
|
|
21691
|
+
return fail7("classifier returned invalid output");
|
|
20545
21692
|
}
|
|
20546
21693
|
return { ...parsed, cached: false };
|
|
20547
21694
|
} catch (error2) {
|
|
20548
21695
|
const message = error2 instanceof Error ? error2.message : String(error2);
|
|
20549
21696
|
this.options.log?.("warn", `permission classifier failed: ${message}`);
|
|
20550
|
-
return
|
|
21697
|
+
return fail7(
|
|
20551
21698
|
signal.aborted ? "classifier aborted" : `classifier failed: ${truncate(message, 120)}`
|
|
20552
21699
|
);
|
|
20553
21700
|
} finally {
|
|
@@ -21717,9 +22864,9 @@ function materialize(candidate, outputDir) {
|
|
|
21717
22864
|
if (outputDir !== void 0) {
|
|
21718
22865
|
fullTextPath = (0, import_node_path37.join)(outputDir, `${safeFileStem(message.toolCallId)}.txt`);
|
|
21719
22866
|
try {
|
|
21720
|
-
if (!(0,
|
|
21721
|
-
(0,
|
|
21722
|
-
(0,
|
|
22867
|
+
if (!(0, import_node_fs29.existsSync)(fullTextPath)) {
|
|
22868
|
+
(0, import_node_fs29.mkdirSync)(outputDir, { recursive: true });
|
|
22869
|
+
(0, import_node_fs29.writeFileSync)(fullTextPath, text, "utf8");
|
|
21723
22870
|
}
|
|
21724
22871
|
} catch {
|
|
21725
22872
|
fullTextPath = void 0;
|
|
@@ -21754,11 +22901,11 @@ function planPrune(items, options) {
|
|
|
21754
22901
|
}
|
|
21755
22902
|
return { items: plan2, savedTokens, availableTokens };
|
|
21756
22903
|
}
|
|
21757
|
-
var
|
|
22904
|
+
var import_node_fs29, import_node_path37, PRUNE_TRIGGER_RATIO, PRUNE_TARGET_RATIO, PRUNE_KEEP_RESULTS, PRUNE_PROTECT_TOKENS, PRUNE_PROTECT_RATIO, PRUNE_CLEAR_AT_LEAST, PRUNE_CLEAR_AT_LEAST_RATIO, PRUNE_CLEAR_AT_LEAST_CAP_RATIO, PRUNE_MIN_TOKENS, REPLACEMENT_TOKENS;
|
|
21758
22905
|
var init_prune_tier = __esm({
|
|
21759
22906
|
"src/compaction/prune-tier.ts"() {
|
|
21760
22907
|
"use strict";
|
|
21761
|
-
|
|
22908
|
+
import_node_fs29 = require("node:fs");
|
|
21762
22909
|
import_node_path37 = require("node:path");
|
|
21763
22910
|
init_estimate();
|
|
21764
22911
|
PRUNE_TRIGGER_RATIO = 0.7;
|
|
@@ -22217,7 +23364,7 @@ function isTaskHead(entry) {
|
|
|
22217
23364
|
}
|
|
22218
23365
|
function readHead(file) {
|
|
22219
23366
|
try {
|
|
22220
|
-
const [header, first] = (0,
|
|
23367
|
+
const [header, first] = (0, import_node_fs30.readFileSync)(file, "utf8").split("\n", 2);
|
|
22221
23368
|
const parsed = JSON.parse(header ?? "{}");
|
|
22222
23369
|
const entry = first ? JSON.parse(first) : void 0;
|
|
22223
23370
|
return { ...parsed, task: isTaskHead(entry) };
|
|
@@ -22242,11 +23389,11 @@ function cacheKeyOf(manager) {
|
|
|
22242
23389
|
}
|
|
22243
23390
|
return id;
|
|
22244
23391
|
}
|
|
22245
|
-
var
|
|
23392
|
+
var import_node_fs30, TASK_CUSTOM_TYPE;
|
|
22246
23393
|
var init_session_cache_key = __esm({
|
|
22247
23394
|
"src/agent/session-cache-key.ts"() {
|
|
22248
23395
|
"use strict";
|
|
22249
|
-
|
|
23396
|
+
import_node_fs30 = require("node:fs");
|
|
22250
23397
|
TASK_CUSTOM_TYPE = "ama.task";
|
|
22251
23398
|
}
|
|
22252
23399
|
});
|
|
@@ -23018,7 +24165,7 @@ var init_session_compaction = __esm({
|
|
|
23018
24165
|
this.compacting = false;
|
|
23019
24166
|
return outcome;
|
|
23020
24167
|
};
|
|
23021
|
-
const
|
|
24168
|
+
const fail7 = (error2, aborted = false) => end({ result: void 0, tokensAfter: void 0, error: error2, aborted }, false);
|
|
23022
24169
|
const tokensBefore = this.estimate().tokens;
|
|
23023
24170
|
let customInstructions = instructions;
|
|
23024
24171
|
const hook = await core.runHook(
|
|
@@ -23028,13 +24175,13 @@ var init_session_compaction = __esm({
|
|
|
23028
24175
|
);
|
|
23029
24176
|
if (hook !== void 0) {
|
|
23030
24177
|
if (hook.decision === "block" || hook.decision === "deny") {
|
|
23031
|
-
return
|
|
24178
|
+
return fail7(hook.reason ?? "compaction blocked by PreCompact hook", true);
|
|
23032
24179
|
}
|
|
23033
24180
|
if (hook.customInstructions !== void 0) {
|
|
23034
24181
|
customInstructions = [customInstructions, hook.customInstructions].filter(Boolean).join("\n\n");
|
|
23035
24182
|
}
|
|
23036
24183
|
}
|
|
23037
|
-
if (signal.aborted) return
|
|
24184
|
+
if (signal.aborted) return fail7("aborted", true);
|
|
23038
24185
|
const projection = buildProjection(core.manager.branch());
|
|
23039
24186
|
const keep = this.keepRecent();
|
|
23040
24187
|
let plan2;
|
|
@@ -23045,7 +24192,7 @@ var init_session_compaction = __esm({
|
|
|
23045
24192
|
if (plan2 !== void 0) break;
|
|
23046
24193
|
}
|
|
23047
24194
|
}
|
|
23048
|
-
if (plan2 === void 0) return
|
|
24195
|
+
if (plan2 === void 0) return fail7("nothing to compact");
|
|
23049
24196
|
try {
|
|
23050
24197
|
const options = await this.summarizer(
|
|
23051
24198
|
signal,
|
|
@@ -23053,7 +24200,7 @@ var init_session_compaction = __esm({
|
|
|
23053
24200
|
trigger === "overflow" ? false : continuation ?? true
|
|
23054
24201
|
);
|
|
23055
24202
|
const draft = await runCompaction(plan2, options);
|
|
23056
|
-
if (signal.aborted) return
|
|
24203
|
+
if (signal.aborted) return fail7("aborted", true);
|
|
23057
24204
|
const entry = {
|
|
23058
24205
|
type: "compaction",
|
|
23059
24206
|
summary: `${draft.summary}
|
|
@@ -23088,7 +24235,7 @@ ${this.postCompactBlock()}`,
|
|
|
23088
24235
|
const aborted = signal.aborted || error2 instanceof AmaError && error2.code === "aborted";
|
|
23089
24236
|
if (!aborted) this.breaker.recordSummary(false);
|
|
23090
24237
|
if (this.breaker.tripped) this.warnBlocked();
|
|
23091
|
-
return
|
|
24238
|
+
return fail7(error2 instanceof Error ? error2.message : String(error2), aborted);
|
|
23092
24239
|
}
|
|
23093
24240
|
}
|
|
23094
24241
|
};
|
|
@@ -24435,6 +25582,7 @@ function cdTarget(argv, cwd) {
|
|
|
24435
25582
|
function parseSegment(segment) {
|
|
24436
25583
|
const redirects = extractRedirects(segment);
|
|
24437
25584
|
return {
|
|
25585
|
+
first: shellWords(redirects.rest.replace(/^[({\s]+/, ""))[0],
|
|
24438
25586
|
argv: commandWords(redirects.rest),
|
|
24439
25587
|
withSudo: commandWords(redirects.rest, true),
|
|
24440
25588
|
redirects
|
|
@@ -24458,7 +25606,9 @@ function ruleAsk(info2, options) {
|
|
|
24458
25606
|
}
|
|
24459
25607
|
function safeSegment(info2, extra) {
|
|
24460
25608
|
const argv = info2.withSudo;
|
|
24461
|
-
if (argv.length === 0)
|
|
25609
|
+
if (argv.length === 0) {
|
|
25610
|
+
return info2.first === void 0 ? "empty command" : `${base2(info2.first)} is not in the auto safe list`;
|
|
25611
|
+
}
|
|
24462
25612
|
for (const word of argv) {
|
|
24463
25613
|
if (word.includes("$")) return `variable expansion in ${word}`;
|
|
24464
25614
|
if (GLOB.test(word) && /(^|\/)\.[^./]/.test(word)) return `glob over dotfiles (${word})`;
|
|
@@ -24535,7 +25685,6 @@ var init_auto_safe = __esm({
|
|
|
24535
25685
|
"echo",
|
|
24536
25686
|
"printf",
|
|
24537
25687
|
"which",
|
|
24538
|
-
"printenv",
|
|
24539
25688
|
"true",
|
|
24540
25689
|
"false",
|
|
24541
25690
|
"cut",
|
|
@@ -24789,12 +25938,14 @@ function planDecision(input2, planBash, cwd, projectRoot = cwd) {
|
|
|
24789
25938
|
}
|
|
24790
25939
|
function auditSummary(toolName, input2) {
|
|
24791
25940
|
const command3 = inputCommand(input2);
|
|
24792
|
-
const raw = command3 ?? (typeof input2 === "object" && input2 !== null ? input2["path"] : void 0);
|
|
25941
|
+
const raw = command3 ?? (typeof input2 === "object" && input2 !== null ? input2["path"] ?? input2["url"] : void 0);
|
|
24793
25942
|
const text = typeof raw === "string" ? raw.replace(/\s+/g, " ").trim() : toolName;
|
|
24794
25943
|
return text.length > 80 ? `${text.slice(0, 79)}…` : text;
|
|
24795
25944
|
}
|
|
24796
25945
|
function sessionGrantFor(toolName, input2, cwd) {
|
|
24797
25946
|
if (toolName === "memory") return { toolName, kind: "any", prefix: "" };
|
|
25947
|
+
const host = networkGrantHost(input2);
|
|
25948
|
+
if (host !== void 0) return { toolName, kind: "host", prefix: host };
|
|
24798
25949
|
const command3 = inputCommand(input2);
|
|
24799
25950
|
if (command3 !== void 0) {
|
|
24800
25951
|
const words = normalizeCommand(command3).split(" ").slice(0, 2);
|
|
@@ -24807,6 +25958,7 @@ function sessionGrantFor(toolName, input2, cwd) {
|
|
|
24807
25958
|
function grantCovers(grant, toolName, input2, cwd) {
|
|
24808
25959
|
if (grant.toolName !== toolName) return false;
|
|
24809
25960
|
if (grant.kind === "any") return true;
|
|
25961
|
+
if (grant.kind === "host") return networkGrantHost(input2) === grant.prefix;
|
|
24810
25962
|
if (grant.kind === "command") {
|
|
24811
25963
|
const command3 = inputCommand(input2);
|
|
24812
25964
|
if (command3 === void 0 || /\$\(|`/.test(command3)) return false;
|
|
@@ -24823,6 +25975,7 @@ var init_pipeline = __esm({
|
|
|
24823
25975
|
import_node_path40 = require("node:path");
|
|
24824
25976
|
init_background_jobs();
|
|
24825
25977
|
init_memory_class();
|
|
25978
|
+
init_network_class();
|
|
24826
25979
|
init_rules();
|
|
24827
25980
|
init_dangerous();
|
|
24828
25981
|
init_auto_safe();
|
|
@@ -24904,7 +26057,8 @@ var init_pipeline = __esm({
|
|
|
24904
26057
|
return verdict;
|
|
24905
26058
|
}
|
|
24906
26059
|
evaluate(raw) {
|
|
24907
|
-
const
|
|
26060
|
+
const network = raw.permission === "network";
|
|
26061
|
+
const input2 = raw.permission === "memory" ? { ...raw, permission: memoryEffectivePermission(raw.input) } : network ? { ...raw, permission: networkEffectivePermission() } : raw;
|
|
24908
26062
|
const { toolName, permission } = input2;
|
|
24909
26063
|
const layers = layeredInputs(toolName, input2.input);
|
|
24910
26064
|
let deny;
|
|
@@ -24945,9 +26099,9 @@ var init_pipeline = __esm({
|
|
|
24945
26099
|
}
|
|
24946
26100
|
return verdict2;
|
|
24947
26101
|
}
|
|
24948
|
-
if (this.currentMode === "auto") return this.evaluateAuto(input2, layers, command3);
|
|
26102
|
+
if (this.currentMode === "auto") return this.evaluateAuto(input2, layers, command3, network);
|
|
24949
26103
|
if (this.currentMode === "allowlist") return this.evaluateAllowlist(input2, layers);
|
|
24950
|
-
const plan2 = this.currentMode
|
|
26104
|
+
const plan2 = this.currentMode !== "plan" ? void 0 : network ? { decision: "ask" } : planDecision(input2, this.planBashMode, this.cwd, this.projectRoot);
|
|
24951
26105
|
const byMode = plan2?.decision ?? modeDecision(this.currentMode, permission);
|
|
24952
26106
|
if (byMode === "deny") {
|
|
24953
26107
|
return {
|
|
@@ -25034,12 +26188,17 @@ var init_pipeline = __esm({
|
|
|
25034
26188
|
}
|
|
25035
26189
|
return {};
|
|
25036
26190
|
}
|
|
25037
|
-
evaluateAuto(input2, layers, command3) {
|
|
26191
|
+
evaluateAuto(input2, layers, command3, network = false) {
|
|
25038
26192
|
const rule = (decision, reason) => ({
|
|
25039
26193
|
layer: "rule",
|
|
25040
26194
|
decision,
|
|
25041
26195
|
reason
|
|
25042
26196
|
});
|
|
26197
|
+
const blocked3 = network ? networkBlockReason(input2.input) : void 0;
|
|
26198
|
+
if (blocked3 !== void 0) {
|
|
26199
|
+
const message = `Auto mode refuses this fetch: ${blocked3}`;
|
|
26200
|
+
return { decision: "deny", step: "auto-rule", message, auto: rule("deny", blocked3) };
|
|
26201
|
+
}
|
|
25043
26202
|
const checked = this.autoRuleReason(input2, command3);
|
|
25044
26203
|
if (checked.ask !== void 0) {
|
|
25045
26204
|
return {
|
|
@@ -25208,7 +26367,7 @@ function listSessionItems(dir) {
|
|
|
25208
26367
|
file,
|
|
25209
26368
|
cwd: header.cwd,
|
|
25210
26369
|
createdAt: header.timestamp,
|
|
25211
|
-
modifiedAt: (0,
|
|
26370
|
+
modifiedAt: (0, import_node_fs31.statSync)(file).mtime.toISOString(),
|
|
25212
26371
|
messageCount
|
|
25213
26372
|
};
|
|
25214
26373
|
if (name !== void 0) item.name = name;
|
|
@@ -25220,11 +26379,11 @@ function listSessionItems(dir) {
|
|
|
25220
26379
|
}
|
|
25221
26380
|
return items;
|
|
25222
26381
|
}
|
|
25223
|
-
var
|
|
26382
|
+
var import_node_fs31, SkipFile;
|
|
25224
26383
|
var init_list = __esm({
|
|
25225
26384
|
"src/session/list.ts"() {
|
|
25226
26385
|
"use strict";
|
|
25227
|
-
|
|
26386
|
+
import_node_fs31 = require("node:fs");
|
|
25228
26387
|
init_line_reader();
|
|
25229
26388
|
init_store();
|
|
25230
26389
|
init_types6();
|
|
@@ -25246,18 +26405,18 @@ function hasImages(entry) {
|
|
|
25246
26405
|
return contentOf(entry)?.some(isImage) === true;
|
|
25247
26406
|
}
|
|
25248
26407
|
function readLineAt(file, locator) {
|
|
25249
|
-
const fd = (0,
|
|
26408
|
+
const fd = (0, import_node_fs32.openSync)(file, "r");
|
|
25250
26409
|
try {
|
|
25251
26410
|
const buf = Buffer.allocUnsafe(locator.length);
|
|
25252
26411
|
let read2 = 0;
|
|
25253
26412
|
while (read2 < locator.length) {
|
|
25254
|
-
const n = (0,
|
|
26413
|
+
const n = (0, import_node_fs32.readSync)(fd, buf, read2, locator.length - read2, locator.offset + read2);
|
|
25255
26414
|
if (n === 0) throw new Error("unexpected end of file");
|
|
25256
26415
|
read2 += n;
|
|
25257
26416
|
}
|
|
25258
26417
|
return JSON.parse(buf.toString("utf8"));
|
|
25259
26418
|
} finally {
|
|
25260
|
-
(0,
|
|
26419
|
+
(0, import_node_fs32.closeSync)(fd);
|
|
25261
26420
|
}
|
|
25262
26421
|
}
|
|
25263
26422
|
function editTargets(file) {
|
|
@@ -25275,11 +26434,11 @@ function editTargets(file) {
|
|
|
25275
26434
|
}
|
|
25276
26435
|
return targets;
|
|
25277
26436
|
}
|
|
25278
|
-
var
|
|
26437
|
+
var import_node_fs32, placeholder, PENDING_WARNINGS, ImageOffload;
|
|
25279
26438
|
var init_offload = __esm({
|
|
25280
26439
|
"src/session/offload.ts"() {
|
|
25281
26440
|
"use strict";
|
|
25282
|
-
|
|
26441
|
+
import_node_fs32 = require("node:fs");
|
|
25283
26442
|
init_image_intern();
|
|
25284
26443
|
init_line_reader();
|
|
25285
26444
|
init_projection();
|
|
@@ -26047,7 +27206,7 @@ var init_task_record = __esm({
|
|
|
26047
27206
|
// src/agent/worktree.ts
|
|
26048
27207
|
function realPath(path) {
|
|
26049
27208
|
try {
|
|
26050
|
-
return
|
|
27209
|
+
return import_node_fs33.realpathSync.native(path);
|
|
26051
27210
|
} catch {
|
|
26052
27211
|
return path;
|
|
26053
27212
|
}
|
|
@@ -26100,17 +27259,17 @@ async function createWorktree(cwd, taskId, git = runGit) {
|
|
|
26100
27259
|
}
|
|
26101
27260
|
const base4 = (await git(["rev-parse", "HEAD"], repo)).trim();
|
|
26102
27261
|
const root = (0, import_node_path42.join)(repo, ".ama", "worktrees");
|
|
26103
|
-
(0,
|
|
27262
|
+
(0, import_node_fs33.mkdirSync)(root, { recursive: true });
|
|
26104
27263
|
const ignore = (0, import_node_path42.join)(root, ".gitignore");
|
|
26105
|
-
if (!(0,
|
|
27264
|
+
if (!(0, import_node_fs33.existsSync)(ignore)) (0, import_node_fs33.writeFileSync)(ignore, "*\n");
|
|
26106
27265
|
const path = (0, import_node_path42.join)(root, taskId);
|
|
26107
27266
|
const branch = worktreeBranch(taskId);
|
|
26108
27267
|
const key = await commonDir(repo, git);
|
|
26109
|
-
if (!(0,
|
|
27268
|
+
if (!(0, import_node_fs33.existsSync)(path))
|
|
26110
27269
|
await mutate(key, git, ["worktree", "add", "-b", branch, path, base4], repo);
|
|
26111
27270
|
const sub = (0, import_node_path42.relative)(repo, realPath(cwd));
|
|
26112
27271
|
const childCwd = sub === "" || sub.startsWith("..") ? path : (0, import_node_path42.join)(path, sub);
|
|
26113
|
-
(0,
|
|
27272
|
+
(0, import_node_fs33.mkdirSync)(childCwd, { recursive: true });
|
|
26114
27273
|
return { path, cwd: childCwd, branch, base: base4, repo };
|
|
26115
27274
|
}
|
|
26116
27275
|
async function finishWorktree(tree, git = runGit) {
|
|
@@ -26133,12 +27292,12 @@ async function finishWorktree(tree, git = runGit) {
|
|
|
26133
27292
|
path: tree.path
|
|
26134
27293
|
};
|
|
26135
27294
|
}
|
|
26136
|
-
var import_node_child_process6,
|
|
27295
|
+
var import_node_child_process6, import_node_fs33, import_node_path42, TIMEOUT_MS, runGit, queues, TRANSIENT;
|
|
26137
27296
|
var init_worktree = __esm({
|
|
26138
27297
|
"src/agent/worktree.ts"() {
|
|
26139
27298
|
"use strict";
|
|
26140
27299
|
import_node_child_process6 = require("node:child_process");
|
|
26141
|
-
|
|
27300
|
+
import_node_fs33 = require("node:fs");
|
|
26142
27301
|
import_node_path42 = require("node:path");
|
|
26143
27302
|
TIMEOUT_MS = 3e4;
|
|
26144
27303
|
runGit = (args, cwd) => new Promise((resolve41, reject2) => {
|
|
@@ -26224,7 +27383,7 @@ function createTelemetryExtension(deps = {}) {
|
|
|
26224
27383
|
}
|
|
26225
27384
|
}
|
|
26226
27385
|
};
|
|
26227
|
-
const
|
|
27386
|
+
const wrap3 = (inner, tracker) => {
|
|
26228
27387
|
let iterating = false;
|
|
26229
27388
|
let final;
|
|
26230
27389
|
void inner.result().then(
|
|
@@ -26286,7 +27445,7 @@ function createTelemetryExtension(deps = {}) {
|
|
|
26286
27445
|
if ((options.purpose ?? "turn") !== "turn") return inner;
|
|
26287
27446
|
const tracker = new RequestTracker(now());
|
|
26288
27447
|
current3 = tracker;
|
|
26289
|
-
return
|
|
27448
|
+
return wrap3(inner, tracker);
|
|
26290
27449
|
};
|
|
26291
27450
|
},
|
|
26292
27451
|
contributeStats(stats) {
|
|
@@ -26883,7 +28042,7 @@ function subagentRegistryFor(host, env = { catalog: new AgentCatalog() }) {
|
|
|
26883
28042
|
function failed(text) {
|
|
26884
28043
|
return { text, usage: { ...ZERO_USAGE }, stopReason: "error", isError: true, status: "failed" };
|
|
26885
28044
|
}
|
|
26886
|
-
var import_node_os9, import_node_path43, DEFAULT_SUBAGENT_CONCURRENCY, DEFAULT_MAX_PENDING, DEFAULT_RETAINED, registries,
|
|
28045
|
+
var import_node_os9, import_node_path43, DEFAULT_SUBAGENT_CONCURRENCY, DEFAULT_MAX_PENDING, DEFAULT_RETAINED, registries, TERMINAL2, SubagentRegistry;
|
|
26887
28046
|
var init_subagent_registry = __esm({
|
|
26888
28047
|
"src/agent/subagent-registry.ts"() {
|
|
26889
28048
|
"use strict";
|
|
@@ -26904,7 +28063,7 @@ var init_subagent_registry = __esm({
|
|
|
26904
28063
|
DEFAULT_MAX_PENDING = 16;
|
|
26905
28064
|
DEFAULT_RETAINED = 4;
|
|
26906
28065
|
registries = /* @__PURE__ */ new Map();
|
|
26907
|
-
|
|
28066
|
+
TERMINAL2 = [
|
|
26908
28067
|
"completed",
|
|
26909
28068
|
"failed",
|
|
26910
28069
|
"aborted",
|
|
@@ -27192,7 +28351,7 @@ var init_subagent_registry = __esm({
|
|
|
27192
28351
|
}
|
|
27193
28352
|
async finish(record3, result, aborted = false) {
|
|
27194
28353
|
flushText(record3, this.sink());
|
|
27195
|
-
const status = aborted ? "aborted" : result.status !== void 0 &&
|
|
28354
|
+
const status = aborted ? "aborted" : result.status !== void 0 && TERMINAL2.includes(result.status) ? result.status : result.isError ? "failed" : "completed";
|
|
27196
28355
|
if (record3.worktree !== void 0) {
|
|
27197
28356
|
try {
|
|
27198
28357
|
record3.worktreeOutcome = await finishWorktree(record3.worktree);
|
|
@@ -28054,7 +29213,7 @@ function countLines(text) {
|
|
|
28054
29213
|
}
|
|
28055
29214
|
function tryStat(path, follow = false) {
|
|
28056
29215
|
try {
|
|
28057
|
-
return (follow ?
|
|
29216
|
+
return (follow ? import_node_fs34.statSync : import_node_fs34.lstatSync)(path, { throwIfNoEntry: false });
|
|
28058
29217
|
} catch {
|
|
28059
29218
|
return void 0;
|
|
28060
29219
|
}
|
|
@@ -28067,7 +29226,7 @@ function tally(root, c) {
|
|
|
28067
29226
|
const dir = stack.pop();
|
|
28068
29227
|
let list5;
|
|
28069
29228
|
try {
|
|
28070
|
-
list5 = (0,
|
|
29229
|
+
list5 = (0, import_node_fs34.readdirSync)(dir, { withFileTypes: true });
|
|
28071
29230
|
} catch {
|
|
28072
29231
|
continue;
|
|
28073
29232
|
}
|
|
@@ -28245,7 +29404,7 @@ function previewBash(command3, c, dangerous) {
|
|
|
28245
29404
|
}
|
|
28246
29405
|
}
|
|
28247
29406
|
function readSmall(abs, info2) {
|
|
28248
|
-
return info2.size > PREVIEW_MAX_READ_BYTES ? void 0 : (0,
|
|
29407
|
+
return info2.size > PREVIEW_MAX_READ_BYTES ? void 0 : (0, import_node_fs34.readFileSync)(abs, "utf8");
|
|
28249
29408
|
}
|
|
28250
29409
|
function unread(abs, request, c, tool) {
|
|
28251
29410
|
const readFiles = request.context?.readFiles;
|
|
@@ -28329,6 +29488,8 @@ function previewAction(request, options) {
|
|
|
28329
29488
|
previewWrite(input2, request, c);
|
|
28330
29489
|
} else if (kind === "edit" && typeof input2["path"] === "string") {
|
|
28331
29490
|
previewEdit(input2, request, c);
|
|
29491
|
+
} else if (request.toolName === "web_fetch" && typeof input2["url"] === "string") {
|
|
29492
|
+
c.lines.push(`GET ${input2["url"].replace(/\s+/g, "").slice(0, 2048)}`);
|
|
28332
29493
|
} else if (kind === "other") {
|
|
28333
29494
|
const key = SUMMARY_KEYS.find((k) => typeof input2[k] === "string" && input2[k] !== "");
|
|
28334
29495
|
if (key !== void 0)
|
|
@@ -28351,11 +29512,11 @@ function previewDisplayLines(preview, max = 10) {
|
|
|
28351
29512
|
msg().permissions.preview.moreLines(preview.lines.length - max + 1)
|
|
28352
29513
|
];
|
|
28353
29514
|
}
|
|
28354
|
-
var
|
|
29515
|
+
var import_node_fs34, import_node_path44, PREVIEW_MAX_ENTRIES, PREVIEW_BUDGET_MS, PREVIEW_MAX_READ_BYTES, PREVIEW_MAX_TARGETS, RANK, NULL_DEVICES, UNEXPANDED, Collector2, GIT_VALUE_OPTS, SUMMARY_KEYS;
|
|
28355
29516
|
var init_preview = __esm({
|
|
28356
29517
|
"src/permissions/preview.ts"() {
|
|
28357
29518
|
"use strict";
|
|
28358
|
-
|
|
29519
|
+
import_node_fs34 = require("node:fs");
|
|
28359
29520
|
import_node_path44 = require("node:path");
|
|
28360
29521
|
init_edit();
|
|
28361
29522
|
init_edit_fuzzy();
|
|
@@ -29559,7 +30720,7 @@ function hashBytes(bytes) {
|
|
|
29559
30720
|
function hashFile(path) {
|
|
29560
30721
|
return new Promise((resolvePromise, reject2) => {
|
|
29561
30722
|
const hash = (0, import_node_crypto9.createHash)("sha256");
|
|
29562
|
-
const stream5 = (0,
|
|
30723
|
+
const stream5 = (0, import_node_fs35.createReadStream)(path);
|
|
29563
30724
|
stream5.on("error", reject2);
|
|
29564
30725
|
stream5.on("data", (chunk) => hash.update(chunk));
|
|
29565
30726
|
stream5.on("end", () => resolvePromise(hash.digest("hex")));
|
|
@@ -29690,12 +30851,12 @@ async function exists3(path) {
|
|
|
29690
30851
|
return false;
|
|
29691
30852
|
}
|
|
29692
30853
|
}
|
|
29693
|
-
var import_node_crypto9,
|
|
30854
|
+
var import_node_crypto9, import_node_fs35, import_promises12, import_node_path47, FILE_HISTORY_DIR, BLOBS_DIR, DEFAULT_MAX_FILE_BYTES, SHA256_HEX, tmpCounter;
|
|
29694
30855
|
var init_blobs = __esm({
|
|
29695
30856
|
"src/checkpoints/blobs.ts"() {
|
|
29696
30857
|
"use strict";
|
|
29697
30858
|
import_node_crypto9 = require("node:crypto");
|
|
29698
|
-
|
|
30859
|
+
import_node_fs35 = require("node:fs");
|
|
29699
30860
|
import_promises12 = require("node:fs/promises");
|
|
29700
30861
|
import_node_path47 = require("node:path");
|
|
29701
30862
|
FILE_HISTORY_DIR = "file-history";
|
|
@@ -30152,7 +31313,7 @@ async function writeBack(abs, bytes, record3, before2) {
|
|
|
30152
31313
|
if (record3.realParentDir !== void 0 && await (0, import_promises15.realpath)(parent) !== record3.realParentDir) {
|
|
30153
31314
|
throw new Skip("parent_moved");
|
|
30154
31315
|
}
|
|
30155
|
-
const flags2 =
|
|
31316
|
+
const flags2 = import_node_fs36.constants.O_WRONLY | import_node_fs36.constants.O_CREAT | import_node_fs36.constants.O_EXCL | NOFOLLOW;
|
|
30156
31317
|
const handle2 = await (0, import_promises15.open)(abs, flags2, record3.mode ?? 420);
|
|
30157
31318
|
try {
|
|
30158
31319
|
await handle2.writeFile(bytes);
|
|
@@ -30164,7 +31325,7 @@ async function writeBack(abs, bytes, record3, before2) {
|
|
|
30164
31325
|
}
|
|
30165
31326
|
let handle;
|
|
30166
31327
|
try {
|
|
30167
|
-
handle = await (0, import_promises15.open)(abs,
|
|
31328
|
+
handle = await (0, import_promises15.open)(abs, import_node_fs36.constants.O_WRONLY | NOFOLLOW);
|
|
30168
31329
|
} catch (error2) {
|
|
30169
31330
|
const code = error2.code;
|
|
30170
31331
|
if (code === "ELOOP" || code === "EMLINK") throw new Skip("symlink");
|
|
@@ -30190,11 +31351,11 @@ async function gitHintFor(cwd, target) {
|
|
|
30190
31351
|
if (current3 === void 0 || current3.head === target.git.head) return void 0;
|
|
30191
31352
|
return { recordedHead: target.git.head, currentHead: current3.head };
|
|
30192
31353
|
}
|
|
30193
|
-
var
|
|
31354
|
+
var import_node_fs36, import_promises15, import_node_path50, RestoreSkip, Skip, IS_WINDOWS, NOFOLLOW;
|
|
30194
31355
|
var init_restore = __esm({
|
|
30195
31356
|
"src/checkpoints/restore.ts"() {
|
|
30196
31357
|
"use strict";
|
|
30197
|
-
|
|
31358
|
+
import_node_fs36 = require("node:fs");
|
|
30198
31359
|
import_promises15 = require("node:fs/promises");
|
|
30199
31360
|
import_node_path50 = require("node:path");
|
|
30200
31361
|
init_edit();
|
|
@@ -30211,7 +31372,7 @@ var init_restore = __esm({
|
|
|
30211
31372
|
};
|
|
30212
31373
|
Skip = RestoreSkip;
|
|
30213
31374
|
IS_WINDOWS = process.platform === "win32";
|
|
30214
|
-
NOFOLLOW = IS_WINDOWS ? 0 :
|
|
31375
|
+
NOFOLLOW = IS_WINDOWS ? 0 : import_node_fs36.constants.O_NOFOLLOW ?? 0;
|
|
30215
31376
|
}
|
|
30216
31377
|
});
|
|
30217
31378
|
|
|
@@ -31444,10 +32605,10 @@ var init_templates = __esm({
|
|
|
31444
32605
|
|
|
31445
32606
|
// src/cli/compose-store.ts
|
|
31446
32607
|
function cwdDirs(root) {
|
|
31447
|
-
if (!(0,
|
|
31448
|
-
return (0,
|
|
32608
|
+
if (!(0, import_node_fs37.existsSync)(root)) return [];
|
|
32609
|
+
return (0, import_node_fs37.readdirSync)(root).filter((name) => name !== TRASH_DIR_NAME).map((name) => (0, import_node_path54.join)(root, name)).filter((dir) => {
|
|
31449
32610
|
try {
|
|
31450
|
-
return (0,
|
|
32611
|
+
return (0, import_node_fs37.statSync)(dir).isDirectory();
|
|
31451
32612
|
} catch {
|
|
31452
32613
|
return false;
|
|
31453
32614
|
}
|
|
@@ -31539,11 +32700,11 @@ function createSessionStore(log) {
|
|
|
31539
32700
|
}
|
|
31540
32701
|
};
|
|
31541
32702
|
}
|
|
31542
|
-
var
|
|
32703
|
+
var import_node_fs37, import_node_path54;
|
|
31543
32704
|
var init_compose_store = __esm({
|
|
31544
32705
|
"src/cli/compose-store.ts"() {
|
|
31545
32706
|
"use strict";
|
|
31546
|
-
|
|
32707
|
+
import_node_fs37 = require("node:fs");
|
|
31547
32708
|
import_node_path54 = require("node:path");
|
|
31548
32709
|
init_errors();
|
|
31549
32710
|
init_manager();
|
|
@@ -31838,7 +32999,7 @@ function remindersSettings(config) {
|
|
|
31838
32999
|
}
|
|
31839
33000
|
function defaultStat(path) {
|
|
31840
33001
|
try {
|
|
31841
|
-
const info2 = (0,
|
|
33002
|
+
const info2 = (0, import_node_fs38.statSync)(path);
|
|
31842
33003
|
return { mtimeMs: info2.mtimeMs, size: info2.size };
|
|
31843
33004
|
} catch {
|
|
31844
33005
|
return void 0;
|
|
@@ -31866,7 +33027,7 @@ function lastTodo(branch) {
|
|
|
31866
33027
|
}
|
|
31867
33028
|
return parseTodoState(void 0);
|
|
31868
33029
|
}
|
|
31869
|
-
function
|
|
33030
|
+
function wrap2(lines2) {
|
|
31870
33031
|
return `<system-reminder>
|
|
31871
33032
|
${lines2.join("\n\n")}
|
|
31872
33033
|
</system-reminder>`;
|
|
@@ -31919,12 +33080,12 @@ function createRemindersExtension(core, settings = {}, deps = {}) {
|
|
|
31919
33080
|
dispose
|
|
31920
33081
|
};
|
|
31921
33082
|
}
|
|
31922
|
-
var import_node_child_process8,
|
|
33083
|
+
var import_node_child_process8, import_node_fs38, import_node_path55, REMINDER_CUSTOM_TYPE, DEFAULT_TODO_REMINDER_TURNS, CONTEXT_REMINDER_RATIOS, BUDGET_REMINDER_RATIO, MAX_CHANGED_FILES, FILE_TOOLS, Reminders;
|
|
31923
33084
|
var init_reminders = __esm({
|
|
31924
33085
|
"src/agent/reminders.ts"() {
|
|
31925
33086
|
"use strict";
|
|
31926
33087
|
import_node_child_process8 = require("node:child_process");
|
|
31927
|
-
|
|
33088
|
+
import_node_fs38 = require("node:fs");
|
|
31928
33089
|
import_node_path55 = require("node:path");
|
|
31929
33090
|
init_estimate();
|
|
31930
33091
|
init_projection();
|
|
@@ -32017,7 +33178,7 @@ var init_reminders = __esm({
|
|
|
32017
33178
|
const budget = inRun ? this.budgetLine() : void 0;
|
|
32018
33179
|
for (const line2 of [jobs, todo, files, context, budget])
|
|
32019
33180
|
if (line2 !== void 0) lines2.push(line2);
|
|
32020
|
-
return lines2.length === 0 ? void 0 :
|
|
33181
|
+
return lines2.length === 0 ? void 0 : wrap2(lines2);
|
|
32021
33182
|
}
|
|
32022
33183
|
jobLines() {
|
|
32023
33184
|
const exited = jobsForSession(this.core.manager.id).takeExited();
|
|
@@ -32484,17 +33645,17 @@ function resolvePlanDirectory(configured2, projectRoot, dataDir) {
|
|
|
32484
33645
|
return { dir };
|
|
32485
33646
|
}
|
|
32486
33647
|
function writePlanFile(dir, sessionId, version, markdown) {
|
|
32487
|
-
(0,
|
|
33648
|
+
(0, import_node_fs39.mkdirSync)(dir, { recursive: true });
|
|
32488
33649
|
const file = (0, import_node_path56.join)(dir, `${sessionId}-v${version}.md`);
|
|
32489
|
-
(0,
|
|
33650
|
+
(0, import_node_fs39.writeFileSync)(file, markdown.endsWith("\n") ? markdown : `${markdown}
|
|
32490
33651
|
`, "utf8");
|
|
32491
33652
|
return file;
|
|
32492
33653
|
}
|
|
32493
|
-
var
|
|
33654
|
+
var import_node_fs39, import_node_path56, PLAN_CUSTOM_TYPE2, PLAN_STATE_CUSTOM_TYPE;
|
|
32494
33655
|
var init_store3 = __esm({
|
|
32495
33656
|
"src/plan/store.ts"() {
|
|
32496
33657
|
"use strict";
|
|
32497
|
-
|
|
33658
|
+
import_node_fs39 = require("node:fs");
|
|
32498
33659
|
import_node_path56 = require("node:path");
|
|
32499
33660
|
init_todo();
|
|
32500
33661
|
init_i18n();
|
|
@@ -33030,7 +34191,7 @@ function permissionModeOf(value) {
|
|
|
33030
34191
|
}
|
|
33031
34192
|
function parseAgentDefinition(text, filePath, source) {
|
|
33032
34193
|
const warnings = [];
|
|
33033
|
-
const
|
|
34194
|
+
const fail7 = (message) => {
|
|
33034
34195
|
warnings.push(`${filePath}: ${message}`);
|
|
33035
34196
|
return { warnings };
|
|
33036
34197
|
};
|
|
@@ -33040,42 +34201,42 @@ function parseAgentDefinition(text, filePath, source) {
|
|
|
33040
34201
|
const rawName = data2["name"];
|
|
33041
34202
|
const name = typeof rawName === "string" && rawName !== "" ? rawName : (0, import_node_path57.basename)(filePath, ".md");
|
|
33042
34203
|
if (!AGENT_NAME_RE.test(name))
|
|
33043
|
-
return
|
|
34204
|
+
return fail7(`invalid agent name "${name}" (lowercase letters, digits, -; at most 64)`);
|
|
33044
34205
|
const description = data2["description"];
|
|
33045
34206
|
if (typeof description !== "string" || description.trim() === "")
|
|
33046
|
-
return
|
|
34207
|
+
return fail7(`missing description; agent "${name}" not loaded`);
|
|
33047
34208
|
if (description.length > MAX_AGENT_DESCRIPTION)
|
|
33048
|
-
return
|
|
34209
|
+
return fail7(`description longer than ${MAX_AGENT_DESCRIPTION} characters`);
|
|
33049
34210
|
const runnerRaw = data2["runner"] ?? "ama";
|
|
33050
34211
|
const runner = String(runnerRaw).trim();
|
|
33051
34212
|
if (!isRunner(runner))
|
|
33052
|
-
return
|
|
34213
|
+
return fail7(`unknown runner "${runner}" (ama | claude | codex | acp:<program>)`);
|
|
33053
34214
|
const tools = nameList(data2["tools"]);
|
|
33054
34215
|
const disallowedTools = nameList(data2["disallowed-tools"]);
|
|
33055
34216
|
if (tools !== void 0 && disallowedTools !== void 0)
|
|
33056
|
-
return
|
|
34217
|
+
return fail7("tools and disallowed-tools are mutually exclusive");
|
|
33057
34218
|
const permissionMode = permissionModeOf(data2["permission-mode"]);
|
|
33058
34219
|
if (permissionMode === void 0)
|
|
33059
|
-
return
|
|
34220
|
+
return fail7(
|
|
33060
34221
|
`permission-mode must be plan or inherit (got "${String(data2["permission-mode"])}")`
|
|
33061
34222
|
);
|
|
33062
34223
|
const model = data2["model"] === void 0 || data2["model"] === null ? "inherit" : data2["model"];
|
|
33063
|
-
if (typeof model !== "string" || model.trim() === "") return
|
|
34224
|
+
if (typeof model !== "string" || model.trim() === "") return fail7("model must be a string");
|
|
33064
34225
|
const thinking = data2["thinking"];
|
|
33065
34226
|
if (thinking !== void 0 && thinking !== null && !THINKING2.includes(thinking))
|
|
33066
|
-
return
|
|
34227
|
+
return fail7(`thinking must be one of ${THINKING2.join(", ")}`);
|
|
33067
34228
|
const maxTurns = data2["max-turns"] ?? DEFAULT_AGENT_MAX_TURNS;
|
|
33068
34229
|
if (typeof maxTurns !== "number" || !Number.isInteger(maxTurns) || maxTurns < 1)
|
|
33069
|
-
return
|
|
34230
|
+
return fail7("max-turns must be an integer ≥ 1");
|
|
33070
34231
|
const isolation = data2["isolation"] ?? "none";
|
|
33071
34232
|
if (isolation !== "none" && isolation !== "worktree")
|
|
33072
|
-
return
|
|
34233
|
+
return fail7("isolation must be none or worktree");
|
|
33073
34234
|
const background = data2["background"];
|
|
33074
34235
|
if (background !== void 0 && typeof background !== "boolean")
|
|
33075
|
-
return
|
|
34236
|
+
return fail7("background must be true or false");
|
|
33076
34237
|
const context = data2["context"];
|
|
33077
34238
|
if (context !== void 0 && context !== null && context !== "fork" && context !== "fresh")
|
|
33078
|
-
return
|
|
34239
|
+
return fail7("context must be fork or fresh");
|
|
33079
34240
|
if (runner !== "ama") {
|
|
33080
34241
|
const ignored = ["tools", "disallowed-tools", "permission-mode", "context"].filter(
|
|
33081
34242
|
(key) => data2[key] !== void 0
|
|
@@ -33136,14 +34297,14 @@ function agentSources(options) {
|
|
|
33136
34297
|
}
|
|
33137
34298
|
function isDir2(path) {
|
|
33138
34299
|
try {
|
|
33139
|
-
return (0,
|
|
34300
|
+
return (0, import_node_fs40.statSync)(path).isDirectory();
|
|
33140
34301
|
} catch {
|
|
33141
34302
|
return false;
|
|
33142
34303
|
}
|
|
33143
34304
|
}
|
|
33144
34305
|
function markdownFiles(dir) {
|
|
33145
34306
|
try {
|
|
33146
|
-
return (0,
|
|
34307
|
+
return (0, import_node_fs40.readdirSync)(dir, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".md")).map((entry) => entry.name).sort().map((name) => (0, import_node_path58.join)(dir, name));
|
|
33147
34308
|
} catch {
|
|
33148
34309
|
return [];
|
|
33149
34310
|
}
|
|
@@ -33163,7 +34324,7 @@ function discoverAgents(sources, options) {
|
|
|
33163
34324
|
for (const file of markdownFiles(source.dir)) {
|
|
33164
34325
|
let text;
|
|
33165
34326
|
try {
|
|
33166
|
-
text = (0,
|
|
34327
|
+
text = (0, import_node_fs40.readFileSync)(file, "utf8");
|
|
33167
34328
|
} catch (error2) {
|
|
33168
34329
|
result.warnings.push(`${file}: ${error2.message}`);
|
|
33169
34330
|
continue;
|
|
@@ -33185,11 +34346,11 @@ function discoverAgents(sources, options) {
|
|
|
33185
34346
|
}
|
|
33186
34347
|
return result;
|
|
33187
34348
|
}
|
|
33188
|
-
var
|
|
34349
|
+
var import_node_fs40, import_node_path58;
|
|
33189
34350
|
var init_discover = __esm({
|
|
33190
34351
|
"src/agents/discover.ts"() {
|
|
33191
34352
|
"use strict";
|
|
33192
|
-
|
|
34353
|
+
import_node_fs40 = require("node:fs");
|
|
33193
34354
|
import_node_path58 = require("node:path");
|
|
33194
34355
|
init_parse();
|
|
33195
34356
|
}
|
|
@@ -33527,7 +34688,7 @@ var init_process = __esm({
|
|
|
33527
34688
|
// src/drivers/probe.ts
|
|
33528
34689
|
function defaultIsFile(path) {
|
|
33529
34690
|
try {
|
|
33530
|
-
return (0,
|
|
34691
|
+
return (0, import_node_fs41.statSync)(path).isFile();
|
|
33531
34692
|
} catch {
|
|
33532
34693
|
return false;
|
|
33533
34694
|
}
|
|
@@ -33589,12 +34750,12 @@ function defaultRunVersion(env, platform) {
|
|
|
33589
34750
|
);
|
|
33590
34751
|
});
|
|
33591
34752
|
}
|
|
33592
|
-
var import_node_child_process10,
|
|
34753
|
+
var import_node_child_process10, import_node_fs41, import_node_path59, VERSION_TIMEOUT_MS, ProgramProbe;
|
|
33593
34754
|
var init_probe = __esm({
|
|
33594
34755
|
"src/drivers/probe.ts"() {
|
|
33595
34756
|
"use strict";
|
|
33596
34757
|
import_node_child_process10 = require("node:child_process");
|
|
33597
|
-
|
|
34758
|
+
import_node_fs41 = require("node:fs");
|
|
33598
34759
|
import_node_path59 = require("node:path");
|
|
33599
34760
|
init_process();
|
|
33600
34761
|
VERSION_TIMEOUT_MS = 5e3;
|
|
@@ -33647,16 +34808,16 @@ var init_probe = __esm({
|
|
|
33647
34808
|
}
|
|
33648
34809
|
mtime(path) {
|
|
33649
34810
|
try {
|
|
33650
|
-
return (0,
|
|
34811
|
+
return (0, import_node_fs41.statSync)(path).mtimeMs;
|
|
33651
34812
|
} catch {
|
|
33652
34813
|
return 0;
|
|
33653
34814
|
}
|
|
33654
34815
|
}
|
|
33655
34816
|
readCache() {
|
|
33656
34817
|
const file = this.deps.cacheFile;
|
|
33657
|
-
if (file === void 0 || !(0,
|
|
34818
|
+
if (file === void 0 || !(0, import_node_fs41.existsSync)(file)) return {};
|
|
33658
34819
|
try {
|
|
33659
|
-
const parsed = JSON.parse((0,
|
|
34820
|
+
const parsed = JSON.parse((0, import_node_fs41.readFileSync)(file, "utf8"));
|
|
33660
34821
|
return parsed.programs ?? {};
|
|
33661
34822
|
} catch {
|
|
33662
34823
|
return {};
|
|
@@ -33667,8 +34828,8 @@ var init_probe = __esm({
|
|
|
33667
34828
|
if (file === void 0) return;
|
|
33668
34829
|
try {
|
|
33669
34830
|
const programs = { ...this.readCache(), [path]: entry };
|
|
33670
|
-
(0,
|
|
33671
|
-
(0,
|
|
34831
|
+
(0, import_node_fs41.mkdirSync)((0, import_node_path59.dirname)(file), { recursive: true });
|
|
34832
|
+
(0, import_node_fs41.writeFileSync)(file, `${JSON.stringify({ version: 1, programs }, null, 2)}
|
|
33672
34833
|
`);
|
|
33673
34834
|
} catch {
|
|
33674
34835
|
}
|
|
@@ -33876,6 +35037,7 @@ var init_client = __esm({
|
|
|
33876
35037
|
onNotification: (method, params) => {
|
|
33877
35038
|
if (method === ACP_METHODS.sessionUpdate)
|
|
33878
35039
|
options.onUpdate?.(params);
|
|
35040
|
+
else if (method === ACP_METHODS.elicitationComplete) this.onElicitationComplete(params);
|
|
33879
35041
|
},
|
|
33880
35042
|
onClose: () => {
|
|
33881
35043
|
for (const set of this.pendingPermissions.values()) for (const c of set) c.abort();
|
|
@@ -33891,14 +35053,25 @@ var init_client = __esm({
|
|
|
33891
35053
|
* - `mcpServers`:开会话时可经 {@link AcpSessionOptions} 传 MCP 服务器;
|
|
33892
35054
|
* - `elicitation`:构造参数 `onElicitation` 接 `elicitation/create`;
|
|
33893
35055
|
* - `configOptions`:`setConfigOption` 与开会话答的 `configOptions`;
|
|
33894
|
-
* - `terminal`:构造参数 `onTerminal` 接 `terminal
|
|
35056
|
+
* - `terminal`:构造参数 `onTerminal` 接 `terminal/*`;
|
|
35057
|
+
* - `auth`:`authenticate` / `logout`、构造参数 `authTerminal`、`isAuthRequiredError`;
|
|
35058
|
+
* - `elicitationComplete`:构造参数 `onElicitationComplete` 接 `elicitation/complete`,表单字段含多选与 `oneOf`。
|
|
33895
35059
|
*/
|
|
33896
|
-
static features = {
|
|
35060
|
+
static features = {
|
|
35061
|
+
mcpServers: true,
|
|
35062
|
+
elicitation: true,
|
|
35063
|
+
configOptions: true,
|
|
35064
|
+
terminal: true,
|
|
35065
|
+
auth: true,
|
|
35066
|
+
elicitationComplete: true
|
|
35067
|
+
};
|
|
33897
35068
|
peer;
|
|
33898
35069
|
/** sessionId → 挂起权限请求的取消器。 */
|
|
33899
35070
|
pendingPermissions = /* @__PURE__ */ new Map();
|
|
33900
35071
|
/** sessionId(没给就是空串)→ 挂起 elicitation 的取消器。 */
|
|
33901
35072
|
pendingElicitations = /* @__PURE__ */ new Map();
|
|
35073
|
+
/** elicitationId → 挂起 elicitation 的取消器(`elicitation/complete` 用)。 */
|
|
35074
|
+
elicitationsById = /* @__PURE__ */ new Map();
|
|
33902
35075
|
initResult;
|
|
33903
35076
|
get closed() {
|
|
33904
35077
|
return this.peer.closed;
|
|
@@ -33925,7 +35098,10 @@ var init_client = __esm({
|
|
|
33925
35098
|
fs: { readTextFile: false, writeTextFile: false },
|
|
33926
35099
|
terminal: this.options.onTerminal !== void 0,
|
|
33927
35100
|
session: { configOptions: {} },
|
|
33928
|
-
...this.options.
|
|
35101
|
+
...this.options.authTerminal === true ? { auth: { terminal: true } } : {},
|
|
35102
|
+
...this.options.onElicitation !== void 0 || this.options.onElicitationComplete ? {
|
|
35103
|
+
elicitation: this.options.onElicitationComplete !== void 0 ? { form: {}, url: {} } : {}
|
|
35104
|
+
} : {}
|
|
33929
35105
|
},
|
|
33930
35106
|
...this.options.clientInfo !== void 0 ? { clientInfo: this.options.clientInfo } : {}
|
|
33931
35107
|
},
|
|
@@ -33951,9 +35127,30 @@ var init_client = __esm({
|
|
|
33951
35127
|
supportsClose() {
|
|
33952
35128
|
return this.agentCapabilities.sessionCapabilities?.close != null;
|
|
33953
35129
|
}
|
|
35130
|
+
/** Agent 声明了 `auth.logout`(存在即支持)。 */
|
|
35131
|
+
supportsLogout() {
|
|
35132
|
+
return this.agentCapabilities.auth?.logout != null;
|
|
35133
|
+
}
|
|
33954
35134
|
supportsImages() {
|
|
33955
35135
|
return this.agentCapabilities.promptCapabilities?.image === true;
|
|
33956
35136
|
}
|
|
35137
|
+
/**
|
|
35138
|
+
* 用 agent 型认证方法登录(`methodId` 取自 `authMethods`)。terminal 型方法不经 `authenticate`:已知是
|
|
35139
|
+
* terminal 型时抛 -32602,由宿主在终端里跑该方法的 `args` / `env`。失败的错误码原样抛出。
|
|
35140
|
+
*/
|
|
35141
|
+
async authenticate(methodId, signal) {
|
|
35142
|
+
const known = this.authMethods.find((method) => method.id === methodId);
|
|
35143
|
+
if (known !== void 0 && isTerminalAuthMethod(known))
|
|
35144
|
+
throw new RpcError(
|
|
35145
|
+
RPC_ERRORS.invalidParams,
|
|
35146
|
+
`auth method ${methodId} is a terminal method: run it in a terminal, not through authenticate`
|
|
35147
|
+
);
|
|
35148
|
+
return this.peer.request(ACP_METHODS.authenticate, { methodId }, signal);
|
|
35149
|
+
}
|
|
35150
|
+
/** 登出当前账号;Agent 没声明 `auth.logout`(见 `supportsLogout`)时会答 method not found。 */
|
|
35151
|
+
logout(signal) {
|
|
35152
|
+
return this.peer.request(ACP_METHODS.logout, {}, signal);
|
|
35153
|
+
}
|
|
33957
35154
|
newSession(cwd, signal, options) {
|
|
33958
35155
|
return this.peer.request(
|
|
33959
35156
|
ACP_METHODS.sessionNew,
|
|
@@ -33977,14 +35174,34 @@ var init_client = __esm({
|
|
|
33977
35174
|
signal
|
|
33978
35175
|
);
|
|
33979
35176
|
}
|
|
33980
|
-
|
|
33981
|
-
|
|
33982
|
-
|
|
33983
|
-
|
|
33984
|
-
|
|
35177
|
+
/** 一页会话;`cwd` 过滤(绝对路径),`cursor` 取自上一页的 `nextCursor`。 */
|
|
35178
|
+
listSessions(cwd, cursor, signal) {
|
|
35179
|
+
return this.peer.request(
|
|
35180
|
+
ACP_METHODS.sessionList,
|
|
35181
|
+
{
|
|
35182
|
+
...cwd !== void 0 ? { cwd } : {},
|
|
35183
|
+
...cursor !== void 0 ? { cursor } : {}
|
|
35184
|
+
},
|
|
35185
|
+
signal
|
|
35186
|
+
);
|
|
35187
|
+
}
|
|
35188
|
+
/** 跟 `nextCursor` 翻页取全(`maxPages` 防对端游标不终止,缺省 100 页)。 */
|
|
35189
|
+
async listAllSessions(cwd, signal, maxPages = 100) {
|
|
35190
|
+
const sessions = [];
|
|
35191
|
+
let cursor;
|
|
35192
|
+
for (let page2 = 0; page2 < maxPages; page2++) {
|
|
35193
|
+
const result = await this.listSessions(cwd, cursor, signal);
|
|
35194
|
+
sessions.push(...result.sessions ?? []);
|
|
35195
|
+
if (typeof result.nextCursor !== "string" || result.nextCursor === "") break;
|
|
35196
|
+
cursor = result.nextCursor;
|
|
35197
|
+
}
|
|
35198
|
+
return sessions;
|
|
33985
35199
|
}
|
|
33986
|
-
|
|
33987
|
-
|
|
35200
|
+
/** 关闭会话:规范要求 Agent 先取消进行中的工作,所以本端先把该会话挂起的请求收掉。 */
|
|
35201
|
+
closeSession(sessionId, signal) {
|
|
35202
|
+
for (const controller of this.pendingPermissions.get(sessionId) ?? []) controller.abort();
|
|
35203
|
+
for (const controller of this.pendingElicitations.get(sessionId) ?? []) controller.abort();
|
|
35204
|
+
return this.peer.request(ACP_METHODS.sessionClose, { sessionId }, signal);
|
|
33988
35205
|
}
|
|
33989
35206
|
prompt(sessionId, prompt, signal) {
|
|
33990
35207
|
return this.peer.request(ACP_METHODS.sessionPrompt, { sessionId, prompt }, signal);
|
|
@@ -34051,6 +35268,8 @@ var init_client = __esm({
|
|
|
34051
35268
|
const set = this.pendingElicitations.get(key) ?? /* @__PURE__ */ new Set();
|
|
34052
35269
|
set.add(controller);
|
|
34053
35270
|
this.pendingElicitations.set(key, set);
|
|
35271
|
+
const id = typeof request.elicitationId === "string" ? request.elicitationId : void 0;
|
|
35272
|
+
if (id !== void 0) this.elicitationsById.set(id, controller);
|
|
34054
35273
|
const signal = AbortSignal.any([controller.signal, connection]);
|
|
34055
35274
|
try {
|
|
34056
35275
|
const answer = await Promise.race([
|
|
@@ -34065,16 +35284,25 @@ var init_client = __esm({
|
|
|
34065
35284
|
return elicitationAnswer(answer);
|
|
34066
35285
|
} finally {
|
|
34067
35286
|
set.delete(controller);
|
|
35287
|
+
if (id !== void 0 && this.elicitationsById.get(id) === controller)
|
|
35288
|
+
this.elicitationsById.delete(id);
|
|
34068
35289
|
}
|
|
34069
35290
|
}
|
|
35291
|
+
/** 通知没有答复:参数不对就忽略;还挂着的同 id elicitation 先收掉,再交给宿主。 */
|
|
35292
|
+
onElicitationComplete(params) {
|
|
35293
|
+
const id = params?.elicitationId;
|
|
35294
|
+
if (typeof id !== "string") return;
|
|
35295
|
+
this.elicitationsById.get(id)?.abort();
|
|
35296
|
+
this.options.onElicitationComplete?.(params);
|
|
35297
|
+
}
|
|
34070
35298
|
};
|
|
34071
35299
|
}
|
|
34072
35300
|
});
|
|
34073
35301
|
|
|
34074
35302
|
// src/drivers/acp/driver.ts
|
|
34075
|
-
function toAcpContent(
|
|
35303
|
+
function toAcpContent(blocks2, images) {
|
|
34076
35304
|
const out = [];
|
|
34077
|
-
for (const block of
|
|
35305
|
+
for (const block of blocks2) {
|
|
34078
35306
|
if (block.type === "text") out.push({ type: "text", text: block.text });
|
|
34079
35307
|
else if (images) out.push({ type: "image", data: block.data, mimeType: block.mimeType });
|
|
34080
35308
|
}
|
|
@@ -34578,12 +35806,12 @@ function claudeArgs(options, sessionId, manualName = "manual") {
|
|
|
34578
35806
|
return args;
|
|
34579
35807
|
}
|
|
34580
35808
|
function userLine(content) {
|
|
34581
|
-
const
|
|
35809
|
+
const blocks2 = content.map(
|
|
34582
35810
|
(b) => b.type === "text" ? { type: "text", text: b.text } : { type: "image", source: { type: "base64", media_type: b.mimeType, data: b.data } }
|
|
34583
35811
|
);
|
|
34584
35812
|
return `${JSON.stringify({
|
|
34585
35813
|
type: "user",
|
|
34586
|
-
message: { role: "user", content:
|
|
35814
|
+
message: { role: "user", content: blocks2 },
|
|
34587
35815
|
parent_tool_use_id: null
|
|
34588
35816
|
})}
|
|
34589
35817
|
`;
|
|
@@ -35839,19 +37067,19 @@ ${item["text"]}`
|
|
|
35839
37067
|
|
|
35840
37068
|
// src/drivers/native/pi-gate.ts
|
|
35841
37069
|
function writePiGate() {
|
|
35842
|
-
const dir = (0,
|
|
37070
|
+
const dir = (0, import_node_fs42.mkdtempSync)((0, import_node_path60.join)((0, import_node_os11.tmpdir)(), "ama-pi-"));
|
|
35843
37071
|
const path = (0, import_node_path60.join)(dir, "ama-approval-gate.ts");
|
|
35844
|
-
(0,
|
|
37072
|
+
(0, import_node_fs42.writeFileSync)(path, PI_GATE_SOURCE, { mode: 384 });
|
|
35845
37073
|
return {
|
|
35846
37074
|
path,
|
|
35847
|
-
dispose: () => (0,
|
|
37075
|
+
dispose: () => (0, import_node_fs42.rmSync)(dir, { recursive: true, force: true })
|
|
35848
37076
|
};
|
|
35849
37077
|
}
|
|
35850
|
-
var
|
|
37078
|
+
var import_node_fs42, import_node_os11, import_node_path60, PI_GATE_TITLE, PI_READ_ONLY_TOOLS, PI_GATE_SOURCE;
|
|
35851
37079
|
var init_pi_gate = __esm({
|
|
35852
37080
|
"src/drivers/native/pi-gate.ts"() {
|
|
35853
37081
|
"use strict";
|
|
35854
|
-
|
|
37082
|
+
import_node_fs42 = require("node:fs");
|
|
35855
37083
|
import_node_os11 = require("node:os");
|
|
35856
37084
|
import_node_path60 = require("node:path");
|
|
35857
37085
|
PI_GATE_TITLE = "ama-approval";
|
|
@@ -36346,7 +37574,7 @@ function pidsFile(dataDir) {
|
|
|
36346
37574
|
}
|
|
36347
37575
|
function read(file) {
|
|
36348
37576
|
try {
|
|
36349
|
-
const parsed = JSON.parse((0,
|
|
37577
|
+
const parsed = JSON.parse((0, import_node_fs43.readFileSync)(file, "utf8"));
|
|
36350
37578
|
return Array.isArray(parsed.entries) ? parsed.entries : [];
|
|
36351
37579
|
} catch {
|
|
36352
37580
|
return [];
|
|
@@ -36354,11 +37582,11 @@ function read(file) {
|
|
|
36354
37582
|
}
|
|
36355
37583
|
function write(file, entries) {
|
|
36356
37584
|
try {
|
|
36357
|
-
(0,
|
|
37585
|
+
(0, import_node_fs43.mkdirSync)((0, import_node_path62.dirname)(file), { recursive: true });
|
|
36358
37586
|
const tmp = `${file}.${process.pid}.tmp`;
|
|
36359
|
-
(0,
|
|
37587
|
+
(0, import_node_fs43.writeFileSync)(tmp, `${JSON.stringify({ version: 1, entries }, null, 2)}
|
|
36360
37588
|
`);
|
|
36361
|
-
(0,
|
|
37589
|
+
(0, import_node_fs43.renameSync)(tmp, file);
|
|
36362
37590
|
} catch {
|
|
36363
37591
|
}
|
|
36364
37592
|
}
|
|
@@ -36374,12 +37602,12 @@ function psCommand(pid) {
|
|
|
36374
37602
|
const out = (0, import_node_child_process11.spawnSync)("ps", ["-o", "command=", "-p", String(pid)], { encoding: "utf8" });
|
|
36375
37603
|
return out.status === 0 ? out.stdout.trim() : void 0;
|
|
36376
37604
|
}
|
|
36377
|
-
var import_node_child_process11,
|
|
37605
|
+
var import_node_child_process11, import_node_fs43, import_node_path62, PidRegistry;
|
|
36378
37606
|
var init_pids = __esm({
|
|
36379
37607
|
"src/drivers/pids.ts"() {
|
|
36380
37608
|
"use strict";
|
|
36381
37609
|
import_node_child_process11 = require("node:child_process");
|
|
36382
|
-
|
|
37610
|
+
import_node_fs43 = require("node:fs");
|
|
36383
37611
|
import_node_path62 = require("node:path");
|
|
36384
37612
|
init_process_tree();
|
|
36385
37613
|
PidRegistry = class {
|
|
@@ -36644,7 +37872,7 @@ function toUsage(turn) {
|
|
|
36644
37872
|
usage.cost = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: u.costUsd };
|
|
36645
37873
|
return usage;
|
|
36646
37874
|
}
|
|
36647
|
-
function
|
|
37875
|
+
function statusOf2(turn, timedOut, stopped) {
|
|
36648
37876
|
if (timedOut) return "failed";
|
|
36649
37877
|
switch (turn.stopReason) {
|
|
36650
37878
|
case "end_turn":
|
|
@@ -37037,7 +38265,7 @@ var init_runner2 = __esm({
|
|
|
37037
38265
|
});
|
|
37038
38266
|
this.emit({ type: "usage", usage, unit, amount });
|
|
37039
38267
|
}
|
|
37040
|
-
const status =
|
|
38268
|
+
const status = statusOf2(turn, timedOut, this.stopped);
|
|
37041
38269
|
this.emitTurnTrace(
|
|
37042
38270
|
turnStartedAt,
|
|
37043
38271
|
timedOut ? "timeout" : turn.stopReason,
|
|
@@ -37157,7 +38385,7 @@ var init_agents2 = __esm({
|
|
|
37157
38385
|
driverDeps;
|
|
37158
38386
|
/** `task(agent=<spec>)` 的 runner;不可用时抛 AmaError(`agent_host_only` / `agent_unknown`)。 */
|
|
37159
38387
|
resolve(spec2) {
|
|
37160
|
-
const hosted = this.hostRunners.
|
|
38388
|
+
const hosted = this.hostRunners.resolve(spec2);
|
|
37161
38389
|
if (hosted !== void 0) return hosted;
|
|
37162
38390
|
if (this.options.hosted)
|
|
37163
38391
|
throw new AmaError(
|
|
@@ -37644,6 +38872,7 @@ function subagentEnvironment(deps, catalog) {
|
|
|
37644
38872
|
if (retain !== void 0) env.retain = retain;
|
|
37645
38873
|
const sub = config.subagents;
|
|
37646
38874
|
env.background = resolveTaskBackground(sub?.background, deps.assembly.unattended === true);
|
|
38875
|
+
if (isCoordinatorPreset(config)) env.background = true;
|
|
37647
38876
|
const after = sub?.autoBackgroundAfterMs;
|
|
37648
38877
|
if (typeof after === "number" && after > 0) env.autoBackgroundAfterMs = after;
|
|
37649
38878
|
return env;
|
|
@@ -37696,6 +38925,8 @@ function createSubagentsFactory(deps) {
|
|
|
37696
38925
|
bindTaskAgents(task, catalog);
|
|
37697
38926
|
const env = subagentEnvironment(deps, catalog);
|
|
37698
38927
|
bindTaskBackground(task, env.background === true);
|
|
38928
|
+
if (isCoordinatorPreset(deps.assembly.config))
|
|
38929
|
+
bindTaskCtlWaitCap(deps.assembly.tools.get("task_ctl"), COORDINATOR_WAIT_MAX_MS);
|
|
37699
38930
|
return ({ core }) => core.depth > 0 ? void 0 : createSubagentExtension(core, env, wiring);
|
|
37700
38931
|
}
|
|
37701
38932
|
var warned;
|
|
@@ -37707,6 +38938,8 @@ var init_compose_agents = __esm({
|
|
|
37707
38938
|
init_discover();
|
|
37708
38939
|
init_external();
|
|
37709
38940
|
init_api_impl();
|
|
38941
|
+
init_presets2();
|
|
38942
|
+
init_task_ctl();
|
|
37710
38943
|
init_task();
|
|
37711
38944
|
init_subagent_background();
|
|
37712
38945
|
init_i18n();
|
|
@@ -37812,7 +39045,7 @@ function sourceText2(source, cache3, log) {
|
|
|
37812
39045
|
if (cached !== void 0) return cached;
|
|
37813
39046
|
let text = "";
|
|
37814
39047
|
try {
|
|
37815
|
-
text = (0,
|
|
39048
|
+
text = (0, import_node_fs44.readFileSync)(source.path, "utf8");
|
|
37816
39049
|
} catch (error2) {
|
|
37817
39050
|
log(
|
|
37818
39051
|
"warn",
|
|
@@ -38166,11 +39399,11 @@ async function disposeSessionAlongside(target, session, fallback) {
|
|
|
38166
39399
|
await session.dispose();
|
|
38167
39400
|
record3.live.delete(session);
|
|
38168
39401
|
}
|
|
38169
|
-
var
|
|
39402
|
+
var import_node_fs44, records, LOG_LEVELS;
|
|
38170
39403
|
var init_compose_session = __esm({
|
|
38171
39404
|
"src/cli/compose-session.ts"() {
|
|
38172
39405
|
"use strict";
|
|
38173
|
-
|
|
39406
|
+
import_node_fs44 = require("node:fs");
|
|
38174
39407
|
init_limits();
|
|
38175
39408
|
init_session2();
|
|
38176
39409
|
init_session_subagent();
|
|
@@ -39026,7 +40259,7 @@ var init_acp_sessions = __esm({
|
|
|
39026
40259
|
// src/modes/acp/acp-server.ts
|
|
39027
40260
|
function canonical(path) {
|
|
39028
40261
|
try {
|
|
39029
|
-
return
|
|
40262
|
+
return import_node_fs45.realpathSync.native((0, import_node_path65.resolve)(path));
|
|
39030
40263
|
} catch {
|
|
39031
40264
|
return (0, import_node_path65.resolve)(path);
|
|
39032
40265
|
}
|
|
@@ -39037,12 +40270,12 @@ function str(params, key) {
|
|
|
39037
40270
|
throw new RpcError(RPC_ERRORS.invalidParams, msg().acp.core.missingParam(key));
|
|
39038
40271
|
return value;
|
|
39039
40272
|
}
|
|
39040
|
-
function promptOf(
|
|
39041
|
-
if (!Array.isArray(
|
|
40273
|
+
function promptOf(blocks2) {
|
|
40274
|
+
if (!Array.isArray(blocks2))
|
|
39042
40275
|
throw new RpcError(RPC_ERRORS.invalidParams, msg().acp.core.promptNotArray);
|
|
39043
40276
|
const parts = [];
|
|
39044
40277
|
const images = [];
|
|
39045
|
-
for (const block of
|
|
40278
|
+
for (const block of blocks2) {
|
|
39046
40279
|
if (block.type === "text") parts.push(block.text);
|
|
39047
40280
|
else if (block.type === "image")
|
|
39048
40281
|
images.push({ type: "image", data: block.data, mimeType: block.mimeType });
|
|
@@ -39057,11 +40290,11 @@ ${block.resource.text}
|
|
|
39057
40290
|
function countOf(value) {
|
|
39058
40291
|
return Array.isArray(value) ? value.length : 0;
|
|
39059
40292
|
}
|
|
39060
|
-
var
|
|
40293
|
+
var import_node_fs45, import_node_path65, ACP_AGENT_CAPABILITIES, SESSION_ID_SHAPE, AcpServer;
|
|
39061
40294
|
var init_acp_server = __esm({
|
|
39062
40295
|
"src/modes/acp/acp-server.ts"() {
|
|
39063
40296
|
"use strict";
|
|
39064
|
-
|
|
40297
|
+
import_node_fs45 = require("node:fs");
|
|
39065
40298
|
import_node_path65 = require("node:path");
|
|
39066
40299
|
init_shared();
|
|
39067
40300
|
init_compose_session();
|
|
@@ -39785,7 +41018,7 @@ async function bootstrap(argsIn, deps, io) {
|
|
|
39785
41018
|
() => deps.sessions.open(sessionRequest, { sessionDir: paths.sessionDir, cwd: paths.cwd })
|
|
39786
41019
|
);
|
|
39787
41020
|
let sessionCwd = sessionManager.cwd;
|
|
39788
|
-
if (!(0,
|
|
41021
|
+
if (!(0, import_node_fs46.existsSync)(sessionCwd)) {
|
|
39789
41022
|
const replacement = interactive ? await deps.ui?.askCwd?.(sessionCwd) : void 0;
|
|
39790
41023
|
if (replacement === void 0) {
|
|
39791
41024
|
throw new StartupError(
|
|
@@ -40179,11 +41412,11 @@ function reportError(error2, io, fallback = ExitCode.RuntimeError) {
|
|
|
40179
41412
|
if (isAmaError(error2) && error2.exitCode !== void 0) return error2.exitCode;
|
|
40180
41413
|
return fallback;
|
|
40181
41414
|
}
|
|
40182
|
-
var
|
|
41415
|
+
var import_node_fs46, import_node_path67;
|
|
40183
41416
|
var init_bootstrap = __esm({
|
|
40184
41417
|
"src/cli/bootstrap.ts"() {
|
|
40185
41418
|
"use strict";
|
|
40186
|
-
|
|
41419
|
+
import_node_fs46 = require("node:fs");
|
|
40187
41420
|
import_node_path67 = require("node:path");
|
|
40188
41421
|
init_auth_file();
|
|
40189
41422
|
init_context_files();
|
|
@@ -40210,7 +41443,7 @@ var init_bootstrap = __esm({
|
|
|
40210
41443
|
// src/auth/oauth/token-store.ts
|
|
40211
41444
|
function readRaw(path) {
|
|
40212
41445
|
try {
|
|
40213
|
-
const value = JSON.parse(retryTransientFs(() => (0,
|
|
41446
|
+
const value = JSON.parse(retryTransientFs(() => (0, import_node_fs47.readFileSync)(path, "utf8")));
|
|
40214
41447
|
return typeof value === "object" && value !== null && typeof value.providers === "object" ? value : void 0;
|
|
40215
41448
|
} catch {
|
|
40216
41449
|
return void 0;
|
|
@@ -40242,12 +41475,12 @@ function isStaleLock(path, now = Date.now()) {
|
|
|
40242
41475
|
let age;
|
|
40243
41476
|
let pid;
|
|
40244
41477
|
try {
|
|
40245
|
-
age = now - (0,
|
|
40246
|
-
const value = JSON.parse((0,
|
|
41478
|
+
age = now - (0, import_node_fs47.statSync)(path).mtimeMs;
|
|
41479
|
+
const value = JSON.parse((0, import_node_fs47.readFileSync)(path, "utf8"));
|
|
40247
41480
|
pid = typeof value.pid === "number" ? value.pid : void 0;
|
|
40248
41481
|
} catch {
|
|
40249
41482
|
try {
|
|
40250
|
-
age = now - (0,
|
|
41483
|
+
age = now - (0, import_node_fs47.statSync)(path).mtimeMs;
|
|
40251
41484
|
} catch {
|
|
40252
41485
|
return false;
|
|
40253
41486
|
}
|
|
@@ -40256,11 +41489,11 @@ function isStaleLock(path, now = Date.now()) {
|
|
|
40256
41489
|
}
|
|
40257
41490
|
function tryAcquire(path) {
|
|
40258
41491
|
try {
|
|
40259
|
-
const fd = (0,
|
|
41492
|
+
const fd = (0, import_node_fs47.openSync)(path, "wx", 384);
|
|
40260
41493
|
try {
|
|
40261
|
-
(0,
|
|
41494
|
+
(0, import_node_fs47.writeSync)(fd, JSON.stringify({ pid: process.pid, at: (/* @__PURE__ */ new Date()).toISOString() }));
|
|
40262
41495
|
} finally {
|
|
40263
|
-
(0,
|
|
41496
|
+
(0, import_node_fs47.closeSync)(fd);
|
|
40264
41497
|
}
|
|
40265
41498
|
return true;
|
|
40266
41499
|
} catch (error2) {
|
|
@@ -40271,13 +41504,13 @@ function tryAcquire(path) {
|
|
|
40271
41504
|
}
|
|
40272
41505
|
async function withRefreshLock(authFile, fn, options = {}) {
|
|
40273
41506
|
const path = lockPath(authFile);
|
|
40274
|
-
(0,
|
|
41507
|
+
(0, import_node_fs47.mkdirSync)((0, import_node_path68.dirname)(path), { recursive: true, mode: 448 });
|
|
40275
41508
|
const deadline = Date.now() + (options.waitMs ?? LOCK_WAIT_MS);
|
|
40276
41509
|
for (; ; ) {
|
|
40277
41510
|
if (tryAcquire(path)) break;
|
|
40278
41511
|
if (isStaleLock(path)) {
|
|
40279
41512
|
try {
|
|
40280
|
-
(0,
|
|
41513
|
+
(0, import_node_fs47.unlinkSync)(path);
|
|
40281
41514
|
} catch {
|
|
40282
41515
|
}
|
|
40283
41516
|
continue;
|
|
@@ -40292,16 +41525,16 @@ async function withRefreshLock(authFile, fn, options = {}) {
|
|
|
40292
41525
|
return await fn();
|
|
40293
41526
|
} finally {
|
|
40294
41527
|
try {
|
|
40295
|
-
(0,
|
|
41528
|
+
(0, import_node_fs47.unlinkSync)(path);
|
|
40296
41529
|
} catch {
|
|
40297
41530
|
}
|
|
40298
41531
|
}
|
|
40299
41532
|
}
|
|
40300
|
-
var
|
|
41533
|
+
var import_node_fs47, import_node_path68, LOCK_WAIT_MS, LOCK_STALE_MS, LOCK_POLL_MS;
|
|
40301
41534
|
var init_token_store = __esm({
|
|
40302
41535
|
"src/auth/oauth/token-store.ts"() {
|
|
40303
41536
|
"use strict";
|
|
40304
|
-
|
|
41537
|
+
import_node_fs47 = require("node:fs");
|
|
40305
41538
|
import_node_path68 = require("node:path");
|
|
40306
41539
|
init_auth_file();
|
|
40307
41540
|
init_fs_retry();
|
|
@@ -40336,7 +41569,7 @@ function toEntry(value) {
|
|
|
40336
41569
|
function readDiscoveredCache(dataDir, provider) {
|
|
40337
41570
|
let parsed;
|
|
40338
41571
|
try {
|
|
40339
|
-
parsed = JSON.parse((0,
|
|
41572
|
+
parsed = JSON.parse((0, import_node_fs48.readFileSync)(discoveredCachePath(dataDir, provider), "utf8"));
|
|
40340
41573
|
} catch {
|
|
40341
41574
|
return void 0;
|
|
40342
41575
|
}
|
|
@@ -40360,17 +41593,17 @@ function writeDiscoveredCache(dataDir, provider, input2, now = Date.now()) {
|
|
|
40360
41593
|
...input2.flavor !== void 0 ? { flavor: input2.flavor } : {},
|
|
40361
41594
|
models: input2.models.map(toEntry).filter((m) => m !== void 0)
|
|
40362
41595
|
};
|
|
40363
|
-
(0,
|
|
41596
|
+
(0, import_node_fs48.mkdirSync)((0, import_node_path69.dirname)(path), { recursive: true, mode: 448 });
|
|
40364
41597
|
const tmp = `${path}.${process.pid}.tmp`;
|
|
40365
|
-
(0,
|
|
41598
|
+
(0, import_node_fs48.writeFileSync)(tmp, `${JSON.stringify(file, null, 2)}
|
|
40366
41599
|
`);
|
|
40367
|
-
(0,
|
|
41600
|
+
(0, import_node_fs48.renameSync)(tmp, path);
|
|
40368
41601
|
return path;
|
|
40369
41602
|
}
|
|
40370
41603
|
function clearDiscoveredCache(dataDir, provider) {
|
|
40371
41604
|
const path = discoveredCachePath(dataDir, provider);
|
|
40372
|
-
if (!(0,
|
|
40373
|
-
(0,
|
|
41605
|
+
if (!(0, import_node_fs48.existsSync)(path)) return false;
|
|
41606
|
+
(0, import_node_fs48.rmSync)(path, { force: true });
|
|
40374
41607
|
return true;
|
|
40375
41608
|
}
|
|
40376
41609
|
function thinkingMapOf(levels) {
|
|
@@ -40424,11 +41657,11 @@ function mergeDiscoveredModels(registry3, dataDir, modelsDev, loginFlavor = () =
|
|
|
40424
41657
|
}
|
|
40425
41658
|
return merged;
|
|
40426
41659
|
}
|
|
40427
|
-
var
|
|
41660
|
+
var import_node_fs48, import_node_path69, DISCOVERED_CACHE_VERSION, EFFORT_LEVELS, SUBSCRIPTION_FALLBACK_CONTEXT_WINDOW, SUBSCRIPTION_PROVIDERS;
|
|
40428
41661
|
var init_discovered_cache = __esm({
|
|
40429
41662
|
"src/ai/providers/discovered-cache.ts"() {
|
|
40430
41663
|
"use strict";
|
|
40431
|
-
|
|
41664
|
+
import_node_fs48 = require("node:fs");
|
|
40432
41665
|
import_node_path69 = require("node:path");
|
|
40433
41666
|
init_catalog2();
|
|
40434
41667
|
init_enrich();
|
|
@@ -42316,7 +43549,7 @@ function parseKeybindings(value) {
|
|
|
42316
43549
|
function loadKeybindingsFile(path) {
|
|
42317
43550
|
let text;
|
|
42318
43551
|
try {
|
|
42319
|
-
text = (0,
|
|
43552
|
+
text = (0, import_node_fs50.readFileSync)(path, "utf8");
|
|
42320
43553
|
} catch (error2) {
|
|
42321
43554
|
if (error2.code === "ENOENT") return { overrides: {}, warnings: [] };
|
|
42322
43555
|
return {
|
|
@@ -42333,12 +43566,12 @@ function loadKeybindingsFile(path) {
|
|
|
42333
43566
|
};
|
|
42334
43567
|
}
|
|
42335
43568
|
}
|
|
42336
|
-
var
|
|
43569
|
+
var import_node_fs50, DEFAULT_KEYBINDINGS, Keybindings, defaultKeybindings;
|
|
42337
43570
|
var init_keybindings = __esm({
|
|
42338
43571
|
"src/tui/keybindings.ts"() {
|
|
42339
43572
|
"use strict";
|
|
42340
43573
|
init_i18n();
|
|
42341
|
-
|
|
43574
|
+
import_node_fs50 = require("node:fs");
|
|
42342
43575
|
init_keys();
|
|
42343
43576
|
DEFAULT_KEYBINDINGS = {
|
|
42344
43577
|
"tui.editor.submit": ["enter"],
|
|
@@ -42486,7 +43719,7 @@ function isBlockStart(line2) {
|
|
|
42486
43719
|
function splitLines2(source) {
|
|
42487
43720
|
return source.replace(/\r\n?/g, "\n").split("\n");
|
|
42488
43721
|
}
|
|
42489
|
-
function parseLines(lines2, from,
|
|
43722
|
+
function parseLines(lines2, from, blocks2, spans) {
|
|
42490
43723
|
let i = from;
|
|
42491
43724
|
while (i < lines2.length) {
|
|
42492
43725
|
const line2 = lines2[i];
|
|
@@ -42495,13 +43728,13 @@ function parseLines(lines2, from, blocks, spans) {
|
|
|
42495
43728
|
continue;
|
|
42496
43729
|
}
|
|
42497
43730
|
const start = i;
|
|
42498
|
-
const before2 =
|
|
42499
|
-
i = parseBlock(lines2, i,
|
|
42500
|
-
for (let k = before2; k <
|
|
43731
|
+
const before2 = blocks2.length;
|
|
43732
|
+
i = parseBlock(lines2, i, blocks2);
|
|
43733
|
+
for (let k = before2; k < blocks2.length; k++) spans.push({ start, end: i });
|
|
42501
43734
|
}
|
|
42502
|
-
return
|
|
43735
|
+
return blocks2;
|
|
42503
43736
|
}
|
|
42504
|
-
function parseBlock(lines2, i,
|
|
43737
|
+
function parseBlock(lines2, i, blocks2) {
|
|
42505
43738
|
const line2 = lines2[i];
|
|
42506
43739
|
const start = i;
|
|
42507
43740
|
const fence2 = FENCE_RE.exec(line2);
|
|
@@ -42512,12 +43745,12 @@ function parseBlock(lines2, i, blocks) {
|
|
|
42512
43745
|
while (i < lines2.length && !lines2[i].trimStart().startsWith(marker)) body2.push(lines2[i++]);
|
|
42513
43746
|
if (i < lines2.length) i++;
|
|
42514
43747
|
const src = lines2.slice(start, i).join("\n");
|
|
42515
|
-
|
|
43748
|
+
blocks2.push({ kind: "code", lang: fence2[2] ?? "", lines: body2, source: src });
|
|
42516
43749
|
return i;
|
|
42517
43750
|
}
|
|
42518
43751
|
const heading = HEADING_RE.exec(line2);
|
|
42519
43752
|
if (heading) {
|
|
42520
|
-
|
|
43753
|
+
blocks2.push({
|
|
42521
43754
|
kind: "heading",
|
|
42522
43755
|
level: heading[1].length,
|
|
42523
43756
|
text: heading[2] ?? "",
|
|
@@ -42527,7 +43760,7 @@ function parseBlock(lines2, i, blocks) {
|
|
|
42527
43760
|
return i;
|
|
42528
43761
|
}
|
|
42529
43762
|
if (HR_RE.test(line2)) {
|
|
42530
|
-
|
|
43763
|
+
blocks2.push({ kind: "hr", source: line2 });
|
|
42531
43764
|
i++;
|
|
42532
43765
|
return i;
|
|
42533
43766
|
}
|
|
@@ -42538,13 +43771,13 @@ function parseBlock(lines2, i, blocks) {
|
|
|
42538
43771
|
if (TABLE_SEP_RE.test(row3)) continue;
|
|
42539
43772
|
rows.push(splitTableRow(row3));
|
|
42540
43773
|
}
|
|
42541
|
-
|
|
43774
|
+
blocks2.push({ kind: "table", rows, source: lines2.slice(start, i).join("\n") });
|
|
42542
43775
|
return i;
|
|
42543
43776
|
}
|
|
42544
43777
|
if (QUOTE_RE.test(line2)) {
|
|
42545
43778
|
const body2 = [];
|
|
42546
43779
|
while (i < lines2.length && QUOTE_RE.test(lines2[i])) body2.push(QUOTE_RE.exec(lines2[i++])[1]);
|
|
42547
|
-
|
|
43780
|
+
blocks2.push({
|
|
42548
43781
|
kind: "quote",
|
|
42549
43782
|
text: body2.join("\n"),
|
|
42550
43783
|
source: lines2.slice(start, i).join("\n")
|
|
@@ -42552,17 +43785,17 @@ function parseBlock(lines2, i, blocks) {
|
|
|
42552
43785
|
return i;
|
|
42553
43786
|
}
|
|
42554
43787
|
if (LIST_RE.test(line2)) {
|
|
42555
|
-
return parseList(lines2, i,
|
|
43788
|
+
return parseList(lines2, i, blocks2);
|
|
42556
43789
|
}
|
|
42557
43790
|
const body = [line2];
|
|
42558
43791
|
i++;
|
|
42559
43792
|
while (i < lines2.length && lines2[i].trim() !== "" && !isBlockStart(lines2[i])) {
|
|
42560
43793
|
body.push(lines2[i++]);
|
|
42561
43794
|
}
|
|
42562
|
-
|
|
43795
|
+
blocks2.push({ kind: "paragraph", text: joinSoftBreaks(body), source: body.join("\n") });
|
|
42563
43796
|
return i;
|
|
42564
43797
|
}
|
|
42565
|
-
function parseList(lines2, start,
|
|
43798
|
+
function parseList(lines2, start, blocks2) {
|
|
42566
43799
|
const items = [];
|
|
42567
43800
|
const indents = [];
|
|
42568
43801
|
let i = start;
|
|
@@ -42589,7 +43822,7 @@ function parseList(lines2, start, blocks) {
|
|
|
42589
43822
|
}
|
|
42590
43823
|
break;
|
|
42591
43824
|
}
|
|
42592
|
-
|
|
43825
|
+
blocks2.push({ kind: "list", items, source: lines2.slice(start, i).join("\n") });
|
|
42593
43826
|
return i;
|
|
42594
43827
|
}
|
|
42595
43828
|
function joinSoftBreaks(lines2) {
|
|
@@ -42609,7 +43842,7 @@ function splitTableRow(row3) {
|
|
|
42609
43842
|
const trimmed = row3.trim().replace(/^\|/, "").replace(/\|$/, "");
|
|
42610
43843
|
return trimmed.split(/(?<!\\)\|/).map((cell) => cell.trim().replace(/\\\|/g, "|"));
|
|
42611
43844
|
}
|
|
42612
|
-
function
|
|
43845
|
+
function renderInline2(text, theme) {
|
|
42613
43846
|
let out = "";
|
|
42614
43847
|
let i = 0;
|
|
42615
43848
|
while (i < text.length) {
|
|
@@ -42630,7 +43863,7 @@ function renderInline(text, theme) {
|
|
|
42630
43863
|
}
|
|
42631
43864
|
const emphasis = matchDelimited(text, i, ["**", "__", "~~", "*", "_"]);
|
|
42632
43865
|
if (emphasis) {
|
|
42633
|
-
const inner =
|
|
43866
|
+
const inner = renderInline2(emphasis.inner, theme);
|
|
42634
43867
|
if (emphasis.delim === "**" || emphasis.delim === "__") out += theme.bold(inner);
|
|
42635
43868
|
else if (emphasis.delim === "~~") out += `\x1B[9m${inner}\x1B[29m`;
|
|
42636
43869
|
else out += theme.italic(inner);
|
|
@@ -42640,7 +43873,7 @@ function renderInline(text, theme) {
|
|
|
42640
43873
|
if (ch2 === "[") {
|
|
42641
43874
|
const link = /^\[([^\]]*)\]\(([^)\s]*)(?:\s+"[^"]*")?\)/.exec(text.slice(i));
|
|
42642
43875
|
if (link) {
|
|
42643
|
-
const label2 =
|
|
43876
|
+
const label2 = renderInline2(link[1], theme);
|
|
42644
43877
|
const url = link[2];
|
|
42645
43878
|
out += link[1] === url || url === "" ? theme.fg("link", theme.underline(label2 || url)) : theme.fg("link", theme.underline(label2)) + theme.fg("dim", ` (${url})`);
|
|
42646
43879
|
i += link[0].length;
|
|
@@ -42685,31 +43918,31 @@ function matchDelimited(text, i, delims) {
|
|
|
42685
43918
|
}
|
|
42686
43919
|
return null;
|
|
42687
43920
|
}
|
|
42688
|
-
function
|
|
43921
|
+
function renderBlock2(block, width2, theme) {
|
|
42689
43922
|
switch (block.kind) {
|
|
42690
43923
|
case "heading": {
|
|
42691
|
-
const text =
|
|
43924
|
+
const text = renderInline2(block.text, theme);
|
|
42692
43925
|
const styled = block.level <= 2 ? theme.fg("accent", theme.bold(text)) : theme.fg("text", theme.bold(text));
|
|
42693
43926
|
return wrapTextWithAnsi(styled, width2);
|
|
42694
43927
|
}
|
|
42695
43928
|
case "paragraph":
|
|
42696
|
-
return wrapTextWithAnsi(
|
|
43929
|
+
return wrapTextWithAnsi(renderInline2(block.text, theme), width2);
|
|
42697
43930
|
case "hr":
|
|
42698
43931
|
return [theme.fg("border", theme.glyphs.rule.repeat(Math.max(1, width2)))];
|
|
42699
43932
|
case "quote": {
|
|
42700
43933
|
const bar = theme.fg("border", theme.glyphs.card) + " ";
|
|
42701
|
-
const body = theme.fg("muted", theme.italic(
|
|
43934
|
+
const body = theme.fg("muted", theme.italic(renderInline2(block.text, theme)));
|
|
42702
43935
|
return wrapTextWithAnsi(body, Math.max(1, width2 - 2)).map((line2) => bar + line2);
|
|
42703
43936
|
}
|
|
42704
43937
|
case "list":
|
|
42705
|
-
return
|
|
43938
|
+
return renderList2(block.items, width2, theme);
|
|
42706
43939
|
case "code":
|
|
42707
43940
|
return renderCode(block.lang, block.lines, width2, theme);
|
|
42708
43941
|
case "table":
|
|
42709
|
-
return
|
|
43942
|
+
return renderTable2(block.rows, width2, theme);
|
|
42710
43943
|
}
|
|
42711
43944
|
}
|
|
42712
|
-
function
|
|
43945
|
+
function renderList2(items, width2, theme) {
|
|
42713
43946
|
const lines2 = [];
|
|
42714
43947
|
const bullets = theme.glyphs.bullets;
|
|
42715
43948
|
const columns = [];
|
|
@@ -42726,7 +43959,7 @@ function renderList(items, width2, theme) {
|
|
|
42726
43959
|
unordered.length = depth;
|
|
42727
43960
|
columns.push(headWidth);
|
|
42728
43961
|
unordered.push(level);
|
|
42729
|
-
const body = wrapTextWithAnsi(
|
|
43962
|
+
const body = wrapTextWithAnsi(renderInline2(item.text, theme), Math.max(1, width2 - headWidth));
|
|
42730
43963
|
body.forEach((line2, index2) => {
|
|
42731
43964
|
lines2.push((index2 === 0 ? head : " ".repeat(headWidth)) + line2);
|
|
42732
43965
|
});
|
|
@@ -42770,10 +44003,10 @@ function wrapCode(line2, width2) {
|
|
|
42770
44003
|
out.push(current3);
|
|
42771
44004
|
return out;
|
|
42772
44005
|
}
|
|
42773
|
-
function
|
|
44006
|
+
function renderTable2(rows, width2, theme) {
|
|
42774
44007
|
const cols = Math.max(0, ...rows.map((r) => r.length));
|
|
42775
44008
|
const widths = new Array(cols).fill(0);
|
|
42776
|
-
const rendered = rows.map((row3) => row3.map((cell) =>
|
|
44009
|
+
const rendered = rows.map((row3) => row3.map((cell) => renderInline2(cell, theme)));
|
|
42777
44010
|
for (const row3 of rendered) {
|
|
42778
44011
|
row3.forEach((cell, c) => widths[c] = Math.max(widths[c], visibleWidth(cell)));
|
|
42779
44012
|
}
|
|
@@ -42887,7 +44120,7 @@ var init_markdown = __esm({
|
|
|
42887
44120
|
used.add(key);
|
|
42888
44121
|
let rendered = this.blockCache.get(key);
|
|
42889
44122
|
if (!rendered) {
|
|
42890
|
-
rendered =
|
|
44123
|
+
rendered = renderBlock2(block, inner, this.theme).map((line2) => pad3 + line2);
|
|
42891
44124
|
this.blockCache.set(key, rendered);
|
|
42892
44125
|
}
|
|
42893
44126
|
if (index2 > 0) lines2.push("");
|
|
@@ -43175,7 +44408,7 @@ var init_editor_buffer = __esm({
|
|
|
43175
44408
|
function loadHistoryFile(path, limit = 500) {
|
|
43176
44409
|
let text;
|
|
43177
44410
|
try {
|
|
43178
|
-
text = (0,
|
|
44411
|
+
text = (0, import_node_fs51.readFileSync)(path, "utf8");
|
|
43179
44412
|
} catch {
|
|
43180
44413
|
return [];
|
|
43181
44414
|
}
|
|
@@ -43192,11 +44425,11 @@ function loadHistoryFile(path, limit = 500) {
|
|
|
43192
44425
|
}
|
|
43193
44426
|
function appendHistoryFile(path, entry, limit) {
|
|
43194
44427
|
try {
|
|
43195
|
-
(0,
|
|
43196
|
-
(0,
|
|
44428
|
+
(0, import_node_fs51.mkdirSync)((0, import_node_path71.dirname)(path), { recursive: true });
|
|
44429
|
+
(0, import_node_fs51.appendFileSync)(path, JSON.stringify(entry) + "\n", { mode: 384 });
|
|
43197
44430
|
const all = loadHistoryFile(path, Number.MAX_SAFE_INTEGER);
|
|
43198
44431
|
if (all.length > limit * 2) {
|
|
43199
|
-
(0,
|
|
44432
|
+
(0, import_node_fs51.writeFileSync)(
|
|
43200
44433
|
path,
|
|
43201
44434
|
all.slice(-limit).map((e) => JSON.stringify(e) + "\n").join("")
|
|
43202
44435
|
);
|
|
@@ -43204,11 +44437,11 @@ function appendHistoryFile(path, entry, limit) {
|
|
|
43204
44437
|
} catch {
|
|
43205
44438
|
}
|
|
43206
44439
|
}
|
|
43207
|
-
var
|
|
44440
|
+
var import_node_fs51, import_node_path71;
|
|
43208
44441
|
var init_editor_history = __esm({
|
|
43209
44442
|
"src/tui/components/editor-history.ts"() {
|
|
43210
44443
|
"use strict";
|
|
43211
|
-
|
|
44444
|
+
import_node_fs51 = require("node:fs");
|
|
43212
44445
|
import_node_path71 = require("node:path");
|
|
43213
44446
|
}
|
|
43214
44447
|
});
|
|
@@ -43347,11 +44580,11 @@ var init_select_list = __esm({
|
|
|
43347
44580
|
this.setSelectedIndex(index2);
|
|
43348
44581
|
return true;
|
|
43349
44582
|
}
|
|
43350
|
-
moveSelection(delta,
|
|
44583
|
+
moveSelection(delta, wrap3 = true) {
|
|
43351
44584
|
const n = this.filtered.length;
|
|
43352
44585
|
if (n === 0) return;
|
|
43353
44586
|
let next = this.selected + delta;
|
|
43354
|
-
if (
|
|
44587
|
+
if (wrap3 && Math.abs(delta) === 1) next = (next + n) % n;
|
|
43355
44588
|
this.setSelectedIndex(next);
|
|
43356
44589
|
}
|
|
43357
44590
|
handleInput(data2) {
|
|
@@ -44244,14 +45477,14 @@ var init_key_value = __esm({
|
|
|
44244
45477
|
const keyWidth = Math.min(longest, Math.max(share, MIN_KEY_WIDTH));
|
|
44245
45478
|
const valueWidth = width2 - keyWidth - gap;
|
|
44246
45479
|
const { theme, keyColor = "dim" } = this.options;
|
|
44247
|
-
const
|
|
45480
|
+
const wrap3 = this.options.wrap === true;
|
|
44248
45481
|
const lines2 = this.rows.flatMap(({ key, value }) => {
|
|
44249
45482
|
if (key === "" && value === "") return [""];
|
|
44250
45483
|
const shownKey = truncateToWidth(key, Math.max(keyWidth, 1));
|
|
44251
45484
|
const styledKey = theme ? theme.fg(keyColor, shownKey) : shownKey;
|
|
44252
45485
|
if (valueWidth < 1) return [truncateToWidth(styledKey, width2)];
|
|
44253
45486
|
const head = padToWidth(styledKey, keyWidth) + " ".repeat(gap);
|
|
44254
|
-
if (!
|
|
45487
|
+
if (!wrap3) {
|
|
44255
45488
|
const flat2 = value.replace(/\r?\n/g, " ⏎ ");
|
|
44256
45489
|
return [head + truncateToWidth(flat2, valueWidth)];
|
|
44257
45490
|
}
|
|
@@ -44648,22 +45881,22 @@ function toolDeclaration(tool, options = {}) {
|
|
|
44648
45881
|
}
|
|
44649
45882
|
function buildDeclarationBlock(tools, inlineBudget = DEFAULT_INLINE_BUDGET) {
|
|
44650
45883
|
const sorted = [...tools].sort((a, b) => a.tool.name < b.tool.name ? -1 : 1);
|
|
44651
|
-
const
|
|
45884
|
+
const inline2 = [];
|
|
44652
45885
|
const namesOnly = [];
|
|
44653
45886
|
let used = 0;
|
|
44654
45887
|
for (const { tool, textResult } of sorted) {
|
|
44655
45888
|
const decl = toolDeclaration(tool, textResult === false ? { textResult } : {});
|
|
44656
45889
|
const cost2 = estimateTokens2(decl);
|
|
44657
45890
|
if (namesOnly.length === 0 && used + cost2 <= inlineBudget) {
|
|
44658
|
-
|
|
45891
|
+
inline2.push(decl);
|
|
44659
45892
|
used += cost2;
|
|
44660
45893
|
} else namesOnly.push(tool.name);
|
|
44661
45894
|
}
|
|
44662
45895
|
const parts = [];
|
|
44663
45896
|
if (sorted.some(({ tool }) => tool.name === "bash")) parts.push(BASH_RESULT_DECLARATION);
|
|
44664
|
-
if (
|
|
45897
|
+
if (inline2.length > 0) {
|
|
44665
45898
|
parts.push(`declare const tools: {
|
|
44666
|
-
${indent(
|
|
45899
|
+
${indent(inline2.join("\n"))}
|
|
44667
45900
|
};`);
|
|
44668
45901
|
}
|
|
44669
45902
|
if (namesOnly.length > 0) {
|
|
@@ -44671,7 +45904,7 @@ ${indent(inline.join("\n"))}
|
|
|
44671
45904
|
`// Also callable (use describeTool(name) for the signature): ${namesOnly.join(", ")}`
|
|
44672
45905
|
);
|
|
44673
45906
|
}
|
|
44674
|
-
return { inline, namesOnly, text: parts.join("\n") };
|
|
45907
|
+
return { inline: inline2, namesOnly, text: parts.join("\n") };
|
|
44675
45908
|
}
|
|
44676
45909
|
function indent(text) {
|
|
44677
45910
|
return text.split("\n").map((line2) => line2 === "" ? line2 : ` ${line2}`).join("\n");
|
|
@@ -44791,7 +46024,7 @@ function modelsDevUrl(env = process.env) {
|
|
|
44791
46024
|
}
|
|
44792
46025
|
function readModelsDevCache(dataDir) {
|
|
44793
46026
|
try {
|
|
44794
|
-
const value = JSON.parse((0,
|
|
46027
|
+
const value = JSON.parse((0, import_node_fs52.readFileSync)(modelsDevCachePath(dataDir), "utf8"));
|
|
44795
46028
|
if (typeof value !== "object" || value === null) return void 0;
|
|
44796
46029
|
const file = value;
|
|
44797
46030
|
if (file.version !== 2 || typeof file.fetchedAt !== "string") return void 0;
|
|
@@ -44804,10 +46037,10 @@ function readModelsDevCache(dataDir) {
|
|
|
44804
46037
|
}
|
|
44805
46038
|
function writeModelsDevCache(dataDir, file) {
|
|
44806
46039
|
const path = modelsDevCachePath(dataDir);
|
|
44807
|
-
(0,
|
|
46040
|
+
(0, import_node_fs52.mkdirSync)((0, import_node_path73.dirname)(path), { recursive: true, mode: 448 });
|
|
44808
46041
|
const tmp = `${path}.${process.pid}.tmp`;
|
|
44809
|
-
(0,
|
|
44810
|
-
(0,
|
|
46042
|
+
(0, import_node_fs52.writeFileSync)(tmp, JSON.stringify(file));
|
|
46043
|
+
(0, import_node_fs52.renameSync)(tmp, path);
|
|
44811
46044
|
memo = void 0;
|
|
44812
46045
|
}
|
|
44813
46046
|
function overrideApplies(file) {
|
|
@@ -44817,7 +46050,7 @@ function loadModelsDevIndex(dataDir) {
|
|
|
44817
46050
|
const path = modelsDevCachePath(dataDir);
|
|
44818
46051
|
let key;
|
|
44819
46052
|
try {
|
|
44820
|
-
const stat16 = (0,
|
|
46053
|
+
const stat16 = (0, import_node_fs52.statSync)(path);
|
|
44821
46054
|
key = `${path}\0${stat16.mtimeMs}\0${stat16.size}`;
|
|
44822
46055
|
} catch {
|
|
44823
46056
|
return builtinSnapshotIndex();
|
|
@@ -44839,7 +46072,7 @@ async function refreshModelsDev(options) {
|
|
|
44839
46072
|
const url = modelsDevUrl(options.env);
|
|
44840
46073
|
const now = options.now ?? Date.now;
|
|
44841
46074
|
const before2 = loadModelsDevIndex(options.dataDir);
|
|
44842
|
-
const
|
|
46075
|
+
const fail7 = (reason) => ({
|
|
44843
46076
|
status: "failed",
|
|
44844
46077
|
url,
|
|
44845
46078
|
index: before2,
|
|
@@ -44848,7 +46081,7 @@ async function refreshModelsDev(options) {
|
|
|
44848
46081
|
const list5 = snapshotList();
|
|
44849
46082
|
const unknown = (options.providers ?? []).filter((p) => !list5.providers.includes(p));
|
|
44850
46083
|
if (unknown.length > 0)
|
|
44851
|
-
return
|
|
46084
|
+
return fail7(msg().errors.models.notListed(unknown.join(", "), list5.providers.join(", ")));
|
|
44852
46085
|
let fresh;
|
|
44853
46086
|
try {
|
|
44854
46087
|
const response = await (options.fetch ?? fetch)(url, {
|
|
@@ -44858,7 +46091,7 @@ async function refreshModelsDev(options) {
|
|
|
44858
46091
|
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
|
44859
46092
|
fresh = buildSnapshot(await response.json(), list5, options.providers);
|
|
44860
46093
|
} catch (error2) {
|
|
44861
|
-
return
|
|
46094
|
+
return fail7(error2 instanceof Error ? error2.message : String(error2));
|
|
44862
46095
|
}
|
|
44863
46096
|
const fetchedAt = new Date(now()).toISOString();
|
|
44864
46097
|
const previous = readModelsDevCache(options.dataDir);
|
|
@@ -44902,11 +46135,11 @@ function describeRefresh(result, limit = 20) {
|
|
|
44902
46135
|
}
|
|
44903
46136
|
return lines2.join("\n");
|
|
44904
46137
|
}
|
|
44905
|
-
var
|
|
46138
|
+
var import_node_fs52, import_node_path73, MODELS_DEV_URL, MODELS_DEV_URL_ENV, MODELS_DEV_FILE, MODELS_DEV_TIMEOUT_MS, memo;
|
|
44906
46139
|
var init_models_dev_cache = __esm({
|
|
44907
46140
|
"src/ai/providers/models-dev-cache.ts"() {
|
|
44908
46141
|
"use strict";
|
|
44909
|
-
|
|
46142
|
+
import_node_fs52 = require("node:fs");
|
|
44910
46143
|
import_node_path73 = require("node:path");
|
|
44911
46144
|
init_models_dev();
|
|
44912
46145
|
init_models_dev_snapshot();
|
|
@@ -45252,40 +46485,40 @@ function minimalConfig() {
|
|
|
45252
46485
|
}
|
|
45253
46486
|
function writeAtomic2(path, text, mode) {
|
|
45254
46487
|
const tmp = `${path}.${process.pid}.tmp`;
|
|
45255
|
-
(0,
|
|
45256
|
-
(0,
|
|
46488
|
+
(0, import_node_fs53.writeFileSync)(tmp, text, { mode });
|
|
46489
|
+
(0, import_node_fs53.renameSync)(tmp, path);
|
|
45257
46490
|
}
|
|
45258
46491
|
function initConfigDir(dir, options = {}) {
|
|
45259
|
-
const dirCreated = !(0,
|
|
45260
|
-
(0,
|
|
45261
|
-
if (dirCreated && process.platform !== "win32") (0,
|
|
46492
|
+
const dirCreated = !(0, import_node_fs53.existsSync)(dir);
|
|
46493
|
+
(0, import_node_fs53.mkdirSync)(dir, { recursive: true, mode: 448 });
|
|
46494
|
+
if (dirCreated && process.platform !== "win32") (0, import_node_fs53.chmodSync)(dir, 448);
|
|
45262
46495
|
const files = [];
|
|
45263
46496
|
const config = (0, import_node_path74.join)(dir, CONFIG_FILE);
|
|
45264
46497
|
const text = `${JSON.stringify(minimalConfig(), null, 2)}
|
|
45265
46498
|
`;
|
|
45266
|
-
if (!(0,
|
|
46499
|
+
if (!(0, import_node_fs53.existsSync)(config)) {
|
|
45267
46500
|
writeAtomic2(config, text, 420);
|
|
45268
46501
|
files.push({ path: config, status: "created" });
|
|
45269
46502
|
} else if (options.force) {
|
|
45270
|
-
(0,
|
|
46503
|
+
(0, import_node_fs53.copyFileSync)(config, `${config}.bak`);
|
|
45271
46504
|
writeAtomic2(config, text, 420);
|
|
45272
46505
|
files.push({ path: config, status: "overwritten" });
|
|
45273
46506
|
} else files.push({ path: config, status: "exists" });
|
|
45274
46507
|
const schema = (0, import_node_path74.join)(dir, CONFIG_SCHEMA_FILE);
|
|
45275
46508
|
const schemaText = configSchemaText();
|
|
45276
|
-
if (!(0,
|
|
46509
|
+
if (!(0, import_node_fs53.existsSync)(schema)) {
|
|
45277
46510
|
writeAtomic2(schema, schemaText, 420);
|
|
45278
46511
|
files.push({ path: schema, status: "created" });
|
|
45279
|
-
} else if ((0,
|
|
46512
|
+
} else if ((0, import_node_fs53.readFileSync)(schema, "utf8") !== schemaText) {
|
|
45280
46513
|
writeAtomic2(schema, schemaText, 420);
|
|
45281
46514
|
files.push({ path: schema, status: "updated" });
|
|
45282
46515
|
} else files.push({ path: schema, status: "unchanged" });
|
|
45283
46516
|
const auth = (0, import_node_path74.join)(dir, AUTH_FILE);
|
|
45284
|
-
if ((0,
|
|
46517
|
+
if ((0, import_node_fs53.existsSync)(auth)) files.push({ path: auth, status: "exists" });
|
|
45285
46518
|
return { dir, dirCreated, files };
|
|
45286
46519
|
}
|
|
45287
46520
|
function autoInitConfigDir(dir, env) {
|
|
45288
|
-
if (env[NO_INIT_ENV] === "1" || (0,
|
|
46521
|
+
if (env[NO_INIT_ENV] === "1" || (0, import_node_fs53.existsSync)(dir)) return false;
|
|
45289
46522
|
try {
|
|
45290
46523
|
initConfigDir(dir);
|
|
45291
46524
|
return true;
|
|
@@ -45303,11 +46536,11 @@ function describeInit(result) {
|
|
|
45303
46536
|
return `${lines2.join("\n")}
|
|
45304
46537
|
`;
|
|
45305
46538
|
}
|
|
45306
|
-
var
|
|
46539
|
+
var import_node_fs53, import_node_path74, NO_INIT_ENV;
|
|
45307
46540
|
var init_init = __esm({
|
|
45308
46541
|
"src/config/init.ts"() {
|
|
45309
46542
|
"use strict";
|
|
45310
|
-
|
|
46543
|
+
import_node_fs53 = require("node:fs");
|
|
45311
46544
|
import_node_path74 = require("node:path");
|
|
45312
46545
|
init_i18n();
|
|
45313
46546
|
init_json_schema();
|
|
@@ -45551,13 +46784,13 @@ function normalizeToolId(id) {
|
|
|
45551
46784
|
return cleaned.length > 0 ? cleaned : "tool_call";
|
|
45552
46785
|
}
|
|
45553
46786
|
function convertBlocks(content) {
|
|
45554
|
-
const
|
|
46787
|
+
const blocks2 = [];
|
|
45555
46788
|
for (const block of content) {
|
|
45556
46789
|
if (block.type === "text") {
|
|
45557
46790
|
if (block.text.trim().length > 0)
|
|
45558
|
-
|
|
46791
|
+
blocks2.push({ type: "text", text: sanitizeText(block.text) });
|
|
45559
46792
|
} else {
|
|
45560
|
-
|
|
46793
|
+
blocks2.push({
|
|
45561
46794
|
type: "image",
|
|
45562
46795
|
source: {
|
|
45563
46796
|
type: "base64",
|
|
@@ -45567,33 +46800,33 @@ function convertBlocks(content) {
|
|
|
45567
46800
|
});
|
|
45568
46801
|
}
|
|
45569
46802
|
}
|
|
45570
|
-
return
|
|
46803
|
+
return blocks2;
|
|
45571
46804
|
}
|
|
45572
46805
|
function convertUser(message) {
|
|
45573
46806
|
if (typeof message.content === "string") {
|
|
45574
46807
|
if (message.content.trim().length === 0) return void 0;
|
|
45575
46808
|
return { role: "user", content: sanitizeText(message.content) };
|
|
45576
46809
|
}
|
|
45577
|
-
const
|
|
45578
|
-
return
|
|
46810
|
+
const blocks2 = convertBlocks(message.content);
|
|
46811
|
+
return blocks2.length > 0 ? { role: "user", content: blocks2 } : void 0;
|
|
45579
46812
|
}
|
|
45580
46813
|
function convertAssistant(message) {
|
|
45581
|
-
const
|
|
46814
|
+
const blocks2 = [];
|
|
45582
46815
|
for (const block of message.content) {
|
|
45583
46816
|
if (block.type === "text") {
|
|
45584
46817
|
if (block.text.trim().length > 0)
|
|
45585
|
-
|
|
46818
|
+
blocks2.push({ type: "text", text: sanitizeText(block.text) });
|
|
45586
46819
|
} else if (block.type === "thinking") {
|
|
45587
46820
|
const signature2 = block.thinkingSignature ?? "";
|
|
45588
46821
|
if (block.redacted && signature2) {
|
|
45589
|
-
|
|
46822
|
+
blocks2.push({ type: "redacted_thinking", data: signature2 });
|
|
45590
46823
|
} else if (signature2.trim().length > 0) {
|
|
45591
|
-
|
|
46824
|
+
blocks2.push({ type: "thinking", thinking: sanitizeText(block.thinking), signature: signature2 });
|
|
45592
46825
|
} else if (block.thinking.trim().length > 0) {
|
|
45593
|
-
|
|
46826
|
+
blocks2.push({ type: "text", text: sanitizeText(block.thinking) });
|
|
45594
46827
|
}
|
|
45595
46828
|
} else {
|
|
45596
|
-
|
|
46829
|
+
blocks2.push({
|
|
45597
46830
|
type: "tool_use",
|
|
45598
46831
|
id: normalizeToolId(block.id),
|
|
45599
46832
|
name: block.name,
|
|
@@ -45601,7 +46834,7 @@ function convertAssistant(message) {
|
|
|
45601
46834
|
});
|
|
45602
46835
|
}
|
|
45603
46836
|
}
|
|
45604
|
-
return
|
|
46837
|
+
return blocks2.length > 0 ? { role: "assistant", content: blocks2 } : void 0;
|
|
45605
46838
|
}
|
|
45606
46839
|
function convertToolResult(message) {
|
|
45607
46840
|
const content = typeof message.content === "string" || !message.content.some((b) => b.type === "image") ? sanitizeText(contentText2(message.content)) : convertBlocks(message.content);
|
|
@@ -46464,8 +47697,8 @@ function convertToolResults(model, results, compat) {
|
|
|
46464
47697
|
const images = [];
|
|
46465
47698
|
for (const result of results) {
|
|
46466
47699
|
const text = contentText2(result.content);
|
|
46467
|
-
const
|
|
46468
|
-
const hasImages2 =
|
|
47700
|
+
const blocks2 = typeof result.content === "string" ? [] : result.content;
|
|
47701
|
+
const hasImages2 = blocks2.some((b) => b.type === "image");
|
|
46469
47702
|
const message = {
|
|
46470
47703
|
role: "tool",
|
|
46471
47704
|
tool_call_id: normalizeCallId(model, result.toolCallId),
|
|
@@ -46476,7 +47709,7 @@ function convertToolResults(model, results, compat) {
|
|
|
46476
47709
|
if (compat.requiresToolResultName) message["name"] = result.toolName;
|
|
46477
47710
|
messages.push(message);
|
|
46478
47711
|
if (hasImages2 && model.input.includes("image")) {
|
|
46479
|
-
for (const block of
|
|
47712
|
+
for (const block of blocks2) if (block.type === "image") images.push(imagePart(block));
|
|
46480
47713
|
}
|
|
46481
47714
|
}
|
|
46482
47715
|
return { messages, images };
|
|
@@ -46726,9 +47959,9 @@ function imagePart2(block) {
|
|
|
46726
47959
|
};
|
|
46727
47960
|
}
|
|
46728
47961
|
function convertUser4(message) {
|
|
46729
|
-
const
|
|
47962
|
+
const blocks2 = typeof message.content === "string" ? [{ type: "text", text: message.content }] : message.content;
|
|
46730
47963
|
const content = [];
|
|
46731
|
-
for (const block of
|
|
47964
|
+
for (const block of blocks2) {
|
|
46732
47965
|
if (block.type === "image") content.push(imagePart2(block));
|
|
46733
47966
|
else if (block.text.length > 0) {
|
|
46734
47967
|
content.push({ type: "input_text", text: sanitizeText(block.text) });
|
|
@@ -47982,12 +49215,12 @@ function handleChunk2(chunk, state, tracker) {
|
|
|
47982
49215
|
}
|
|
47983
49216
|
const usage = obj6(chunk["usageMetadata"]);
|
|
47984
49217
|
if (usage) output.usage = parseGoogleUsage(usage);
|
|
47985
|
-
const
|
|
49218
|
+
const blocked3 = str7(obj6(chunk["promptFeedback"])?.["blockReason"]);
|
|
47986
49219
|
const candidates2 = Array.isArray(chunk["candidates"]) ? chunk["candidates"] : [];
|
|
47987
49220
|
const candidate = obj6(candidates2[0]);
|
|
47988
|
-
if (!candidate &&
|
|
47989
|
-
output.rawStopReason =
|
|
47990
|
-
throw new ProviderStopError(`Prompt blocked: ${
|
|
49221
|
+
if (!candidate && blocked3) {
|
|
49222
|
+
output.rawStopReason = blocked3;
|
|
49223
|
+
throw new ProviderStopError(`Prompt blocked: ${blocked3}`);
|
|
47991
49224
|
}
|
|
47992
49225
|
const parts = obj6(candidate?.["content"])?.["parts"];
|
|
47993
49226
|
if (Array.isArray(parts)) {
|
|
@@ -48198,7 +49431,7 @@ function defaultConfigDir(env = process.env) {
|
|
|
48198
49431
|
function readAuthFile2(path, onWarning) {
|
|
48199
49432
|
let raw;
|
|
48200
49433
|
try {
|
|
48201
|
-
raw = (0,
|
|
49434
|
+
raw = (0, import_node_fs54.readFileSync)(path, "utf8");
|
|
48202
49435
|
} catch (error2) {
|
|
48203
49436
|
const code = error2.code;
|
|
48204
49437
|
if (code !== "ENOENT") onWarning?.(`cannot read auth file ${path}`);
|
|
@@ -48206,7 +49439,7 @@ function readAuthFile2(path, onWarning) {
|
|
|
48206
49439
|
}
|
|
48207
49440
|
if (process.platform !== "win32") {
|
|
48208
49441
|
try {
|
|
48209
|
-
const mode = (0,
|
|
49442
|
+
const mode = (0, import_node_fs54.statSync)(path).mode & 511;
|
|
48210
49443
|
if ((mode & 63) !== 0) {
|
|
48211
49444
|
onWarning?.(
|
|
48212
49445
|
`auth file ${path} has permissions ${mode.toString(8).padStart(4, "0")}; expected 0600`
|
|
@@ -48240,12 +49473,12 @@ function expandEnvRefs(value, env) {
|
|
|
48240
49473
|
);
|
|
48241
49474
|
return missing || out.length === 0 ? void 0 : out;
|
|
48242
49475
|
}
|
|
48243
|
-
var import_node_child_process13,
|
|
49476
|
+
var import_node_child_process13, import_node_fs54, import_node_os12, import_node_path75, ApiKeyResolver;
|
|
48244
49477
|
var init_auth2 = __esm({
|
|
48245
49478
|
"src/ai/providers/auth.ts"() {
|
|
48246
49479
|
"use strict";
|
|
48247
49480
|
import_node_child_process13 = require("node:child_process");
|
|
48248
|
-
|
|
49481
|
+
import_node_fs54 = require("node:fs");
|
|
48249
49482
|
import_node_os12 = require("node:os");
|
|
48250
49483
|
import_node_path75 = require("node:path");
|
|
48251
49484
|
init_live();
|
|
@@ -49033,25 +50266,25 @@ var init_settings_registry = __esm({
|
|
|
49033
50266
|
|
|
49034
50267
|
// src/config/write.ts
|
|
49035
50268
|
function writeConfigFile(path, config, options = {}) {
|
|
49036
|
-
(0,
|
|
50269
|
+
(0, import_node_fs55.mkdirSync)((0, import_node_path77.dirname)(path), { recursive: true });
|
|
49037
50270
|
let mode;
|
|
49038
50271
|
try {
|
|
49039
|
-
mode = (0,
|
|
50272
|
+
mode = (0, import_node_fs55.statSync)(path).mode & 511;
|
|
49040
50273
|
} catch {
|
|
49041
50274
|
mode = void 0;
|
|
49042
50275
|
}
|
|
49043
|
-
if (mode !== void 0 && options.backup !== false) (0,
|
|
50276
|
+
if (mode !== void 0 && options.backup !== false) (0, import_node_fs55.copyFileSync)(path, `${path}.bak`);
|
|
49044
50277
|
const tmp = `${path}.${process.pid}.tmp`;
|
|
49045
|
-
(0,
|
|
50278
|
+
(0, import_node_fs55.writeFileSync)(tmp, `${JSON.stringify(config, null, 2)}
|
|
49046
50279
|
`, { mode: mode ?? 420 });
|
|
49047
|
-
if (mode !== void 0) (0,
|
|
49048
|
-
(0,
|
|
50280
|
+
if (mode !== void 0) (0, import_node_fs55.chmodSync)(tmp, mode);
|
|
50281
|
+
(0, import_node_fs55.renameSync)(tmp, path);
|
|
49049
50282
|
}
|
|
49050
|
-
var
|
|
50283
|
+
var import_node_fs55, import_node_path77;
|
|
49051
50284
|
var init_write2 = __esm({
|
|
49052
50285
|
"src/config/write.ts"() {
|
|
49053
50286
|
"use strict";
|
|
49054
|
-
|
|
50287
|
+
import_node_fs55 = require("node:fs");
|
|
49055
50288
|
import_node_path77 = require("node:path");
|
|
49056
50289
|
}
|
|
49057
50290
|
});
|
|
@@ -49250,7 +50483,7 @@ function parseEnum(key, text, options) {
|
|
|
49250
50483
|
function readTarget(path, scope) {
|
|
49251
50484
|
let text;
|
|
49252
50485
|
try {
|
|
49253
|
-
text = (0,
|
|
50486
|
+
text = (0, import_node_fs56.readFileSync)(path, "utf8");
|
|
49254
50487
|
} catch (error2) {
|
|
49255
50488
|
if (error2.code === "ENOENT")
|
|
49256
50489
|
return scope === "user" ? minimalConfig() : { version: CONFIG_FILE_VERSION };
|
|
@@ -49332,11 +50565,11 @@ function formatSettingValue(value) {
|
|
|
49332
50565
|
if (typeof value === "string") return value;
|
|
49333
50566
|
return JSON.stringify(value);
|
|
49334
50567
|
}
|
|
49335
|
-
var
|
|
50568
|
+
var import_node_fs56, ConfigEditError, same, ABOVE, TRUE, FALSE, UNSET;
|
|
49336
50569
|
var init_edit2 = __esm({
|
|
49337
50570
|
"src/config/edit.ts"() {
|
|
49338
50571
|
"use strict";
|
|
49339
|
-
|
|
50572
|
+
import_node_fs56 = require("node:fs");
|
|
49340
50573
|
init_errors();
|
|
49341
50574
|
init_i18n();
|
|
49342
50575
|
init_init();
|
|
@@ -49416,7 +50649,7 @@ async function readClipboardImage(dataDir, deps = {}) {
|
|
|
49416
50649
|
await (0, import_promises22.mkdir)(dir, { recursive: true });
|
|
49417
50650
|
const stamp = new Date((deps.now ?? Date.now)()).toISOString().replace(/[:.]/g, "-");
|
|
49418
50651
|
let file = (0, import_node_path80.join)(dir, `${stamp}.png`);
|
|
49419
|
-
for (let n = 1; (0,
|
|
50652
|
+
for (let n = 1; (0, import_node_fs62.existsSync)(file); n++) file = (0, import_node_path80.join)(dir, `${stamp}-${n}.png`);
|
|
49420
50653
|
let anyTool = false;
|
|
49421
50654
|
for (const attempt of attempts(platform, file, env)) {
|
|
49422
50655
|
const options = attempt.via === "file" && attempt.env !== void 0 ? { env: attempt.env } : {};
|
|
@@ -49456,11 +50689,11 @@ async function gcClipboardImages(dataDir, options = {}) {
|
|
|
49456
50689
|
}
|
|
49457
50690
|
return removed;
|
|
49458
50691
|
}
|
|
49459
|
-
var
|
|
50692
|
+
var import_node_fs62, import_promises22, import_node_path80, CLIPBOARD_DIR, CLIPBOARD_MAX_AGE_DAYS, OSASCRIPT, POWERSHELL;
|
|
49460
50693
|
var init_clipboard_image = __esm({
|
|
49461
50694
|
"src/tools/clipboard-image.ts"() {
|
|
49462
50695
|
"use strict";
|
|
49463
|
-
|
|
50696
|
+
import_node_fs62 = require("node:fs");
|
|
49464
50697
|
import_promises22 = require("node:fs/promises");
|
|
49465
50698
|
import_node_path80 = require("node:path");
|
|
49466
50699
|
init_image_file();
|
|
@@ -51175,6 +52408,8 @@ function toolSummary(name, args, cwd) {
|
|
|
51175
52408
|
}
|
|
51176
52409
|
case "task":
|
|
51177
52410
|
return flat(str8("description") ?? str8("prompt") ?? "");
|
|
52411
|
+
case "web_fetch":
|
|
52412
|
+
return flat((str8("url") ?? "").replace(/^https?:\/\//i, ""));
|
|
51178
52413
|
default:
|
|
51179
52414
|
if (path !== void 0) return displayPath2(path, cwd);
|
|
51180
52415
|
for (const key of [
|
|
@@ -51302,10 +52537,28 @@ function resultSummary(input2, theme) {
|
|
|
51302
52537
|
] : [];
|
|
51303
52538
|
return muted([m.done, duration, ...tokens].join(" · "));
|
|
51304
52539
|
}
|
|
52540
|
+
case "web_fetch": {
|
|
52541
|
+
const finalUrl = details["finalUrl"];
|
|
52542
|
+
if (num9(details["bytes"]) === 0 && typeof finalUrl === "string" && lines2[0]?.startsWith("Redirected"))
|
|
52543
|
+
return muted(m.fetchRedirect(finalUrl));
|
|
52544
|
+
const title = typeof details["title"] === "string" ? flat(details["title"], 60) : void 0;
|
|
52545
|
+
const format = typeof details["format"] === "string" ? details["format"] : "";
|
|
52546
|
+
return muted(m.fetched(title, formatSize(num9(details["bytes"]) ?? 0), format));
|
|
52547
|
+
}
|
|
51305
52548
|
default:
|
|
51306
52549
|
return muted(count2 === 0 ? m.done : m.outputLines(count2));
|
|
51307
52550
|
}
|
|
51308
52551
|
}
|
|
52552
|
+
function fetchHost(toolName, input2) {
|
|
52553
|
+
if (toolName !== "web_fetch") return void 0;
|
|
52554
|
+
const raw = record(input2)["url"];
|
|
52555
|
+
if (typeof raw !== "string") return void 0;
|
|
52556
|
+
try {
|
|
52557
|
+
return new URL(raw.trim()).hostname.replace(/^\[|\]$/g, "").toLowerCase() || void 0;
|
|
52558
|
+
} catch {
|
|
52559
|
+
return void 0;
|
|
52560
|
+
}
|
|
52561
|
+
}
|
|
51309
52562
|
var import_node_path85;
|
|
51310
52563
|
var init_tool_summary = __esm({
|
|
51311
52564
|
"src/modes/interactive/tool-summary.ts"() {
|
|
@@ -51314,6 +52567,7 @@ var init_tool_summary = __esm({
|
|
|
51314
52567
|
import_node_path85 = require("node:path");
|
|
51315
52568
|
init_tui2();
|
|
51316
52569
|
init_status_bar();
|
|
52570
|
+
init_truncate();
|
|
51317
52571
|
}
|
|
51318
52572
|
});
|
|
51319
52573
|
|
|
@@ -52128,7 +53382,7 @@ function childLoader(read2 = readTraceInput) {
|
|
|
52128
53382
|
const load2 = ((file) => {
|
|
52129
53383
|
let stamp = "";
|
|
52130
53384
|
try {
|
|
52131
|
-
const st = (0,
|
|
53385
|
+
const st = (0, import_node_fs65.statSync)(file);
|
|
52132
53386
|
stamp = `${st.mtimeMs}:${st.size}`;
|
|
52133
53387
|
} catch {
|
|
52134
53388
|
stamp = "missing";
|
|
@@ -52172,11 +53426,11 @@ function traceText(session, taskId) {
|
|
|
52172
53426
|
`${msg().trace.taskTitle(node.taskId, node.agent)}${summary2}`
|
|
52173
53427
|
);
|
|
52174
53428
|
}
|
|
52175
|
-
var
|
|
53429
|
+
var import_node_fs65, LiveTracker, lineTraceCommand;
|
|
52176
53430
|
var init_session3 = __esm({
|
|
52177
53431
|
"src/trace/session.ts"() {
|
|
52178
53432
|
"use strict";
|
|
52179
|
-
|
|
53433
|
+
import_node_fs65 = require("node:fs");
|
|
52180
53434
|
init_session2();
|
|
52181
53435
|
init_i18n();
|
|
52182
53436
|
init_scan();
|
|
@@ -52359,7 +53613,7 @@ function ancestorDirs(cwd) {
|
|
|
52359
53613
|
let dir = (0, import_node_path89.resolve)(cwd);
|
|
52360
53614
|
for (; ; ) {
|
|
52361
53615
|
out.push(dir);
|
|
52362
|
-
if ((0,
|
|
53616
|
+
if ((0, import_node_fs67.existsSync)((0, import_node_path89.join)(dir, ".git"))) return out;
|
|
52363
53617
|
const parent = (0, import_node_path89.dirname)(dir);
|
|
52364
53618
|
if (parent === dir) return out;
|
|
52365
53619
|
dir = parent;
|
|
@@ -52421,7 +53675,7 @@ async function isDir3(path) {
|
|
|
52421
53675
|
async function findSkillFiles(dir, depth = 0) {
|
|
52422
53676
|
if (depth > MAX_DEPTH3) return [];
|
|
52423
53677
|
const own = (0, import_node_path89.join)(dir, SKILL_FILE);
|
|
52424
|
-
if ((0,
|
|
53678
|
+
if ((0, import_node_fs67.existsSync)(own)) return [own];
|
|
52425
53679
|
let names;
|
|
52426
53680
|
try {
|
|
52427
53681
|
names = await (0, import_promises24.readdir)(dir);
|
|
@@ -52473,11 +53727,11 @@ async function discoverSkills(sources, options) {
|
|
|
52473
53727
|
}
|
|
52474
53728
|
return result;
|
|
52475
53729
|
}
|
|
52476
|
-
var
|
|
53730
|
+
var import_node_fs67, import_promises24, import_node_path89, SKILL_FILE, SKILL_NAME_RE, MAX_SKILL_NAME, MAX_SKILL_DESCRIPTION, MAX_DEPTH3, SKIP_DIRS;
|
|
52477
53731
|
var init_discover2 = __esm({
|
|
52478
53732
|
"src/skills/discover.ts"() {
|
|
52479
53733
|
"use strict";
|
|
52480
|
-
|
|
53734
|
+
import_node_fs67 = require("node:fs");
|
|
52481
53735
|
import_promises24 = require("node:fs/promises");
|
|
52482
53736
|
import_node_path89 = require("node:path");
|
|
52483
53737
|
init_frontmatter2();
|
|
@@ -52601,7 +53855,7 @@ function resolveSandboxEntry(moduleUrl = __ama_import_meta_url) {
|
|
|
52601
53855
|
candidates2.push((0, import_node_path90.join)(here, "sandbox-entry.js"));
|
|
52602
53856
|
candidates2.push((0, import_node_path90.join)(here, "sandbox-entry.ts"));
|
|
52603
53857
|
for (const candidate of candidates2) {
|
|
52604
|
-
if ((0,
|
|
53858
|
+
if ((0, import_node_fs68.existsSync)(candidate)) return (0, import_node_fs68.realpathSync)(candidate);
|
|
52605
53859
|
}
|
|
52606
53860
|
return void 0;
|
|
52607
53861
|
}
|
|
@@ -52833,12 +54087,12 @@ async function runSandbox(request) {
|
|
|
52833
54087
|
child.stdin.end();
|
|
52834
54088
|
return result;
|
|
52835
54089
|
}
|
|
52836
|
-
var import_node_child_process16,
|
|
54090
|
+
var import_node_child_process16, import_node_fs68, import_node_path90, import_node_url2, MAX_COLLECTED_OUTPUT_CHARS, ABORT_GRACE_MS, DEFAULT_CODEMODE_HEAP_MB, CODEMODE_OS_POLICY;
|
|
52837
54091
|
var init_host_side = __esm({
|
|
52838
54092
|
"src/codemode/host-side.ts"() {
|
|
52839
54093
|
"use strict";
|
|
52840
54094
|
import_node_child_process16 = require("node:child_process");
|
|
52841
|
-
|
|
54095
|
+
import_node_fs68 = require("node:fs");
|
|
52842
54096
|
import_node_path90 = require("node:path");
|
|
52843
54097
|
import_node_url2 = require("node:url");
|
|
52844
54098
|
init_detect();
|
|
@@ -53004,9 +54258,9 @@ ${output.slice(-half)}`;
|
|
|
53004
54258
|
function saveFullOutput(ctx, text) {
|
|
53005
54259
|
try {
|
|
53006
54260
|
const dir = ctx.outputDir ?? (0, import_node_path91.join)((0, import_node_os14.tmpdir)(), "ama-codemode");
|
|
53007
|
-
(0,
|
|
54261
|
+
(0, import_node_fs69.mkdirSync)(dir, { recursive: true });
|
|
53008
54262
|
const file = (0, import_node_path91.join)(dir, `${ctx.toolCallId.replace(/[^A-Za-z0-9_-]/g, "_")}.txt`);
|
|
53009
|
-
(0,
|
|
54263
|
+
(0, import_node_fs69.writeFileSync)(file, text, "utf8");
|
|
53010
54264
|
return file;
|
|
53011
54265
|
} catch {
|
|
53012
54266
|
return void 0;
|
|
@@ -53158,11 +54412,11 @@ function codemodeToolFactory(overrides = {}) {
|
|
|
53158
54412
|
return createCodemodeTool(options);
|
|
53159
54413
|
};
|
|
53160
54414
|
}
|
|
53161
|
-
var
|
|
54415
|
+
var import_node_fs69, import_node_os14, import_node_path91, CODEMODE_TOOL_NAME2, DEFAULT_MAX_TOOL_RESULT_CHARS2, CODEMODE_EXAMPLE, SCRIPT_ONLY_GLOBALS, TAIL_CHARS, CODEMODE_ONLY_GUIDELINE;
|
|
53162
54416
|
var init_tool = __esm({
|
|
53163
54417
|
"src/codemode/tool.ts"() {
|
|
53164
54418
|
"use strict";
|
|
53165
|
-
|
|
54419
|
+
import_node_fs69 = require("node:fs");
|
|
53166
54420
|
import_node_os14 = require("node:os");
|
|
53167
54421
|
import_node_path91 = require("node:path");
|
|
53168
54422
|
init_presets2();
|
|
@@ -53188,7 +54442,7 @@ var init_tool = __esm({
|
|
|
53188
54442
|
});
|
|
53189
54443
|
|
|
53190
54444
|
// src/memory/tool.ts
|
|
53191
|
-
function
|
|
54445
|
+
function fail6(input2, code, message) {
|
|
53192
54446
|
const details = { command: String(input2.command ?? ""), code };
|
|
53193
54447
|
if (typeof input2.path === "string") details.path = input2.path;
|
|
53194
54448
|
return { content: message, isError: true, details };
|
|
@@ -53220,11 +54474,11 @@ function createMemoryTool(runtime) {
|
|
|
53220
54474
|
const write2 = command3 !== "view";
|
|
53221
54475
|
if (ctx.depth > 0) {
|
|
53222
54476
|
if (runtime.subagents === "off")
|
|
53223
|
-
return
|
|
53224
|
-
if (write2) return
|
|
54477
|
+
return fail6(input2, "subagent", "subagents cannot access memory");
|
|
54478
|
+
if (write2) return fail6(input2, "subagent", "subagents cannot modify memory");
|
|
53225
54479
|
}
|
|
53226
54480
|
if (write2 && !runtime.writesEnabled)
|
|
53227
|
-
return
|
|
54481
|
+
return fail6(input2, "disabled", "memory writes are turned off for this session");
|
|
53228
54482
|
const store = runtime.store;
|
|
53229
54483
|
try {
|
|
53230
54484
|
switch (command3) {
|
|
@@ -53244,7 +54498,7 @@ function createMemoryTool(runtime) {
|
|
|
53244
54498
|
};
|
|
53245
54499
|
}
|
|
53246
54500
|
default:
|
|
53247
|
-
return
|
|
54501
|
+
return fail6(
|
|
53248
54502
|
input2,
|
|
53249
54503
|
"invalid_command",
|
|
53250
54504
|
'command must be "view", "create", "str_replace" or "delete"'
|
|
@@ -53252,7 +54506,7 @@ function createMemoryTool(runtime) {
|
|
|
53252
54506
|
}
|
|
53253
54507
|
} catch (error2) {
|
|
53254
54508
|
if (error2 instanceof MemoryError || error2 instanceof MemoryLockError)
|
|
53255
|
-
return
|
|
54509
|
+
return fail6(input2, error2.code, error2.message);
|
|
53256
54510
|
throw error2;
|
|
53257
54511
|
}
|
|
53258
54512
|
}
|
|
@@ -53276,7 +54530,7 @@ var init_tool2 = __esm({
|
|
|
53276
54530
|
// src/cli/codemode-notice.ts
|
|
53277
54531
|
function readNotices(path) {
|
|
53278
54532
|
try {
|
|
53279
|
-
const value = JSON.parse((0,
|
|
54533
|
+
const value = JSON.parse((0, import_node_fs70.readFileSync)(path, "utf8"));
|
|
53280
54534
|
if (typeof value === "object" && value !== null && !Array.isArray(value)) {
|
|
53281
54535
|
const shown2 = value[KEY];
|
|
53282
54536
|
return {
|
|
@@ -53300,20 +54554,20 @@ function takeCodemodeNotice(input2) {
|
|
|
53300
54554
|
const shown2 = notices[KEY] ?? [];
|
|
53301
54555
|
if (shown2.includes(input2.configDir)) return void 0;
|
|
53302
54556
|
try {
|
|
53303
|
-
(0,
|
|
54557
|
+
(0, import_node_fs70.mkdirSync)(input2.dataDir, { recursive: true });
|
|
53304
54558
|
const tmp = `${path}.${process.pid}.tmp`;
|
|
53305
|
-
(0,
|
|
54559
|
+
(0, import_node_fs70.writeFileSync)(tmp, `${JSON.stringify({ ...notices, [KEY]: [...shown2, input2.configDir] })}
|
|
53306
54560
|
`);
|
|
53307
|
-
(0,
|
|
54561
|
+
(0, import_node_fs70.renameSync)(tmp, path);
|
|
53308
54562
|
} catch {
|
|
53309
54563
|
}
|
|
53310
54564
|
return codemodeNoticeText(input2.capability);
|
|
53311
54565
|
}
|
|
53312
|
-
var
|
|
54566
|
+
var import_node_fs70, import_node_path92, NOTICES_FILE, KEY;
|
|
53313
54567
|
var init_codemode_notice = __esm({
|
|
53314
54568
|
"src/cli/codemode-notice.ts"() {
|
|
53315
54569
|
"use strict";
|
|
53316
|
-
|
|
54570
|
+
import_node_fs70 = require("node:fs");
|
|
53317
54571
|
import_node_path92 = require("node:path");
|
|
53318
54572
|
init_presets2();
|
|
53319
54573
|
init_i18n();
|
|
@@ -53330,7 +54584,7 @@ function readEntries(dataDir, now) {
|
|
|
53330
54584
|
const out = /* @__PURE__ */ new Map();
|
|
53331
54585
|
let parsed;
|
|
53332
54586
|
try {
|
|
53333
|
-
parsed = JSON.parse((0,
|
|
54587
|
+
parsed = JSON.parse((0, import_node_fs71.readFileSync)(maxTokensCachePath(dataDir), "utf8"));
|
|
53334
54588
|
} catch {
|
|
53335
54589
|
return out;
|
|
53336
54590
|
}
|
|
@@ -53364,11 +54618,11 @@ function recordMaxTokensCap(dataDir, key, cap, now = Date.now) {
|
|
|
53364
54618
|
const path = maxTokensCachePath(dataDir);
|
|
53365
54619
|
const tmp = `${path}.${process.pid}.tmp`;
|
|
53366
54620
|
try {
|
|
53367
|
-
(0,
|
|
54621
|
+
(0, import_node_fs71.mkdirSync)((0, import_node_path93.dirname)(path), { recursive: true, mode: 448 });
|
|
53368
54622
|
const caps = Object.fromEntries([...entries].sort(([a], [b]) => a < b ? -1 : 1));
|
|
53369
|
-
(0,
|
|
54623
|
+
(0, import_node_fs71.writeFileSync)(tmp, `${JSON.stringify({ version: MAX_TOKENS_CACHE_VERSION, caps }, null, 2)}
|
|
53370
54624
|
`);
|
|
53371
|
-
(0,
|
|
54625
|
+
(0, import_node_fs71.renameSync)(tmp, path);
|
|
53372
54626
|
} catch {
|
|
53373
54627
|
}
|
|
53374
54628
|
}
|
|
@@ -53384,11 +54638,11 @@ function attachMaxTokensCache(dataDir, now = Date.now) {
|
|
|
53384
54638
|
attached2.set(dataDir, detach);
|
|
53385
54639
|
return detach;
|
|
53386
54640
|
}
|
|
53387
|
-
var
|
|
54641
|
+
var import_node_fs71, import_node_path93, MAX_TOKENS_CACHE_VERSION, MAX_TOKENS_CACHE_TTL_MS, attached2;
|
|
53388
54642
|
var init_max_tokens_cache = __esm({
|
|
53389
54643
|
"src/ai/providers/max-tokens-cache.ts"() {
|
|
53390
54644
|
"use strict";
|
|
53391
|
-
|
|
54645
|
+
import_node_fs71 = require("node:fs");
|
|
53392
54646
|
import_node_path93 = require("node:path");
|
|
53393
54647
|
init_max_tokens();
|
|
53394
54648
|
MAX_TOKENS_CACHE_VERSION = 1;
|
|
@@ -53542,7 +54796,7 @@ function findImageRefs(text, cwd) {
|
|
|
53542
54796
|
token = token.replace(/\\ /g, " ").replace(/[,\uFF0C\u3002;\uFF1B)\uFF09]+$/, "");
|
|
53543
54797
|
if (token === "" || imageMimeFromPath(token) === void 0) continue;
|
|
53544
54798
|
const path = expand(token, cwd);
|
|
53545
|
-
if (!explicit && !(0,
|
|
54799
|
+
if (!explicit && !(0, import_node_fs72.existsSync)(path)) continue;
|
|
53546
54800
|
if (seen.has(path)) continue;
|
|
53547
54801
|
seen.add(path);
|
|
53548
54802
|
out.push({ path, explicit });
|
|
@@ -53571,9 +54825,9 @@ async function loadPromptImages(refs, model, options = {}) {
|
|
|
53571
54825
|
...model !== void 0 ? { maxBase64Bytes: imageLimits(model).perImageBase64 } : {},
|
|
53572
54826
|
...options
|
|
53573
54827
|
};
|
|
53574
|
-
const
|
|
53575
|
-
for (const ref of wanted)
|
|
53576
|
-
return
|
|
54828
|
+
const blocks2 = [];
|
|
54829
|
+
for (const ref of wanted) blocks2.push((await loadLocalized(ref.path, fit)).block);
|
|
54830
|
+
return blocks2;
|
|
53577
54831
|
}
|
|
53578
54832
|
async function promptImages(text, extra, cwd, model, options = {}) {
|
|
53579
54833
|
const refs = [
|
|
@@ -53601,11 +54855,11 @@ async function loadLocalized(path, options) {
|
|
|
53601
54855
|
throw error2;
|
|
53602
54856
|
}
|
|
53603
54857
|
}
|
|
53604
|
-
var
|
|
54858
|
+
var import_node_fs72, import_node_os15, import_node_path94, TOKEN;
|
|
53605
54859
|
var init_image_input = __esm({
|
|
53606
54860
|
"src/modes/image-input.ts"() {
|
|
53607
54861
|
"use strict";
|
|
53608
|
-
|
|
54862
|
+
import_node_fs72 = require("node:fs");
|
|
53609
54863
|
import_node_os15 = require("node:os");
|
|
53610
54864
|
import_node_path94 = require("node:path");
|
|
53611
54865
|
init_channels();
|
|
@@ -54404,7 +55658,7 @@ function trustChoices() {
|
|
|
54404
55658
|
}
|
|
54405
55659
|
function isDirectory2(path) {
|
|
54406
55660
|
try {
|
|
54407
|
-
return (0,
|
|
55661
|
+
return (0, import_node_fs73.statSync)(path).isDirectory();
|
|
54408
55662
|
} catch {
|
|
54409
55663
|
return false;
|
|
54410
55664
|
}
|
|
@@ -54459,7 +55713,7 @@ function createStartupUi(options = {}) {
|
|
|
54459
55713
|
validate: (text) => {
|
|
54460
55714
|
if (text === "") return m.cwdEmpty;
|
|
54461
55715
|
const abs = (0, import_node_path95.resolve)(text);
|
|
54462
|
-
if (!(0,
|
|
55716
|
+
if (!(0, import_node_fs73.existsSync)(abs)) return m.cwdMissing(abs);
|
|
54463
55717
|
if (!isDirectory2(abs)) return m.cwdNotDir(abs);
|
|
54464
55718
|
return void 0;
|
|
54465
55719
|
}
|
|
@@ -54467,12 +55721,12 @@ function createStartupUi(options = {}) {
|
|
|
54467
55721
|
}
|
|
54468
55722
|
};
|
|
54469
55723
|
}
|
|
54470
|
-
var
|
|
55724
|
+
var import_node_fs73, import_node_path95;
|
|
54471
55725
|
var init_startup_ui = __esm({
|
|
54472
55726
|
"src/modes/interactive/startup-ui.ts"() {
|
|
54473
55727
|
"use strict";
|
|
54474
55728
|
init_i18n();
|
|
54475
|
-
|
|
55729
|
+
import_node_fs73 = require("node:fs");
|
|
54476
55730
|
import_node_path95 = require("node:path");
|
|
54477
55731
|
init_tui2();
|
|
54478
55732
|
init_model_items();
|
|
@@ -54913,8 +56167,8 @@ var init_startup_screen = __esm({
|
|
|
54913
56167
|
});
|
|
54914
56168
|
|
|
54915
56169
|
// src/modes/interactive/panels.ts
|
|
54916
|
-
function keyValue(rows, theme,
|
|
54917
|
-
return new KeyValue(rows, { theme, maxKeyRatio: 0.3, ...
|
|
56170
|
+
function keyValue(rows, theme, wrap3 = false) {
|
|
56171
|
+
return new KeyValue(rows, { theme, maxKeyRatio: 0.3, ...wrap3 ? { wrap: true } : {} });
|
|
54918
56172
|
}
|
|
54919
56173
|
function cacheSection(session, theme, now) {
|
|
54920
56174
|
return [
|
|
@@ -55212,7 +56466,7 @@ function contextPanel(session, theme) {
|
|
|
55212
56466
|
const m = msg().report.contextReport;
|
|
55213
56467
|
const snap = contextSnapshot(session);
|
|
55214
56468
|
const { breakdown } = snap;
|
|
55215
|
-
const table3 = (rows,
|
|
56469
|
+
const table3 = (rows, wrap3 = false) => new KeyValue(rows, { theme, maxKeyRatio: 0.3, ...wrap3 ? { wrap: true } : {} });
|
|
55216
56470
|
const largest = largestRows(breakdown);
|
|
55217
56471
|
const parts = [
|
|
55218
56472
|
table3(headerRows(snap)),
|
|
@@ -55271,14 +56525,20 @@ function command(name, key, args) {
|
|
|
55271
56525
|
});
|
|
55272
56526
|
return info2;
|
|
55273
56527
|
}
|
|
56528
|
+
function availableCommands2(runtime, session, list5 = BUILTIN_COMMANDS) {
|
|
56529
|
+
const active = new Set(session.getTools().map((t) => t.name));
|
|
56530
|
+
const registered = new Set(runtime.tools.list());
|
|
56531
|
+
const has = (requires) => requires === "memory" ? registered.has("memory") : requires === "task" ? active.has("task") || active.has("codemode") && registered.has("task") : true;
|
|
56532
|
+
return list5.filter((c) => has(c.requires));
|
|
56533
|
+
}
|
|
55274
56534
|
function parseSlash(line2) {
|
|
55275
56535
|
const m = /^\/([A-Za-z?][\w-]*)(?:\s+([\s\S]*))?$/.exec(line2.trim());
|
|
55276
56536
|
if (m === null) return void 0;
|
|
55277
56537
|
const raw = m[1].toLowerCase();
|
|
55278
56538
|
return { name: ALIASES[raw] ?? raw, args: (m[2] ?? "").trim() };
|
|
55279
56539
|
}
|
|
55280
|
-
function helpText2() {
|
|
55281
|
-
const lines2 =
|
|
56540
|
+
function helpText2(ctx) {
|
|
56541
|
+
const lines2 = availableCommands2(ctx.runtime, ctx.session()).map(
|
|
55282
56542
|
(c) => `/${c.name}${c.args !== void 0 ? ` ${c.args}` : ""} ${c.description}`
|
|
55283
56543
|
);
|
|
55284
56544
|
const m = msg().report.commands;
|
|
@@ -55325,7 +56585,7 @@ async function runSlashCommand(line2, ctx) {
|
|
|
55325
56585
|
const session = ctx.session();
|
|
55326
56586
|
switch (name) {
|
|
55327
56587
|
case "help":
|
|
55328
|
-
return { kind: "handled", message: helpText2() };
|
|
56588
|
+
return { kind: "handled", message: helpText2(ctx) };
|
|
55329
56589
|
case "exit":
|
|
55330
56590
|
return { kind: "exit" };
|
|
55331
56591
|
case "new": {
|
|
@@ -55497,7 +56757,9 @@ var init_commands_core = __esm({
|
|
|
55497
56757
|
command("cache", "cache", "[warm off|streaming|idle | fingerprint]"),
|
|
55498
56758
|
command("statusline", "statusline", "[full|compact]"),
|
|
55499
56759
|
command("plan", "plan", { key: "planArgs" }),
|
|
55500
|
-
command("tasks", "tasks", "[id] | stop <id> | bg [id]"),
|
|
56760
|
+
Object.assign(command("tasks", "tasks", "[id] | stop <id> | bg [id]"), {
|
|
56761
|
+
requires: "task"
|
|
56762
|
+
}),
|
|
55501
56763
|
command("agents", "agents"),
|
|
55502
56764
|
command("paste", "paste"),
|
|
55503
56765
|
command("interrupt", "interrupt", { key: "interruptArgs" }),
|
|
@@ -55505,7 +56767,9 @@ var init_commands_core = __esm({
|
|
|
55505
56767
|
// [W6-C0] 第六波(W6-S / W6-T1 / W6-M 实现)
|
|
55506
56768
|
command("config", "config", "[key=value]"),
|
|
55507
56769
|
command("trace", "trace", { key: "traceArgs" }),
|
|
55508
|
-
command("memory", "memory", { key: "memoryArgs" })
|
|
56770
|
+
Object.assign(command("memory", "memory", { key: "memoryArgs" }), {
|
|
56771
|
+
requires: "memory"
|
|
56772
|
+
})
|
|
55509
56773
|
];
|
|
55510
56774
|
ALIASES = { quit: "exit", q: "exit", "?": "help" };
|
|
55511
56775
|
}
|
|
@@ -55605,9 +56869,9 @@ async function availableModels(runtime) {
|
|
|
55605
56869
|
}
|
|
55606
56870
|
return out;
|
|
55607
56871
|
}
|
|
55608
|
-
function commands(runtime) {
|
|
56872
|
+
function commands(runtime, session) {
|
|
55609
56873
|
return [
|
|
55610
|
-
...
|
|
56874
|
+
...availableCommands2(runtime, session).map((c) => ({
|
|
55611
56875
|
name: c.name,
|
|
55612
56876
|
description: c.description,
|
|
55613
56877
|
source: "builtin"
|
|
@@ -55817,7 +57081,7 @@ var init_commands = __esm({
|
|
|
55817
57081
|
ctx.session().setPermissionMode(p.mode);
|
|
55818
57082
|
return { mode: p.mode };
|
|
55819
57083
|
},
|
|
55820
|
-
get_commands: async (_p, ctx) => ({ commands: commands(ctx.runtime) }),
|
|
57084
|
+
get_commands: async (_p, ctx) => ({ commands: commands(ctx.runtime, ctx.session()) }),
|
|
55821
57085
|
get_skills: async (_p, ctx) => ({ skills: ctx.runtime.resources.skills }),
|
|
55822
57086
|
// [W5-F] 计划 / 任务命令(docs/history/wave5-plan.md §6.5、§7.5)
|
|
55823
57087
|
plan_response: async (p, ctx) => {
|
|
@@ -56312,8 +57576,8 @@ var init_config_panel = __esm({
|
|
|
56312
57576
|
const dynamic = value.value === void 0 ? settingDynamicDefault(row3.id) : void 0;
|
|
56313
57577
|
const text = dynamic === void 0 ? doc : `${doc} · ${dynamic}`;
|
|
56314
57578
|
const spec2 = settingsRegistry().find((x) => x.key === row3.id);
|
|
56315
|
-
const
|
|
56316
|
-
const lines2 =
|
|
57579
|
+
const blocked3 = spec2 === void 0 ? void 0 : blockedReason(spec2, value, this.scope);
|
|
57580
|
+
const lines2 = blocked3 === void 0 ? [] : [theme.fg("warning", truncateToWidth(blocked3, width2))];
|
|
56317
57581
|
if (text !== "") lines2.push(...wrapTextWithAnsi(theme.fg("dim", text), width2));
|
|
56318
57582
|
return lines2.slice(0, 3);
|
|
56319
57583
|
}
|
|
@@ -57356,8 +58620,8 @@ var init_config_ui = __esm({
|
|
|
57356
58620
|
const spec2 = settingSpec(key);
|
|
57357
58621
|
if (panel === void 0 || spec2 === void 0) return;
|
|
57358
58622
|
const current3 = getConfigValue(readSnapshot(this.input()), key);
|
|
57359
|
-
const
|
|
57360
|
-
if (
|
|
58623
|
+
const blocked3 = blockedReason(spec2, current3, scope);
|
|
58624
|
+
if (blocked3 !== void 0) return panel.setNotice(blocked3, "warning");
|
|
57361
58625
|
const value = current3.value;
|
|
57362
58626
|
switch (spec2.kind) {
|
|
57363
58627
|
case "bool":
|
|
@@ -57647,27 +58911,27 @@ function runEditor(command3, file) {
|
|
|
57647
58911
|
return result.status;
|
|
57648
58912
|
}
|
|
57649
58913
|
async function editExternally(text, name, deps) {
|
|
57650
|
-
const dir = (0,
|
|
58914
|
+
const dir = (0, import_node_fs74.mkdtempSync)((0, import_node_path97.join)((0, import_node_os16.tmpdir)(), "ama-edit-"));
|
|
57651
58915
|
const file = (0, import_node_path97.join)(dir, name);
|
|
57652
|
-
(0,
|
|
58916
|
+
(0, import_node_fs74.writeFileSync)(file, text);
|
|
57653
58917
|
deps.suspend();
|
|
57654
58918
|
try {
|
|
57655
58919
|
const code = (deps.run ?? runEditor)(editorCommand(deps.env, deps.platform), file);
|
|
57656
58920
|
if (code !== 0) return void 0;
|
|
57657
|
-
return (0,
|
|
58921
|
+
return (0, import_node_fs74.readFileSync)(file, "utf8");
|
|
57658
58922
|
} catch {
|
|
57659
58923
|
return void 0;
|
|
57660
58924
|
} finally {
|
|
57661
58925
|
deps.resume();
|
|
57662
|
-
(0,
|
|
58926
|
+
(0, import_node_fs74.rmSync)(dir, { recursive: true, force: true });
|
|
57663
58927
|
}
|
|
57664
58928
|
}
|
|
57665
|
-
var import_node_child_process17,
|
|
58929
|
+
var import_node_child_process17, import_node_fs74, import_node_os16, import_node_path97;
|
|
57666
58930
|
var init_external_editor = __esm({
|
|
57667
58931
|
"src/modes/interactive/external-editor.ts"() {
|
|
57668
58932
|
"use strict";
|
|
57669
58933
|
import_node_child_process17 = require("node:child_process");
|
|
57670
|
-
|
|
58934
|
+
import_node_fs74 = require("node:fs");
|
|
57671
58935
|
import_node_os16 = require("node:os");
|
|
57672
58936
|
import_node_path97 = require("node:path");
|
|
57673
58937
|
}
|
|
@@ -58631,6 +59895,10 @@ function describeRequest(request, theme, options = {}) {
|
|
|
58631
59895
|
const { shown: shown2, hidden } = lines(input2["command"], COMMAND_LINES);
|
|
58632
59896
|
out.push(...shown2.map((l, i) => theme.fg("code", (i === 0 ? "$ " : " ") + l)));
|
|
58633
59897
|
if (hidden > 0) out.push(more(hidden));
|
|
59898
|
+
} else if (request.toolName === "web_fetch" && typeof input2["url"] === "string") {
|
|
59899
|
+
const { shown: shown2, hidden } = lines(input2["url"].replace(/(.{72})/g, "$1\n"), COMMAND_LINES);
|
|
59900
|
+
out.push(...shown2.map((l) => theme.fg("code", l)));
|
|
59901
|
+
if (hidden > 0) out.push(more(hidden));
|
|
58634
59902
|
} else if (request.toolName === "write" && typeof input2["content"] === "string") {
|
|
58635
59903
|
const count2 = lines(input2["content"], Number.MAX_SAFE_INTEGER).shown.length;
|
|
58636
59904
|
out.push(
|
|
@@ -58699,8 +59967,10 @@ function approvalOutcomeText(request, outcome, taskAgent) {
|
|
|
58699
59967
|
switch (outcome) {
|
|
58700
59968
|
case "allow":
|
|
58701
59969
|
return m.allow(what);
|
|
58702
|
-
case "allow_session":
|
|
58703
|
-
|
|
59970
|
+
case "allow_session": {
|
|
59971
|
+
const host = fetchHost(request.toolName, request.input);
|
|
59972
|
+
return host === void 0 ? m.allowSession(what) : m.allowSessionHost(what, host);
|
|
59973
|
+
}
|
|
58704
59974
|
case "deny":
|
|
58705
59975
|
return m.deny(what);
|
|
58706
59976
|
case "cancelled":
|
|
@@ -58790,10 +60060,12 @@ var init_approval_dialog = __esm({
|
|
|
58790
60060
|
const { theme } = this.host;
|
|
58791
60061
|
const g = theme.glyphs;
|
|
58792
60062
|
const keyWidth = compact ? 1 : Math.max(...APPROVAL_OPTIONS.map((o) => o.keys.length));
|
|
60063
|
+
const host = fetchHost(this.request.toolName, this.request.input);
|
|
58793
60064
|
return APPROVAL_OPTIONS.map((option2, i) => {
|
|
58794
60065
|
const selected = i === this.selected;
|
|
58795
60066
|
const keys = compact ? option2.keys.slice(0, 1) : option2.keys;
|
|
58796
|
-
const
|
|
60067
|
+
const text = option2.decision === "allow_session" && host !== void 0 ? msg().approval.option.allowSessionHost(host) : option2.label;
|
|
60068
|
+
const left = `${selected ? g.prompt : " "} ${i + 1}. ${text}`;
|
|
58797
60069
|
const right = keys.padEnd(keyWidth);
|
|
58798
60070
|
const room = Math.max(1, width2 - visibleWidth(right) - 1);
|
|
58799
60071
|
const label2 = selected ? theme.fg("accent", theme.bold(left)) : left;
|
|
@@ -61212,6 +62484,9 @@ function command2(name, key) {
|
|
|
61212
62484
|
}
|
|
61213
62485
|
};
|
|
61214
62486
|
}
|
|
62487
|
+
function completionCommands(runtime, session) {
|
|
62488
|
+
return availableCommands2(runtime, session, ALL_COMMANDS);
|
|
62489
|
+
}
|
|
61215
62490
|
function keyHints() {
|
|
61216
62491
|
return msg().interactive.commands.keyHints;
|
|
61217
62492
|
}
|
|
@@ -64336,7 +65611,7 @@ var init_program_status = __esm({
|
|
|
64336
65611
|
});
|
|
64337
65612
|
|
|
64338
65613
|
// src/modes/interactive/program-status-ui.ts
|
|
64339
|
-
function
|
|
65614
|
+
function blocked2(kind, text) {
|
|
64340
65615
|
return { state: "blocked", kind, msg: text };
|
|
64341
65616
|
}
|
|
64342
65617
|
function programStatusUi(deps) {
|
|
@@ -64492,9 +65767,9 @@ var init_program_status_ui = __esm({
|
|
|
64492
65767
|
/** 当前根记录(测试也用)。 */
|
|
64493
65768
|
root() {
|
|
64494
65769
|
const pending = [...this.approvals.values()].at(-1);
|
|
64495
|
-
if (pending !== void 0) return
|
|
64496
|
-
if (this.plan !== void 0) return
|
|
64497
|
-
if (this.auth !== void 0) return
|
|
65770
|
+
if (pending !== void 0) return blocked2("permission", pending.msg);
|
|
65771
|
+
if (this.plan !== void 0) return blocked2("question", this.plan);
|
|
65772
|
+
if (this.auth !== void 0) return blocked2("auth", this.auth);
|
|
64498
65773
|
if (this.running)
|
|
64499
65774
|
return { state: "working", ...this.activity !== void 0 ? { msg: this.activity } : {} };
|
|
64500
65775
|
return this.outcome ?? { state: "idle" };
|
|
@@ -64618,7 +65893,7 @@ function runInteractiveMode(runtime, context, options = {}) {
|
|
|
64618
65893
|
const { hint, bar: status } = area;
|
|
64619
65894
|
const historyFile = options.historyFile === false ? void 0 : options.historyFile ?? (0, import_node_path101.join)(runtime.paths.dataDir, "history");
|
|
64620
65895
|
const completion = new InteractiveCompletion({
|
|
64621
|
-
commands: () =>
|
|
65896
|
+
commands: () => completionCommands(runtime, session),
|
|
64622
65897
|
prompts: () => runtime.resources.prompts,
|
|
64623
65898
|
skills: () => runtime.resources.skills,
|
|
64624
65899
|
cwd: () => session.state.cwd,
|
|
@@ -64645,6 +65920,7 @@ function runInteractiveMode(runtime, context, options = {}) {
|
|
|
64645
65920
|
tui.addChild(status);
|
|
64646
65921
|
tui.addChild(area.quota);
|
|
64647
65922
|
let finished = false;
|
|
65923
|
+
const hintTimers = options.hintTimers ?? realHintTimers;
|
|
64648
65924
|
let hintTimer;
|
|
64649
65925
|
let resolveExit = () => void 0;
|
|
64650
65926
|
const render = () => tui.requestRender();
|
|
@@ -64654,14 +65930,13 @@ function runInteractiveMode(runtime, context, options = {}) {
|
|
|
64654
65930
|
};
|
|
64655
65931
|
const showHint = (text, ms = HINT_MS) => {
|
|
64656
65932
|
hint.setText(text === "" ? "" : theme.fg("dim", text));
|
|
64657
|
-
if (hintTimer !== void 0)
|
|
65933
|
+
if (hintTimer !== void 0) hintTimers.clear(hintTimer);
|
|
64658
65934
|
hintTimer = void 0;
|
|
64659
65935
|
if (text !== "") {
|
|
64660
|
-
hintTimer =
|
|
65936
|
+
hintTimer = hintTimers.set(() => {
|
|
64661
65937
|
hint.setText("");
|
|
64662
65938
|
render();
|
|
64663
65939
|
}, ms);
|
|
64664
|
-
hintTimer.unref?.();
|
|
64665
65940
|
}
|
|
64666
65941
|
render();
|
|
64667
65942
|
};
|
|
@@ -64914,7 +66189,7 @@ function runInteractiveMode(runtime, context, options = {}) {
|
|
|
64914
66189
|
if (finished) return;
|
|
64915
66190
|
finished = true;
|
|
64916
66191
|
logoAnimation?.finish();
|
|
64917
|
-
if (hintTimer !== void 0)
|
|
66192
|
+
if (hintTimer !== void 0) hintTimers.clear(hintTimer);
|
|
64918
66193
|
loader.stop();
|
|
64919
66194
|
area.dispose();
|
|
64920
66195
|
osc7501.exit();
|
|
@@ -64980,7 +66255,7 @@ function runInteractiveMode(runtime, context, options = {}) {
|
|
|
64980
66255
|
}
|
|
64981
66256
|
});
|
|
64982
66257
|
}
|
|
64983
|
-
var import_node_path101, HINT_MS;
|
|
66258
|
+
var import_node_path101, HINT_MS, realHintTimers;
|
|
64984
66259
|
var init_interactive_mode = __esm({
|
|
64985
66260
|
"src/modes/interactive/interactive-mode.ts"() {
|
|
64986
66261
|
"use strict";
|
|
@@ -65019,6 +66294,14 @@ var init_interactive_mode = __esm({
|
|
|
65019
66294
|
init_tool_view();
|
|
65020
66295
|
init_task_background();
|
|
65021
66296
|
HINT_MS = 2500;
|
|
66297
|
+
realHintTimers = {
|
|
66298
|
+
set: (fn, ms) => {
|
|
66299
|
+
const handle = setTimeout(fn, ms);
|
|
66300
|
+
handle.unref?.();
|
|
66301
|
+
return handle;
|
|
66302
|
+
},
|
|
66303
|
+
clear: (handle) => clearTimeout(handle)
|
|
66304
|
+
};
|
|
65022
66305
|
}
|
|
65023
66306
|
});
|
|
65024
66307
|
|
|
@@ -65061,7 +66344,7 @@ function choose(answer, values) {
|
|
|
65061
66344
|
}
|
|
65062
66345
|
function isDirectory3(path) {
|
|
65063
66346
|
try {
|
|
65064
|
-
return (0,
|
|
66347
|
+
return (0, import_node_fs75.statSync)(path).isDirectory();
|
|
65065
66348
|
} catch {
|
|
65066
66349
|
return false;
|
|
65067
66350
|
}
|
|
@@ -65106,7 +66389,7 @@ function createTextStartupUi(io) {
|
|
|
65106
66389
|
const answer = (await ask([m.cwdMissing(missing)], m.cwdAnswer))?.trim();
|
|
65107
66390
|
if (answer === void 0 || answer === "") return void 0;
|
|
65108
66391
|
const abs = (0, import_node_path102.resolve)(answer);
|
|
65109
|
-
if (!(0,
|
|
66392
|
+
if (!(0, import_node_fs75.existsSync)(abs) || !isDirectory3(abs)) {
|
|
65110
66393
|
io.write(m.notDirectory(abs));
|
|
65111
66394
|
return void 0;
|
|
65112
66395
|
}
|
|
@@ -65114,11 +66397,11 @@ function createTextStartupUi(io) {
|
|
|
65114
66397
|
}
|
|
65115
66398
|
};
|
|
65116
66399
|
}
|
|
65117
|
-
var
|
|
66400
|
+
var import_node_fs75, import_node_path102;
|
|
65118
66401
|
var init_startup_ui_text = __esm({
|
|
65119
66402
|
"src/modes/startup-ui-text.ts"() {
|
|
65120
66403
|
"use strict";
|
|
65121
|
-
|
|
66404
|
+
import_node_fs75 = require("node:fs");
|
|
65122
66405
|
import_node_path102 = require("node:path");
|
|
65123
66406
|
init_i18n();
|
|
65124
66407
|
}
|
|
@@ -65155,6 +66438,7 @@ function createTools(input2, options, state) {
|
|
|
65155
66438
|
};
|
|
65156
66439
|
const builtins = builtinTools({
|
|
65157
66440
|
bash,
|
|
66441
|
+
...options.webFetch !== void 0 ? { webFetch: options.webFetch } : {},
|
|
65158
66442
|
read: {
|
|
65159
66443
|
supportsImages: (ctx2) => modelAcceptsImages(state, ctx2.model),
|
|
65160
66444
|
imageOptions: (ctx2) => imageFitOptionsFor(state.providers, ctx2.model, input2.config.images)
|
|
@@ -65564,7 +66848,7 @@ var init_memory3 = __esm({
|
|
|
65564
66848
|
});
|
|
65565
66849
|
|
|
65566
66850
|
// src/cli/main.ts
|
|
65567
|
-
var
|
|
66851
|
+
var import_node_fs76 = require("node:fs");
|
|
65568
66852
|
var import_node_path104 = require("node:path");
|
|
65569
66853
|
var import_node_url3 = require("node:url");
|
|
65570
66854
|
init_version();
|
|
@@ -66101,7 +67385,7 @@ init_token_client();
|
|
|
66101
67385
|
|
|
66102
67386
|
// src/auth/chatgpt/host-id.ts
|
|
66103
67387
|
var import_node_crypto19 = require("node:crypto");
|
|
66104
|
-
var
|
|
67388
|
+
var import_node_fs49 = require("node:fs");
|
|
66105
67389
|
var import_node_path70 = require("node:path");
|
|
66106
67390
|
var HOST_ID_FILE = "chatgpt-host.json";
|
|
66107
67391
|
function hostIdPath(dataDir) {
|
|
@@ -66110,14 +67394,14 @@ function hostIdPath(dataDir) {
|
|
|
66110
67394
|
function readOrCreateHostId(dataDir) {
|
|
66111
67395
|
const path = hostIdPath(dataDir);
|
|
66112
67396
|
try {
|
|
66113
|
-
const value = JSON.parse((0,
|
|
67397
|
+
const value = JSON.parse((0, import_node_fs49.readFileSync)(path, "utf8"));
|
|
66114
67398
|
if (typeof value.hostId === "string" && /^urn:uuid:[0-9a-f-]{36}$/i.test(value.hostId))
|
|
66115
67399
|
return value.hostId;
|
|
66116
67400
|
} catch {
|
|
66117
67401
|
}
|
|
66118
67402
|
const hostId = `urn:uuid:${(0, import_node_crypto19.randomUUID)()}`;
|
|
66119
|
-
(0,
|
|
66120
|
-
(0,
|
|
67403
|
+
(0, import_node_fs49.mkdirSync)((0, import_node_path70.dirname)(path), { recursive: true, mode: 448 });
|
|
67404
|
+
(0, import_node_fs49.writeFileSync)(path, `${JSON.stringify({ version: 1, hostId }, null, 2)}
|
|
66121
67405
|
`, { mode: 384 });
|
|
66122
67406
|
return hostId;
|
|
66123
67407
|
}
|
|
@@ -66630,7 +67914,7 @@ init_merge();
|
|
|
66630
67914
|
init_key_docs();
|
|
66631
67915
|
init_paths();
|
|
66632
67916
|
var import_node_child_process14 = require("node:child_process");
|
|
66633
|
-
var
|
|
67917
|
+
var import_node_fs58 = require("node:fs");
|
|
66634
67918
|
var import_node_path79 = require("node:path");
|
|
66635
67919
|
init_models_dev_cache();
|
|
66636
67920
|
init_init();
|
|
@@ -66692,7 +67976,7 @@ init_ansi();
|
|
|
66692
67976
|
// src/cli/subcommands/config-set.ts
|
|
66693
67977
|
init_i18n();
|
|
66694
67978
|
init_edit2();
|
|
66695
|
-
var
|
|
67979
|
+
var import_node_fs57 = require("node:fs");
|
|
66696
67980
|
var import_node_path78 = require("node:path");
|
|
66697
67981
|
init_init();
|
|
66698
67982
|
init_paths();
|
|
@@ -66822,7 +68106,7 @@ async function runConfigEdit(action, argv, io, deps = {}) {
|
|
|
66822
68106
|
if (key === "permission.mode" && value === "full-auto" && scope === "user") {
|
|
66823
68107
|
if (!await confirmBypass(io, flags2.has("yes"), deps)) return ExitCode.Config;
|
|
66824
68108
|
}
|
|
66825
|
-
if (scope === "user" && !(0,
|
|
68109
|
+
if (scope === "user" && !(0, import_node_fs57.existsSync)((0, import_node_path78.join)(input2.configDir, CONFIG_FILE)))
|
|
66826
68110
|
initConfigDir(input2.configDir);
|
|
66827
68111
|
report(io, setConfigValue({ ...input2, scope, key, value }), value);
|
|
66828
68112
|
return ExitCode.Ok;
|
|
@@ -66835,7 +68119,7 @@ function showPaths(io) {
|
|
|
66835
68119
|
const configDir = resolveConfigDir({ env: io.env });
|
|
66836
68120
|
const dataDir = resolveDataDir({ env: io.env });
|
|
66837
68121
|
const m = msg().subcommands.configShow;
|
|
66838
|
-
const mark = (path) => `${path}${(0,
|
|
68122
|
+
const mark = (path) => `${path}${(0, import_node_fs58.existsSync)(path) ? "" : m.missing}`;
|
|
66839
68123
|
const width2 = Math.max(...[m.configDir, m.dataDir, m.projectLevel].map(visibleWidth)) + 2;
|
|
66840
68124
|
const label2 = (text) => padToWidth(text, width2);
|
|
66841
68125
|
const lines2 = [
|
|
@@ -66856,7 +68140,7 @@ function showPaths(io) {
|
|
|
66856
68140
|
function editConfig(io) {
|
|
66857
68141
|
const configDir = resolveConfigDir({ env: io.env });
|
|
66858
68142
|
const path = (0, import_node_path79.join)(configDir, CONFIG_FILE);
|
|
66859
|
-
if (!(0,
|
|
68143
|
+
if (!(0, import_node_fs58.existsSync)(path)) initConfigDir(configDir);
|
|
66860
68144
|
const editor = (io.env["VISUAL"] ?? io.env["EDITOR"] ?? "").trim();
|
|
66861
68145
|
if (editor === "") {
|
|
66862
68146
|
io.stdout(msg().subcommands.configShow.noEditor(path));
|
|
@@ -67148,7 +68432,7 @@ async function runConfig(argv, io, deps) {
|
|
|
67148
68432
|
}
|
|
67149
68433
|
|
|
67150
68434
|
// src/cli/subcommands/doctor.ts
|
|
67151
|
-
var
|
|
68435
|
+
var import_node_fs59 = require("node:fs");
|
|
67152
68436
|
init_blobs();
|
|
67153
68437
|
init_shadow_git();
|
|
67154
68438
|
init_gc();
|
|
@@ -67167,7 +68451,7 @@ init_args();
|
|
|
67167
68451
|
init_exit_codes();
|
|
67168
68452
|
|
|
67169
68453
|
// src/cli/proxy.ts
|
|
67170
|
-
var
|
|
68454
|
+
var http2 = __toESM(require("node:http"), 1);
|
|
67171
68455
|
init_i18n();
|
|
67172
68456
|
function pick5(env, name) {
|
|
67173
68457
|
const value = env[name.toLowerCase()] ?? env[name.toUpperCase()];
|
|
@@ -67175,18 +68459,18 @@ function pick5(env, name) {
|
|
|
67175
68459
|
}
|
|
67176
68460
|
function readProxyEnv(env) {
|
|
67177
68461
|
const out = {};
|
|
67178
|
-
const
|
|
68462
|
+
const https2 = pick5(env, "https_proxy");
|
|
67179
68463
|
const plain = pick5(env, "http_proxy");
|
|
67180
68464
|
const no = pick5(env, "no_proxy");
|
|
67181
|
-
if (
|
|
68465
|
+
if (https2 !== void 0) out.httpsProxy = https2;
|
|
67182
68466
|
if (plain !== void 0) out.httpProxy = plain;
|
|
67183
68467
|
if (no !== void 0) out.noProxy = no;
|
|
67184
68468
|
return out;
|
|
67185
68469
|
}
|
|
67186
68470
|
function defaultProxyRuntime() {
|
|
67187
|
-
const fn =
|
|
68471
|
+
const fn = http2.setGlobalProxyFromEnv;
|
|
67188
68472
|
return {
|
|
67189
|
-
setGlobalProxyFromEnv: typeof fn === "function" ? fn.bind(
|
|
68473
|
+
setGlobalProxyFromEnv: typeof fn === "function" ? fn.bind(http2) : void 0,
|
|
67190
68474
|
execArgv: process.execArgv,
|
|
67191
68475
|
version: process.versions.node
|
|
67192
68476
|
};
|
|
@@ -67521,7 +68805,7 @@ async function runDoctor(argv, io, deps) {
|
|
|
67521
68805
|
const m = msg().report.doctor;
|
|
67522
68806
|
report2.section(m.dirsTitle);
|
|
67523
68807
|
report2.item(m.configDir(level.configDir));
|
|
67524
|
-
report2.item(m.dataDir(level.dataDir, (0,
|
|
68808
|
+
report2.item(m.dataDir(level.dataDir, (0, import_node_fs59.existsSync)(level.dataDir)));
|
|
67525
68809
|
await fileHistoryLine(report2, level.dataDir);
|
|
67526
68810
|
report2.section(m.layersTitle);
|
|
67527
68811
|
report2.item(m.builtinDefaults);
|
|
@@ -67749,7 +69033,7 @@ init_discovered_cache();
|
|
|
67749
69033
|
init_catalog2();
|
|
67750
69034
|
init_models_dev_cache();
|
|
67751
69035
|
init_models_dev();
|
|
67752
|
-
var
|
|
69036
|
+
var import_node_fs60 = require("node:fs");
|
|
67753
69037
|
init_load();
|
|
67754
69038
|
init_write2();
|
|
67755
69039
|
init_args();
|
|
@@ -68112,7 +69396,7 @@ function writeEntries(ctx, provider, entries, notes) {
|
|
|
68112
69396
|
return 0;
|
|
68113
69397
|
}
|
|
68114
69398
|
models.push(...added);
|
|
68115
|
-
const backup = (0,
|
|
69399
|
+
const backup = (0, import_node_fs60.existsSync)(path);
|
|
68116
69400
|
writeConfigFile(path, config, { backup: true });
|
|
68117
69401
|
io.stdout(m.written(path, provider.id, added.length, kept, backup));
|
|
68118
69402
|
if (notes.noTools.size > 0) io.stdout(m.skippedNoTools([...notes.noTools].join(", ")));
|
|
@@ -68537,7 +69821,7 @@ async function runModels(argv, io, deps) {
|
|
|
68537
69821
|
}
|
|
68538
69822
|
|
|
68539
69823
|
// src/cli/subcommands/providers.ts
|
|
68540
|
-
var
|
|
69824
|
+
var import_node_fs61 = require("node:fs");
|
|
68541
69825
|
init_models_dev_cache();
|
|
68542
69826
|
init_models_dev();
|
|
68543
69827
|
init_auth_file();
|
|
@@ -68884,7 +70168,7 @@ function yesNo(value) {
|
|
|
68884
70168
|
const t = msg().subcommands.providersPlan;
|
|
68885
70169
|
return value === void 0 ? "?" : value ? t.yes : t.no;
|
|
68886
70170
|
}
|
|
68887
|
-
function
|
|
70171
|
+
function renderTable3(plans2) {
|
|
68888
70172
|
const h = msg().subcommands.providersPlan.head;
|
|
68889
70173
|
const head = [
|
|
68890
70174
|
h.model,
|
|
@@ -69140,7 +70424,7 @@ async function add(ctx, id, refresh) {
|
|
|
69140
70424
|
});
|
|
69141
70425
|
if (result.cancelled !== void 0) return result.cancelled;
|
|
69142
70426
|
io.stdout(`
|
|
69143
|
-
${
|
|
70427
|
+
${renderTable3(result.plans)}`);
|
|
69144
70428
|
if (refresh) {
|
|
69145
70429
|
const gone = [...existingIds].filter((m2) => !listed2.some((l) => l.id === m2));
|
|
69146
70430
|
if (gone.length > 0) io.stdout(m.goneUpstream(gone));
|
|
@@ -69194,7 +70478,7 @@ ${renderTable2(result.plans)}`);
|
|
|
69194
70478
|
const providers = config.providers ??= {};
|
|
69195
70479
|
providers[id] = merged.config;
|
|
69196
70480
|
if (defaultPick !== void 0) config.defaultModel = `${id}/${defaultPick.id}`;
|
|
69197
|
-
const backup = (0,
|
|
70481
|
+
const backup = (0, import_node_fs61.existsSync)(level.userConfigPath);
|
|
69198
70482
|
writeConfigFile(level.userConfigPath, config, { backup: true });
|
|
69199
70483
|
if (key.store !== void 0) setAuthKey(level.authFile, id, key.store);
|
|
69200
70484
|
io.stdout(m.written(level.userConfigPath, backup));
|
|
@@ -69319,7 +70603,7 @@ init_reuse();
|
|
|
69319
70603
|
init_clipboard_image();
|
|
69320
70604
|
|
|
69321
70605
|
// src/cli/subcommands/sessions-export.ts
|
|
69322
|
-
var
|
|
70606
|
+
var import_node_fs63 = require("node:fs");
|
|
69323
70607
|
var import_node_path81 = require("node:path");
|
|
69324
70608
|
init_paths();
|
|
69325
70609
|
|
|
@@ -69551,7 +70835,7 @@ async function runSessionsExport(argv, io) {
|
|
|
69551
70835
|
return ExitCode.Ok;
|
|
69552
70836
|
}
|
|
69553
70837
|
const target = (0, import_node_path81.resolve)(io.cwd, expandHome(output, { env: io.env }));
|
|
69554
|
-
(0,
|
|
70838
|
+
(0, import_node_fs63.writeFileSync)(target, text, { mode: 384 });
|
|
69555
70839
|
io.stderr(msg().subcommands.sessionsExport.exported(target));
|
|
69556
70840
|
return ExitCode.Ok;
|
|
69557
70841
|
}
|
|
@@ -69883,7 +71167,7 @@ function aggregateStats(summaries, options = {}) {
|
|
|
69883
71167
|
}
|
|
69884
71168
|
|
|
69885
71169
|
// src/session/stats-index.ts
|
|
69886
|
-
var
|
|
71170
|
+
var import_node_fs64 = require("node:fs");
|
|
69887
71171
|
var import_node_path82 = require("node:path");
|
|
69888
71172
|
|
|
69889
71173
|
// src/session/stats-scan.ts
|
|
@@ -70097,7 +71381,7 @@ function collectSummaries(files, options = {}) {
|
|
|
70097
71381
|
let index2 = { version: INDEX_VERSION, zone, files: {} };
|
|
70098
71382
|
if (options.indexFile !== void 0) {
|
|
70099
71383
|
try {
|
|
70100
|
-
const loaded = JSON.parse((0,
|
|
71384
|
+
const loaded = JSON.parse((0, import_node_fs64.readFileSync)(options.indexFile, "utf8"));
|
|
70101
71385
|
if (loaded.version === INDEX_VERSION && loaded.zone === zone && typeof loaded.files === "object")
|
|
70102
71386
|
index2 = loaded;
|
|
70103
71387
|
} catch {
|
|
@@ -70108,7 +71392,7 @@ function collectSummaries(files, options = {}) {
|
|
|
70108
71392
|
for (const file of files) {
|
|
70109
71393
|
let stat16;
|
|
70110
71394
|
try {
|
|
70111
|
-
stat16 = (0,
|
|
71395
|
+
stat16 = (0, import_node_fs64.statSync)(file);
|
|
70112
71396
|
} catch {
|
|
70113
71397
|
result.invalid++;
|
|
70114
71398
|
continue;
|
|
@@ -70138,10 +71422,10 @@ function collectSummaries(files, options = {}) {
|
|
|
70138
71422
|
}
|
|
70139
71423
|
if (dirty && options.indexFile !== void 0) {
|
|
70140
71424
|
try {
|
|
70141
|
-
(0,
|
|
71425
|
+
(0, import_node_fs64.mkdirSync)((0, import_node_path82.dirname)(options.indexFile), { recursive: true, mode: 448 });
|
|
70142
71426
|
const tmp = `${options.indexFile}.${process.pid}.tmp`;
|
|
70143
|
-
(0,
|
|
70144
|
-
(0,
|
|
71427
|
+
(0, import_node_fs64.writeFileSync)(tmp, JSON.stringify(index2), { mode: 384 });
|
|
71428
|
+
(0, import_node_fs64.renameSync)(tmp, options.indexFile);
|
|
70145
71429
|
} catch {
|
|
70146
71430
|
}
|
|
70147
71431
|
}
|
|
@@ -70427,7 +71711,7 @@ async function runSessionsSearch(argv, io) {
|
|
|
70427
71711
|
|
|
70428
71712
|
// src/cli/subcommands/sessions-trace.ts
|
|
70429
71713
|
var import_node_child_process15 = require("node:child_process");
|
|
70430
|
-
var
|
|
71714
|
+
var import_node_fs66 = require("node:fs");
|
|
70431
71715
|
var import_node_os13 = require("node:os");
|
|
70432
71716
|
var import_node_path86 = require("node:path");
|
|
70433
71717
|
init_paths();
|
|
@@ -70835,9 +72119,9 @@ function openCommand(platform, file) {
|
|
|
70835
72119
|
return { command: "xdg-open", args: [file] };
|
|
70836
72120
|
}
|
|
70837
72121
|
function spawnOpen({ command: command3, args }) {
|
|
70838
|
-
return new Promise((done,
|
|
72122
|
+
return new Promise((done, fail7) => {
|
|
70839
72123
|
const child = (0, import_node_child_process15.spawn)(command3, args, { detached: true, stdio: "ignore" });
|
|
70840
|
-
child.once("error",
|
|
72124
|
+
child.once("error", fail7);
|
|
70841
72125
|
child.once("spawn", () => {
|
|
70842
72126
|
child.unref();
|
|
70843
72127
|
done();
|
|
@@ -70866,7 +72150,7 @@ function splitHtmlFlag(argv) {
|
|
|
70866
72150
|
}
|
|
70867
72151
|
function locate(io, target, dirFlag) {
|
|
70868
72152
|
const asPath = (0, import_node_path86.resolve)(io.cwd, expandHome(target, { env: io.env }));
|
|
70869
|
-
if (/[\\/]|\.jsonl$/.test(target) && (0,
|
|
72153
|
+
if (/[\\/]|\.jsonl$/.test(target) && (0, import_node_fs66.existsSync)(asPath)) return asPath;
|
|
70870
72154
|
const root = dirFlag !== void 0 ? (0, import_node_path86.resolve)(io.cwd, expandHome(dirFlag, { env: io.env })) : (0, import_node_path86.join)(resolveDataDir({ env: io.env }), "sessions");
|
|
70871
72155
|
return findSessionFileReadOnly(root, target, io.cwd);
|
|
70872
72156
|
}
|
|
@@ -70939,7 +72223,7 @@ async function runSessionsTrace(argv, io, deps = {}) {
|
|
|
70939
72223
|
io.stdout(text);
|
|
70940
72224
|
return ExitCode.Ok;
|
|
70941
72225
|
}
|
|
70942
|
-
(0,
|
|
72226
|
+
(0, import_node_fs66.writeFileSync)(outPath, text, { mode: 384 });
|
|
70943
72227
|
io.stderr(m.wrote(outPath));
|
|
70944
72228
|
if (open3) {
|
|
70945
72229
|
try {
|
|
@@ -71140,7 +72424,7 @@ function readStdinDefault() {
|
|
|
71140
72424
|
}
|
|
71141
72425
|
function stdinKindDefault() {
|
|
71142
72426
|
try {
|
|
71143
|
-
const stat16 = (0,
|
|
72427
|
+
const stat16 = (0, import_node_fs76.fstatSync)(0);
|
|
71144
72428
|
if (stat16.isFile()) return "file";
|
|
71145
72429
|
if (stat16.isFIFO()) return "fifo";
|
|
71146
72430
|
if (stat16.isSocket()) return "socket";
|
|
@@ -71200,7 +72484,7 @@ function defaultIo() {
|
|
|
71200
72484
|
}
|
|
71201
72485
|
function peekUserLanguage(env) {
|
|
71202
72486
|
try {
|
|
71203
|
-
const raw = (0,
|
|
72487
|
+
const raw = (0, import_node_fs76.readFileSync)((0, import_node_path104.join)(resolveConfigDir({ env }), "config.json"), "utf8");
|
|
71204
72488
|
const value = JSON.parse(raw).ui?.language;
|
|
71205
72489
|
return value === "auto" || value === "zh" || value === "en" ? value : void 0;
|
|
71206
72490
|
} catch {
|
|
@@ -71288,7 +72572,7 @@ function isDirectRun() {
|
|
|
71288
72572
|
const entry = process.argv[1];
|
|
71289
72573
|
if (entry === void 0) return false;
|
|
71290
72574
|
try {
|
|
71291
|
-
return (0,
|
|
72575
|
+
return (0, import_node_fs76.realpathSync)(entry) === (0, import_node_fs76.realpathSync)((0, import_node_url3.fileURLToPath)(__ama_import_meta_url));
|
|
71292
72576
|
} catch {
|
|
71293
72577
|
return false;
|
|
71294
72578
|
}
|