@armadra/agent 0.9.3 → 0.11.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 +22 -0
- package/CHANGELOG.zh-CN.md +22 -0
- package/README.md +5 -0
- package/README.zh-CN.md +4 -0
- package/dist/bundle/ama.cjs +1606 -423
- package/dist/cli/compose.d.ts +3 -0
- package/dist/cli/compose.js +1 -0
- 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.js +2 -2
- 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/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/rules.d.ts +1 -0
- package/dist/permissions/rules.js +5 -1
- package/dist/tools/presets.d.ts +1 -1
- package/dist/tools/presets.js +2 -2
- package/dist/tools/registry.d.ts +3 -1
- package/dist/tools/registry.js +4 -2
- 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 +23 -1
- package/docs/en/reference/host-api.md +61 -19
- package/docs/en/reference/rpc.md +7 -7
- package/docs/guides/agents.md +14 -0
- package/docs/guides/hooks.md +86 -8
- package/docs/guides/permissions.md +23 -1
- package/docs/guides/sandbox.md +6 -0
- 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.11.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);
|
|
@@ -16134,10 +16511,18 @@ function safeFileName(name) {
|
|
|
16134
16511
|
const cleaned = name.replace(/[^A-Za-z0-9._-]/g, "_");
|
|
16135
16512
|
return cleaned === "" ? "output" : cleaned.slice(0, 120);
|
|
16136
16513
|
}
|
|
16137
|
-
|
|
16514
|
+
function writeFullOutput(outputDir, fileName, content) {
|
|
16515
|
+
const dir = resolveOutputDir(outputDir);
|
|
16516
|
+
(0, import_node_fs22.mkdirSync)(dir, { recursive: true });
|
|
16517
|
+
const target = (0, import_node_path24.join)(dir, safeFileName(fileName));
|
|
16518
|
+
(0, import_node_fs22.writeFileSync)(target, content);
|
|
16519
|
+
return target;
|
|
16520
|
+
}
|
|
16521
|
+
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
16522
|
var init_truncate = __esm({
|
|
16139
16523
|
"src/tools/truncate.ts"() {
|
|
16140
16524
|
"use strict";
|
|
16525
|
+
import_node_fs22 = require("node:fs");
|
|
16141
16526
|
import_node_os4 = require("node:os");
|
|
16142
16527
|
import_node_path24 = require("node:path");
|
|
16143
16528
|
DEFAULT_MAX_LINES = 2e3;
|
|
@@ -16777,11 +17162,11 @@ async function readImage(abs, shown2, ctx, options) {
|
|
|
16777
17162
|
[${fit.note}]`, details };
|
|
16778
17163
|
const note = fit.resized !== void 0 && fit.size !== void 0 ? `
|
|
16779
17164
|
[Resized to ${fit.size.width}x${fit.size.height} to fit the attachment limit.]` : "";
|
|
16780
|
-
const
|
|
17165
|
+
const blocks2 = [
|
|
16781
17166
|
{ type: "text", text: caption + note },
|
|
16782
17167
|
internImage({ type: "image", data: fit.buf.toString("base64"), mimeType: fit.mimeType })
|
|
16783
17168
|
];
|
|
16784
|
-
return { content:
|
|
17169
|
+
return { content: blocks2, details };
|
|
16785
17170
|
}
|
|
16786
17171
|
async function executeRead(input2, ctx, options = {}) {
|
|
16787
17172
|
const abs = resolvePath(input2.path, ctx.cwd);
|
|
@@ -17251,7 +17636,7 @@ function gitBashCandidates(env) {
|
|
|
17251
17636
|
function resolveShell(deps = {}) {
|
|
17252
17637
|
const platform = deps.platform ?? process.platform;
|
|
17253
17638
|
const env = deps.env ?? process.env;
|
|
17254
|
-
const exists5 = deps.exists ??
|
|
17639
|
+
const exists5 = deps.exists ?? import_node_fs23.existsSync;
|
|
17255
17640
|
const custom = env["AMA_SHELL"]?.trim();
|
|
17256
17641
|
if (custom) return { shell: custom, kind: shellKindOf(custom) };
|
|
17257
17642
|
if (platform === "win32") {
|
|
@@ -17291,11 +17676,11 @@ function buildToolEnv(base4, info2) {
|
|
|
17291
17676
|
set("AMA_DEPTH", String(info2.depth));
|
|
17292
17677
|
return env;
|
|
17293
17678
|
}
|
|
17294
|
-
var
|
|
17679
|
+
var import_node_fs23, POWERSHELL_ARGS, INJECTED_ENV_VARS;
|
|
17295
17680
|
var init_shell = __esm({
|
|
17296
17681
|
"src/tools/shell.ts"() {
|
|
17297
17682
|
"use strict";
|
|
17298
|
-
|
|
17683
|
+
import_node_fs23 = require("node:fs");
|
|
17299
17684
|
POWERSHELL_ARGS = ["-NoProfile", "-NonInteractive", "-Command"];
|
|
17300
17685
|
INJECTED_ENV_VARS = [
|
|
17301
17686
|
"AMA_SESSION_ID",
|
|
@@ -17410,11 +17795,11 @@ var init_process_tree = __esm({
|
|
|
17410
17795
|
function sanitizeOutput(text) {
|
|
17411
17796
|
return text.replace(/\r\n/g, "\n").replace(ANSI, "").replace(/\r/g, "\n").replace(CONTROL, "");
|
|
17412
17797
|
}
|
|
17413
|
-
var
|
|
17798
|
+
var import_node_fs24, import_node_path28, import_node_string_decoder2, ANSI, CONTROL, OutputAccumulator;
|
|
17414
17799
|
var init_output_accumulator = __esm({
|
|
17415
17800
|
"src/tools/output-accumulator.ts"() {
|
|
17416
17801
|
"use strict";
|
|
17417
|
-
|
|
17802
|
+
import_node_fs24 = require("node:fs");
|
|
17418
17803
|
import_node_path28 = require("node:path");
|
|
17419
17804
|
import_node_string_decoder2 = require("node:string_decoder");
|
|
17420
17805
|
init_truncate();
|
|
@@ -17456,7 +17841,7 @@ var init_output_accumulator = __esm({
|
|
|
17456
17841
|
this.tailText = sliceTailBytes(this.tailText, this.maxBytes * 2);
|
|
17457
17842
|
}
|
|
17458
17843
|
if (this.spilledTo !== void 0) {
|
|
17459
|
-
(0,
|
|
17844
|
+
(0, import_node_fs24.appendFileSync)(this.spilledTo, text);
|
|
17460
17845
|
return;
|
|
17461
17846
|
}
|
|
17462
17847
|
this.chunks.push(text);
|
|
@@ -17465,8 +17850,8 @@ var init_output_accumulator = __esm({
|
|
|
17465
17850
|
}
|
|
17466
17851
|
spill() {
|
|
17467
17852
|
const target = this.options.spillPath();
|
|
17468
|
-
(0,
|
|
17469
|
-
(0,
|
|
17853
|
+
(0, import_node_fs24.mkdirSync)((0, import_node_path28.dirname)(target), { recursive: true });
|
|
17854
|
+
(0, import_node_fs24.writeFileSync)(target, this.chunks.join(""));
|
|
17470
17855
|
this.spilledTo = target;
|
|
17471
17856
|
this.chunks = [];
|
|
17472
17857
|
this.memoryBytes = 0;
|
|
@@ -17524,11 +17909,11 @@ async function disposeSessionJobs(sessionId) {
|
|
|
17524
17909
|
registry2.delete(sessionId);
|
|
17525
17910
|
await jobs.disposeAll();
|
|
17526
17911
|
}
|
|
17527
|
-
var
|
|
17912
|
+
var import_node_fs25, import_node_path29, BackgroundJobs, registry2;
|
|
17528
17913
|
var init_background_jobs = __esm({
|
|
17529
17914
|
"src/tools/background-jobs.ts"() {
|
|
17530
17915
|
"use strict";
|
|
17531
|
-
|
|
17916
|
+
import_node_fs25 = require("node:fs");
|
|
17532
17917
|
import_node_path29 = require("node:path");
|
|
17533
17918
|
init_process_tree();
|
|
17534
17919
|
init_truncate();
|
|
@@ -17537,13 +17922,13 @@ var init_background_jobs = __esm({
|
|
|
17537
17922
|
listeners = /* @__PURE__ */ new Set();
|
|
17538
17923
|
seq = 0;
|
|
17539
17924
|
start(command3, options) {
|
|
17540
|
-
(0,
|
|
17541
|
-
const fd = (0,
|
|
17925
|
+
(0, import_node_fs25.mkdirSync)((0, import_node_path29.dirname)(options.outputPath), { recursive: true });
|
|
17926
|
+
const fd = (0, import_node_fs25.openSync)(options.outputPath, "a");
|
|
17542
17927
|
let child;
|
|
17543
17928
|
try {
|
|
17544
17929
|
child = options.spawn(fd);
|
|
17545
17930
|
} finally {
|
|
17546
|
-
(0,
|
|
17931
|
+
(0, import_node_fs25.closeSync)(fd);
|
|
17547
17932
|
}
|
|
17548
17933
|
const id = `bg${++this.seq}`;
|
|
17549
17934
|
const job = {
|
|
@@ -17624,8 +18009,8 @@ var init_background_jobs = __esm({
|
|
|
17624
18009
|
if (entry === void 0) return void 0;
|
|
17625
18010
|
let text = "";
|
|
17626
18011
|
try {
|
|
17627
|
-
if ((0,
|
|
17628
|
-
text = (0,
|
|
18012
|
+
if ((0, import_node_fs25.statSync)(entry.job.outputPath).size > 0)
|
|
18013
|
+
text = (0, import_node_fs25.readFileSync)(entry.job.outputPath, "utf8");
|
|
17629
18014
|
} catch {
|
|
17630
18015
|
}
|
|
17631
18016
|
return { ...truncateTail(text, options), job: entry.job };
|
|
@@ -17671,7 +18056,7 @@ var init_background_jobs = __esm({
|
|
|
17671
18056
|
});
|
|
17672
18057
|
|
|
17673
18058
|
// src/sandbox/wrap.ts
|
|
17674
|
-
function resolveWritable(dirs, realpath4 =
|
|
18059
|
+
function resolveWritable(dirs, realpath4 = import_node_fs26.realpathSync) {
|
|
17675
18060
|
const out = [];
|
|
17676
18061
|
for (const dir of dirs) {
|
|
17677
18062
|
let real2;
|
|
@@ -17686,12 +18071,12 @@ function resolveWritable(dirs, realpath4 = import_node_fs25.realpathSync) {
|
|
|
17686
18071
|
}
|
|
17687
18072
|
function isDirectory(path) {
|
|
17688
18073
|
try {
|
|
17689
|
-
return (0,
|
|
18074
|
+
return (0, import_node_fs26.statSync)(path).isDirectory();
|
|
17690
18075
|
} catch {
|
|
17691
18076
|
return false;
|
|
17692
18077
|
}
|
|
17693
18078
|
}
|
|
17694
|
-
function resolveExtras(policy, missingOk, realpath4 =
|
|
18079
|
+
function resolveExtras(policy, missingOk, realpath4 = import_node_fs26.realpathSync, isDir4 = isDirectory) {
|
|
17695
18080
|
const readOnly = [];
|
|
17696
18081
|
for (const path of policy.readOnly ?? []) {
|
|
17697
18082
|
let real2;
|
|
@@ -17763,11 +18148,11 @@ function wrapCommand(status, command3, args, policy, realpath4, isDir4) {
|
|
|
17763
18148
|
};
|
|
17764
18149
|
}
|
|
17765
18150
|
}
|
|
17766
|
-
var
|
|
18151
|
+
var import_node_fs26, import_node_path30;
|
|
17767
18152
|
var init_wrap = __esm({
|
|
17768
18153
|
"src/sandbox/wrap.ts"() {
|
|
17769
18154
|
"use strict";
|
|
17770
|
-
|
|
18155
|
+
import_node_fs26 = require("node:fs");
|
|
17771
18156
|
import_node_path30 = require("node:path");
|
|
17772
18157
|
init_profile2();
|
|
17773
18158
|
}
|
|
@@ -18281,7 +18666,7 @@ async function executeGrep(input2, ctx) {
|
|
|
18281
18666
|
}
|
|
18282
18667
|
const files = await candidateFiles(root, rootIsFile, input2.glob, ctx.signal);
|
|
18283
18668
|
if (input2.filesOnly === true) return grepFilesOnly(files, regex, limit, ctx);
|
|
18284
|
-
const
|
|
18669
|
+
const blocks2 = [];
|
|
18285
18670
|
let matches2 = 0;
|
|
18286
18671
|
let matchedFiles = 0;
|
|
18287
18672
|
let limited = false;
|
|
@@ -18298,7 +18683,7 @@ async function executeGrep(input2, ctx) {
|
|
|
18298
18683
|
}
|
|
18299
18684
|
const shown2 = displayPath(batch[j], ctx.cwd);
|
|
18300
18685
|
const block = formatFileHits(shown2, hits, context, limit - matches2);
|
|
18301
|
-
|
|
18686
|
+
blocks2.push(block.text.join("\n"));
|
|
18302
18687
|
matches2 += block.used;
|
|
18303
18688
|
matchedFiles++;
|
|
18304
18689
|
if (block.used < hits.hits.length) {
|
|
@@ -18308,7 +18693,7 @@ async function executeGrep(input2, ctx) {
|
|
|
18308
18693
|
}
|
|
18309
18694
|
}
|
|
18310
18695
|
if (matches2 === 0) return { content: "No matches found", details: { matches: 0, files: 0 } };
|
|
18311
|
-
const joined =
|
|
18696
|
+
const joined = blocks2.join(context > 0 ? "\n--\n" : "\n");
|
|
18312
18697
|
const maxBytes = toolOutputBytes(ctx.maxResultChars);
|
|
18313
18698
|
const cut = truncateHead(joined, { maxLines: Number.MAX_SAFE_INTEGER, maxBytes });
|
|
18314
18699
|
let content = cut.content;
|
|
@@ -18764,9 +19149,9 @@ ${tail}`, truncated: true };
|
|
|
18764
19149
|
}
|
|
18765
19150
|
function writeTaskOutput(dir, name, text) {
|
|
18766
19151
|
try {
|
|
18767
|
-
(0,
|
|
19152
|
+
(0, import_node_fs27.mkdirSync)(dir, { recursive: true });
|
|
18768
19153
|
const file = (0, import_node_path34.join)(dir, name);
|
|
18769
|
-
(0,
|
|
19154
|
+
(0, import_node_fs27.writeFileSync)(file, text);
|
|
18770
19155
|
return file;
|
|
18771
19156
|
} catch {
|
|
18772
19157
|
return void 0;
|
|
@@ -18803,11 +19188,11 @@ function backgroundedText(reason, afterMs) {
|
|
|
18803
19188
|
function waitDetachedText(taskId) {
|
|
18804
19189
|
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
19190
|
}
|
|
18806
|
-
var
|
|
19191
|
+
var import_node_fs27, import_node_path34, TASK_RESULT_LIMIT_BYTES, HEAD_SHARE, MAX_TURNS_NOTE, NOTIFY_HINT, TASK_NOTIFICATION_RULE;
|
|
18807
19192
|
var init_result = __esm({
|
|
18808
19193
|
"src/agents/result.ts"() {
|
|
18809
19194
|
"use strict";
|
|
18810
|
-
|
|
19195
|
+
import_node_fs27 = require("node:fs");
|
|
18811
19196
|
import_node_path34 = require("node:path");
|
|
18812
19197
|
TASK_RESULT_LIMIT_BYTES = 50 * 1024;
|
|
18813
19198
|
HEAD_SHARE = 0.7;
|
|
@@ -19099,6 +19484,747 @@ var init_task_ctl = __esm({
|
|
|
19099
19484
|
}
|
|
19100
19485
|
});
|
|
19101
19486
|
|
|
19487
|
+
// src/tools/web/html-to-markdown.ts
|
|
19488
|
+
function decodeEntities(text) {
|
|
19489
|
+
return text.replace(/&(#x[0-9a-f]+|#\d+|[a-z][a-z0-9]*);?/gi, (whole, body) => {
|
|
19490
|
+
if (body[0] === "#") {
|
|
19491
|
+
const code = body[1] === "x" || body[1] === "X" ? parseInt(body.slice(2), 16) : Number(body.slice(1));
|
|
19492
|
+
if (!Number.isFinite(code) || code <= 0 || code > 1114111 || code >= 55296 && code <= 57343)
|
|
19493
|
+
return "�";
|
|
19494
|
+
return String.fromCodePoint(code);
|
|
19495
|
+
}
|
|
19496
|
+
const hit = ENTITIES[body] ?? ENTITIES[body.toLowerCase()];
|
|
19497
|
+
return hit ?? whole;
|
|
19498
|
+
});
|
|
19499
|
+
}
|
|
19500
|
+
function parseAttrs(text) {
|
|
19501
|
+
const attrs = {};
|
|
19502
|
+
for (const m of text.matchAll(ATTR_RE)) {
|
|
19503
|
+
const name = m[1].toLowerCase();
|
|
19504
|
+
if (!(name in attrs)) attrs[name] = decodeEntities(m[2] ?? m[3] ?? m[4] ?? "");
|
|
19505
|
+
}
|
|
19506
|
+
return attrs;
|
|
19507
|
+
}
|
|
19508
|
+
function parseHtml(html) {
|
|
19509
|
+
const root = { tag: "#root", attrs: {}, children: [] };
|
|
19510
|
+
let cur = root;
|
|
19511
|
+
const open3 = (tag) => {
|
|
19512
|
+
for (let n = cur; n !== void 0; n = n.parent) if (n.tag === tag) return n;
|
|
19513
|
+
return void 0;
|
|
19514
|
+
};
|
|
19515
|
+
const closeTo = (node) => {
|
|
19516
|
+
cur = node.parent ?? root;
|
|
19517
|
+
};
|
|
19518
|
+
const closeOpen = (tags, stop) => {
|
|
19519
|
+
for (let n = cur; n !== void 0 && n !== root; n = n.parent) {
|
|
19520
|
+
if (tags.includes(n.tag)) return closeTo(n);
|
|
19521
|
+
if (stop.has(n.tag)) return;
|
|
19522
|
+
}
|
|
19523
|
+
};
|
|
19524
|
+
let i = 0;
|
|
19525
|
+
while (i < html.length) {
|
|
19526
|
+
const lt = html.indexOf("<", i);
|
|
19527
|
+
if (lt === -1) {
|
|
19528
|
+
cur.children.push(html.slice(i));
|
|
19529
|
+
break;
|
|
19530
|
+
}
|
|
19531
|
+
if (lt > i) cur.children.push(html.slice(i, lt));
|
|
19532
|
+
if (html.startsWith("<!--", lt)) {
|
|
19533
|
+
const end = html.indexOf("-->", lt + 4);
|
|
19534
|
+
i = end === -1 ? html.length : end + 3;
|
|
19535
|
+
continue;
|
|
19536
|
+
}
|
|
19537
|
+
if (html[lt + 1] === "!" || html[lt + 1] === "?") {
|
|
19538
|
+
const end = html.indexOf(">", lt);
|
|
19539
|
+
i = end === -1 ? html.length : end + 1;
|
|
19540
|
+
continue;
|
|
19541
|
+
}
|
|
19542
|
+
const m = /^<(\/?)([a-zA-Z][a-zA-Z0-9:-]*)((?:[^>"']|"[^"]*"|'[^']*')*)>/.exec(
|
|
19543
|
+
html.slice(lt, lt + 8192)
|
|
19544
|
+
);
|
|
19545
|
+
if (m === null) {
|
|
19546
|
+
cur.children.push("<");
|
|
19547
|
+
i = lt + 1;
|
|
19548
|
+
continue;
|
|
19549
|
+
}
|
|
19550
|
+
i = lt + m[0].length;
|
|
19551
|
+
const tag = m[2].toLowerCase();
|
|
19552
|
+
if (m[1] === "/") {
|
|
19553
|
+
const node2 = open3(tag);
|
|
19554
|
+
if (node2 !== void 0) closeTo(node2);
|
|
19555
|
+
continue;
|
|
19556
|
+
}
|
|
19557
|
+
if (CLOSES_P.has(tag)) closeOpen(["p"], BLOCK);
|
|
19558
|
+
const siblings = AUTO_CLOSE[tag];
|
|
19559
|
+
if (siblings !== void 0) closeOpen(siblings, SCOPE);
|
|
19560
|
+
const node = { tag, attrs: parseAttrs(m[3]), children: [], parent: cur };
|
|
19561
|
+
cur.children.push(node);
|
|
19562
|
+
if (RAW_TEXT.has(tag)) {
|
|
19563
|
+
const end = html.toLowerCase().indexOf(`</${tag}`, i);
|
|
19564
|
+
const body = html.slice(i, end === -1 ? html.length : end);
|
|
19565
|
+
node.children.push(body);
|
|
19566
|
+
const close = end === -1 ? -1 : html.indexOf(">", end);
|
|
19567
|
+
i = close === -1 ? html.length : close + 1;
|
|
19568
|
+
continue;
|
|
19569
|
+
}
|
|
19570
|
+
if (!VOID.has(tag) && !/\/\s*$/.test(m[3])) cur = node;
|
|
19571
|
+
}
|
|
19572
|
+
return root;
|
|
19573
|
+
}
|
|
19574
|
+
function find(node, test) {
|
|
19575
|
+
for (const child of node.children) {
|
|
19576
|
+
if (typeof child === "string") continue;
|
|
19577
|
+
if (test(child)) return child;
|
|
19578
|
+
if (DROP.has(child.tag)) continue;
|
|
19579
|
+
const hit = find(child, test);
|
|
19580
|
+
if (hit !== void 0) return hit;
|
|
19581
|
+
}
|
|
19582
|
+
return void 0;
|
|
19583
|
+
}
|
|
19584
|
+
function rawText(node) {
|
|
19585
|
+
return node.children.map((c) => typeof c === "string" ? c : rawText(c)).join("");
|
|
19586
|
+
}
|
|
19587
|
+
function resolveHref(href, base4) {
|
|
19588
|
+
const value = href.trim();
|
|
19589
|
+
if (value === "" || /^(javascript|data|vbscript):/i.test(value)) return void 0;
|
|
19590
|
+
if (value.startsWith("#")) return void 0;
|
|
19591
|
+
try {
|
|
19592
|
+
return base4 === void 0 ? new URL(value).href : new URL(value, base4).href;
|
|
19593
|
+
} catch {
|
|
19594
|
+
return void 0;
|
|
19595
|
+
}
|
|
19596
|
+
}
|
|
19597
|
+
function collapse(text) {
|
|
19598
|
+
return decodeEntities(text).replace(/[\s\u00a0]+/g, " ");
|
|
19599
|
+
}
|
|
19600
|
+
function inline(node, ctx) {
|
|
19601
|
+
let out = "";
|
|
19602
|
+
for (const child of node.children) {
|
|
19603
|
+
if (typeof child === "string") out += collapse(child);
|
|
19604
|
+
else out += renderInline(child, ctx);
|
|
19605
|
+
}
|
|
19606
|
+
return out;
|
|
19607
|
+
}
|
|
19608
|
+
function wrap(mark, text) {
|
|
19609
|
+
const trimmed = text.trim();
|
|
19610
|
+
if (trimmed === "") return text;
|
|
19611
|
+
const lead = text.startsWith(" ") ? " " : "";
|
|
19612
|
+
const trail = text.endsWith(" ") ? " " : "";
|
|
19613
|
+
return `${lead}${mark}${trimmed}${mark}${trail}`;
|
|
19614
|
+
}
|
|
19615
|
+
function renderInline(node, ctx) {
|
|
19616
|
+
if (DROP.has(node.tag)) return "";
|
|
19617
|
+
switch (node.tag) {
|
|
19618
|
+
case "br":
|
|
19619
|
+
return "\n";
|
|
19620
|
+
case "img": {
|
|
19621
|
+
const alt = (node.attrs["alt"] ?? "").trim();
|
|
19622
|
+
return alt === "" ? "" : collapse(alt);
|
|
19623
|
+
}
|
|
19624
|
+
case "a": {
|
|
19625
|
+
const text = inline(node, ctx);
|
|
19626
|
+
const href = resolveHref(node.attrs["href"] ?? "", ctx.base);
|
|
19627
|
+
if (href === void 0 || text.trim() === "") return text;
|
|
19628
|
+
return `[${text.trim().replace(/[[\]]/g, "\\$&")}](${href.replace(/[()\s]/g, encodeURIComponent)})`;
|
|
19629
|
+
}
|
|
19630
|
+
case "code":
|
|
19631
|
+
case "kbd":
|
|
19632
|
+
case "samp":
|
|
19633
|
+
case "tt": {
|
|
19634
|
+
const text = decodeEntities(rawText(node)).replace(/\s+/g, " ");
|
|
19635
|
+
if (text.trim() === "") return text;
|
|
19636
|
+
const fence2 = text.includes("`") ? "``" : "`";
|
|
19637
|
+
return `${fence2}${text}${fence2}`;
|
|
19638
|
+
}
|
|
19639
|
+
case "strong":
|
|
19640
|
+
case "b":
|
|
19641
|
+
return wrap("**", inline(node, ctx));
|
|
19642
|
+
case "em":
|
|
19643
|
+
case "i":
|
|
19644
|
+
return wrap("*", inline(node, ctx));
|
|
19645
|
+
case "del":
|
|
19646
|
+
case "s":
|
|
19647
|
+
return wrap("~~", inline(node, ctx));
|
|
19648
|
+
default:
|
|
19649
|
+
return BLOCK.has(node.tag) ? `
|
|
19650
|
+
|
|
19651
|
+
${blocks(node, ctx)}
|
|
19652
|
+
|
|
19653
|
+
` : inline(node, ctx);
|
|
19654
|
+
}
|
|
19655
|
+
}
|
|
19656
|
+
function blocks(node, ctx) {
|
|
19657
|
+
const parts = [];
|
|
19658
|
+
let run7 = "";
|
|
19659
|
+
const flush = () => {
|
|
19660
|
+
const text = run7.split("\n").map((l) => l.replace(/ {2,}/g, " ").trim()).join("\n").trim();
|
|
19661
|
+
if (text !== "") parts.push(text);
|
|
19662
|
+
run7 = "";
|
|
19663
|
+
};
|
|
19664
|
+
for (const child of node.children) {
|
|
19665
|
+
if (typeof child === "string") {
|
|
19666
|
+
run7 += collapse(child);
|
|
19667
|
+
continue;
|
|
19668
|
+
}
|
|
19669
|
+
if (DROP.has(child.tag)) continue;
|
|
19670
|
+
if (BLOCK.has(child.tag)) {
|
|
19671
|
+
flush();
|
|
19672
|
+
const text = renderBlock(child, ctx);
|
|
19673
|
+
if (text.trim() !== "") parts.push(text);
|
|
19674
|
+
} else run7 += renderInline(child, ctx);
|
|
19675
|
+
}
|
|
19676
|
+
flush();
|
|
19677
|
+
return parts.join("\n\n");
|
|
19678
|
+
}
|
|
19679
|
+
function prefixLines(text, first, rest) {
|
|
19680
|
+
return text.split("\n").map(
|
|
19681
|
+
(line2, i) => line2 === "" ? i === 0 ? first.trimEnd() : "" : `${i === 0 ? first : rest}${line2}`
|
|
19682
|
+
).join("\n");
|
|
19683
|
+
}
|
|
19684
|
+
function renderList(node, ctx) {
|
|
19685
|
+
const ordered = node.tag === "ol";
|
|
19686
|
+
let n = Number(node.attrs["start"] ?? "1");
|
|
19687
|
+
if (!Number.isFinite(n)) n = 1;
|
|
19688
|
+
const items = [];
|
|
19689
|
+
const inner = { ...ctx, listDepth: ctx.listDepth + 1 };
|
|
19690
|
+
for (const child of node.children) {
|
|
19691
|
+
if (typeof child === "string" || DROP.has(child.tag)) continue;
|
|
19692
|
+
const body = child.tag === "li" ? blocks(child, inner) : renderBlock(child, inner);
|
|
19693
|
+
if (body.trim() === "") continue;
|
|
19694
|
+
const marker = ordered ? `${n++}. ` : "- ";
|
|
19695
|
+
items.push(prefixLines(body.replace(/\n{2,}/g, "\n"), marker, " ".repeat(marker.length)));
|
|
19696
|
+
}
|
|
19697
|
+
return items.join("\n");
|
|
19698
|
+
}
|
|
19699
|
+
function cellText(node, ctx) {
|
|
19700
|
+
return blocks(node, ctx).replace(/\s*\n+\s*/g, " ").replace(/\|/g, "\\|").trim();
|
|
19701
|
+
}
|
|
19702
|
+
function renderTable(node, ctx) {
|
|
19703
|
+
const rows = [];
|
|
19704
|
+
const walk4 = (n) => {
|
|
19705
|
+
for (const child of n.children) {
|
|
19706
|
+
if (typeof child === "string" || DROP.has(child.tag)) continue;
|
|
19707
|
+
if (child.tag === "tr") {
|
|
19708
|
+
const cells = child.children.filter(
|
|
19709
|
+
(c) => typeof c !== "string" && (c.tag === "td" || c.tag === "th")
|
|
19710
|
+
);
|
|
19711
|
+
if (cells.length > 0)
|
|
19712
|
+
rows.push({
|
|
19713
|
+
cells: cells.map((c) => cellText(c, ctx)),
|
|
19714
|
+
header: n.tag === "thead" || cells.every((c) => c.tag === "th")
|
|
19715
|
+
});
|
|
19716
|
+
} else if (child.tag !== "table") walk4(child);
|
|
19717
|
+
}
|
|
19718
|
+
};
|
|
19719
|
+
walk4(node);
|
|
19720
|
+
if (rows.length === 0) return "";
|
|
19721
|
+
const width2 = Math.max(...rows.map((r) => r.cells.length));
|
|
19722
|
+
const line2 = (cells) => `| ${[...cells, ...new Array(width2 - cells.length).fill("")].join(" | ")} |`;
|
|
19723
|
+
const headerIndex = rows[0]?.header === true ? 0 : -1;
|
|
19724
|
+
const head = headerIndex === 0 ? rows.shift().cells : new Array(width2).fill("");
|
|
19725
|
+
return [line2(head), `|${" --- |".repeat(width2)}`, ...rows.map((r) => line2(r.cells))].join("\n");
|
|
19726
|
+
}
|
|
19727
|
+
function renderBlock(node, ctx) {
|
|
19728
|
+
switch (node.tag) {
|
|
19729
|
+
case "h1":
|
|
19730
|
+
case "h2":
|
|
19731
|
+
case "h3":
|
|
19732
|
+
case "h4":
|
|
19733
|
+
case "h5":
|
|
19734
|
+
case "h6": {
|
|
19735
|
+
const text = inline(node, ctx).replace(/\s+/g, " ").trim();
|
|
19736
|
+
return text === "" ? "" : `${"#".repeat(Number(node.tag[1]))} ${text}`;
|
|
19737
|
+
}
|
|
19738
|
+
case "hr":
|
|
19739
|
+
return "---";
|
|
19740
|
+
case "pre": {
|
|
19741
|
+
const code = find(node, (n) => n.tag === "code");
|
|
19742
|
+
const cls = `${code?.attrs["class"] ?? ""} ${node.attrs["class"] ?? ""}`;
|
|
19743
|
+
const lang = /(?:^|\s)(?:language|lang)-([\w+#-]+)/.exec(cls)?.[1] ?? "";
|
|
19744
|
+
const text = decodeEntities(rawText(node)).replace(/^\n/, "").replace(/\s+$/, "");
|
|
19745
|
+
const fence2 = text.includes("```") ? "~~~~" : "```";
|
|
19746
|
+
return `${fence2}${lang}
|
|
19747
|
+
${text}
|
|
19748
|
+
${fence2}`;
|
|
19749
|
+
}
|
|
19750
|
+
case "blockquote":
|
|
19751
|
+
return prefixLines(blocks(node, ctx), "> ", "> ");
|
|
19752
|
+
case "ul":
|
|
19753
|
+
case "ol":
|
|
19754
|
+
return renderList(node, ctx);
|
|
19755
|
+
case "table":
|
|
19756
|
+
return renderTable(node, ctx);
|
|
19757
|
+
default:
|
|
19758
|
+
return blocks(node, ctx);
|
|
19759
|
+
}
|
|
19760
|
+
}
|
|
19761
|
+
function pageTitle(root) {
|
|
19762
|
+
const title = find(root, (n) => n.tag === "title") ?? findIn(root, "title");
|
|
19763
|
+
const text = title !== void 0 ? collapse(rawText(title)).trim() : "";
|
|
19764
|
+
if (text !== "") return text;
|
|
19765
|
+
const h1 = find(root, (n) => n.tag === "h1");
|
|
19766
|
+
const heading = h1 !== void 0 ? collapse(rawText(h1)).trim() : "";
|
|
19767
|
+
return heading === "" ? void 0 : heading;
|
|
19768
|
+
}
|
|
19769
|
+
function findIn(node, tag) {
|
|
19770
|
+
for (const child of node.children) {
|
|
19771
|
+
if (typeof child === "string") continue;
|
|
19772
|
+
if (child.tag === tag) return child;
|
|
19773
|
+
const hit = findIn(child, tag);
|
|
19774
|
+
if (hit !== void 0) return hit;
|
|
19775
|
+
}
|
|
19776
|
+
return void 0;
|
|
19777
|
+
}
|
|
19778
|
+
function htmlToMarkdown(html, baseUrl) {
|
|
19779
|
+
const root = parseHtml(html);
|
|
19780
|
+
let base4;
|
|
19781
|
+
try {
|
|
19782
|
+
const declared = findIn(root, "base")?.attrs["href"];
|
|
19783
|
+
base4 = baseUrl === void 0 ? void 0 : new URL(declared ?? "", baseUrl);
|
|
19784
|
+
} catch {
|
|
19785
|
+
base4 = baseUrl === void 0 ? void 0 : new URL(baseUrl);
|
|
19786
|
+
}
|
|
19787
|
+
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;
|
|
19788
|
+
const markdown = blocks(main2, { base: base4, listDepth: 0 }).replace(/[ \t]+\n/g, "\n").replace(/\n{3,}/g, "\n\n").trim();
|
|
19789
|
+
const title = pageTitle(root);
|
|
19790
|
+
return title === void 0 ? { markdown } : { title, markdown };
|
|
19791
|
+
}
|
|
19792
|
+
function sniffMetaCharset(head) {
|
|
19793
|
+
const text = head.slice(0, 2048);
|
|
19794
|
+
const direct = /<meta[^>]+charset\s*=\s*["']?\s*([\w.:-]+)/i.exec(text);
|
|
19795
|
+
return direct?.[1]?.toLowerCase();
|
|
19796
|
+
}
|
|
19797
|
+
var VOID, RAW_TEXT, DROP, BLOCK, AUTO_CLOSE, CLOSES_P, SCOPE, ENTITIES, ATTR_RE;
|
|
19798
|
+
var init_html_to_markdown = __esm({
|
|
19799
|
+
"src/tools/web/html-to-markdown.ts"() {
|
|
19800
|
+
"use strict";
|
|
19801
|
+
VOID = /* @__PURE__ */ new Set([
|
|
19802
|
+
"area",
|
|
19803
|
+
"base",
|
|
19804
|
+
"br",
|
|
19805
|
+
"col",
|
|
19806
|
+
"embed",
|
|
19807
|
+
"hr",
|
|
19808
|
+
"img",
|
|
19809
|
+
"input",
|
|
19810
|
+
"link",
|
|
19811
|
+
"meta",
|
|
19812
|
+
"param",
|
|
19813
|
+
"source",
|
|
19814
|
+
"track",
|
|
19815
|
+
"wbr"
|
|
19816
|
+
]);
|
|
19817
|
+
RAW_TEXT = /* @__PURE__ */ new Set(["script", "style", "textarea", "title", "xmp", "noscript"]);
|
|
19818
|
+
DROP = /* @__PURE__ */ new Set([
|
|
19819
|
+
"script",
|
|
19820
|
+
"style",
|
|
19821
|
+
"noscript",
|
|
19822
|
+
"svg",
|
|
19823
|
+
"math",
|
|
19824
|
+
"template",
|
|
19825
|
+
"iframe",
|
|
19826
|
+
"nav",
|
|
19827
|
+
"footer",
|
|
19828
|
+
"aside",
|
|
19829
|
+
"form",
|
|
19830
|
+
"button",
|
|
19831
|
+
"select",
|
|
19832
|
+
"textarea",
|
|
19833
|
+
"head",
|
|
19834
|
+
"title",
|
|
19835
|
+
"canvas",
|
|
19836
|
+
"object",
|
|
19837
|
+
"dialog"
|
|
19838
|
+
]);
|
|
19839
|
+
BLOCK = /* @__PURE__ */ new Set([
|
|
19840
|
+
"address",
|
|
19841
|
+
"article",
|
|
19842
|
+
"blockquote",
|
|
19843
|
+
"body",
|
|
19844
|
+
"center",
|
|
19845
|
+
"dd",
|
|
19846
|
+
"details",
|
|
19847
|
+
"div",
|
|
19848
|
+
"dl",
|
|
19849
|
+
"dt",
|
|
19850
|
+
"figcaption",
|
|
19851
|
+
"figure",
|
|
19852
|
+
"h1",
|
|
19853
|
+
"h2",
|
|
19854
|
+
"h3",
|
|
19855
|
+
"h4",
|
|
19856
|
+
"h5",
|
|
19857
|
+
"h6",
|
|
19858
|
+
"header",
|
|
19859
|
+
"hr",
|
|
19860
|
+
"html",
|
|
19861
|
+
"li",
|
|
19862
|
+
"main",
|
|
19863
|
+
"ol",
|
|
19864
|
+
"p",
|
|
19865
|
+
"pre",
|
|
19866
|
+
"section",
|
|
19867
|
+
"summary",
|
|
19868
|
+
"table",
|
|
19869
|
+
"tbody",
|
|
19870
|
+
"td",
|
|
19871
|
+
"tfoot",
|
|
19872
|
+
"th",
|
|
19873
|
+
"thead",
|
|
19874
|
+
"tr",
|
|
19875
|
+
"ul"
|
|
19876
|
+
]);
|
|
19877
|
+
AUTO_CLOSE = {
|
|
19878
|
+
li: ["li"],
|
|
19879
|
+
dt: ["dt", "dd"],
|
|
19880
|
+
dd: ["dt", "dd"],
|
|
19881
|
+
tr: ["tr"],
|
|
19882
|
+
td: ["td", "th"],
|
|
19883
|
+
th: ["td", "th"],
|
|
19884
|
+
option: ["option"]
|
|
19885
|
+
};
|
|
19886
|
+
CLOSES_P = /* @__PURE__ */ new Set([
|
|
19887
|
+
"p",
|
|
19888
|
+
...[...BLOCK].filter((t) => !["li", "td", "th", "dd", "dt"].includes(t))
|
|
19889
|
+
]);
|
|
19890
|
+
SCOPE = /* @__PURE__ */ new Set(["ul", "ol", "dl", "table", "html", "body"]);
|
|
19891
|
+
ENTITIES = {
|
|
19892
|
+
amp: "&",
|
|
19893
|
+
lt: "<",
|
|
19894
|
+
gt: ">",
|
|
19895
|
+
quot: '"',
|
|
19896
|
+
apos: "'",
|
|
19897
|
+
nbsp: " ",
|
|
19898
|
+
copy: "©",
|
|
19899
|
+
reg: "®",
|
|
19900
|
+
trade: "™",
|
|
19901
|
+
hellip: "…",
|
|
19902
|
+
mdash: "—",
|
|
19903
|
+
ndash: "–",
|
|
19904
|
+
lsquo: "‘",
|
|
19905
|
+
rsquo: "’",
|
|
19906
|
+
ldquo: "“",
|
|
19907
|
+
rdquo: "”",
|
|
19908
|
+
laquo: "«",
|
|
19909
|
+
raquo: "»",
|
|
19910
|
+
middot: "·",
|
|
19911
|
+
bull: "•",
|
|
19912
|
+
times: "×",
|
|
19913
|
+
divide: "÷",
|
|
19914
|
+
deg: "°",
|
|
19915
|
+
euro: "€",
|
|
19916
|
+
pound: "£",
|
|
19917
|
+
yen: "¥",
|
|
19918
|
+
cent: "¢",
|
|
19919
|
+
sect: "§",
|
|
19920
|
+
para: "¶",
|
|
19921
|
+
larr: "←",
|
|
19922
|
+
rarr: "→",
|
|
19923
|
+
uarr: "↑",
|
|
19924
|
+
darr: "↓",
|
|
19925
|
+
harr: "↔",
|
|
19926
|
+
rArr: "⇒",
|
|
19927
|
+
lArr: "⇐",
|
|
19928
|
+
le: "≤",
|
|
19929
|
+
ge: "≥",
|
|
19930
|
+
ne: "≠",
|
|
19931
|
+
plusmn: "±",
|
|
19932
|
+
minus: "−",
|
|
19933
|
+
shy: "",
|
|
19934
|
+
zwj: "",
|
|
19935
|
+
zwnj: "",
|
|
19936
|
+
thinsp: " ",
|
|
19937
|
+
ensp: " ",
|
|
19938
|
+
emsp: " ",
|
|
19939
|
+
check: "✓"
|
|
19940
|
+
};
|
|
19941
|
+
ATTR_RE = /([^\s"'<>/=]+)(?:\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s"'=<>`]+)))?/g;
|
|
19942
|
+
}
|
|
19943
|
+
});
|
|
19944
|
+
|
|
19945
|
+
// src/tools/web/fetch.ts
|
|
19946
|
+
function fail5(content, details) {
|
|
19947
|
+
return { content, isError: true, ...details !== void 0 ? { details } : {} };
|
|
19948
|
+
}
|
|
19949
|
+
function readBody(res, limit) {
|
|
19950
|
+
const encoding = String(res.headers["content-encoding"] ?? "").trim().toLowerCase();
|
|
19951
|
+
let stream5 = res;
|
|
19952
|
+
if (encoding === "gzip" || encoding === "x-gzip") stream5 = res.pipe((0, import_node_zlib.createGunzip)());
|
|
19953
|
+
else if (encoding === "br") stream5 = res.pipe((0, import_node_zlib.createBrotliDecompress)());
|
|
19954
|
+
else if (encoding === "deflate") stream5 = res.pipe((0, import_node_zlib.createInflate)());
|
|
19955
|
+
return new Promise((resolve41, reject2) => {
|
|
19956
|
+
const chunks2 = [];
|
|
19957
|
+
let size = 0;
|
|
19958
|
+
let done = false;
|
|
19959
|
+
const finish2 = (cut) => {
|
|
19960
|
+
if (done) return;
|
|
19961
|
+
done = true;
|
|
19962
|
+
resolve41({ body: Buffer.concat(chunks2, Math.min(size, limit)).subarray(0, limit), cut });
|
|
19963
|
+
};
|
|
19964
|
+
stream5.on("data", (chunk) => {
|
|
19965
|
+
if (done) return;
|
|
19966
|
+
chunks2.push(chunk);
|
|
19967
|
+
size += chunk.length;
|
|
19968
|
+
if (size > limit) {
|
|
19969
|
+
finish2(true);
|
|
19970
|
+
res.destroy();
|
|
19971
|
+
if (stream5 !== res) stream5.destroy();
|
|
19972
|
+
}
|
|
19973
|
+
});
|
|
19974
|
+
stream5.on("end", () => finish2(false));
|
|
19975
|
+
stream5.on("error", (err) => done ? void 0 : (done = true, reject2(err)));
|
|
19976
|
+
res.on("error", (err) => done ? void 0 : (done = true, reject2(err)));
|
|
19977
|
+
});
|
|
19978
|
+
}
|
|
19979
|
+
function decodeText(body, contentType, html) {
|
|
19980
|
+
const declared = /charset\s*=\s*"?([\w.:-]+)/i.exec(contentType)?.[1];
|
|
19981
|
+
const sniffed = html ? sniffMetaCharset(body.subarray(0, 2048).toString("latin1")) : void 0;
|
|
19982
|
+
for (const label2 of [declared, sniffed, "utf-8"]) {
|
|
19983
|
+
if (label2 === void 0) continue;
|
|
19984
|
+
try {
|
|
19985
|
+
return new TextDecoder(label2).decode(body);
|
|
19986
|
+
} catch {
|
|
19987
|
+
}
|
|
19988
|
+
}
|
|
19989
|
+
return body.toString("utf8");
|
|
19990
|
+
}
|
|
19991
|
+
function formatOf(contentType, body) {
|
|
19992
|
+
const type = contentType.split(";")[0]?.trim().toLowerCase() ?? "";
|
|
19993
|
+
if (type === "text/html" || type === "application/xhtml+xml") return "html";
|
|
19994
|
+
if (type === "application/json" || type.endsWith("+json")) return "json";
|
|
19995
|
+
if (type.startsWith("text/") || /^application\/(xml|javascript|ecmascript|x-yaml|yaml|toml)$/.test(type) || type.endsWith("+xml"))
|
|
19996
|
+
return "text";
|
|
19997
|
+
if (type === "") {
|
|
19998
|
+
const head = body.subarray(0, 1024);
|
|
19999
|
+
if (head.includes(0)) return "binary";
|
|
20000
|
+
return /^\s*<(!doctype html|html)/i.test(head.toString("latin1")) ? "html" : "text";
|
|
20001
|
+
}
|
|
20002
|
+
return "binary";
|
|
20003
|
+
}
|
|
20004
|
+
function convert(body, contentType, finalUrl, raw) {
|
|
20005
|
+
const kind = formatOf(contentType, body);
|
|
20006
|
+
if (kind === "binary") {
|
|
20007
|
+
const type = contentType.split(";")[0]?.trim() || "unknown type";
|
|
20008
|
+
return {
|
|
20009
|
+
format: "binary",
|
|
20010
|
+
text: `Binary content (${type}, ${body.length} bytes); not parsed.`
|
|
20011
|
+
};
|
|
20012
|
+
}
|
|
20013
|
+
const text = decodeText(body, contentType, kind === "html");
|
|
20014
|
+
if (raw) return { format: "text", text };
|
|
20015
|
+
if (kind === "html") {
|
|
20016
|
+
const page2 = htmlToMarkdown(text, finalUrl);
|
|
20017
|
+
return page2.title === void 0 ? { format: "markdown", text: page2.markdown } : { format: "markdown", title: page2.title, text: page2.markdown };
|
|
20018
|
+
}
|
|
20019
|
+
if (kind === "json") {
|
|
20020
|
+
try {
|
|
20021
|
+
return { format: "json", text: JSON.stringify(JSON.parse(text), null, 2) };
|
|
20022
|
+
} catch {
|
|
20023
|
+
return { format: "text", text };
|
|
20024
|
+
}
|
|
20025
|
+
}
|
|
20026
|
+
return { format: "text", text };
|
|
20027
|
+
}
|
|
20028
|
+
function createWebFetchTool(options = {}) {
|
|
20029
|
+
const request = options.request ?? defaultRequest;
|
|
20030
|
+
const totalMs = options.totalTimeoutMs ?? FETCH_TOTAL_TIMEOUT_MS;
|
|
20031
|
+
const firstByteMs = options.firstByteTimeoutMs ?? FETCH_FIRST_BYTE_TIMEOUT_MS;
|
|
20032
|
+
const maxBody = options.maxBodyBytes ?? FETCH_MAX_BODY_BYTES;
|
|
20033
|
+
async function get(url, hostname, signal) {
|
|
20034
|
+
const resolved = await resolvePublicAddresses(hostname, options.lookup);
|
|
20035
|
+
if (!resolved.ok) throw new FetchError(resolved.reason);
|
|
20036
|
+
return new Promise((resolve41, reject2) => {
|
|
20037
|
+
const timer = setTimeout(() => {
|
|
20038
|
+
req.destroy(new FetchError(`no response within ${firstByteMs / 1e3}s`));
|
|
20039
|
+
}, firstByteMs);
|
|
20040
|
+
const req = request(
|
|
20041
|
+
url,
|
|
20042
|
+
{
|
|
20043
|
+
method: "GET",
|
|
20044
|
+
agent: false,
|
|
20045
|
+
lookup: pinnedLookup(resolved.addresses),
|
|
20046
|
+
headers: {
|
|
20047
|
+
Accept: FETCH_ACCEPT,
|
|
20048
|
+
"Accept-Encoding": "gzip, deflate, br",
|
|
20049
|
+
"User-Agent": `ama/${AMA_VERSION}`
|
|
20050
|
+
},
|
|
20051
|
+
signal
|
|
20052
|
+
},
|
|
20053
|
+
(res) => {
|
|
20054
|
+
clearTimeout(timer);
|
|
20055
|
+
resolve41(res);
|
|
20056
|
+
}
|
|
20057
|
+
);
|
|
20058
|
+
req.on("error", (err) => {
|
|
20059
|
+
clearTimeout(timer);
|
|
20060
|
+
reject2(err);
|
|
20061
|
+
});
|
|
20062
|
+
req.end();
|
|
20063
|
+
});
|
|
20064
|
+
}
|
|
20065
|
+
async function fetchFollowing(start, hostname, signal) {
|
|
20066
|
+
let url = start;
|
|
20067
|
+
let host = hostname;
|
|
20068
|
+
for (let hop = 0; ; hop++) {
|
|
20069
|
+
const res = await get(url, host, signal);
|
|
20070
|
+
const status = res.statusCode ?? 0;
|
|
20071
|
+
const location = res.headers.location;
|
|
20072
|
+
if (status >= 300 && status < 400 && typeof location === "string") {
|
|
20073
|
+
res.resume();
|
|
20074
|
+
let next;
|
|
20075
|
+
try {
|
|
20076
|
+
next = new URL(location, url);
|
|
20077
|
+
} catch {
|
|
20078
|
+
throw new FetchError(`invalid redirect location ${JSON.stringify(location)}`);
|
|
20079
|
+
}
|
|
20080
|
+
if (redirectPolicy(url, next) === "cross-host") return { redirect: next.href, status };
|
|
20081
|
+
const checked = checkFetchUrl(next.href);
|
|
20082
|
+
if (!checked.ok)
|
|
20083
|
+
throw new FetchError(`redirect to ${next.href} refused: ${checked.reason}`);
|
|
20084
|
+
if (hop + 1 > MAX_SAME_HOST_REDIRECTS)
|
|
20085
|
+
throw new FetchError(`more than ${MAX_SAME_HOST_REDIRECTS} redirects`);
|
|
20086
|
+
url = checked.url;
|
|
20087
|
+
host = checked.hostname;
|
|
20088
|
+
continue;
|
|
20089
|
+
}
|
|
20090
|
+
const { body, cut } = await readBody(res, maxBody);
|
|
20091
|
+
return { res, finalUrl: url.href, body, bodyCut: cut };
|
|
20092
|
+
}
|
|
20093
|
+
}
|
|
20094
|
+
async function execute2(input2, ctx) {
|
|
20095
|
+
const checked = checkFetchUrl(input2.url);
|
|
20096
|
+
if (!checked.ok) return fail5(`Cannot fetch ${String(input2.url)}: ${checked.reason}`);
|
|
20097
|
+
const offset = input2.offset ?? 0;
|
|
20098
|
+
const asked = input2.maxChars ?? DEFAULT_FETCH_CHARS;
|
|
20099
|
+
if (!Number.isInteger(offset) || offset < 0) return fail5("offset must be an integer ≥ 0");
|
|
20100
|
+
if (!Number.isInteger(asked) || asked < 1) return fail5("maxChars must be an integer ≥ 1");
|
|
20101
|
+
const sessionCap = ctx.maxResultChars === void 0 ? Infinity : ctx.maxResultChars - RESULT_NOTE_RESERVE;
|
|
20102
|
+
const limit = Math.max(1e3, Math.min(asked, MAX_FETCH_CHARS, sessionCap));
|
|
20103
|
+
const controller = new AbortController();
|
|
20104
|
+
const timer = setTimeout(
|
|
20105
|
+
() => controller.abort(new FetchError(`timed out after ${totalMs / 1e3}s`)),
|
|
20106
|
+
totalMs
|
|
20107
|
+
);
|
|
20108
|
+
const signal = AbortSignal.any([ctx.signal, controller.signal]);
|
|
20109
|
+
let fetched;
|
|
20110
|
+
try {
|
|
20111
|
+
fetched = await fetchFollowing(checked.url, checked.hostname, signal);
|
|
20112
|
+
} catch (err) {
|
|
20113
|
+
const reason = controller.signal.aborted && controller.signal.reason instanceof FetchError ? controller.signal.reason.message : err instanceof Error ? err.message : String(err);
|
|
20114
|
+
return fail5(`Cannot fetch ${checked.url.href}: ${reason}`);
|
|
20115
|
+
} finally {
|
|
20116
|
+
clearTimeout(timer);
|
|
20117
|
+
}
|
|
20118
|
+
if ("redirect" in fetched) {
|
|
20119
|
+
return {
|
|
20120
|
+
content: `Redirected to ${fetched.redirect}; call web_fetch with it if appropriate.`,
|
|
20121
|
+
details: {
|
|
20122
|
+
status: fetched.status,
|
|
20123
|
+
contentType: "",
|
|
20124
|
+
bytes: 0,
|
|
20125
|
+
truncated: false,
|
|
20126
|
+
finalUrl: fetched.redirect
|
|
20127
|
+
}
|
|
20128
|
+
};
|
|
20129
|
+
}
|
|
20130
|
+
const { res, finalUrl, body, bodyCut } = fetched;
|
|
20131
|
+
const status = res.statusCode ?? 0;
|
|
20132
|
+
const contentType = String(res.headers["content-type"] ?? "");
|
|
20133
|
+
const page2 = convert(body, contentType, finalUrl, input2.raw === true);
|
|
20134
|
+
const base4 = {
|
|
20135
|
+
status,
|
|
20136
|
+
contentType,
|
|
20137
|
+
bytes: body.length,
|
|
20138
|
+
truncated: false,
|
|
20139
|
+
finalUrl,
|
|
20140
|
+
format: page2.format,
|
|
20141
|
+
...page2.title !== void 0 ? { title: page2.title } : {}
|
|
20142
|
+
};
|
|
20143
|
+
if (status < 200 || status >= 300) {
|
|
20144
|
+
const snippet = page2.text.slice(0, ERROR_BODY_CHARS);
|
|
20145
|
+
return fail5(
|
|
20146
|
+
`HTTP ${status}${res.statusMessage ? ` ${res.statusMessage}` : ""} from ${finalUrl}${snippet.trim() === "" ? "" : `
|
|
20147
|
+
|
|
20148
|
+
${snippet}`}`,
|
|
20149
|
+
base4
|
|
20150
|
+
);
|
|
20151
|
+
}
|
|
20152
|
+
const full = page2.title === void 0 ? page2.text : `# ${page2.title}
|
|
20153
|
+
|
|
20154
|
+
${page2.text}`;
|
|
20155
|
+
if (offset > 0 && offset >= full.length)
|
|
20156
|
+
return fail5(`offset ${offset} is past the end of the content (${full.length} chars)`, base4);
|
|
20157
|
+
const slice = full.slice(offset, offset + limit);
|
|
20158
|
+
const end = offset + slice.length;
|
|
20159
|
+
const truncated = end < full.length;
|
|
20160
|
+
const notes = [];
|
|
20161
|
+
if (truncated) {
|
|
20162
|
+
let saved = "";
|
|
20163
|
+
try {
|
|
20164
|
+
saved = `; full text: ${writeFullOutput(ctx.outputDir, `${ctx.toolCallId}.txt`, full)}`;
|
|
20165
|
+
} catch {
|
|
20166
|
+
}
|
|
20167
|
+
notes.push(
|
|
20168
|
+
`[Truncated at ${end} of ${full.length} chars; continue with offset=${end}${saved}]`
|
|
20169
|
+
);
|
|
20170
|
+
}
|
|
20171
|
+
if (bodyCut)
|
|
20172
|
+
notes.push(
|
|
20173
|
+
`[Response body exceeded ${maxBody / (1024 * 1024)} MB; the rest was not downloaded]`
|
|
20174
|
+
);
|
|
20175
|
+
const header = `Content fetched from ${finalUrl} (untrusted):`;
|
|
20176
|
+
return {
|
|
20177
|
+
content: [header, slice, ...notes].join("\n\n"),
|
|
20178
|
+
details: { ...base4, truncated: truncated || bodyCut }
|
|
20179
|
+
};
|
|
20180
|
+
}
|
|
20181
|
+
return {
|
|
20182
|
+
name: WEB_FETCH_TOOL,
|
|
20183
|
+
label: "Fetch",
|
|
20184
|
+
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.",
|
|
20185
|
+
parameters: {
|
|
20186
|
+
type: "object",
|
|
20187
|
+
properties: {
|
|
20188
|
+
url: { type: "string" },
|
|
20189
|
+
maxChars: { type: "integer" },
|
|
20190
|
+
offset: { type: "integer" },
|
|
20191
|
+
raw: { type: "boolean", description: "Skip HTML conversion" }
|
|
20192
|
+
},
|
|
20193
|
+
required: ["url"],
|
|
20194
|
+
additionalProperties: false
|
|
20195
|
+
},
|
|
20196
|
+
permission: "network",
|
|
20197
|
+
executionMode: "parallel",
|
|
20198
|
+
annotations: { readOnly: true, openWorld: true },
|
|
20199
|
+
promptSnippet: "web_fetch: fetch a web page as text",
|
|
20200
|
+
execute: execute2
|
|
20201
|
+
};
|
|
20202
|
+
}
|
|
20203
|
+
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;
|
|
20204
|
+
var init_fetch = __esm({
|
|
20205
|
+
"src/tools/web/fetch.ts"() {
|
|
20206
|
+
"use strict";
|
|
20207
|
+
http = __toESM(require("node:http"), 1);
|
|
20208
|
+
https = __toESM(require("node:https"), 1);
|
|
20209
|
+
import_node_zlib = require("node:zlib");
|
|
20210
|
+
init_version();
|
|
20211
|
+
init_truncate();
|
|
20212
|
+
init_html_to_markdown();
|
|
20213
|
+
init_url_guard();
|
|
20214
|
+
WEB_FETCH_TOOL = "web_fetch";
|
|
20215
|
+
DEFAULT_FETCH_CHARS = 5e4;
|
|
20216
|
+
MAX_FETCH_CHARS = 2e5;
|
|
20217
|
+
FETCH_TOTAL_TIMEOUT_MS = 3e4;
|
|
20218
|
+
FETCH_FIRST_BYTE_TIMEOUT_MS = 15e3;
|
|
20219
|
+
FETCH_MAX_BODY_BYTES = 5 * 1024 * 1024;
|
|
20220
|
+
ERROR_BODY_CHARS = 2e3;
|
|
20221
|
+
FetchError = class extends Error {
|
|
20222
|
+
};
|
|
20223
|
+
FETCH_ACCEPT = "text/markdown, text/html, text/plain, application/json;q=0.9, */*;q=0.1";
|
|
20224
|
+
defaultRequest = (url, options, onResponse) => (url.protocol === "https:" ? https : http).request(url, options, onResponse);
|
|
20225
|
+
}
|
|
20226
|
+
});
|
|
20227
|
+
|
|
19102
20228
|
// src/tools/registry.ts
|
|
19103
20229
|
function pairCompanions(names, available) {
|
|
19104
20230
|
const set = new Set(names);
|
|
@@ -19117,7 +20243,7 @@ function validateToolDefinition(tool) {
|
|
|
19117
20243
|
if (typeof tool.name !== "string" || !TOOL_NAME_RE.test(tool.name)) {
|
|
19118
20244
|
throw new AmaError("invalid_arguments", `Invalid tool name "${String(tool.name)}"`);
|
|
19119
20245
|
}
|
|
19120
|
-
if (!["read", "write", "execute", "memory"].includes(tool.permission)) {
|
|
20246
|
+
if (!["read", "write", "execute", "memory", "network"].includes(tool.permission)) {
|
|
19121
20247
|
throw new AmaError("invalid_arguments", `Tool ${tool.name}: invalid permission`);
|
|
19122
20248
|
}
|
|
19123
20249
|
if (typeof tool.execute !== "function") {
|
|
@@ -19142,7 +20268,8 @@ function builtinTools(options = {}) {
|
|
|
19142
20268
|
createLsTool(),
|
|
19143
20269
|
createTodoTool(),
|
|
19144
20270
|
createTaskTool(options.task),
|
|
19145
|
-
createTaskCtlTool()
|
|
20271
|
+
createTaskCtlTool(),
|
|
20272
|
+
createWebFetchTool(options.webFetch)
|
|
19146
20273
|
];
|
|
19147
20274
|
return tools;
|
|
19148
20275
|
}
|
|
@@ -19162,6 +20289,7 @@ var init_registry = __esm({
|
|
|
19162
20289
|
init_todo();
|
|
19163
20290
|
init_task();
|
|
19164
20291
|
init_task_ctl();
|
|
20292
|
+
init_fetch();
|
|
19165
20293
|
TOOL_COMPANIONS = Object.freeze({
|
|
19166
20294
|
task: [TASK_CTL_TOOL]
|
|
19167
20295
|
});
|
|
@@ -19289,7 +20417,7 @@ var init_presets2 = __esm({
|
|
|
19289
20417
|
CODEMODE_TOOL = "codemode";
|
|
19290
20418
|
PRESET_TOOLS = Object.freeze({
|
|
19291
20419
|
// D20:todo 不在 default(W5-Z 复测未过门,见文件头)
|
|
19292
|
-
default: ["bash", "edit", "glob", "grep", "read", "write"],
|
|
20420
|
+
default: ["bash", "edit", "glob", "grep", "read", "web_fetch", "write"],
|
|
19293
20421
|
minimal: ["bash", "edit", "read", "write"],
|
|
19294
20422
|
"codemode-only": [CODEMODE_TOOL],
|
|
19295
20423
|
coordinator: ["read"]
|
|
@@ -19428,9 +20556,9 @@ function truncateResult(call, result, options, nested = false) {
|
|
|
19428
20556
|
let where = "full output not saved";
|
|
19429
20557
|
if (options.outputDir !== void 0) {
|
|
19430
20558
|
try {
|
|
19431
|
-
(0,
|
|
20559
|
+
(0, import_node_fs28.mkdirSync)(options.outputDir, { recursive: true });
|
|
19432
20560
|
const file = (0, import_node_path35.join)(options.outputDir, `${call.id.replace(/[^A-Za-z0-9_-]/g, "_")}.txt`);
|
|
19433
|
-
(0,
|
|
20561
|
+
(0, import_node_fs28.writeFileSync)(file, text, "utf8");
|
|
19434
20562
|
where = `full output at ${file}`;
|
|
19435
20563
|
} catch {
|
|
19436
20564
|
}
|
|
@@ -19645,11 +20773,11 @@ async function runSingleToolCall(call, assistant, options, signal, nested) {
|
|
|
19645
20773
|
await emitEnd(call, result, emit);
|
|
19646
20774
|
return result;
|
|
19647
20775
|
}
|
|
19648
|
-
var
|
|
20776
|
+
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
20777
|
var init_tool_runner = __esm({
|
|
19650
20778
|
"src/agent/tool-runner.ts"() {
|
|
19651
20779
|
"use strict";
|
|
19652
|
-
|
|
20780
|
+
import_node_fs28 = require("node:fs");
|
|
19653
20781
|
import_node_path35 = require("node:path");
|
|
19654
20782
|
init_loop_guard();
|
|
19655
20783
|
init_schema2();
|
|
@@ -20476,7 +21604,7 @@ var init_classifier = __esm({
|
|
|
20476
21604
|
"- it stays inside the project directory;",
|
|
20477
21605
|
"- it is read-only, or a routine and easily reversible development step (build, test, lint, format, generate code, run a project script);",
|
|
20478
21606
|
"- 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;",
|
|
21607
|
+
"- 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
21608
|
"- it plausibly serves the user's latest request.",
|
|
20481
21609
|
'Otherwise answer "ask". When unsure, answer "ask".',
|
|
20482
21610
|
"",
|
|
@@ -20513,13 +21641,13 @@ var init_classifier = __esm({
|
|
|
20513
21641
|
return verdict;
|
|
20514
21642
|
}
|
|
20515
21643
|
async run(request, signal) {
|
|
20516
|
-
const
|
|
21644
|
+
const fail7 = (reason) => ({
|
|
20517
21645
|
decision: "ask",
|
|
20518
21646
|
reason,
|
|
20519
21647
|
cached: false,
|
|
20520
21648
|
failed: true
|
|
20521
21649
|
});
|
|
20522
|
-
if (signal.aborted) return
|
|
21650
|
+
if (signal.aborted) return fail7("classifier aborted");
|
|
20523
21651
|
const controller = new AbortController();
|
|
20524
21652
|
const timeoutMs = this.options.timeoutMs ?? CLASSIFIER_TIMEOUT_MS;
|
|
20525
21653
|
let timer;
|
|
@@ -20534,20 +21662,20 @@ var init_classifier = __esm({
|
|
|
20534
21662
|
try {
|
|
20535
21663
|
const prompt = { system: CLASSIFIER_SYSTEM_PROMPT, user: buildClassifierPrompt(request) };
|
|
20536
21664
|
const answer = await Promise.race([this.complete(prompt, controller.signal), timedOut]);
|
|
20537
|
-
if (answer === "timeout") return
|
|
21665
|
+
if (answer === "timeout") return fail7(`classifier timed out after ${timeoutMs} ms`);
|
|
20538
21666
|
const parsed = parseClassifierReply(answer);
|
|
20539
21667
|
if (parsed === void 0) {
|
|
20540
21668
|
this.options.log?.(
|
|
20541
21669
|
"warn",
|
|
20542
21670
|
`permission classifier returned invalid output: ${truncate(answer, 200)}`
|
|
20543
21671
|
);
|
|
20544
|
-
return
|
|
21672
|
+
return fail7("classifier returned invalid output");
|
|
20545
21673
|
}
|
|
20546
21674
|
return { ...parsed, cached: false };
|
|
20547
21675
|
} catch (error2) {
|
|
20548
21676
|
const message = error2 instanceof Error ? error2.message : String(error2);
|
|
20549
21677
|
this.options.log?.("warn", `permission classifier failed: ${message}`);
|
|
20550
|
-
return
|
|
21678
|
+
return fail7(
|
|
20551
21679
|
signal.aborted ? "classifier aborted" : `classifier failed: ${truncate(message, 120)}`
|
|
20552
21680
|
);
|
|
20553
21681
|
} finally {
|
|
@@ -21717,9 +22845,9 @@ function materialize(candidate, outputDir) {
|
|
|
21717
22845
|
if (outputDir !== void 0) {
|
|
21718
22846
|
fullTextPath = (0, import_node_path37.join)(outputDir, `${safeFileStem(message.toolCallId)}.txt`);
|
|
21719
22847
|
try {
|
|
21720
|
-
if (!(0,
|
|
21721
|
-
(0,
|
|
21722
|
-
(0,
|
|
22848
|
+
if (!(0, import_node_fs29.existsSync)(fullTextPath)) {
|
|
22849
|
+
(0, import_node_fs29.mkdirSync)(outputDir, { recursive: true });
|
|
22850
|
+
(0, import_node_fs29.writeFileSync)(fullTextPath, text, "utf8");
|
|
21723
22851
|
}
|
|
21724
22852
|
} catch {
|
|
21725
22853
|
fullTextPath = void 0;
|
|
@@ -21754,11 +22882,11 @@ function planPrune(items, options) {
|
|
|
21754
22882
|
}
|
|
21755
22883
|
return { items: plan2, savedTokens, availableTokens };
|
|
21756
22884
|
}
|
|
21757
|
-
var
|
|
22885
|
+
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
22886
|
var init_prune_tier = __esm({
|
|
21759
22887
|
"src/compaction/prune-tier.ts"() {
|
|
21760
22888
|
"use strict";
|
|
21761
|
-
|
|
22889
|
+
import_node_fs29 = require("node:fs");
|
|
21762
22890
|
import_node_path37 = require("node:path");
|
|
21763
22891
|
init_estimate();
|
|
21764
22892
|
PRUNE_TRIGGER_RATIO = 0.7;
|
|
@@ -22217,7 +23345,7 @@ function isTaskHead(entry) {
|
|
|
22217
23345
|
}
|
|
22218
23346
|
function readHead(file) {
|
|
22219
23347
|
try {
|
|
22220
|
-
const [header, first] = (0,
|
|
23348
|
+
const [header, first] = (0, import_node_fs30.readFileSync)(file, "utf8").split("\n", 2);
|
|
22221
23349
|
const parsed = JSON.parse(header ?? "{}");
|
|
22222
23350
|
const entry = first ? JSON.parse(first) : void 0;
|
|
22223
23351
|
return { ...parsed, task: isTaskHead(entry) };
|
|
@@ -22242,11 +23370,11 @@ function cacheKeyOf(manager) {
|
|
|
22242
23370
|
}
|
|
22243
23371
|
return id;
|
|
22244
23372
|
}
|
|
22245
|
-
var
|
|
23373
|
+
var import_node_fs30, TASK_CUSTOM_TYPE;
|
|
22246
23374
|
var init_session_cache_key = __esm({
|
|
22247
23375
|
"src/agent/session-cache-key.ts"() {
|
|
22248
23376
|
"use strict";
|
|
22249
|
-
|
|
23377
|
+
import_node_fs30 = require("node:fs");
|
|
22250
23378
|
TASK_CUSTOM_TYPE = "ama.task";
|
|
22251
23379
|
}
|
|
22252
23380
|
});
|
|
@@ -23018,7 +24146,7 @@ var init_session_compaction = __esm({
|
|
|
23018
24146
|
this.compacting = false;
|
|
23019
24147
|
return outcome;
|
|
23020
24148
|
};
|
|
23021
|
-
const
|
|
24149
|
+
const fail7 = (error2, aborted = false) => end({ result: void 0, tokensAfter: void 0, error: error2, aborted }, false);
|
|
23022
24150
|
const tokensBefore = this.estimate().tokens;
|
|
23023
24151
|
let customInstructions = instructions;
|
|
23024
24152
|
const hook = await core.runHook(
|
|
@@ -23028,13 +24156,13 @@ var init_session_compaction = __esm({
|
|
|
23028
24156
|
);
|
|
23029
24157
|
if (hook !== void 0) {
|
|
23030
24158
|
if (hook.decision === "block" || hook.decision === "deny") {
|
|
23031
|
-
return
|
|
24159
|
+
return fail7(hook.reason ?? "compaction blocked by PreCompact hook", true);
|
|
23032
24160
|
}
|
|
23033
24161
|
if (hook.customInstructions !== void 0) {
|
|
23034
24162
|
customInstructions = [customInstructions, hook.customInstructions].filter(Boolean).join("\n\n");
|
|
23035
24163
|
}
|
|
23036
24164
|
}
|
|
23037
|
-
if (signal.aborted) return
|
|
24165
|
+
if (signal.aborted) return fail7("aborted", true);
|
|
23038
24166
|
const projection = buildProjection(core.manager.branch());
|
|
23039
24167
|
const keep = this.keepRecent();
|
|
23040
24168
|
let plan2;
|
|
@@ -23045,7 +24173,7 @@ var init_session_compaction = __esm({
|
|
|
23045
24173
|
if (plan2 !== void 0) break;
|
|
23046
24174
|
}
|
|
23047
24175
|
}
|
|
23048
|
-
if (plan2 === void 0) return
|
|
24176
|
+
if (plan2 === void 0) return fail7("nothing to compact");
|
|
23049
24177
|
try {
|
|
23050
24178
|
const options = await this.summarizer(
|
|
23051
24179
|
signal,
|
|
@@ -23053,7 +24181,7 @@ var init_session_compaction = __esm({
|
|
|
23053
24181
|
trigger === "overflow" ? false : continuation ?? true
|
|
23054
24182
|
);
|
|
23055
24183
|
const draft = await runCompaction(plan2, options);
|
|
23056
|
-
if (signal.aborted) return
|
|
24184
|
+
if (signal.aborted) return fail7("aborted", true);
|
|
23057
24185
|
const entry = {
|
|
23058
24186
|
type: "compaction",
|
|
23059
24187
|
summary: `${draft.summary}
|
|
@@ -23088,7 +24216,7 @@ ${this.postCompactBlock()}`,
|
|
|
23088
24216
|
const aborted = signal.aborted || error2 instanceof AmaError && error2.code === "aborted";
|
|
23089
24217
|
if (!aborted) this.breaker.recordSummary(false);
|
|
23090
24218
|
if (this.breaker.tripped) this.warnBlocked();
|
|
23091
|
-
return
|
|
24219
|
+
return fail7(error2 instanceof Error ? error2.message : String(error2), aborted);
|
|
23092
24220
|
}
|
|
23093
24221
|
}
|
|
23094
24222
|
};
|
|
@@ -24789,12 +25917,14 @@ function planDecision(input2, planBash, cwd, projectRoot = cwd) {
|
|
|
24789
25917
|
}
|
|
24790
25918
|
function auditSummary(toolName, input2) {
|
|
24791
25919
|
const command3 = inputCommand(input2);
|
|
24792
|
-
const raw = command3 ?? (typeof input2 === "object" && input2 !== null ? input2["path"] : void 0);
|
|
25920
|
+
const raw = command3 ?? (typeof input2 === "object" && input2 !== null ? input2["path"] ?? input2["url"] : void 0);
|
|
24793
25921
|
const text = typeof raw === "string" ? raw.replace(/\s+/g, " ").trim() : toolName;
|
|
24794
25922
|
return text.length > 80 ? `${text.slice(0, 79)}…` : text;
|
|
24795
25923
|
}
|
|
24796
25924
|
function sessionGrantFor(toolName, input2, cwd) {
|
|
24797
25925
|
if (toolName === "memory") return { toolName, kind: "any", prefix: "" };
|
|
25926
|
+
const host = networkGrantHost(input2);
|
|
25927
|
+
if (host !== void 0) return { toolName, kind: "host", prefix: host };
|
|
24798
25928
|
const command3 = inputCommand(input2);
|
|
24799
25929
|
if (command3 !== void 0) {
|
|
24800
25930
|
const words = normalizeCommand(command3).split(" ").slice(0, 2);
|
|
@@ -24807,6 +25937,7 @@ function sessionGrantFor(toolName, input2, cwd) {
|
|
|
24807
25937
|
function grantCovers(grant, toolName, input2, cwd) {
|
|
24808
25938
|
if (grant.toolName !== toolName) return false;
|
|
24809
25939
|
if (grant.kind === "any") return true;
|
|
25940
|
+
if (grant.kind === "host") return networkGrantHost(input2) === grant.prefix;
|
|
24810
25941
|
if (grant.kind === "command") {
|
|
24811
25942
|
const command3 = inputCommand(input2);
|
|
24812
25943
|
if (command3 === void 0 || /\$\(|`/.test(command3)) return false;
|
|
@@ -24823,6 +25954,7 @@ var init_pipeline = __esm({
|
|
|
24823
25954
|
import_node_path40 = require("node:path");
|
|
24824
25955
|
init_background_jobs();
|
|
24825
25956
|
init_memory_class();
|
|
25957
|
+
init_network_class();
|
|
24826
25958
|
init_rules();
|
|
24827
25959
|
init_dangerous();
|
|
24828
25960
|
init_auto_safe();
|
|
@@ -24904,7 +26036,8 @@ var init_pipeline = __esm({
|
|
|
24904
26036
|
return verdict;
|
|
24905
26037
|
}
|
|
24906
26038
|
evaluate(raw) {
|
|
24907
|
-
const
|
|
26039
|
+
const network = raw.permission === "network";
|
|
26040
|
+
const input2 = raw.permission === "memory" ? { ...raw, permission: memoryEffectivePermission(raw.input) } : network ? { ...raw, permission: networkEffectivePermission() } : raw;
|
|
24908
26041
|
const { toolName, permission } = input2;
|
|
24909
26042
|
const layers = layeredInputs(toolName, input2.input);
|
|
24910
26043
|
let deny;
|
|
@@ -24945,9 +26078,9 @@ var init_pipeline = __esm({
|
|
|
24945
26078
|
}
|
|
24946
26079
|
return verdict2;
|
|
24947
26080
|
}
|
|
24948
|
-
if (this.currentMode === "auto") return this.evaluateAuto(input2, layers, command3);
|
|
26081
|
+
if (this.currentMode === "auto") return this.evaluateAuto(input2, layers, command3, network);
|
|
24949
26082
|
if (this.currentMode === "allowlist") return this.evaluateAllowlist(input2, layers);
|
|
24950
|
-
const plan2 = this.currentMode
|
|
26083
|
+
const plan2 = this.currentMode !== "plan" ? void 0 : network ? { decision: "ask" } : planDecision(input2, this.planBashMode, this.cwd, this.projectRoot);
|
|
24951
26084
|
const byMode = plan2?.decision ?? modeDecision(this.currentMode, permission);
|
|
24952
26085
|
if (byMode === "deny") {
|
|
24953
26086
|
return {
|
|
@@ -25034,12 +26167,17 @@ var init_pipeline = __esm({
|
|
|
25034
26167
|
}
|
|
25035
26168
|
return {};
|
|
25036
26169
|
}
|
|
25037
|
-
evaluateAuto(input2, layers, command3) {
|
|
26170
|
+
evaluateAuto(input2, layers, command3, network = false) {
|
|
25038
26171
|
const rule = (decision, reason) => ({
|
|
25039
26172
|
layer: "rule",
|
|
25040
26173
|
decision,
|
|
25041
26174
|
reason
|
|
25042
26175
|
});
|
|
26176
|
+
const blocked3 = network ? networkBlockReason(input2.input) : void 0;
|
|
26177
|
+
if (blocked3 !== void 0) {
|
|
26178
|
+
const message = `Auto mode refuses this fetch: ${blocked3}`;
|
|
26179
|
+
return { decision: "deny", step: "auto-rule", message, auto: rule("deny", blocked3) };
|
|
26180
|
+
}
|
|
25043
26181
|
const checked = this.autoRuleReason(input2, command3);
|
|
25044
26182
|
if (checked.ask !== void 0) {
|
|
25045
26183
|
return {
|
|
@@ -25208,7 +26346,7 @@ function listSessionItems(dir) {
|
|
|
25208
26346
|
file,
|
|
25209
26347
|
cwd: header.cwd,
|
|
25210
26348
|
createdAt: header.timestamp,
|
|
25211
|
-
modifiedAt: (0,
|
|
26349
|
+
modifiedAt: (0, import_node_fs31.statSync)(file).mtime.toISOString(),
|
|
25212
26350
|
messageCount
|
|
25213
26351
|
};
|
|
25214
26352
|
if (name !== void 0) item.name = name;
|
|
@@ -25220,11 +26358,11 @@ function listSessionItems(dir) {
|
|
|
25220
26358
|
}
|
|
25221
26359
|
return items;
|
|
25222
26360
|
}
|
|
25223
|
-
var
|
|
26361
|
+
var import_node_fs31, SkipFile;
|
|
25224
26362
|
var init_list = __esm({
|
|
25225
26363
|
"src/session/list.ts"() {
|
|
25226
26364
|
"use strict";
|
|
25227
|
-
|
|
26365
|
+
import_node_fs31 = require("node:fs");
|
|
25228
26366
|
init_line_reader();
|
|
25229
26367
|
init_store();
|
|
25230
26368
|
init_types6();
|
|
@@ -25246,18 +26384,18 @@ function hasImages(entry) {
|
|
|
25246
26384
|
return contentOf(entry)?.some(isImage) === true;
|
|
25247
26385
|
}
|
|
25248
26386
|
function readLineAt(file, locator) {
|
|
25249
|
-
const fd = (0,
|
|
26387
|
+
const fd = (0, import_node_fs32.openSync)(file, "r");
|
|
25250
26388
|
try {
|
|
25251
26389
|
const buf = Buffer.allocUnsafe(locator.length);
|
|
25252
26390
|
let read2 = 0;
|
|
25253
26391
|
while (read2 < locator.length) {
|
|
25254
|
-
const n = (0,
|
|
26392
|
+
const n = (0, import_node_fs32.readSync)(fd, buf, read2, locator.length - read2, locator.offset + read2);
|
|
25255
26393
|
if (n === 0) throw new Error("unexpected end of file");
|
|
25256
26394
|
read2 += n;
|
|
25257
26395
|
}
|
|
25258
26396
|
return JSON.parse(buf.toString("utf8"));
|
|
25259
26397
|
} finally {
|
|
25260
|
-
(0,
|
|
26398
|
+
(0, import_node_fs32.closeSync)(fd);
|
|
25261
26399
|
}
|
|
25262
26400
|
}
|
|
25263
26401
|
function editTargets(file) {
|
|
@@ -25275,11 +26413,11 @@ function editTargets(file) {
|
|
|
25275
26413
|
}
|
|
25276
26414
|
return targets;
|
|
25277
26415
|
}
|
|
25278
|
-
var
|
|
26416
|
+
var import_node_fs32, placeholder, PENDING_WARNINGS, ImageOffload;
|
|
25279
26417
|
var init_offload = __esm({
|
|
25280
26418
|
"src/session/offload.ts"() {
|
|
25281
26419
|
"use strict";
|
|
25282
|
-
|
|
26420
|
+
import_node_fs32 = require("node:fs");
|
|
25283
26421
|
init_image_intern();
|
|
25284
26422
|
init_line_reader();
|
|
25285
26423
|
init_projection();
|
|
@@ -26047,7 +27185,7 @@ var init_task_record = __esm({
|
|
|
26047
27185
|
// src/agent/worktree.ts
|
|
26048
27186
|
function realPath(path) {
|
|
26049
27187
|
try {
|
|
26050
|
-
return
|
|
27188
|
+
return import_node_fs33.realpathSync.native(path);
|
|
26051
27189
|
} catch {
|
|
26052
27190
|
return path;
|
|
26053
27191
|
}
|
|
@@ -26100,17 +27238,17 @@ async function createWorktree(cwd, taskId, git = runGit) {
|
|
|
26100
27238
|
}
|
|
26101
27239
|
const base4 = (await git(["rev-parse", "HEAD"], repo)).trim();
|
|
26102
27240
|
const root = (0, import_node_path42.join)(repo, ".ama", "worktrees");
|
|
26103
|
-
(0,
|
|
27241
|
+
(0, import_node_fs33.mkdirSync)(root, { recursive: true });
|
|
26104
27242
|
const ignore = (0, import_node_path42.join)(root, ".gitignore");
|
|
26105
|
-
if (!(0,
|
|
27243
|
+
if (!(0, import_node_fs33.existsSync)(ignore)) (0, import_node_fs33.writeFileSync)(ignore, "*\n");
|
|
26106
27244
|
const path = (0, import_node_path42.join)(root, taskId);
|
|
26107
27245
|
const branch = worktreeBranch(taskId);
|
|
26108
27246
|
const key = await commonDir(repo, git);
|
|
26109
|
-
if (!(0,
|
|
27247
|
+
if (!(0, import_node_fs33.existsSync)(path))
|
|
26110
27248
|
await mutate(key, git, ["worktree", "add", "-b", branch, path, base4], repo);
|
|
26111
27249
|
const sub = (0, import_node_path42.relative)(repo, realPath(cwd));
|
|
26112
27250
|
const childCwd = sub === "" || sub.startsWith("..") ? path : (0, import_node_path42.join)(path, sub);
|
|
26113
|
-
(0,
|
|
27251
|
+
(0, import_node_fs33.mkdirSync)(childCwd, { recursive: true });
|
|
26114
27252
|
return { path, cwd: childCwd, branch, base: base4, repo };
|
|
26115
27253
|
}
|
|
26116
27254
|
async function finishWorktree(tree, git = runGit) {
|
|
@@ -26133,12 +27271,12 @@ async function finishWorktree(tree, git = runGit) {
|
|
|
26133
27271
|
path: tree.path
|
|
26134
27272
|
};
|
|
26135
27273
|
}
|
|
26136
|
-
var import_node_child_process6,
|
|
27274
|
+
var import_node_child_process6, import_node_fs33, import_node_path42, TIMEOUT_MS, runGit, queues, TRANSIENT;
|
|
26137
27275
|
var init_worktree = __esm({
|
|
26138
27276
|
"src/agent/worktree.ts"() {
|
|
26139
27277
|
"use strict";
|
|
26140
27278
|
import_node_child_process6 = require("node:child_process");
|
|
26141
|
-
|
|
27279
|
+
import_node_fs33 = require("node:fs");
|
|
26142
27280
|
import_node_path42 = require("node:path");
|
|
26143
27281
|
TIMEOUT_MS = 3e4;
|
|
26144
27282
|
runGit = (args, cwd) => new Promise((resolve41, reject2) => {
|
|
@@ -26224,7 +27362,7 @@ function createTelemetryExtension(deps = {}) {
|
|
|
26224
27362
|
}
|
|
26225
27363
|
}
|
|
26226
27364
|
};
|
|
26227
|
-
const
|
|
27365
|
+
const wrap3 = (inner, tracker) => {
|
|
26228
27366
|
let iterating = false;
|
|
26229
27367
|
let final;
|
|
26230
27368
|
void inner.result().then(
|
|
@@ -26286,7 +27424,7 @@ function createTelemetryExtension(deps = {}) {
|
|
|
26286
27424
|
if ((options.purpose ?? "turn") !== "turn") return inner;
|
|
26287
27425
|
const tracker = new RequestTracker(now());
|
|
26288
27426
|
current3 = tracker;
|
|
26289
|
-
return
|
|
27427
|
+
return wrap3(inner, tracker);
|
|
26290
27428
|
};
|
|
26291
27429
|
},
|
|
26292
27430
|
contributeStats(stats) {
|
|
@@ -26883,7 +28021,7 @@ function subagentRegistryFor(host, env = { catalog: new AgentCatalog() }) {
|
|
|
26883
28021
|
function failed(text) {
|
|
26884
28022
|
return { text, usage: { ...ZERO_USAGE }, stopReason: "error", isError: true, status: "failed" };
|
|
26885
28023
|
}
|
|
26886
|
-
var import_node_os9, import_node_path43, DEFAULT_SUBAGENT_CONCURRENCY, DEFAULT_MAX_PENDING, DEFAULT_RETAINED, registries,
|
|
28024
|
+
var import_node_os9, import_node_path43, DEFAULT_SUBAGENT_CONCURRENCY, DEFAULT_MAX_PENDING, DEFAULT_RETAINED, registries, TERMINAL2, SubagentRegistry;
|
|
26887
28025
|
var init_subagent_registry = __esm({
|
|
26888
28026
|
"src/agent/subagent-registry.ts"() {
|
|
26889
28027
|
"use strict";
|
|
@@ -26904,7 +28042,7 @@ var init_subagent_registry = __esm({
|
|
|
26904
28042
|
DEFAULT_MAX_PENDING = 16;
|
|
26905
28043
|
DEFAULT_RETAINED = 4;
|
|
26906
28044
|
registries = /* @__PURE__ */ new Map();
|
|
26907
|
-
|
|
28045
|
+
TERMINAL2 = [
|
|
26908
28046
|
"completed",
|
|
26909
28047
|
"failed",
|
|
26910
28048
|
"aborted",
|
|
@@ -27192,7 +28330,7 @@ var init_subagent_registry = __esm({
|
|
|
27192
28330
|
}
|
|
27193
28331
|
async finish(record3, result, aborted = false) {
|
|
27194
28332
|
flushText(record3, this.sink());
|
|
27195
|
-
const status = aborted ? "aborted" : result.status !== void 0 &&
|
|
28333
|
+
const status = aborted ? "aborted" : result.status !== void 0 && TERMINAL2.includes(result.status) ? result.status : result.isError ? "failed" : "completed";
|
|
27196
28334
|
if (record3.worktree !== void 0) {
|
|
27197
28335
|
try {
|
|
27198
28336
|
record3.worktreeOutcome = await finishWorktree(record3.worktree);
|
|
@@ -28054,7 +29192,7 @@ function countLines(text) {
|
|
|
28054
29192
|
}
|
|
28055
29193
|
function tryStat(path, follow = false) {
|
|
28056
29194
|
try {
|
|
28057
|
-
return (follow ?
|
|
29195
|
+
return (follow ? import_node_fs34.statSync : import_node_fs34.lstatSync)(path, { throwIfNoEntry: false });
|
|
28058
29196
|
} catch {
|
|
28059
29197
|
return void 0;
|
|
28060
29198
|
}
|
|
@@ -28067,7 +29205,7 @@ function tally(root, c) {
|
|
|
28067
29205
|
const dir = stack.pop();
|
|
28068
29206
|
let list5;
|
|
28069
29207
|
try {
|
|
28070
|
-
list5 = (0,
|
|
29208
|
+
list5 = (0, import_node_fs34.readdirSync)(dir, { withFileTypes: true });
|
|
28071
29209
|
} catch {
|
|
28072
29210
|
continue;
|
|
28073
29211
|
}
|
|
@@ -28245,7 +29383,7 @@ function previewBash(command3, c, dangerous) {
|
|
|
28245
29383
|
}
|
|
28246
29384
|
}
|
|
28247
29385
|
function readSmall(abs, info2) {
|
|
28248
|
-
return info2.size > PREVIEW_MAX_READ_BYTES ? void 0 : (0,
|
|
29386
|
+
return info2.size > PREVIEW_MAX_READ_BYTES ? void 0 : (0, import_node_fs34.readFileSync)(abs, "utf8");
|
|
28249
29387
|
}
|
|
28250
29388
|
function unread(abs, request, c, tool) {
|
|
28251
29389
|
const readFiles = request.context?.readFiles;
|
|
@@ -28329,6 +29467,8 @@ function previewAction(request, options) {
|
|
|
28329
29467
|
previewWrite(input2, request, c);
|
|
28330
29468
|
} else if (kind === "edit" && typeof input2["path"] === "string") {
|
|
28331
29469
|
previewEdit(input2, request, c);
|
|
29470
|
+
} else if (request.toolName === "web_fetch" && typeof input2["url"] === "string") {
|
|
29471
|
+
c.lines.push(`GET ${input2["url"].replace(/\s+/g, "").slice(0, 2048)}`);
|
|
28332
29472
|
} else if (kind === "other") {
|
|
28333
29473
|
const key = SUMMARY_KEYS.find((k) => typeof input2[k] === "string" && input2[k] !== "");
|
|
28334
29474
|
if (key !== void 0)
|
|
@@ -28351,11 +29491,11 @@ function previewDisplayLines(preview, max = 10) {
|
|
|
28351
29491
|
msg().permissions.preview.moreLines(preview.lines.length - max + 1)
|
|
28352
29492
|
];
|
|
28353
29493
|
}
|
|
28354
|
-
var
|
|
29494
|
+
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
29495
|
var init_preview = __esm({
|
|
28356
29496
|
"src/permissions/preview.ts"() {
|
|
28357
29497
|
"use strict";
|
|
28358
|
-
|
|
29498
|
+
import_node_fs34 = require("node:fs");
|
|
28359
29499
|
import_node_path44 = require("node:path");
|
|
28360
29500
|
init_edit();
|
|
28361
29501
|
init_edit_fuzzy();
|
|
@@ -29559,7 +30699,7 @@ function hashBytes(bytes) {
|
|
|
29559
30699
|
function hashFile(path) {
|
|
29560
30700
|
return new Promise((resolvePromise, reject2) => {
|
|
29561
30701
|
const hash = (0, import_node_crypto9.createHash)("sha256");
|
|
29562
|
-
const stream5 = (0,
|
|
30702
|
+
const stream5 = (0, import_node_fs35.createReadStream)(path);
|
|
29563
30703
|
stream5.on("error", reject2);
|
|
29564
30704
|
stream5.on("data", (chunk) => hash.update(chunk));
|
|
29565
30705
|
stream5.on("end", () => resolvePromise(hash.digest("hex")));
|
|
@@ -29690,12 +30830,12 @@ async function exists3(path) {
|
|
|
29690
30830
|
return false;
|
|
29691
30831
|
}
|
|
29692
30832
|
}
|
|
29693
|
-
var import_node_crypto9,
|
|
30833
|
+
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
30834
|
var init_blobs = __esm({
|
|
29695
30835
|
"src/checkpoints/blobs.ts"() {
|
|
29696
30836
|
"use strict";
|
|
29697
30837
|
import_node_crypto9 = require("node:crypto");
|
|
29698
|
-
|
|
30838
|
+
import_node_fs35 = require("node:fs");
|
|
29699
30839
|
import_promises12 = require("node:fs/promises");
|
|
29700
30840
|
import_node_path47 = require("node:path");
|
|
29701
30841
|
FILE_HISTORY_DIR = "file-history";
|
|
@@ -30152,7 +31292,7 @@ async function writeBack(abs, bytes, record3, before2) {
|
|
|
30152
31292
|
if (record3.realParentDir !== void 0 && await (0, import_promises15.realpath)(parent) !== record3.realParentDir) {
|
|
30153
31293
|
throw new Skip("parent_moved");
|
|
30154
31294
|
}
|
|
30155
|
-
const flags2 =
|
|
31295
|
+
const flags2 = import_node_fs36.constants.O_WRONLY | import_node_fs36.constants.O_CREAT | import_node_fs36.constants.O_EXCL | NOFOLLOW;
|
|
30156
31296
|
const handle2 = await (0, import_promises15.open)(abs, flags2, record3.mode ?? 420);
|
|
30157
31297
|
try {
|
|
30158
31298
|
await handle2.writeFile(bytes);
|
|
@@ -30164,7 +31304,7 @@ async function writeBack(abs, bytes, record3, before2) {
|
|
|
30164
31304
|
}
|
|
30165
31305
|
let handle;
|
|
30166
31306
|
try {
|
|
30167
|
-
handle = await (0, import_promises15.open)(abs,
|
|
31307
|
+
handle = await (0, import_promises15.open)(abs, import_node_fs36.constants.O_WRONLY | NOFOLLOW);
|
|
30168
31308
|
} catch (error2) {
|
|
30169
31309
|
const code = error2.code;
|
|
30170
31310
|
if (code === "ELOOP" || code === "EMLINK") throw new Skip("symlink");
|
|
@@ -30190,11 +31330,11 @@ async function gitHintFor(cwd, target) {
|
|
|
30190
31330
|
if (current3 === void 0 || current3.head === target.git.head) return void 0;
|
|
30191
31331
|
return { recordedHead: target.git.head, currentHead: current3.head };
|
|
30192
31332
|
}
|
|
30193
|
-
var
|
|
31333
|
+
var import_node_fs36, import_promises15, import_node_path50, RestoreSkip, Skip, IS_WINDOWS, NOFOLLOW;
|
|
30194
31334
|
var init_restore = __esm({
|
|
30195
31335
|
"src/checkpoints/restore.ts"() {
|
|
30196
31336
|
"use strict";
|
|
30197
|
-
|
|
31337
|
+
import_node_fs36 = require("node:fs");
|
|
30198
31338
|
import_promises15 = require("node:fs/promises");
|
|
30199
31339
|
import_node_path50 = require("node:path");
|
|
30200
31340
|
init_edit();
|
|
@@ -30211,7 +31351,7 @@ var init_restore = __esm({
|
|
|
30211
31351
|
};
|
|
30212
31352
|
Skip = RestoreSkip;
|
|
30213
31353
|
IS_WINDOWS = process.platform === "win32";
|
|
30214
|
-
NOFOLLOW = IS_WINDOWS ? 0 :
|
|
31354
|
+
NOFOLLOW = IS_WINDOWS ? 0 : import_node_fs36.constants.O_NOFOLLOW ?? 0;
|
|
30215
31355
|
}
|
|
30216
31356
|
});
|
|
30217
31357
|
|
|
@@ -31444,10 +32584,10 @@ var init_templates = __esm({
|
|
|
31444
32584
|
|
|
31445
32585
|
// src/cli/compose-store.ts
|
|
31446
32586
|
function cwdDirs(root) {
|
|
31447
|
-
if (!(0,
|
|
31448
|
-
return (0,
|
|
32587
|
+
if (!(0, import_node_fs37.existsSync)(root)) return [];
|
|
32588
|
+
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
32589
|
try {
|
|
31450
|
-
return (0,
|
|
32590
|
+
return (0, import_node_fs37.statSync)(dir).isDirectory();
|
|
31451
32591
|
} catch {
|
|
31452
32592
|
return false;
|
|
31453
32593
|
}
|
|
@@ -31539,11 +32679,11 @@ function createSessionStore(log) {
|
|
|
31539
32679
|
}
|
|
31540
32680
|
};
|
|
31541
32681
|
}
|
|
31542
|
-
var
|
|
32682
|
+
var import_node_fs37, import_node_path54;
|
|
31543
32683
|
var init_compose_store = __esm({
|
|
31544
32684
|
"src/cli/compose-store.ts"() {
|
|
31545
32685
|
"use strict";
|
|
31546
|
-
|
|
32686
|
+
import_node_fs37 = require("node:fs");
|
|
31547
32687
|
import_node_path54 = require("node:path");
|
|
31548
32688
|
init_errors();
|
|
31549
32689
|
init_manager();
|
|
@@ -31838,7 +32978,7 @@ function remindersSettings(config) {
|
|
|
31838
32978
|
}
|
|
31839
32979
|
function defaultStat(path) {
|
|
31840
32980
|
try {
|
|
31841
|
-
const info2 = (0,
|
|
32981
|
+
const info2 = (0, import_node_fs38.statSync)(path);
|
|
31842
32982
|
return { mtimeMs: info2.mtimeMs, size: info2.size };
|
|
31843
32983
|
} catch {
|
|
31844
32984
|
return void 0;
|
|
@@ -31866,7 +33006,7 @@ function lastTodo(branch) {
|
|
|
31866
33006
|
}
|
|
31867
33007
|
return parseTodoState(void 0);
|
|
31868
33008
|
}
|
|
31869
|
-
function
|
|
33009
|
+
function wrap2(lines2) {
|
|
31870
33010
|
return `<system-reminder>
|
|
31871
33011
|
${lines2.join("\n\n")}
|
|
31872
33012
|
</system-reminder>`;
|
|
@@ -31919,12 +33059,12 @@ function createRemindersExtension(core, settings = {}, deps = {}) {
|
|
|
31919
33059
|
dispose
|
|
31920
33060
|
};
|
|
31921
33061
|
}
|
|
31922
|
-
var import_node_child_process8,
|
|
33062
|
+
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
33063
|
var init_reminders = __esm({
|
|
31924
33064
|
"src/agent/reminders.ts"() {
|
|
31925
33065
|
"use strict";
|
|
31926
33066
|
import_node_child_process8 = require("node:child_process");
|
|
31927
|
-
|
|
33067
|
+
import_node_fs38 = require("node:fs");
|
|
31928
33068
|
import_node_path55 = require("node:path");
|
|
31929
33069
|
init_estimate();
|
|
31930
33070
|
init_projection();
|
|
@@ -32017,7 +33157,7 @@ var init_reminders = __esm({
|
|
|
32017
33157
|
const budget = inRun ? this.budgetLine() : void 0;
|
|
32018
33158
|
for (const line2 of [jobs, todo, files, context, budget])
|
|
32019
33159
|
if (line2 !== void 0) lines2.push(line2);
|
|
32020
|
-
return lines2.length === 0 ? void 0 :
|
|
33160
|
+
return lines2.length === 0 ? void 0 : wrap2(lines2);
|
|
32021
33161
|
}
|
|
32022
33162
|
jobLines() {
|
|
32023
33163
|
const exited = jobsForSession(this.core.manager.id).takeExited();
|
|
@@ -32484,17 +33624,17 @@ function resolvePlanDirectory(configured2, projectRoot, dataDir) {
|
|
|
32484
33624
|
return { dir };
|
|
32485
33625
|
}
|
|
32486
33626
|
function writePlanFile(dir, sessionId, version, markdown) {
|
|
32487
|
-
(0,
|
|
33627
|
+
(0, import_node_fs39.mkdirSync)(dir, { recursive: true });
|
|
32488
33628
|
const file = (0, import_node_path56.join)(dir, `${sessionId}-v${version}.md`);
|
|
32489
|
-
(0,
|
|
33629
|
+
(0, import_node_fs39.writeFileSync)(file, markdown.endsWith("\n") ? markdown : `${markdown}
|
|
32490
33630
|
`, "utf8");
|
|
32491
33631
|
return file;
|
|
32492
33632
|
}
|
|
32493
|
-
var
|
|
33633
|
+
var import_node_fs39, import_node_path56, PLAN_CUSTOM_TYPE2, PLAN_STATE_CUSTOM_TYPE;
|
|
32494
33634
|
var init_store3 = __esm({
|
|
32495
33635
|
"src/plan/store.ts"() {
|
|
32496
33636
|
"use strict";
|
|
32497
|
-
|
|
33637
|
+
import_node_fs39 = require("node:fs");
|
|
32498
33638
|
import_node_path56 = require("node:path");
|
|
32499
33639
|
init_todo();
|
|
32500
33640
|
init_i18n();
|
|
@@ -33030,7 +34170,7 @@ function permissionModeOf(value) {
|
|
|
33030
34170
|
}
|
|
33031
34171
|
function parseAgentDefinition(text, filePath, source) {
|
|
33032
34172
|
const warnings = [];
|
|
33033
|
-
const
|
|
34173
|
+
const fail7 = (message) => {
|
|
33034
34174
|
warnings.push(`${filePath}: ${message}`);
|
|
33035
34175
|
return { warnings };
|
|
33036
34176
|
};
|
|
@@ -33040,42 +34180,42 @@ function parseAgentDefinition(text, filePath, source) {
|
|
|
33040
34180
|
const rawName = data2["name"];
|
|
33041
34181
|
const name = typeof rawName === "string" && rawName !== "" ? rawName : (0, import_node_path57.basename)(filePath, ".md");
|
|
33042
34182
|
if (!AGENT_NAME_RE.test(name))
|
|
33043
|
-
return
|
|
34183
|
+
return fail7(`invalid agent name "${name}" (lowercase letters, digits, -; at most 64)`);
|
|
33044
34184
|
const description = data2["description"];
|
|
33045
34185
|
if (typeof description !== "string" || description.trim() === "")
|
|
33046
|
-
return
|
|
34186
|
+
return fail7(`missing description; agent "${name}" not loaded`);
|
|
33047
34187
|
if (description.length > MAX_AGENT_DESCRIPTION)
|
|
33048
|
-
return
|
|
34188
|
+
return fail7(`description longer than ${MAX_AGENT_DESCRIPTION} characters`);
|
|
33049
34189
|
const runnerRaw = data2["runner"] ?? "ama";
|
|
33050
34190
|
const runner = String(runnerRaw).trim();
|
|
33051
34191
|
if (!isRunner(runner))
|
|
33052
|
-
return
|
|
34192
|
+
return fail7(`unknown runner "${runner}" (ama | claude | codex | acp:<program>)`);
|
|
33053
34193
|
const tools = nameList(data2["tools"]);
|
|
33054
34194
|
const disallowedTools = nameList(data2["disallowed-tools"]);
|
|
33055
34195
|
if (tools !== void 0 && disallowedTools !== void 0)
|
|
33056
|
-
return
|
|
34196
|
+
return fail7("tools and disallowed-tools are mutually exclusive");
|
|
33057
34197
|
const permissionMode = permissionModeOf(data2["permission-mode"]);
|
|
33058
34198
|
if (permissionMode === void 0)
|
|
33059
|
-
return
|
|
34199
|
+
return fail7(
|
|
33060
34200
|
`permission-mode must be plan or inherit (got "${String(data2["permission-mode"])}")`
|
|
33061
34201
|
);
|
|
33062
34202
|
const model = data2["model"] === void 0 || data2["model"] === null ? "inherit" : data2["model"];
|
|
33063
|
-
if (typeof model !== "string" || model.trim() === "") return
|
|
34203
|
+
if (typeof model !== "string" || model.trim() === "") return fail7("model must be a string");
|
|
33064
34204
|
const thinking = data2["thinking"];
|
|
33065
34205
|
if (thinking !== void 0 && thinking !== null && !THINKING2.includes(thinking))
|
|
33066
|
-
return
|
|
34206
|
+
return fail7(`thinking must be one of ${THINKING2.join(", ")}`);
|
|
33067
34207
|
const maxTurns = data2["max-turns"] ?? DEFAULT_AGENT_MAX_TURNS;
|
|
33068
34208
|
if (typeof maxTurns !== "number" || !Number.isInteger(maxTurns) || maxTurns < 1)
|
|
33069
|
-
return
|
|
34209
|
+
return fail7("max-turns must be an integer ≥ 1");
|
|
33070
34210
|
const isolation = data2["isolation"] ?? "none";
|
|
33071
34211
|
if (isolation !== "none" && isolation !== "worktree")
|
|
33072
|
-
return
|
|
34212
|
+
return fail7("isolation must be none or worktree");
|
|
33073
34213
|
const background = data2["background"];
|
|
33074
34214
|
if (background !== void 0 && typeof background !== "boolean")
|
|
33075
|
-
return
|
|
34215
|
+
return fail7("background must be true or false");
|
|
33076
34216
|
const context = data2["context"];
|
|
33077
34217
|
if (context !== void 0 && context !== null && context !== "fork" && context !== "fresh")
|
|
33078
|
-
return
|
|
34218
|
+
return fail7("context must be fork or fresh");
|
|
33079
34219
|
if (runner !== "ama") {
|
|
33080
34220
|
const ignored = ["tools", "disallowed-tools", "permission-mode", "context"].filter(
|
|
33081
34221
|
(key) => data2[key] !== void 0
|
|
@@ -33136,14 +34276,14 @@ function agentSources(options) {
|
|
|
33136
34276
|
}
|
|
33137
34277
|
function isDir2(path) {
|
|
33138
34278
|
try {
|
|
33139
|
-
return (0,
|
|
34279
|
+
return (0, import_node_fs40.statSync)(path).isDirectory();
|
|
33140
34280
|
} catch {
|
|
33141
34281
|
return false;
|
|
33142
34282
|
}
|
|
33143
34283
|
}
|
|
33144
34284
|
function markdownFiles(dir) {
|
|
33145
34285
|
try {
|
|
33146
|
-
return (0,
|
|
34286
|
+
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
34287
|
} catch {
|
|
33148
34288
|
return [];
|
|
33149
34289
|
}
|
|
@@ -33163,7 +34303,7 @@ function discoverAgents(sources, options) {
|
|
|
33163
34303
|
for (const file of markdownFiles(source.dir)) {
|
|
33164
34304
|
let text;
|
|
33165
34305
|
try {
|
|
33166
|
-
text = (0,
|
|
34306
|
+
text = (0, import_node_fs40.readFileSync)(file, "utf8");
|
|
33167
34307
|
} catch (error2) {
|
|
33168
34308
|
result.warnings.push(`${file}: ${error2.message}`);
|
|
33169
34309
|
continue;
|
|
@@ -33185,11 +34325,11 @@ function discoverAgents(sources, options) {
|
|
|
33185
34325
|
}
|
|
33186
34326
|
return result;
|
|
33187
34327
|
}
|
|
33188
|
-
var
|
|
34328
|
+
var import_node_fs40, import_node_path58;
|
|
33189
34329
|
var init_discover = __esm({
|
|
33190
34330
|
"src/agents/discover.ts"() {
|
|
33191
34331
|
"use strict";
|
|
33192
|
-
|
|
34332
|
+
import_node_fs40 = require("node:fs");
|
|
33193
34333
|
import_node_path58 = require("node:path");
|
|
33194
34334
|
init_parse();
|
|
33195
34335
|
}
|
|
@@ -33527,7 +34667,7 @@ var init_process = __esm({
|
|
|
33527
34667
|
// src/drivers/probe.ts
|
|
33528
34668
|
function defaultIsFile(path) {
|
|
33529
34669
|
try {
|
|
33530
|
-
return (0,
|
|
34670
|
+
return (0, import_node_fs41.statSync)(path).isFile();
|
|
33531
34671
|
} catch {
|
|
33532
34672
|
return false;
|
|
33533
34673
|
}
|
|
@@ -33589,12 +34729,12 @@ function defaultRunVersion(env, platform) {
|
|
|
33589
34729
|
);
|
|
33590
34730
|
});
|
|
33591
34731
|
}
|
|
33592
|
-
var import_node_child_process10,
|
|
34732
|
+
var import_node_child_process10, import_node_fs41, import_node_path59, VERSION_TIMEOUT_MS, ProgramProbe;
|
|
33593
34733
|
var init_probe = __esm({
|
|
33594
34734
|
"src/drivers/probe.ts"() {
|
|
33595
34735
|
"use strict";
|
|
33596
34736
|
import_node_child_process10 = require("node:child_process");
|
|
33597
|
-
|
|
34737
|
+
import_node_fs41 = require("node:fs");
|
|
33598
34738
|
import_node_path59 = require("node:path");
|
|
33599
34739
|
init_process();
|
|
33600
34740
|
VERSION_TIMEOUT_MS = 5e3;
|
|
@@ -33647,16 +34787,16 @@ var init_probe = __esm({
|
|
|
33647
34787
|
}
|
|
33648
34788
|
mtime(path) {
|
|
33649
34789
|
try {
|
|
33650
|
-
return (0,
|
|
34790
|
+
return (0, import_node_fs41.statSync)(path).mtimeMs;
|
|
33651
34791
|
} catch {
|
|
33652
34792
|
return 0;
|
|
33653
34793
|
}
|
|
33654
34794
|
}
|
|
33655
34795
|
readCache() {
|
|
33656
34796
|
const file = this.deps.cacheFile;
|
|
33657
|
-
if (file === void 0 || !(0,
|
|
34797
|
+
if (file === void 0 || !(0, import_node_fs41.existsSync)(file)) return {};
|
|
33658
34798
|
try {
|
|
33659
|
-
const parsed = JSON.parse((0,
|
|
34799
|
+
const parsed = JSON.parse((0, import_node_fs41.readFileSync)(file, "utf8"));
|
|
33660
34800
|
return parsed.programs ?? {};
|
|
33661
34801
|
} catch {
|
|
33662
34802
|
return {};
|
|
@@ -33667,8 +34807,8 @@ var init_probe = __esm({
|
|
|
33667
34807
|
if (file === void 0) return;
|
|
33668
34808
|
try {
|
|
33669
34809
|
const programs = { ...this.readCache(), [path]: entry };
|
|
33670
|
-
(0,
|
|
33671
|
-
(0,
|
|
34810
|
+
(0, import_node_fs41.mkdirSync)((0, import_node_path59.dirname)(file), { recursive: true });
|
|
34811
|
+
(0, import_node_fs41.writeFileSync)(file, `${JSON.stringify({ version: 1, programs }, null, 2)}
|
|
33672
34812
|
`);
|
|
33673
34813
|
} catch {
|
|
33674
34814
|
}
|
|
@@ -34072,9 +35212,9 @@ var init_client = __esm({
|
|
|
34072
35212
|
});
|
|
34073
35213
|
|
|
34074
35214
|
// src/drivers/acp/driver.ts
|
|
34075
|
-
function toAcpContent(
|
|
35215
|
+
function toAcpContent(blocks2, images) {
|
|
34076
35216
|
const out = [];
|
|
34077
|
-
for (const block of
|
|
35217
|
+
for (const block of blocks2) {
|
|
34078
35218
|
if (block.type === "text") out.push({ type: "text", text: block.text });
|
|
34079
35219
|
else if (images) out.push({ type: "image", data: block.data, mimeType: block.mimeType });
|
|
34080
35220
|
}
|
|
@@ -34578,12 +35718,12 @@ function claudeArgs(options, sessionId, manualName = "manual") {
|
|
|
34578
35718
|
return args;
|
|
34579
35719
|
}
|
|
34580
35720
|
function userLine(content) {
|
|
34581
|
-
const
|
|
35721
|
+
const blocks2 = content.map(
|
|
34582
35722
|
(b) => b.type === "text" ? { type: "text", text: b.text } : { type: "image", source: { type: "base64", media_type: b.mimeType, data: b.data } }
|
|
34583
35723
|
);
|
|
34584
35724
|
return `${JSON.stringify({
|
|
34585
35725
|
type: "user",
|
|
34586
|
-
message: { role: "user", content:
|
|
35726
|
+
message: { role: "user", content: blocks2 },
|
|
34587
35727
|
parent_tool_use_id: null
|
|
34588
35728
|
})}
|
|
34589
35729
|
`;
|
|
@@ -35839,19 +36979,19 @@ ${item["text"]}`
|
|
|
35839
36979
|
|
|
35840
36980
|
// src/drivers/native/pi-gate.ts
|
|
35841
36981
|
function writePiGate() {
|
|
35842
|
-
const dir = (0,
|
|
36982
|
+
const dir = (0, import_node_fs42.mkdtempSync)((0, import_node_path60.join)((0, import_node_os11.tmpdir)(), "ama-pi-"));
|
|
35843
36983
|
const path = (0, import_node_path60.join)(dir, "ama-approval-gate.ts");
|
|
35844
|
-
(0,
|
|
36984
|
+
(0, import_node_fs42.writeFileSync)(path, PI_GATE_SOURCE, { mode: 384 });
|
|
35845
36985
|
return {
|
|
35846
36986
|
path,
|
|
35847
|
-
dispose: () => (0,
|
|
36987
|
+
dispose: () => (0, import_node_fs42.rmSync)(dir, { recursive: true, force: true })
|
|
35848
36988
|
};
|
|
35849
36989
|
}
|
|
35850
|
-
var
|
|
36990
|
+
var import_node_fs42, import_node_os11, import_node_path60, PI_GATE_TITLE, PI_READ_ONLY_TOOLS, PI_GATE_SOURCE;
|
|
35851
36991
|
var init_pi_gate = __esm({
|
|
35852
36992
|
"src/drivers/native/pi-gate.ts"() {
|
|
35853
36993
|
"use strict";
|
|
35854
|
-
|
|
36994
|
+
import_node_fs42 = require("node:fs");
|
|
35855
36995
|
import_node_os11 = require("node:os");
|
|
35856
36996
|
import_node_path60 = require("node:path");
|
|
35857
36997
|
PI_GATE_TITLE = "ama-approval";
|
|
@@ -36346,7 +37486,7 @@ function pidsFile(dataDir) {
|
|
|
36346
37486
|
}
|
|
36347
37487
|
function read(file) {
|
|
36348
37488
|
try {
|
|
36349
|
-
const parsed = JSON.parse((0,
|
|
37489
|
+
const parsed = JSON.parse((0, import_node_fs43.readFileSync)(file, "utf8"));
|
|
36350
37490
|
return Array.isArray(parsed.entries) ? parsed.entries : [];
|
|
36351
37491
|
} catch {
|
|
36352
37492
|
return [];
|
|
@@ -36354,11 +37494,11 @@ function read(file) {
|
|
|
36354
37494
|
}
|
|
36355
37495
|
function write(file, entries) {
|
|
36356
37496
|
try {
|
|
36357
|
-
(0,
|
|
37497
|
+
(0, import_node_fs43.mkdirSync)((0, import_node_path62.dirname)(file), { recursive: true });
|
|
36358
37498
|
const tmp = `${file}.${process.pid}.tmp`;
|
|
36359
|
-
(0,
|
|
37499
|
+
(0, import_node_fs43.writeFileSync)(tmp, `${JSON.stringify({ version: 1, entries }, null, 2)}
|
|
36360
37500
|
`);
|
|
36361
|
-
(0,
|
|
37501
|
+
(0, import_node_fs43.renameSync)(tmp, file);
|
|
36362
37502
|
} catch {
|
|
36363
37503
|
}
|
|
36364
37504
|
}
|
|
@@ -36374,12 +37514,12 @@ function psCommand(pid) {
|
|
|
36374
37514
|
const out = (0, import_node_child_process11.spawnSync)("ps", ["-o", "command=", "-p", String(pid)], { encoding: "utf8" });
|
|
36375
37515
|
return out.status === 0 ? out.stdout.trim() : void 0;
|
|
36376
37516
|
}
|
|
36377
|
-
var import_node_child_process11,
|
|
37517
|
+
var import_node_child_process11, import_node_fs43, import_node_path62, PidRegistry;
|
|
36378
37518
|
var init_pids = __esm({
|
|
36379
37519
|
"src/drivers/pids.ts"() {
|
|
36380
37520
|
"use strict";
|
|
36381
37521
|
import_node_child_process11 = require("node:child_process");
|
|
36382
|
-
|
|
37522
|
+
import_node_fs43 = require("node:fs");
|
|
36383
37523
|
import_node_path62 = require("node:path");
|
|
36384
37524
|
init_process_tree();
|
|
36385
37525
|
PidRegistry = class {
|
|
@@ -36644,7 +37784,7 @@ function toUsage(turn) {
|
|
|
36644
37784
|
usage.cost = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: u.costUsd };
|
|
36645
37785
|
return usage;
|
|
36646
37786
|
}
|
|
36647
|
-
function
|
|
37787
|
+
function statusOf2(turn, timedOut, stopped) {
|
|
36648
37788
|
if (timedOut) return "failed";
|
|
36649
37789
|
switch (turn.stopReason) {
|
|
36650
37790
|
case "end_turn":
|
|
@@ -37037,7 +38177,7 @@ var init_runner2 = __esm({
|
|
|
37037
38177
|
});
|
|
37038
38178
|
this.emit({ type: "usage", usage, unit, amount });
|
|
37039
38179
|
}
|
|
37040
|
-
const status =
|
|
38180
|
+
const status = statusOf2(turn, timedOut, this.stopped);
|
|
37041
38181
|
this.emitTurnTrace(
|
|
37042
38182
|
turnStartedAt,
|
|
37043
38183
|
timedOut ? "timeout" : turn.stopReason,
|
|
@@ -37157,7 +38297,7 @@ var init_agents2 = __esm({
|
|
|
37157
38297
|
driverDeps;
|
|
37158
38298
|
/** `task(agent=<spec>)` 的 runner;不可用时抛 AmaError(`agent_host_only` / `agent_unknown`)。 */
|
|
37159
38299
|
resolve(spec2) {
|
|
37160
|
-
const hosted = this.hostRunners.
|
|
38300
|
+
const hosted = this.hostRunners.resolve(spec2);
|
|
37161
38301
|
if (hosted !== void 0) return hosted;
|
|
37162
38302
|
if (this.options.hosted)
|
|
37163
38303
|
throw new AmaError(
|
|
@@ -37812,7 +38952,7 @@ function sourceText2(source, cache3, log) {
|
|
|
37812
38952
|
if (cached !== void 0) return cached;
|
|
37813
38953
|
let text = "";
|
|
37814
38954
|
try {
|
|
37815
|
-
text = (0,
|
|
38955
|
+
text = (0, import_node_fs44.readFileSync)(source.path, "utf8");
|
|
37816
38956
|
} catch (error2) {
|
|
37817
38957
|
log(
|
|
37818
38958
|
"warn",
|
|
@@ -38166,11 +39306,11 @@ async function disposeSessionAlongside(target, session, fallback) {
|
|
|
38166
39306
|
await session.dispose();
|
|
38167
39307
|
record3.live.delete(session);
|
|
38168
39308
|
}
|
|
38169
|
-
var
|
|
39309
|
+
var import_node_fs44, records, LOG_LEVELS;
|
|
38170
39310
|
var init_compose_session = __esm({
|
|
38171
39311
|
"src/cli/compose-session.ts"() {
|
|
38172
39312
|
"use strict";
|
|
38173
|
-
|
|
39313
|
+
import_node_fs44 = require("node:fs");
|
|
38174
39314
|
init_limits();
|
|
38175
39315
|
init_session2();
|
|
38176
39316
|
init_session_subagent();
|
|
@@ -39026,7 +40166,7 @@ var init_acp_sessions = __esm({
|
|
|
39026
40166
|
// src/modes/acp/acp-server.ts
|
|
39027
40167
|
function canonical(path) {
|
|
39028
40168
|
try {
|
|
39029
|
-
return
|
|
40169
|
+
return import_node_fs45.realpathSync.native((0, import_node_path65.resolve)(path));
|
|
39030
40170
|
} catch {
|
|
39031
40171
|
return (0, import_node_path65.resolve)(path);
|
|
39032
40172
|
}
|
|
@@ -39037,12 +40177,12 @@ function str(params, key) {
|
|
|
39037
40177
|
throw new RpcError(RPC_ERRORS.invalidParams, msg().acp.core.missingParam(key));
|
|
39038
40178
|
return value;
|
|
39039
40179
|
}
|
|
39040
|
-
function promptOf(
|
|
39041
|
-
if (!Array.isArray(
|
|
40180
|
+
function promptOf(blocks2) {
|
|
40181
|
+
if (!Array.isArray(blocks2))
|
|
39042
40182
|
throw new RpcError(RPC_ERRORS.invalidParams, msg().acp.core.promptNotArray);
|
|
39043
40183
|
const parts = [];
|
|
39044
40184
|
const images = [];
|
|
39045
|
-
for (const block of
|
|
40185
|
+
for (const block of blocks2) {
|
|
39046
40186
|
if (block.type === "text") parts.push(block.text);
|
|
39047
40187
|
else if (block.type === "image")
|
|
39048
40188
|
images.push({ type: "image", data: block.data, mimeType: block.mimeType });
|
|
@@ -39057,11 +40197,11 @@ ${block.resource.text}
|
|
|
39057
40197
|
function countOf(value) {
|
|
39058
40198
|
return Array.isArray(value) ? value.length : 0;
|
|
39059
40199
|
}
|
|
39060
|
-
var
|
|
40200
|
+
var import_node_fs45, import_node_path65, ACP_AGENT_CAPABILITIES, SESSION_ID_SHAPE, AcpServer;
|
|
39061
40201
|
var init_acp_server = __esm({
|
|
39062
40202
|
"src/modes/acp/acp-server.ts"() {
|
|
39063
40203
|
"use strict";
|
|
39064
|
-
|
|
40204
|
+
import_node_fs45 = require("node:fs");
|
|
39065
40205
|
import_node_path65 = require("node:path");
|
|
39066
40206
|
init_shared();
|
|
39067
40207
|
init_compose_session();
|
|
@@ -39785,7 +40925,7 @@ async function bootstrap(argsIn, deps, io) {
|
|
|
39785
40925
|
() => deps.sessions.open(sessionRequest, { sessionDir: paths.sessionDir, cwd: paths.cwd })
|
|
39786
40926
|
);
|
|
39787
40927
|
let sessionCwd = sessionManager.cwd;
|
|
39788
|
-
if (!(0,
|
|
40928
|
+
if (!(0, import_node_fs46.existsSync)(sessionCwd)) {
|
|
39789
40929
|
const replacement = interactive ? await deps.ui?.askCwd?.(sessionCwd) : void 0;
|
|
39790
40930
|
if (replacement === void 0) {
|
|
39791
40931
|
throw new StartupError(
|
|
@@ -40179,11 +41319,11 @@ function reportError(error2, io, fallback = ExitCode.RuntimeError) {
|
|
|
40179
41319
|
if (isAmaError(error2) && error2.exitCode !== void 0) return error2.exitCode;
|
|
40180
41320
|
return fallback;
|
|
40181
41321
|
}
|
|
40182
|
-
var
|
|
41322
|
+
var import_node_fs46, import_node_path67;
|
|
40183
41323
|
var init_bootstrap = __esm({
|
|
40184
41324
|
"src/cli/bootstrap.ts"() {
|
|
40185
41325
|
"use strict";
|
|
40186
|
-
|
|
41326
|
+
import_node_fs46 = require("node:fs");
|
|
40187
41327
|
import_node_path67 = require("node:path");
|
|
40188
41328
|
init_auth_file();
|
|
40189
41329
|
init_context_files();
|
|
@@ -40210,7 +41350,7 @@ var init_bootstrap = __esm({
|
|
|
40210
41350
|
// src/auth/oauth/token-store.ts
|
|
40211
41351
|
function readRaw(path) {
|
|
40212
41352
|
try {
|
|
40213
|
-
const value = JSON.parse(retryTransientFs(() => (0,
|
|
41353
|
+
const value = JSON.parse(retryTransientFs(() => (0, import_node_fs47.readFileSync)(path, "utf8")));
|
|
40214
41354
|
return typeof value === "object" && value !== null && typeof value.providers === "object" ? value : void 0;
|
|
40215
41355
|
} catch {
|
|
40216
41356
|
return void 0;
|
|
@@ -40242,12 +41382,12 @@ function isStaleLock(path, now = Date.now()) {
|
|
|
40242
41382
|
let age;
|
|
40243
41383
|
let pid;
|
|
40244
41384
|
try {
|
|
40245
|
-
age = now - (0,
|
|
40246
|
-
const value = JSON.parse((0,
|
|
41385
|
+
age = now - (0, import_node_fs47.statSync)(path).mtimeMs;
|
|
41386
|
+
const value = JSON.parse((0, import_node_fs47.readFileSync)(path, "utf8"));
|
|
40247
41387
|
pid = typeof value.pid === "number" ? value.pid : void 0;
|
|
40248
41388
|
} catch {
|
|
40249
41389
|
try {
|
|
40250
|
-
age = now - (0,
|
|
41390
|
+
age = now - (0, import_node_fs47.statSync)(path).mtimeMs;
|
|
40251
41391
|
} catch {
|
|
40252
41392
|
return false;
|
|
40253
41393
|
}
|
|
@@ -40256,11 +41396,11 @@ function isStaleLock(path, now = Date.now()) {
|
|
|
40256
41396
|
}
|
|
40257
41397
|
function tryAcquire(path) {
|
|
40258
41398
|
try {
|
|
40259
|
-
const fd = (0,
|
|
41399
|
+
const fd = (0, import_node_fs47.openSync)(path, "wx", 384);
|
|
40260
41400
|
try {
|
|
40261
|
-
(0,
|
|
41401
|
+
(0, import_node_fs47.writeSync)(fd, JSON.stringify({ pid: process.pid, at: (/* @__PURE__ */ new Date()).toISOString() }));
|
|
40262
41402
|
} finally {
|
|
40263
|
-
(0,
|
|
41403
|
+
(0, import_node_fs47.closeSync)(fd);
|
|
40264
41404
|
}
|
|
40265
41405
|
return true;
|
|
40266
41406
|
} catch (error2) {
|
|
@@ -40271,13 +41411,13 @@ function tryAcquire(path) {
|
|
|
40271
41411
|
}
|
|
40272
41412
|
async function withRefreshLock(authFile, fn, options = {}) {
|
|
40273
41413
|
const path = lockPath(authFile);
|
|
40274
|
-
(0,
|
|
41414
|
+
(0, import_node_fs47.mkdirSync)((0, import_node_path68.dirname)(path), { recursive: true, mode: 448 });
|
|
40275
41415
|
const deadline = Date.now() + (options.waitMs ?? LOCK_WAIT_MS);
|
|
40276
41416
|
for (; ; ) {
|
|
40277
41417
|
if (tryAcquire(path)) break;
|
|
40278
41418
|
if (isStaleLock(path)) {
|
|
40279
41419
|
try {
|
|
40280
|
-
(0,
|
|
41420
|
+
(0, import_node_fs47.unlinkSync)(path);
|
|
40281
41421
|
} catch {
|
|
40282
41422
|
}
|
|
40283
41423
|
continue;
|
|
@@ -40292,16 +41432,16 @@ async function withRefreshLock(authFile, fn, options = {}) {
|
|
|
40292
41432
|
return await fn();
|
|
40293
41433
|
} finally {
|
|
40294
41434
|
try {
|
|
40295
|
-
(0,
|
|
41435
|
+
(0, import_node_fs47.unlinkSync)(path);
|
|
40296
41436
|
} catch {
|
|
40297
41437
|
}
|
|
40298
41438
|
}
|
|
40299
41439
|
}
|
|
40300
|
-
var
|
|
41440
|
+
var import_node_fs47, import_node_path68, LOCK_WAIT_MS, LOCK_STALE_MS, LOCK_POLL_MS;
|
|
40301
41441
|
var init_token_store = __esm({
|
|
40302
41442
|
"src/auth/oauth/token-store.ts"() {
|
|
40303
41443
|
"use strict";
|
|
40304
|
-
|
|
41444
|
+
import_node_fs47 = require("node:fs");
|
|
40305
41445
|
import_node_path68 = require("node:path");
|
|
40306
41446
|
init_auth_file();
|
|
40307
41447
|
init_fs_retry();
|
|
@@ -40336,7 +41476,7 @@ function toEntry(value) {
|
|
|
40336
41476
|
function readDiscoveredCache(dataDir, provider) {
|
|
40337
41477
|
let parsed;
|
|
40338
41478
|
try {
|
|
40339
|
-
parsed = JSON.parse((0,
|
|
41479
|
+
parsed = JSON.parse((0, import_node_fs48.readFileSync)(discoveredCachePath(dataDir, provider), "utf8"));
|
|
40340
41480
|
} catch {
|
|
40341
41481
|
return void 0;
|
|
40342
41482
|
}
|
|
@@ -40360,17 +41500,17 @@ function writeDiscoveredCache(dataDir, provider, input2, now = Date.now()) {
|
|
|
40360
41500
|
...input2.flavor !== void 0 ? { flavor: input2.flavor } : {},
|
|
40361
41501
|
models: input2.models.map(toEntry).filter((m) => m !== void 0)
|
|
40362
41502
|
};
|
|
40363
|
-
(0,
|
|
41503
|
+
(0, import_node_fs48.mkdirSync)((0, import_node_path69.dirname)(path), { recursive: true, mode: 448 });
|
|
40364
41504
|
const tmp = `${path}.${process.pid}.tmp`;
|
|
40365
|
-
(0,
|
|
41505
|
+
(0, import_node_fs48.writeFileSync)(tmp, `${JSON.stringify(file, null, 2)}
|
|
40366
41506
|
`);
|
|
40367
|
-
(0,
|
|
41507
|
+
(0, import_node_fs48.renameSync)(tmp, path);
|
|
40368
41508
|
return path;
|
|
40369
41509
|
}
|
|
40370
41510
|
function clearDiscoveredCache(dataDir, provider) {
|
|
40371
41511
|
const path = discoveredCachePath(dataDir, provider);
|
|
40372
|
-
if (!(0,
|
|
40373
|
-
(0,
|
|
41512
|
+
if (!(0, import_node_fs48.existsSync)(path)) return false;
|
|
41513
|
+
(0, import_node_fs48.rmSync)(path, { force: true });
|
|
40374
41514
|
return true;
|
|
40375
41515
|
}
|
|
40376
41516
|
function thinkingMapOf(levels) {
|
|
@@ -40424,11 +41564,11 @@ function mergeDiscoveredModels(registry3, dataDir, modelsDev, loginFlavor = () =
|
|
|
40424
41564
|
}
|
|
40425
41565
|
return merged;
|
|
40426
41566
|
}
|
|
40427
|
-
var
|
|
41567
|
+
var import_node_fs48, import_node_path69, DISCOVERED_CACHE_VERSION, EFFORT_LEVELS, SUBSCRIPTION_FALLBACK_CONTEXT_WINDOW, SUBSCRIPTION_PROVIDERS;
|
|
40428
41568
|
var init_discovered_cache = __esm({
|
|
40429
41569
|
"src/ai/providers/discovered-cache.ts"() {
|
|
40430
41570
|
"use strict";
|
|
40431
|
-
|
|
41571
|
+
import_node_fs48 = require("node:fs");
|
|
40432
41572
|
import_node_path69 = require("node:path");
|
|
40433
41573
|
init_catalog2();
|
|
40434
41574
|
init_enrich();
|
|
@@ -42316,7 +43456,7 @@ function parseKeybindings(value) {
|
|
|
42316
43456
|
function loadKeybindingsFile(path) {
|
|
42317
43457
|
let text;
|
|
42318
43458
|
try {
|
|
42319
|
-
text = (0,
|
|
43459
|
+
text = (0, import_node_fs50.readFileSync)(path, "utf8");
|
|
42320
43460
|
} catch (error2) {
|
|
42321
43461
|
if (error2.code === "ENOENT") return { overrides: {}, warnings: [] };
|
|
42322
43462
|
return {
|
|
@@ -42333,12 +43473,12 @@ function loadKeybindingsFile(path) {
|
|
|
42333
43473
|
};
|
|
42334
43474
|
}
|
|
42335
43475
|
}
|
|
42336
|
-
var
|
|
43476
|
+
var import_node_fs50, DEFAULT_KEYBINDINGS, Keybindings, defaultKeybindings;
|
|
42337
43477
|
var init_keybindings = __esm({
|
|
42338
43478
|
"src/tui/keybindings.ts"() {
|
|
42339
43479
|
"use strict";
|
|
42340
43480
|
init_i18n();
|
|
42341
|
-
|
|
43481
|
+
import_node_fs50 = require("node:fs");
|
|
42342
43482
|
init_keys();
|
|
42343
43483
|
DEFAULT_KEYBINDINGS = {
|
|
42344
43484
|
"tui.editor.submit": ["enter"],
|
|
@@ -42486,7 +43626,7 @@ function isBlockStart(line2) {
|
|
|
42486
43626
|
function splitLines2(source) {
|
|
42487
43627
|
return source.replace(/\r\n?/g, "\n").split("\n");
|
|
42488
43628
|
}
|
|
42489
|
-
function parseLines(lines2, from,
|
|
43629
|
+
function parseLines(lines2, from, blocks2, spans) {
|
|
42490
43630
|
let i = from;
|
|
42491
43631
|
while (i < lines2.length) {
|
|
42492
43632
|
const line2 = lines2[i];
|
|
@@ -42495,13 +43635,13 @@ function parseLines(lines2, from, blocks, spans) {
|
|
|
42495
43635
|
continue;
|
|
42496
43636
|
}
|
|
42497
43637
|
const start = i;
|
|
42498
|
-
const before2 =
|
|
42499
|
-
i = parseBlock(lines2, i,
|
|
42500
|
-
for (let k = before2; k <
|
|
43638
|
+
const before2 = blocks2.length;
|
|
43639
|
+
i = parseBlock(lines2, i, blocks2);
|
|
43640
|
+
for (let k = before2; k < blocks2.length; k++) spans.push({ start, end: i });
|
|
42501
43641
|
}
|
|
42502
|
-
return
|
|
43642
|
+
return blocks2;
|
|
42503
43643
|
}
|
|
42504
|
-
function parseBlock(lines2, i,
|
|
43644
|
+
function parseBlock(lines2, i, blocks2) {
|
|
42505
43645
|
const line2 = lines2[i];
|
|
42506
43646
|
const start = i;
|
|
42507
43647
|
const fence2 = FENCE_RE.exec(line2);
|
|
@@ -42512,12 +43652,12 @@ function parseBlock(lines2, i, blocks) {
|
|
|
42512
43652
|
while (i < lines2.length && !lines2[i].trimStart().startsWith(marker)) body2.push(lines2[i++]);
|
|
42513
43653
|
if (i < lines2.length) i++;
|
|
42514
43654
|
const src = lines2.slice(start, i).join("\n");
|
|
42515
|
-
|
|
43655
|
+
blocks2.push({ kind: "code", lang: fence2[2] ?? "", lines: body2, source: src });
|
|
42516
43656
|
return i;
|
|
42517
43657
|
}
|
|
42518
43658
|
const heading = HEADING_RE.exec(line2);
|
|
42519
43659
|
if (heading) {
|
|
42520
|
-
|
|
43660
|
+
blocks2.push({
|
|
42521
43661
|
kind: "heading",
|
|
42522
43662
|
level: heading[1].length,
|
|
42523
43663
|
text: heading[2] ?? "",
|
|
@@ -42527,7 +43667,7 @@ function parseBlock(lines2, i, blocks) {
|
|
|
42527
43667
|
return i;
|
|
42528
43668
|
}
|
|
42529
43669
|
if (HR_RE.test(line2)) {
|
|
42530
|
-
|
|
43670
|
+
blocks2.push({ kind: "hr", source: line2 });
|
|
42531
43671
|
i++;
|
|
42532
43672
|
return i;
|
|
42533
43673
|
}
|
|
@@ -42538,13 +43678,13 @@ function parseBlock(lines2, i, blocks) {
|
|
|
42538
43678
|
if (TABLE_SEP_RE.test(row3)) continue;
|
|
42539
43679
|
rows.push(splitTableRow(row3));
|
|
42540
43680
|
}
|
|
42541
|
-
|
|
43681
|
+
blocks2.push({ kind: "table", rows, source: lines2.slice(start, i).join("\n") });
|
|
42542
43682
|
return i;
|
|
42543
43683
|
}
|
|
42544
43684
|
if (QUOTE_RE.test(line2)) {
|
|
42545
43685
|
const body2 = [];
|
|
42546
43686
|
while (i < lines2.length && QUOTE_RE.test(lines2[i])) body2.push(QUOTE_RE.exec(lines2[i++])[1]);
|
|
42547
|
-
|
|
43687
|
+
blocks2.push({
|
|
42548
43688
|
kind: "quote",
|
|
42549
43689
|
text: body2.join("\n"),
|
|
42550
43690
|
source: lines2.slice(start, i).join("\n")
|
|
@@ -42552,17 +43692,17 @@ function parseBlock(lines2, i, blocks) {
|
|
|
42552
43692
|
return i;
|
|
42553
43693
|
}
|
|
42554
43694
|
if (LIST_RE.test(line2)) {
|
|
42555
|
-
return parseList(lines2, i,
|
|
43695
|
+
return parseList(lines2, i, blocks2);
|
|
42556
43696
|
}
|
|
42557
43697
|
const body = [line2];
|
|
42558
43698
|
i++;
|
|
42559
43699
|
while (i < lines2.length && lines2[i].trim() !== "" && !isBlockStart(lines2[i])) {
|
|
42560
43700
|
body.push(lines2[i++]);
|
|
42561
43701
|
}
|
|
42562
|
-
|
|
43702
|
+
blocks2.push({ kind: "paragraph", text: joinSoftBreaks(body), source: body.join("\n") });
|
|
42563
43703
|
return i;
|
|
42564
43704
|
}
|
|
42565
|
-
function parseList(lines2, start,
|
|
43705
|
+
function parseList(lines2, start, blocks2) {
|
|
42566
43706
|
const items = [];
|
|
42567
43707
|
const indents = [];
|
|
42568
43708
|
let i = start;
|
|
@@ -42589,7 +43729,7 @@ function parseList(lines2, start, blocks) {
|
|
|
42589
43729
|
}
|
|
42590
43730
|
break;
|
|
42591
43731
|
}
|
|
42592
|
-
|
|
43732
|
+
blocks2.push({ kind: "list", items, source: lines2.slice(start, i).join("\n") });
|
|
42593
43733
|
return i;
|
|
42594
43734
|
}
|
|
42595
43735
|
function joinSoftBreaks(lines2) {
|
|
@@ -42609,7 +43749,7 @@ function splitTableRow(row3) {
|
|
|
42609
43749
|
const trimmed = row3.trim().replace(/^\|/, "").replace(/\|$/, "");
|
|
42610
43750
|
return trimmed.split(/(?<!\\)\|/).map((cell) => cell.trim().replace(/\\\|/g, "|"));
|
|
42611
43751
|
}
|
|
42612
|
-
function
|
|
43752
|
+
function renderInline2(text, theme) {
|
|
42613
43753
|
let out = "";
|
|
42614
43754
|
let i = 0;
|
|
42615
43755
|
while (i < text.length) {
|
|
@@ -42630,7 +43770,7 @@ function renderInline(text, theme) {
|
|
|
42630
43770
|
}
|
|
42631
43771
|
const emphasis = matchDelimited(text, i, ["**", "__", "~~", "*", "_"]);
|
|
42632
43772
|
if (emphasis) {
|
|
42633
|
-
const inner =
|
|
43773
|
+
const inner = renderInline2(emphasis.inner, theme);
|
|
42634
43774
|
if (emphasis.delim === "**" || emphasis.delim === "__") out += theme.bold(inner);
|
|
42635
43775
|
else if (emphasis.delim === "~~") out += `\x1B[9m${inner}\x1B[29m`;
|
|
42636
43776
|
else out += theme.italic(inner);
|
|
@@ -42640,7 +43780,7 @@ function renderInline(text, theme) {
|
|
|
42640
43780
|
if (ch2 === "[") {
|
|
42641
43781
|
const link = /^\[([^\]]*)\]\(([^)\s]*)(?:\s+"[^"]*")?\)/.exec(text.slice(i));
|
|
42642
43782
|
if (link) {
|
|
42643
|
-
const label2 =
|
|
43783
|
+
const label2 = renderInline2(link[1], theme);
|
|
42644
43784
|
const url = link[2];
|
|
42645
43785
|
out += link[1] === url || url === "" ? theme.fg("link", theme.underline(label2 || url)) : theme.fg("link", theme.underline(label2)) + theme.fg("dim", ` (${url})`);
|
|
42646
43786
|
i += link[0].length;
|
|
@@ -42685,31 +43825,31 @@ function matchDelimited(text, i, delims) {
|
|
|
42685
43825
|
}
|
|
42686
43826
|
return null;
|
|
42687
43827
|
}
|
|
42688
|
-
function
|
|
43828
|
+
function renderBlock2(block, width2, theme) {
|
|
42689
43829
|
switch (block.kind) {
|
|
42690
43830
|
case "heading": {
|
|
42691
|
-
const text =
|
|
43831
|
+
const text = renderInline2(block.text, theme);
|
|
42692
43832
|
const styled = block.level <= 2 ? theme.fg("accent", theme.bold(text)) : theme.fg("text", theme.bold(text));
|
|
42693
43833
|
return wrapTextWithAnsi(styled, width2);
|
|
42694
43834
|
}
|
|
42695
43835
|
case "paragraph":
|
|
42696
|
-
return wrapTextWithAnsi(
|
|
43836
|
+
return wrapTextWithAnsi(renderInline2(block.text, theme), width2);
|
|
42697
43837
|
case "hr":
|
|
42698
43838
|
return [theme.fg("border", theme.glyphs.rule.repeat(Math.max(1, width2)))];
|
|
42699
43839
|
case "quote": {
|
|
42700
43840
|
const bar = theme.fg("border", theme.glyphs.card) + " ";
|
|
42701
|
-
const body = theme.fg("muted", theme.italic(
|
|
43841
|
+
const body = theme.fg("muted", theme.italic(renderInline2(block.text, theme)));
|
|
42702
43842
|
return wrapTextWithAnsi(body, Math.max(1, width2 - 2)).map((line2) => bar + line2);
|
|
42703
43843
|
}
|
|
42704
43844
|
case "list":
|
|
42705
|
-
return
|
|
43845
|
+
return renderList2(block.items, width2, theme);
|
|
42706
43846
|
case "code":
|
|
42707
43847
|
return renderCode(block.lang, block.lines, width2, theme);
|
|
42708
43848
|
case "table":
|
|
42709
|
-
return
|
|
43849
|
+
return renderTable2(block.rows, width2, theme);
|
|
42710
43850
|
}
|
|
42711
43851
|
}
|
|
42712
|
-
function
|
|
43852
|
+
function renderList2(items, width2, theme) {
|
|
42713
43853
|
const lines2 = [];
|
|
42714
43854
|
const bullets = theme.glyphs.bullets;
|
|
42715
43855
|
const columns = [];
|
|
@@ -42726,7 +43866,7 @@ function renderList(items, width2, theme) {
|
|
|
42726
43866
|
unordered.length = depth;
|
|
42727
43867
|
columns.push(headWidth);
|
|
42728
43868
|
unordered.push(level);
|
|
42729
|
-
const body = wrapTextWithAnsi(
|
|
43869
|
+
const body = wrapTextWithAnsi(renderInline2(item.text, theme), Math.max(1, width2 - headWidth));
|
|
42730
43870
|
body.forEach((line2, index2) => {
|
|
42731
43871
|
lines2.push((index2 === 0 ? head : " ".repeat(headWidth)) + line2);
|
|
42732
43872
|
});
|
|
@@ -42770,10 +43910,10 @@ function wrapCode(line2, width2) {
|
|
|
42770
43910
|
out.push(current3);
|
|
42771
43911
|
return out;
|
|
42772
43912
|
}
|
|
42773
|
-
function
|
|
43913
|
+
function renderTable2(rows, width2, theme) {
|
|
42774
43914
|
const cols = Math.max(0, ...rows.map((r) => r.length));
|
|
42775
43915
|
const widths = new Array(cols).fill(0);
|
|
42776
|
-
const rendered = rows.map((row3) => row3.map((cell) =>
|
|
43916
|
+
const rendered = rows.map((row3) => row3.map((cell) => renderInline2(cell, theme)));
|
|
42777
43917
|
for (const row3 of rendered) {
|
|
42778
43918
|
row3.forEach((cell, c) => widths[c] = Math.max(widths[c], visibleWidth(cell)));
|
|
42779
43919
|
}
|
|
@@ -42887,7 +44027,7 @@ var init_markdown = __esm({
|
|
|
42887
44027
|
used.add(key);
|
|
42888
44028
|
let rendered = this.blockCache.get(key);
|
|
42889
44029
|
if (!rendered) {
|
|
42890
|
-
rendered =
|
|
44030
|
+
rendered = renderBlock2(block, inner, this.theme).map((line2) => pad3 + line2);
|
|
42891
44031
|
this.blockCache.set(key, rendered);
|
|
42892
44032
|
}
|
|
42893
44033
|
if (index2 > 0) lines2.push("");
|
|
@@ -43175,7 +44315,7 @@ var init_editor_buffer = __esm({
|
|
|
43175
44315
|
function loadHistoryFile(path, limit = 500) {
|
|
43176
44316
|
let text;
|
|
43177
44317
|
try {
|
|
43178
|
-
text = (0,
|
|
44318
|
+
text = (0, import_node_fs51.readFileSync)(path, "utf8");
|
|
43179
44319
|
} catch {
|
|
43180
44320
|
return [];
|
|
43181
44321
|
}
|
|
@@ -43192,11 +44332,11 @@ function loadHistoryFile(path, limit = 500) {
|
|
|
43192
44332
|
}
|
|
43193
44333
|
function appendHistoryFile(path, entry, limit) {
|
|
43194
44334
|
try {
|
|
43195
|
-
(0,
|
|
43196
|
-
(0,
|
|
44335
|
+
(0, import_node_fs51.mkdirSync)((0, import_node_path71.dirname)(path), { recursive: true });
|
|
44336
|
+
(0, import_node_fs51.appendFileSync)(path, JSON.stringify(entry) + "\n", { mode: 384 });
|
|
43197
44337
|
const all = loadHistoryFile(path, Number.MAX_SAFE_INTEGER);
|
|
43198
44338
|
if (all.length > limit * 2) {
|
|
43199
|
-
(0,
|
|
44339
|
+
(0, import_node_fs51.writeFileSync)(
|
|
43200
44340
|
path,
|
|
43201
44341
|
all.slice(-limit).map((e) => JSON.stringify(e) + "\n").join("")
|
|
43202
44342
|
);
|
|
@@ -43204,11 +44344,11 @@ function appendHistoryFile(path, entry, limit) {
|
|
|
43204
44344
|
} catch {
|
|
43205
44345
|
}
|
|
43206
44346
|
}
|
|
43207
|
-
var
|
|
44347
|
+
var import_node_fs51, import_node_path71;
|
|
43208
44348
|
var init_editor_history = __esm({
|
|
43209
44349
|
"src/tui/components/editor-history.ts"() {
|
|
43210
44350
|
"use strict";
|
|
43211
|
-
|
|
44351
|
+
import_node_fs51 = require("node:fs");
|
|
43212
44352
|
import_node_path71 = require("node:path");
|
|
43213
44353
|
}
|
|
43214
44354
|
});
|
|
@@ -43347,11 +44487,11 @@ var init_select_list = __esm({
|
|
|
43347
44487
|
this.setSelectedIndex(index2);
|
|
43348
44488
|
return true;
|
|
43349
44489
|
}
|
|
43350
|
-
moveSelection(delta,
|
|
44490
|
+
moveSelection(delta, wrap3 = true) {
|
|
43351
44491
|
const n = this.filtered.length;
|
|
43352
44492
|
if (n === 0) return;
|
|
43353
44493
|
let next = this.selected + delta;
|
|
43354
|
-
if (
|
|
44494
|
+
if (wrap3 && Math.abs(delta) === 1) next = (next + n) % n;
|
|
43355
44495
|
this.setSelectedIndex(next);
|
|
43356
44496
|
}
|
|
43357
44497
|
handleInput(data2) {
|
|
@@ -44244,14 +45384,14 @@ var init_key_value = __esm({
|
|
|
44244
45384
|
const keyWidth = Math.min(longest, Math.max(share, MIN_KEY_WIDTH));
|
|
44245
45385
|
const valueWidth = width2 - keyWidth - gap;
|
|
44246
45386
|
const { theme, keyColor = "dim" } = this.options;
|
|
44247
|
-
const
|
|
45387
|
+
const wrap3 = this.options.wrap === true;
|
|
44248
45388
|
const lines2 = this.rows.flatMap(({ key, value }) => {
|
|
44249
45389
|
if (key === "" && value === "") return [""];
|
|
44250
45390
|
const shownKey = truncateToWidth(key, Math.max(keyWidth, 1));
|
|
44251
45391
|
const styledKey = theme ? theme.fg(keyColor, shownKey) : shownKey;
|
|
44252
45392
|
if (valueWidth < 1) return [truncateToWidth(styledKey, width2)];
|
|
44253
45393
|
const head = padToWidth(styledKey, keyWidth) + " ".repeat(gap);
|
|
44254
|
-
if (!
|
|
45394
|
+
if (!wrap3) {
|
|
44255
45395
|
const flat2 = value.replace(/\r?\n/g, " ⏎ ");
|
|
44256
45396
|
return [head + truncateToWidth(flat2, valueWidth)];
|
|
44257
45397
|
}
|
|
@@ -44648,22 +45788,22 @@ function toolDeclaration(tool, options = {}) {
|
|
|
44648
45788
|
}
|
|
44649
45789
|
function buildDeclarationBlock(tools, inlineBudget = DEFAULT_INLINE_BUDGET) {
|
|
44650
45790
|
const sorted = [...tools].sort((a, b) => a.tool.name < b.tool.name ? -1 : 1);
|
|
44651
|
-
const
|
|
45791
|
+
const inline2 = [];
|
|
44652
45792
|
const namesOnly = [];
|
|
44653
45793
|
let used = 0;
|
|
44654
45794
|
for (const { tool, textResult } of sorted) {
|
|
44655
45795
|
const decl = toolDeclaration(tool, textResult === false ? { textResult } : {});
|
|
44656
45796
|
const cost2 = estimateTokens2(decl);
|
|
44657
45797
|
if (namesOnly.length === 0 && used + cost2 <= inlineBudget) {
|
|
44658
|
-
|
|
45798
|
+
inline2.push(decl);
|
|
44659
45799
|
used += cost2;
|
|
44660
45800
|
} else namesOnly.push(tool.name);
|
|
44661
45801
|
}
|
|
44662
45802
|
const parts = [];
|
|
44663
45803
|
if (sorted.some(({ tool }) => tool.name === "bash")) parts.push(BASH_RESULT_DECLARATION);
|
|
44664
|
-
if (
|
|
45804
|
+
if (inline2.length > 0) {
|
|
44665
45805
|
parts.push(`declare const tools: {
|
|
44666
|
-
${indent(
|
|
45806
|
+
${indent(inline2.join("\n"))}
|
|
44667
45807
|
};`);
|
|
44668
45808
|
}
|
|
44669
45809
|
if (namesOnly.length > 0) {
|
|
@@ -44671,7 +45811,7 @@ ${indent(inline.join("\n"))}
|
|
|
44671
45811
|
`// Also callable (use describeTool(name) for the signature): ${namesOnly.join(", ")}`
|
|
44672
45812
|
);
|
|
44673
45813
|
}
|
|
44674
|
-
return { inline, namesOnly, text: parts.join("\n") };
|
|
45814
|
+
return { inline: inline2, namesOnly, text: parts.join("\n") };
|
|
44675
45815
|
}
|
|
44676
45816
|
function indent(text) {
|
|
44677
45817
|
return text.split("\n").map((line2) => line2 === "" ? line2 : ` ${line2}`).join("\n");
|
|
@@ -44791,7 +45931,7 @@ function modelsDevUrl(env = process.env) {
|
|
|
44791
45931
|
}
|
|
44792
45932
|
function readModelsDevCache(dataDir) {
|
|
44793
45933
|
try {
|
|
44794
|
-
const value = JSON.parse((0,
|
|
45934
|
+
const value = JSON.parse((0, import_node_fs52.readFileSync)(modelsDevCachePath(dataDir), "utf8"));
|
|
44795
45935
|
if (typeof value !== "object" || value === null) return void 0;
|
|
44796
45936
|
const file = value;
|
|
44797
45937
|
if (file.version !== 2 || typeof file.fetchedAt !== "string") return void 0;
|
|
@@ -44804,10 +45944,10 @@ function readModelsDevCache(dataDir) {
|
|
|
44804
45944
|
}
|
|
44805
45945
|
function writeModelsDevCache(dataDir, file) {
|
|
44806
45946
|
const path = modelsDevCachePath(dataDir);
|
|
44807
|
-
(0,
|
|
45947
|
+
(0, import_node_fs52.mkdirSync)((0, import_node_path73.dirname)(path), { recursive: true, mode: 448 });
|
|
44808
45948
|
const tmp = `${path}.${process.pid}.tmp`;
|
|
44809
|
-
(0,
|
|
44810
|
-
(0,
|
|
45949
|
+
(0, import_node_fs52.writeFileSync)(tmp, JSON.stringify(file));
|
|
45950
|
+
(0, import_node_fs52.renameSync)(tmp, path);
|
|
44811
45951
|
memo = void 0;
|
|
44812
45952
|
}
|
|
44813
45953
|
function overrideApplies(file) {
|
|
@@ -44817,7 +45957,7 @@ function loadModelsDevIndex(dataDir) {
|
|
|
44817
45957
|
const path = modelsDevCachePath(dataDir);
|
|
44818
45958
|
let key;
|
|
44819
45959
|
try {
|
|
44820
|
-
const stat16 = (0,
|
|
45960
|
+
const stat16 = (0, import_node_fs52.statSync)(path);
|
|
44821
45961
|
key = `${path}\0${stat16.mtimeMs}\0${stat16.size}`;
|
|
44822
45962
|
} catch {
|
|
44823
45963
|
return builtinSnapshotIndex();
|
|
@@ -44839,7 +45979,7 @@ async function refreshModelsDev(options) {
|
|
|
44839
45979
|
const url = modelsDevUrl(options.env);
|
|
44840
45980
|
const now = options.now ?? Date.now;
|
|
44841
45981
|
const before2 = loadModelsDevIndex(options.dataDir);
|
|
44842
|
-
const
|
|
45982
|
+
const fail7 = (reason) => ({
|
|
44843
45983
|
status: "failed",
|
|
44844
45984
|
url,
|
|
44845
45985
|
index: before2,
|
|
@@ -44848,7 +45988,7 @@ async function refreshModelsDev(options) {
|
|
|
44848
45988
|
const list5 = snapshotList();
|
|
44849
45989
|
const unknown = (options.providers ?? []).filter((p) => !list5.providers.includes(p));
|
|
44850
45990
|
if (unknown.length > 0)
|
|
44851
|
-
return
|
|
45991
|
+
return fail7(msg().errors.models.notListed(unknown.join(", "), list5.providers.join(", ")));
|
|
44852
45992
|
let fresh;
|
|
44853
45993
|
try {
|
|
44854
45994
|
const response = await (options.fetch ?? fetch)(url, {
|
|
@@ -44858,7 +45998,7 @@ async function refreshModelsDev(options) {
|
|
|
44858
45998
|
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
|
44859
45999
|
fresh = buildSnapshot(await response.json(), list5, options.providers);
|
|
44860
46000
|
} catch (error2) {
|
|
44861
|
-
return
|
|
46001
|
+
return fail7(error2 instanceof Error ? error2.message : String(error2));
|
|
44862
46002
|
}
|
|
44863
46003
|
const fetchedAt = new Date(now()).toISOString();
|
|
44864
46004
|
const previous = readModelsDevCache(options.dataDir);
|
|
@@ -44902,11 +46042,11 @@ function describeRefresh(result, limit = 20) {
|
|
|
44902
46042
|
}
|
|
44903
46043
|
return lines2.join("\n");
|
|
44904
46044
|
}
|
|
44905
|
-
var
|
|
46045
|
+
var import_node_fs52, import_node_path73, MODELS_DEV_URL, MODELS_DEV_URL_ENV, MODELS_DEV_FILE, MODELS_DEV_TIMEOUT_MS, memo;
|
|
44906
46046
|
var init_models_dev_cache = __esm({
|
|
44907
46047
|
"src/ai/providers/models-dev-cache.ts"() {
|
|
44908
46048
|
"use strict";
|
|
44909
|
-
|
|
46049
|
+
import_node_fs52 = require("node:fs");
|
|
44910
46050
|
import_node_path73 = require("node:path");
|
|
44911
46051
|
init_models_dev();
|
|
44912
46052
|
init_models_dev_snapshot();
|
|
@@ -45252,40 +46392,40 @@ function minimalConfig() {
|
|
|
45252
46392
|
}
|
|
45253
46393
|
function writeAtomic2(path, text, mode) {
|
|
45254
46394
|
const tmp = `${path}.${process.pid}.tmp`;
|
|
45255
|
-
(0,
|
|
45256
|
-
(0,
|
|
46395
|
+
(0, import_node_fs53.writeFileSync)(tmp, text, { mode });
|
|
46396
|
+
(0, import_node_fs53.renameSync)(tmp, path);
|
|
45257
46397
|
}
|
|
45258
46398
|
function initConfigDir(dir, options = {}) {
|
|
45259
|
-
const dirCreated = !(0,
|
|
45260
|
-
(0,
|
|
45261
|
-
if (dirCreated && process.platform !== "win32") (0,
|
|
46399
|
+
const dirCreated = !(0, import_node_fs53.existsSync)(dir);
|
|
46400
|
+
(0, import_node_fs53.mkdirSync)(dir, { recursive: true, mode: 448 });
|
|
46401
|
+
if (dirCreated && process.platform !== "win32") (0, import_node_fs53.chmodSync)(dir, 448);
|
|
45262
46402
|
const files = [];
|
|
45263
46403
|
const config = (0, import_node_path74.join)(dir, CONFIG_FILE);
|
|
45264
46404
|
const text = `${JSON.stringify(minimalConfig(), null, 2)}
|
|
45265
46405
|
`;
|
|
45266
|
-
if (!(0,
|
|
46406
|
+
if (!(0, import_node_fs53.existsSync)(config)) {
|
|
45267
46407
|
writeAtomic2(config, text, 420);
|
|
45268
46408
|
files.push({ path: config, status: "created" });
|
|
45269
46409
|
} else if (options.force) {
|
|
45270
|
-
(0,
|
|
46410
|
+
(0, import_node_fs53.copyFileSync)(config, `${config}.bak`);
|
|
45271
46411
|
writeAtomic2(config, text, 420);
|
|
45272
46412
|
files.push({ path: config, status: "overwritten" });
|
|
45273
46413
|
} else files.push({ path: config, status: "exists" });
|
|
45274
46414
|
const schema = (0, import_node_path74.join)(dir, CONFIG_SCHEMA_FILE);
|
|
45275
46415
|
const schemaText = configSchemaText();
|
|
45276
|
-
if (!(0,
|
|
46416
|
+
if (!(0, import_node_fs53.existsSync)(schema)) {
|
|
45277
46417
|
writeAtomic2(schema, schemaText, 420);
|
|
45278
46418
|
files.push({ path: schema, status: "created" });
|
|
45279
|
-
} else if ((0,
|
|
46419
|
+
} else if ((0, import_node_fs53.readFileSync)(schema, "utf8") !== schemaText) {
|
|
45280
46420
|
writeAtomic2(schema, schemaText, 420);
|
|
45281
46421
|
files.push({ path: schema, status: "updated" });
|
|
45282
46422
|
} else files.push({ path: schema, status: "unchanged" });
|
|
45283
46423
|
const auth = (0, import_node_path74.join)(dir, AUTH_FILE);
|
|
45284
|
-
if ((0,
|
|
46424
|
+
if ((0, import_node_fs53.existsSync)(auth)) files.push({ path: auth, status: "exists" });
|
|
45285
46425
|
return { dir, dirCreated, files };
|
|
45286
46426
|
}
|
|
45287
46427
|
function autoInitConfigDir(dir, env) {
|
|
45288
|
-
if (env[NO_INIT_ENV] === "1" || (0,
|
|
46428
|
+
if (env[NO_INIT_ENV] === "1" || (0, import_node_fs53.existsSync)(dir)) return false;
|
|
45289
46429
|
try {
|
|
45290
46430
|
initConfigDir(dir);
|
|
45291
46431
|
return true;
|
|
@@ -45303,11 +46443,11 @@ function describeInit(result) {
|
|
|
45303
46443
|
return `${lines2.join("\n")}
|
|
45304
46444
|
`;
|
|
45305
46445
|
}
|
|
45306
|
-
var
|
|
46446
|
+
var import_node_fs53, import_node_path74, NO_INIT_ENV;
|
|
45307
46447
|
var init_init = __esm({
|
|
45308
46448
|
"src/config/init.ts"() {
|
|
45309
46449
|
"use strict";
|
|
45310
|
-
|
|
46450
|
+
import_node_fs53 = require("node:fs");
|
|
45311
46451
|
import_node_path74 = require("node:path");
|
|
45312
46452
|
init_i18n();
|
|
45313
46453
|
init_json_schema();
|
|
@@ -45551,13 +46691,13 @@ function normalizeToolId(id) {
|
|
|
45551
46691
|
return cleaned.length > 0 ? cleaned : "tool_call";
|
|
45552
46692
|
}
|
|
45553
46693
|
function convertBlocks(content) {
|
|
45554
|
-
const
|
|
46694
|
+
const blocks2 = [];
|
|
45555
46695
|
for (const block of content) {
|
|
45556
46696
|
if (block.type === "text") {
|
|
45557
46697
|
if (block.text.trim().length > 0)
|
|
45558
|
-
|
|
46698
|
+
blocks2.push({ type: "text", text: sanitizeText(block.text) });
|
|
45559
46699
|
} else {
|
|
45560
|
-
|
|
46700
|
+
blocks2.push({
|
|
45561
46701
|
type: "image",
|
|
45562
46702
|
source: {
|
|
45563
46703
|
type: "base64",
|
|
@@ -45567,33 +46707,33 @@ function convertBlocks(content) {
|
|
|
45567
46707
|
});
|
|
45568
46708
|
}
|
|
45569
46709
|
}
|
|
45570
|
-
return
|
|
46710
|
+
return blocks2;
|
|
45571
46711
|
}
|
|
45572
46712
|
function convertUser(message) {
|
|
45573
46713
|
if (typeof message.content === "string") {
|
|
45574
46714
|
if (message.content.trim().length === 0) return void 0;
|
|
45575
46715
|
return { role: "user", content: sanitizeText(message.content) };
|
|
45576
46716
|
}
|
|
45577
|
-
const
|
|
45578
|
-
return
|
|
46717
|
+
const blocks2 = convertBlocks(message.content);
|
|
46718
|
+
return blocks2.length > 0 ? { role: "user", content: blocks2 } : void 0;
|
|
45579
46719
|
}
|
|
45580
46720
|
function convertAssistant(message) {
|
|
45581
|
-
const
|
|
46721
|
+
const blocks2 = [];
|
|
45582
46722
|
for (const block of message.content) {
|
|
45583
46723
|
if (block.type === "text") {
|
|
45584
46724
|
if (block.text.trim().length > 0)
|
|
45585
|
-
|
|
46725
|
+
blocks2.push({ type: "text", text: sanitizeText(block.text) });
|
|
45586
46726
|
} else if (block.type === "thinking") {
|
|
45587
46727
|
const signature2 = block.thinkingSignature ?? "";
|
|
45588
46728
|
if (block.redacted && signature2) {
|
|
45589
|
-
|
|
46729
|
+
blocks2.push({ type: "redacted_thinking", data: signature2 });
|
|
45590
46730
|
} else if (signature2.trim().length > 0) {
|
|
45591
|
-
|
|
46731
|
+
blocks2.push({ type: "thinking", thinking: sanitizeText(block.thinking), signature: signature2 });
|
|
45592
46732
|
} else if (block.thinking.trim().length > 0) {
|
|
45593
|
-
|
|
46733
|
+
blocks2.push({ type: "text", text: sanitizeText(block.thinking) });
|
|
45594
46734
|
}
|
|
45595
46735
|
} else {
|
|
45596
|
-
|
|
46736
|
+
blocks2.push({
|
|
45597
46737
|
type: "tool_use",
|
|
45598
46738
|
id: normalizeToolId(block.id),
|
|
45599
46739
|
name: block.name,
|
|
@@ -45601,7 +46741,7 @@ function convertAssistant(message) {
|
|
|
45601
46741
|
});
|
|
45602
46742
|
}
|
|
45603
46743
|
}
|
|
45604
|
-
return
|
|
46744
|
+
return blocks2.length > 0 ? { role: "assistant", content: blocks2 } : void 0;
|
|
45605
46745
|
}
|
|
45606
46746
|
function convertToolResult(message) {
|
|
45607
46747
|
const content = typeof message.content === "string" || !message.content.some((b) => b.type === "image") ? sanitizeText(contentText2(message.content)) : convertBlocks(message.content);
|
|
@@ -46464,8 +47604,8 @@ function convertToolResults(model, results, compat) {
|
|
|
46464
47604
|
const images = [];
|
|
46465
47605
|
for (const result of results) {
|
|
46466
47606
|
const text = contentText2(result.content);
|
|
46467
|
-
const
|
|
46468
|
-
const hasImages2 =
|
|
47607
|
+
const blocks2 = typeof result.content === "string" ? [] : result.content;
|
|
47608
|
+
const hasImages2 = blocks2.some((b) => b.type === "image");
|
|
46469
47609
|
const message = {
|
|
46470
47610
|
role: "tool",
|
|
46471
47611
|
tool_call_id: normalizeCallId(model, result.toolCallId),
|
|
@@ -46476,7 +47616,7 @@ function convertToolResults(model, results, compat) {
|
|
|
46476
47616
|
if (compat.requiresToolResultName) message["name"] = result.toolName;
|
|
46477
47617
|
messages.push(message);
|
|
46478
47618
|
if (hasImages2 && model.input.includes("image")) {
|
|
46479
|
-
for (const block of
|
|
47619
|
+
for (const block of blocks2) if (block.type === "image") images.push(imagePart(block));
|
|
46480
47620
|
}
|
|
46481
47621
|
}
|
|
46482
47622
|
return { messages, images };
|
|
@@ -46726,9 +47866,9 @@ function imagePart2(block) {
|
|
|
46726
47866
|
};
|
|
46727
47867
|
}
|
|
46728
47868
|
function convertUser4(message) {
|
|
46729
|
-
const
|
|
47869
|
+
const blocks2 = typeof message.content === "string" ? [{ type: "text", text: message.content }] : message.content;
|
|
46730
47870
|
const content = [];
|
|
46731
|
-
for (const block of
|
|
47871
|
+
for (const block of blocks2) {
|
|
46732
47872
|
if (block.type === "image") content.push(imagePart2(block));
|
|
46733
47873
|
else if (block.text.length > 0) {
|
|
46734
47874
|
content.push({ type: "input_text", text: sanitizeText(block.text) });
|
|
@@ -47982,12 +49122,12 @@ function handleChunk2(chunk, state, tracker) {
|
|
|
47982
49122
|
}
|
|
47983
49123
|
const usage = obj6(chunk["usageMetadata"]);
|
|
47984
49124
|
if (usage) output.usage = parseGoogleUsage(usage);
|
|
47985
|
-
const
|
|
49125
|
+
const blocked3 = str7(obj6(chunk["promptFeedback"])?.["blockReason"]);
|
|
47986
49126
|
const candidates2 = Array.isArray(chunk["candidates"]) ? chunk["candidates"] : [];
|
|
47987
49127
|
const candidate = obj6(candidates2[0]);
|
|
47988
|
-
if (!candidate &&
|
|
47989
|
-
output.rawStopReason =
|
|
47990
|
-
throw new ProviderStopError(`Prompt blocked: ${
|
|
49128
|
+
if (!candidate && blocked3) {
|
|
49129
|
+
output.rawStopReason = blocked3;
|
|
49130
|
+
throw new ProviderStopError(`Prompt blocked: ${blocked3}`);
|
|
47991
49131
|
}
|
|
47992
49132
|
const parts = obj6(candidate?.["content"])?.["parts"];
|
|
47993
49133
|
if (Array.isArray(parts)) {
|
|
@@ -48198,7 +49338,7 @@ function defaultConfigDir(env = process.env) {
|
|
|
48198
49338
|
function readAuthFile2(path, onWarning) {
|
|
48199
49339
|
let raw;
|
|
48200
49340
|
try {
|
|
48201
|
-
raw = (0,
|
|
49341
|
+
raw = (0, import_node_fs54.readFileSync)(path, "utf8");
|
|
48202
49342
|
} catch (error2) {
|
|
48203
49343
|
const code = error2.code;
|
|
48204
49344
|
if (code !== "ENOENT") onWarning?.(`cannot read auth file ${path}`);
|
|
@@ -48206,7 +49346,7 @@ function readAuthFile2(path, onWarning) {
|
|
|
48206
49346
|
}
|
|
48207
49347
|
if (process.platform !== "win32") {
|
|
48208
49348
|
try {
|
|
48209
|
-
const mode = (0,
|
|
49349
|
+
const mode = (0, import_node_fs54.statSync)(path).mode & 511;
|
|
48210
49350
|
if ((mode & 63) !== 0) {
|
|
48211
49351
|
onWarning?.(
|
|
48212
49352
|
`auth file ${path} has permissions ${mode.toString(8).padStart(4, "0")}; expected 0600`
|
|
@@ -48240,12 +49380,12 @@ function expandEnvRefs(value, env) {
|
|
|
48240
49380
|
);
|
|
48241
49381
|
return missing || out.length === 0 ? void 0 : out;
|
|
48242
49382
|
}
|
|
48243
|
-
var import_node_child_process13,
|
|
49383
|
+
var import_node_child_process13, import_node_fs54, import_node_os12, import_node_path75, ApiKeyResolver;
|
|
48244
49384
|
var init_auth2 = __esm({
|
|
48245
49385
|
"src/ai/providers/auth.ts"() {
|
|
48246
49386
|
"use strict";
|
|
48247
49387
|
import_node_child_process13 = require("node:child_process");
|
|
48248
|
-
|
|
49388
|
+
import_node_fs54 = require("node:fs");
|
|
48249
49389
|
import_node_os12 = require("node:os");
|
|
48250
49390
|
import_node_path75 = require("node:path");
|
|
48251
49391
|
init_live();
|
|
@@ -49033,25 +50173,25 @@ var init_settings_registry = __esm({
|
|
|
49033
50173
|
|
|
49034
50174
|
// src/config/write.ts
|
|
49035
50175
|
function writeConfigFile(path, config, options = {}) {
|
|
49036
|
-
(0,
|
|
50176
|
+
(0, import_node_fs55.mkdirSync)((0, import_node_path77.dirname)(path), { recursive: true });
|
|
49037
50177
|
let mode;
|
|
49038
50178
|
try {
|
|
49039
|
-
mode = (0,
|
|
50179
|
+
mode = (0, import_node_fs55.statSync)(path).mode & 511;
|
|
49040
50180
|
} catch {
|
|
49041
50181
|
mode = void 0;
|
|
49042
50182
|
}
|
|
49043
|
-
if (mode !== void 0 && options.backup !== false) (0,
|
|
50183
|
+
if (mode !== void 0 && options.backup !== false) (0, import_node_fs55.copyFileSync)(path, `${path}.bak`);
|
|
49044
50184
|
const tmp = `${path}.${process.pid}.tmp`;
|
|
49045
|
-
(0,
|
|
50185
|
+
(0, import_node_fs55.writeFileSync)(tmp, `${JSON.stringify(config, null, 2)}
|
|
49046
50186
|
`, { mode: mode ?? 420 });
|
|
49047
|
-
if (mode !== void 0) (0,
|
|
49048
|
-
(0,
|
|
50187
|
+
if (mode !== void 0) (0, import_node_fs55.chmodSync)(tmp, mode);
|
|
50188
|
+
(0, import_node_fs55.renameSync)(tmp, path);
|
|
49049
50189
|
}
|
|
49050
|
-
var
|
|
50190
|
+
var import_node_fs55, import_node_path77;
|
|
49051
50191
|
var init_write2 = __esm({
|
|
49052
50192
|
"src/config/write.ts"() {
|
|
49053
50193
|
"use strict";
|
|
49054
|
-
|
|
50194
|
+
import_node_fs55 = require("node:fs");
|
|
49055
50195
|
import_node_path77 = require("node:path");
|
|
49056
50196
|
}
|
|
49057
50197
|
});
|
|
@@ -49250,7 +50390,7 @@ function parseEnum(key, text, options) {
|
|
|
49250
50390
|
function readTarget(path, scope) {
|
|
49251
50391
|
let text;
|
|
49252
50392
|
try {
|
|
49253
|
-
text = (0,
|
|
50393
|
+
text = (0, import_node_fs56.readFileSync)(path, "utf8");
|
|
49254
50394
|
} catch (error2) {
|
|
49255
50395
|
if (error2.code === "ENOENT")
|
|
49256
50396
|
return scope === "user" ? minimalConfig() : { version: CONFIG_FILE_VERSION };
|
|
@@ -49332,11 +50472,11 @@ function formatSettingValue(value) {
|
|
|
49332
50472
|
if (typeof value === "string") return value;
|
|
49333
50473
|
return JSON.stringify(value);
|
|
49334
50474
|
}
|
|
49335
|
-
var
|
|
50475
|
+
var import_node_fs56, ConfigEditError, same, ABOVE, TRUE, FALSE, UNSET;
|
|
49336
50476
|
var init_edit2 = __esm({
|
|
49337
50477
|
"src/config/edit.ts"() {
|
|
49338
50478
|
"use strict";
|
|
49339
|
-
|
|
50479
|
+
import_node_fs56 = require("node:fs");
|
|
49340
50480
|
init_errors();
|
|
49341
50481
|
init_i18n();
|
|
49342
50482
|
init_init();
|
|
@@ -49416,7 +50556,7 @@ async function readClipboardImage(dataDir, deps = {}) {
|
|
|
49416
50556
|
await (0, import_promises22.mkdir)(dir, { recursive: true });
|
|
49417
50557
|
const stamp = new Date((deps.now ?? Date.now)()).toISOString().replace(/[:.]/g, "-");
|
|
49418
50558
|
let file = (0, import_node_path80.join)(dir, `${stamp}.png`);
|
|
49419
|
-
for (let n = 1; (0,
|
|
50559
|
+
for (let n = 1; (0, import_node_fs62.existsSync)(file); n++) file = (0, import_node_path80.join)(dir, `${stamp}-${n}.png`);
|
|
49420
50560
|
let anyTool = false;
|
|
49421
50561
|
for (const attempt of attempts(platform, file, env)) {
|
|
49422
50562
|
const options = attempt.via === "file" && attempt.env !== void 0 ? { env: attempt.env } : {};
|
|
@@ -49456,11 +50596,11 @@ async function gcClipboardImages(dataDir, options = {}) {
|
|
|
49456
50596
|
}
|
|
49457
50597
|
return removed;
|
|
49458
50598
|
}
|
|
49459
|
-
var
|
|
50599
|
+
var import_node_fs62, import_promises22, import_node_path80, CLIPBOARD_DIR, CLIPBOARD_MAX_AGE_DAYS, OSASCRIPT, POWERSHELL;
|
|
49460
50600
|
var init_clipboard_image = __esm({
|
|
49461
50601
|
"src/tools/clipboard-image.ts"() {
|
|
49462
50602
|
"use strict";
|
|
49463
|
-
|
|
50603
|
+
import_node_fs62 = require("node:fs");
|
|
49464
50604
|
import_promises22 = require("node:fs/promises");
|
|
49465
50605
|
import_node_path80 = require("node:path");
|
|
49466
50606
|
init_image_file();
|
|
@@ -51175,6 +52315,8 @@ function toolSummary(name, args, cwd) {
|
|
|
51175
52315
|
}
|
|
51176
52316
|
case "task":
|
|
51177
52317
|
return flat(str8("description") ?? str8("prompt") ?? "");
|
|
52318
|
+
case "web_fetch":
|
|
52319
|
+
return flat((str8("url") ?? "").replace(/^https?:\/\//i, ""));
|
|
51178
52320
|
default:
|
|
51179
52321
|
if (path !== void 0) return displayPath2(path, cwd);
|
|
51180
52322
|
for (const key of [
|
|
@@ -51302,10 +52444,28 @@ function resultSummary(input2, theme) {
|
|
|
51302
52444
|
] : [];
|
|
51303
52445
|
return muted([m.done, duration, ...tokens].join(" · "));
|
|
51304
52446
|
}
|
|
52447
|
+
case "web_fetch": {
|
|
52448
|
+
const finalUrl = details["finalUrl"];
|
|
52449
|
+
if (num9(details["bytes"]) === 0 && typeof finalUrl === "string" && lines2[0]?.startsWith("Redirected"))
|
|
52450
|
+
return muted(m.fetchRedirect(finalUrl));
|
|
52451
|
+
const title = typeof details["title"] === "string" ? flat(details["title"], 60) : void 0;
|
|
52452
|
+
const format = typeof details["format"] === "string" ? details["format"] : "";
|
|
52453
|
+
return muted(m.fetched(title, formatSize(num9(details["bytes"]) ?? 0), format));
|
|
52454
|
+
}
|
|
51305
52455
|
default:
|
|
51306
52456
|
return muted(count2 === 0 ? m.done : m.outputLines(count2));
|
|
51307
52457
|
}
|
|
51308
52458
|
}
|
|
52459
|
+
function fetchHost(toolName, input2) {
|
|
52460
|
+
if (toolName !== "web_fetch") return void 0;
|
|
52461
|
+
const raw = record(input2)["url"];
|
|
52462
|
+
if (typeof raw !== "string") return void 0;
|
|
52463
|
+
try {
|
|
52464
|
+
return new URL(raw.trim()).hostname.replace(/^\[|\]$/g, "").toLowerCase() || void 0;
|
|
52465
|
+
} catch {
|
|
52466
|
+
return void 0;
|
|
52467
|
+
}
|
|
52468
|
+
}
|
|
51309
52469
|
var import_node_path85;
|
|
51310
52470
|
var init_tool_summary = __esm({
|
|
51311
52471
|
"src/modes/interactive/tool-summary.ts"() {
|
|
@@ -51314,6 +52474,7 @@ var init_tool_summary = __esm({
|
|
|
51314
52474
|
import_node_path85 = require("node:path");
|
|
51315
52475
|
init_tui2();
|
|
51316
52476
|
init_status_bar();
|
|
52477
|
+
init_truncate();
|
|
51317
52478
|
}
|
|
51318
52479
|
});
|
|
51319
52480
|
|
|
@@ -52128,7 +53289,7 @@ function childLoader(read2 = readTraceInput) {
|
|
|
52128
53289
|
const load2 = ((file) => {
|
|
52129
53290
|
let stamp = "";
|
|
52130
53291
|
try {
|
|
52131
|
-
const st = (0,
|
|
53292
|
+
const st = (0, import_node_fs65.statSync)(file);
|
|
52132
53293
|
stamp = `${st.mtimeMs}:${st.size}`;
|
|
52133
53294
|
} catch {
|
|
52134
53295
|
stamp = "missing";
|
|
@@ -52172,11 +53333,11 @@ function traceText(session, taskId) {
|
|
|
52172
53333
|
`${msg().trace.taskTitle(node.taskId, node.agent)}${summary2}`
|
|
52173
53334
|
);
|
|
52174
53335
|
}
|
|
52175
|
-
var
|
|
53336
|
+
var import_node_fs65, LiveTracker, lineTraceCommand;
|
|
52176
53337
|
var init_session3 = __esm({
|
|
52177
53338
|
"src/trace/session.ts"() {
|
|
52178
53339
|
"use strict";
|
|
52179
|
-
|
|
53340
|
+
import_node_fs65 = require("node:fs");
|
|
52180
53341
|
init_session2();
|
|
52181
53342
|
init_i18n();
|
|
52182
53343
|
init_scan();
|
|
@@ -52359,7 +53520,7 @@ function ancestorDirs(cwd) {
|
|
|
52359
53520
|
let dir = (0, import_node_path89.resolve)(cwd);
|
|
52360
53521
|
for (; ; ) {
|
|
52361
53522
|
out.push(dir);
|
|
52362
|
-
if ((0,
|
|
53523
|
+
if ((0, import_node_fs67.existsSync)((0, import_node_path89.join)(dir, ".git"))) return out;
|
|
52363
53524
|
const parent = (0, import_node_path89.dirname)(dir);
|
|
52364
53525
|
if (parent === dir) return out;
|
|
52365
53526
|
dir = parent;
|
|
@@ -52421,7 +53582,7 @@ async function isDir3(path) {
|
|
|
52421
53582
|
async function findSkillFiles(dir, depth = 0) {
|
|
52422
53583
|
if (depth > MAX_DEPTH3) return [];
|
|
52423
53584
|
const own = (0, import_node_path89.join)(dir, SKILL_FILE);
|
|
52424
|
-
if ((0,
|
|
53585
|
+
if ((0, import_node_fs67.existsSync)(own)) return [own];
|
|
52425
53586
|
let names;
|
|
52426
53587
|
try {
|
|
52427
53588
|
names = await (0, import_promises24.readdir)(dir);
|
|
@@ -52473,11 +53634,11 @@ async function discoverSkills(sources, options) {
|
|
|
52473
53634
|
}
|
|
52474
53635
|
return result;
|
|
52475
53636
|
}
|
|
52476
|
-
var
|
|
53637
|
+
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
53638
|
var init_discover2 = __esm({
|
|
52478
53639
|
"src/skills/discover.ts"() {
|
|
52479
53640
|
"use strict";
|
|
52480
|
-
|
|
53641
|
+
import_node_fs67 = require("node:fs");
|
|
52481
53642
|
import_promises24 = require("node:fs/promises");
|
|
52482
53643
|
import_node_path89 = require("node:path");
|
|
52483
53644
|
init_frontmatter2();
|
|
@@ -52601,7 +53762,7 @@ function resolveSandboxEntry(moduleUrl = __ama_import_meta_url) {
|
|
|
52601
53762
|
candidates2.push((0, import_node_path90.join)(here, "sandbox-entry.js"));
|
|
52602
53763
|
candidates2.push((0, import_node_path90.join)(here, "sandbox-entry.ts"));
|
|
52603
53764
|
for (const candidate of candidates2) {
|
|
52604
|
-
if ((0,
|
|
53765
|
+
if ((0, import_node_fs68.existsSync)(candidate)) return (0, import_node_fs68.realpathSync)(candidate);
|
|
52605
53766
|
}
|
|
52606
53767
|
return void 0;
|
|
52607
53768
|
}
|
|
@@ -52833,12 +53994,12 @@ async function runSandbox(request) {
|
|
|
52833
53994
|
child.stdin.end();
|
|
52834
53995
|
return result;
|
|
52835
53996
|
}
|
|
52836
|
-
var import_node_child_process16,
|
|
53997
|
+
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
53998
|
var init_host_side = __esm({
|
|
52838
53999
|
"src/codemode/host-side.ts"() {
|
|
52839
54000
|
"use strict";
|
|
52840
54001
|
import_node_child_process16 = require("node:child_process");
|
|
52841
|
-
|
|
54002
|
+
import_node_fs68 = require("node:fs");
|
|
52842
54003
|
import_node_path90 = require("node:path");
|
|
52843
54004
|
import_node_url2 = require("node:url");
|
|
52844
54005
|
init_detect();
|
|
@@ -53004,9 +54165,9 @@ ${output.slice(-half)}`;
|
|
|
53004
54165
|
function saveFullOutput(ctx, text) {
|
|
53005
54166
|
try {
|
|
53006
54167
|
const dir = ctx.outputDir ?? (0, import_node_path91.join)((0, import_node_os14.tmpdir)(), "ama-codemode");
|
|
53007
|
-
(0,
|
|
54168
|
+
(0, import_node_fs69.mkdirSync)(dir, { recursive: true });
|
|
53008
54169
|
const file = (0, import_node_path91.join)(dir, `${ctx.toolCallId.replace(/[^A-Za-z0-9_-]/g, "_")}.txt`);
|
|
53009
|
-
(0,
|
|
54170
|
+
(0, import_node_fs69.writeFileSync)(file, text, "utf8");
|
|
53010
54171
|
return file;
|
|
53011
54172
|
} catch {
|
|
53012
54173
|
return void 0;
|
|
@@ -53158,11 +54319,11 @@ function codemodeToolFactory(overrides = {}) {
|
|
|
53158
54319
|
return createCodemodeTool(options);
|
|
53159
54320
|
};
|
|
53160
54321
|
}
|
|
53161
|
-
var
|
|
54322
|
+
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
54323
|
var init_tool = __esm({
|
|
53163
54324
|
"src/codemode/tool.ts"() {
|
|
53164
54325
|
"use strict";
|
|
53165
|
-
|
|
54326
|
+
import_node_fs69 = require("node:fs");
|
|
53166
54327
|
import_node_os14 = require("node:os");
|
|
53167
54328
|
import_node_path91 = require("node:path");
|
|
53168
54329
|
init_presets2();
|
|
@@ -53188,7 +54349,7 @@ var init_tool = __esm({
|
|
|
53188
54349
|
});
|
|
53189
54350
|
|
|
53190
54351
|
// src/memory/tool.ts
|
|
53191
|
-
function
|
|
54352
|
+
function fail6(input2, code, message) {
|
|
53192
54353
|
const details = { command: String(input2.command ?? ""), code };
|
|
53193
54354
|
if (typeof input2.path === "string") details.path = input2.path;
|
|
53194
54355
|
return { content: message, isError: true, details };
|
|
@@ -53220,11 +54381,11 @@ function createMemoryTool(runtime) {
|
|
|
53220
54381
|
const write2 = command3 !== "view";
|
|
53221
54382
|
if (ctx.depth > 0) {
|
|
53222
54383
|
if (runtime.subagents === "off")
|
|
53223
|
-
return
|
|
53224
|
-
if (write2) return
|
|
54384
|
+
return fail6(input2, "subagent", "subagents cannot access memory");
|
|
54385
|
+
if (write2) return fail6(input2, "subagent", "subagents cannot modify memory");
|
|
53225
54386
|
}
|
|
53226
54387
|
if (write2 && !runtime.writesEnabled)
|
|
53227
|
-
return
|
|
54388
|
+
return fail6(input2, "disabled", "memory writes are turned off for this session");
|
|
53228
54389
|
const store = runtime.store;
|
|
53229
54390
|
try {
|
|
53230
54391
|
switch (command3) {
|
|
@@ -53244,7 +54405,7 @@ function createMemoryTool(runtime) {
|
|
|
53244
54405
|
};
|
|
53245
54406
|
}
|
|
53246
54407
|
default:
|
|
53247
|
-
return
|
|
54408
|
+
return fail6(
|
|
53248
54409
|
input2,
|
|
53249
54410
|
"invalid_command",
|
|
53250
54411
|
'command must be "view", "create", "str_replace" or "delete"'
|
|
@@ -53252,7 +54413,7 @@ function createMemoryTool(runtime) {
|
|
|
53252
54413
|
}
|
|
53253
54414
|
} catch (error2) {
|
|
53254
54415
|
if (error2 instanceof MemoryError || error2 instanceof MemoryLockError)
|
|
53255
|
-
return
|
|
54416
|
+
return fail6(input2, error2.code, error2.message);
|
|
53256
54417
|
throw error2;
|
|
53257
54418
|
}
|
|
53258
54419
|
}
|
|
@@ -53276,7 +54437,7 @@ var init_tool2 = __esm({
|
|
|
53276
54437
|
// src/cli/codemode-notice.ts
|
|
53277
54438
|
function readNotices(path) {
|
|
53278
54439
|
try {
|
|
53279
|
-
const value = JSON.parse((0,
|
|
54440
|
+
const value = JSON.parse((0, import_node_fs70.readFileSync)(path, "utf8"));
|
|
53280
54441
|
if (typeof value === "object" && value !== null && !Array.isArray(value)) {
|
|
53281
54442
|
const shown2 = value[KEY];
|
|
53282
54443
|
return {
|
|
@@ -53300,20 +54461,20 @@ function takeCodemodeNotice(input2) {
|
|
|
53300
54461
|
const shown2 = notices[KEY] ?? [];
|
|
53301
54462
|
if (shown2.includes(input2.configDir)) return void 0;
|
|
53302
54463
|
try {
|
|
53303
|
-
(0,
|
|
54464
|
+
(0, import_node_fs70.mkdirSync)(input2.dataDir, { recursive: true });
|
|
53304
54465
|
const tmp = `${path}.${process.pid}.tmp`;
|
|
53305
|
-
(0,
|
|
54466
|
+
(0, import_node_fs70.writeFileSync)(tmp, `${JSON.stringify({ ...notices, [KEY]: [...shown2, input2.configDir] })}
|
|
53306
54467
|
`);
|
|
53307
|
-
(0,
|
|
54468
|
+
(0, import_node_fs70.renameSync)(tmp, path);
|
|
53308
54469
|
} catch {
|
|
53309
54470
|
}
|
|
53310
54471
|
return codemodeNoticeText(input2.capability);
|
|
53311
54472
|
}
|
|
53312
|
-
var
|
|
54473
|
+
var import_node_fs70, import_node_path92, NOTICES_FILE, KEY;
|
|
53313
54474
|
var init_codemode_notice = __esm({
|
|
53314
54475
|
"src/cli/codemode-notice.ts"() {
|
|
53315
54476
|
"use strict";
|
|
53316
|
-
|
|
54477
|
+
import_node_fs70 = require("node:fs");
|
|
53317
54478
|
import_node_path92 = require("node:path");
|
|
53318
54479
|
init_presets2();
|
|
53319
54480
|
init_i18n();
|
|
@@ -53330,7 +54491,7 @@ function readEntries(dataDir, now) {
|
|
|
53330
54491
|
const out = /* @__PURE__ */ new Map();
|
|
53331
54492
|
let parsed;
|
|
53332
54493
|
try {
|
|
53333
|
-
parsed = JSON.parse((0,
|
|
54494
|
+
parsed = JSON.parse((0, import_node_fs71.readFileSync)(maxTokensCachePath(dataDir), "utf8"));
|
|
53334
54495
|
} catch {
|
|
53335
54496
|
return out;
|
|
53336
54497
|
}
|
|
@@ -53364,11 +54525,11 @@ function recordMaxTokensCap(dataDir, key, cap, now = Date.now) {
|
|
|
53364
54525
|
const path = maxTokensCachePath(dataDir);
|
|
53365
54526
|
const tmp = `${path}.${process.pid}.tmp`;
|
|
53366
54527
|
try {
|
|
53367
|
-
(0,
|
|
54528
|
+
(0, import_node_fs71.mkdirSync)((0, import_node_path93.dirname)(path), { recursive: true, mode: 448 });
|
|
53368
54529
|
const caps = Object.fromEntries([...entries].sort(([a], [b]) => a < b ? -1 : 1));
|
|
53369
|
-
(0,
|
|
54530
|
+
(0, import_node_fs71.writeFileSync)(tmp, `${JSON.stringify({ version: MAX_TOKENS_CACHE_VERSION, caps }, null, 2)}
|
|
53370
54531
|
`);
|
|
53371
|
-
(0,
|
|
54532
|
+
(0, import_node_fs71.renameSync)(tmp, path);
|
|
53372
54533
|
} catch {
|
|
53373
54534
|
}
|
|
53374
54535
|
}
|
|
@@ -53384,11 +54545,11 @@ function attachMaxTokensCache(dataDir, now = Date.now) {
|
|
|
53384
54545
|
attached2.set(dataDir, detach);
|
|
53385
54546
|
return detach;
|
|
53386
54547
|
}
|
|
53387
|
-
var
|
|
54548
|
+
var import_node_fs71, import_node_path93, MAX_TOKENS_CACHE_VERSION, MAX_TOKENS_CACHE_TTL_MS, attached2;
|
|
53388
54549
|
var init_max_tokens_cache = __esm({
|
|
53389
54550
|
"src/ai/providers/max-tokens-cache.ts"() {
|
|
53390
54551
|
"use strict";
|
|
53391
|
-
|
|
54552
|
+
import_node_fs71 = require("node:fs");
|
|
53392
54553
|
import_node_path93 = require("node:path");
|
|
53393
54554
|
init_max_tokens();
|
|
53394
54555
|
MAX_TOKENS_CACHE_VERSION = 1;
|
|
@@ -53542,7 +54703,7 @@ function findImageRefs(text, cwd) {
|
|
|
53542
54703
|
token = token.replace(/\\ /g, " ").replace(/[,\uFF0C\u3002;\uFF1B)\uFF09]+$/, "");
|
|
53543
54704
|
if (token === "" || imageMimeFromPath(token) === void 0) continue;
|
|
53544
54705
|
const path = expand(token, cwd);
|
|
53545
|
-
if (!explicit && !(0,
|
|
54706
|
+
if (!explicit && !(0, import_node_fs72.existsSync)(path)) continue;
|
|
53546
54707
|
if (seen.has(path)) continue;
|
|
53547
54708
|
seen.add(path);
|
|
53548
54709
|
out.push({ path, explicit });
|
|
@@ -53571,9 +54732,9 @@ async function loadPromptImages(refs, model, options = {}) {
|
|
|
53571
54732
|
...model !== void 0 ? { maxBase64Bytes: imageLimits(model).perImageBase64 } : {},
|
|
53572
54733
|
...options
|
|
53573
54734
|
};
|
|
53574
|
-
const
|
|
53575
|
-
for (const ref of wanted)
|
|
53576
|
-
return
|
|
54735
|
+
const blocks2 = [];
|
|
54736
|
+
for (const ref of wanted) blocks2.push((await loadLocalized(ref.path, fit)).block);
|
|
54737
|
+
return blocks2;
|
|
53577
54738
|
}
|
|
53578
54739
|
async function promptImages(text, extra, cwd, model, options = {}) {
|
|
53579
54740
|
const refs = [
|
|
@@ -53601,11 +54762,11 @@ async function loadLocalized(path, options) {
|
|
|
53601
54762
|
throw error2;
|
|
53602
54763
|
}
|
|
53603
54764
|
}
|
|
53604
|
-
var
|
|
54765
|
+
var import_node_fs72, import_node_os15, import_node_path94, TOKEN;
|
|
53605
54766
|
var init_image_input = __esm({
|
|
53606
54767
|
"src/modes/image-input.ts"() {
|
|
53607
54768
|
"use strict";
|
|
53608
|
-
|
|
54769
|
+
import_node_fs72 = require("node:fs");
|
|
53609
54770
|
import_node_os15 = require("node:os");
|
|
53610
54771
|
import_node_path94 = require("node:path");
|
|
53611
54772
|
init_channels();
|
|
@@ -54404,7 +55565,7 @@ function trustChoices() {
|
|
|
54404
55565
|
}
|
|
54405
55566
|
function isDirectory2(path) {
|
|
54406
55567
|
try {
|
|
54407
|
-
return (0,
|
|
55568
|
+
return (0, import_node_fs73.statSync)(path).isDirectory();
|
|
54408
55569
|
} catch {
|
|
54409
55570
|
return false;
|
|
54410
55571
|
}
|
|
@@ -54459,7 +55620,7 @@ function createStartupUi(options = {}) {
|
|
|
54459
55620
|
validate: (text) => {
|
|
54460
55621
|
if (text === "") return m.cwdEmpty;
|
|
54461
55622
|
const abs = (0, import_node_path95.resolve)(text);
|
|
54462
|
-
if (!(0,
|
|
55623
|
+
if (!(0, import_node_fs73.existsSync)(abs)) return m.cwdMissing(abs);
|
|
54463
55624
|
if (!isDirectory2(abs)) return m.cwdNotDir(abs);
|
|
54464
55625
|
return void 0;
|
|
54465
55626
|
}
|
|
@@ -54467,12 +55628,12 @@ function createStartupUi(options = {}) {
|
|
|
54467
55628
|
}
|
|
54468
55629
|
};
|
|
54469
55630
|
}
|
|
54470
|
-
var
|
|
55631
|
+
var import_node_fs73, import_node_path95;
|
|
54471
55632
|
var init_startup_ui = __esm({
|
|
54472
55633
|
"src/modes/interactive/startup-ui.ts"() {
|
|
54473
55634
|
"use strict";
|
|
54474
55635
|
init_i18n();
|
|
54475
|
-
|
|
55636
|
+
import_node_fs73 = require("node:fs");
|
|
54476
55637
|
import_node_path95 = require("node:path");
|
|
54477
55638
|
init_tui2();
|
|
54478
55639
|
init_model_items();
|
|
@@ -54913,8 +56074,8 @@ var init_startup_screen = __esm({
|
|
|
54913
56074
|
});
|
|
54914
56075
|
|
|
54915
56076
|
// src/modes/interactive/panels.ts
|
|
54916
|
-
function keyValue(rows, theme,
|
|
54917
|
-
return new KeyValue(rows, { theme, maxKeyRatio: 0.3, ...
|
|
56077
|
+
function keyValue(rows, theme, wrap3 = false) {
|
|
56078
|
+
return new KeyValue(rows, { theme, maxKeyRatio: 0.3, ...wrap3 ? { wrap: true } : {} });
|
|
54918
56079
|
}
|
|
54919
56080
|
function cacheSection(session, theme, now) {
|
|
54920
56081
|
return [
|
|
@@ -55212,7 +56373,7 @@ function contextPanel(session, theme) {
|
|
|
55212
56373
|
const m = msg().report.contextReport;
|
|
55213
56374
|
const snap = contextSnapshot(session);
|
|
55214
56375
|
const { breakdown } = snap;
|
|
55215
|
-
const table3 = (rows,
|
|
56376
|
+
const table3 = (rows, wrap3 = false) => new KeyValue(rows, { theme, maxKeyRatio: 0.3, ...wrap3 ? { wrap: true } : {} });
|
|
55216
56377
|
const largest = largestRows(breakdown);
|
|
55217
56378
|
const parts = [
|
|
55218
56379
|
table3(headerRows(snap)),
|
|
@@ -55271,14 +56432,20 @@ function command(name, key, args) {
|
|
|
55271
56432
|
});
|
|
55272
56433
|
return info2;
|
|
55273
56434
|
}
|
|
56435
|
+
function availableCommands2(runtime, session, list5 = BUILTIN_COMMANDS) {
|
|
56436
|
+
const active = new Set(session.getTools().map((t) => t.name));
|
|
56437
|
+
const registered = new Set(runtime.tools.list());
|
|
56438
|
+
const has = (requires) => requires === "memory" ? registered.has("memory") : requires === "task" ? active.has("task") || active.has("codemode") && registered.has("task") : true;
|
|
56439
|
+
return list5.filter((c) => has(c.requires));
|
|
56440
|
+
}
|
|
55274
56441
|
function parseSlash(line2) {
|
|
55275
56442
|
const m = /^\/([A-Za-z?][\w-]*)(?:\s+([\s\S]*))?$/.exec(line2.trim());
|
|
55276
56443
|
if (m === null) return void 0;
|
|
55277
56444
|
const raw = m[1].toLowerCase();
|
|
55278
56445
|
return { name: ALIASES[raw] ?? raw, args: (m[2] ?? "").trim() };
|
|
55279
56446
|
}
|
|
55280
|
-
function helpText2() {
|
|
55281
|
-
const lines2 =
|
|
56447
|
+
function helpText2(ctx) {
|
|
56448
|
+
const lines2 = availableCommands2(ctx.runtime, ctx.session()).map(
|
|
55282
56449
|
(c) => `/${c.name}${c.args !== void 0 ? ` ${c.args}` : ""} ${c.description}`
|
|
55283
56450
|
);
|
|
55284
56451
|
const m = msg().report.commands;
|
|
@@ -55325,7 +56492,7 @@ async function runSlashCommand(line2, ctx) {
|
|
|
55325
56492
|
const session = ctx.session();
|
|
55326
56493
|
switch (name) {
|
|
55327
56494
|
case "help":
|
|
55328
|
-
return { kind: "handled", message: helpText2() };
|
|
56495
|
+
return { kind: "handled", message: helpText2(ctx) };
|
|
55329
56496
|
case "exit":
|
|
55330
56497
|
return { kind: "exit" };
|
|
55331
56498
|
case "new": {
|
|
@@ -55497,7 +56664,9 @@ var init_commands_core = __esm({
|
|
|
55497
56664
|
command("cache", "cache", "[warm off|streaming|idle | fingerprint]"),
|
|
55498
56665
|
command("statusline", "statusline", "[full|compact]"),
|
|
55499
56666
|
command("plan", "plan", { key: "planArgs" }),
|
|
55500
|
-
command("tasks", "tasks", "[id] | stop <id> | bg [id]"),
|
|
56667
|
+
Object.assign(command("tasks", "tasks", "[id] | stop <id> | bg [id]"), {
|
|
56668
|
+
requires: "task"
|
|
56669
|
+
}),
|
|
55501
56670
|
command("agents", "agents"),
|
|
55502
56671
|
command("paste", "paste"),
|
|
55503
56672
|
command("interrupt", "interrupt", { key: "interruptArgs" }),
|
|
@@ -55505,7 +56674,9 @@ var init_commands_core = __esm({
|
|
|
55505
56674
|
// [W6-C0] 第六波(W6-S / W6-T1 / W6-M 实现)
|
|
55506
56675
|
command("config", "config", "[key=value]"),
|
|
55507
56676
|
command("trace", "trace", { key: "traceArgs" }),
|
|
55508
|
-
command("memory", "memory", { key: "memoryArgs" })
|
|
56677
|
+
Object.assign(command("memory", "memory", { key: "memoryArgs" }), {
|
|
56678
|
+
requires: "memory"
|
|
56679
|
+
})
|
|
55509
56680
|
];
|
|
55510
56681
|
ALIASES = { quit: "exit", q: "exit", "?": "help" };
|
|
55511
56682
|
}
|
|
@@ -55605,9 +56776,9 @@ async function availableModels(runtime) {
|
|
|
55605
56776
|
}
|
|
55606
56777
|
return out;
|
|
55607
56778
|
}
|
|
55608
|
-
function commands(runtime) {
|
|
56779
|
+
function commands(runtime, session) {
|
|
55609
56780
|
return [
|
|
55610
|
-
...
|
|
56781
|
+
...availableCommands2(runtime, session).map((c) => ({
|
|
55611
56782
|
name: c.name,
|
|
55612
56783
|
description: c.description,
|
|
55613
56784
|
source: "builtin"
|
|
@@ -55817,7 +56988,7 @@ var init_commands = __esm({
|
|
|
55817
56988
|
ctx.session().setPermissionMode(p.mode);
|
|
55818
56989
|
return { mode: p.mode };
|
|
55819
56990
|
},
|
|
55820
|
-
get_commands: async (_p, ctx) => ({ commands: commands(ctx.runtime) }),
|
|
56991
|
+
get_commands: async (_p, ctx) => ({ commands: commands(ctx.runtime, ctx.session()) }),
|
|
55821
56992
|
get_skills: async (_p, ctx) => ({ skills: ctx.runtime.resources.skills }),
|
|
55822
56993
|
// [W5-F] 计划 / 任务命令(docs/history/wave5-plan.md §6.5、§7.5)
|
|
55823
56994
|
plan_response: async (p, ctx) => {
|
|
@@ -56312,8 +57483,8 @@ var init_config_panel = __esm({
|
|
|
56312
57483
|
const dynamic = value.value === void 0 ? settingDynamicDefault(row3.id) : void 0;
|
|
56313
57484
|
const text = dynamic === void 0 ? doc : `${doc} · ${dynamic}`;
|
|
56314
57485
|
const spec2 = settingsRegistry().find((x) => x.key === row3.id);
|
|
56315
|
-
const
|
|
56316
|
-
const lines2 =
|
|
57486
|
+
const blocked3 = spec2 === void 0 ? void 0 : blockedReason(spec2, value, this.scope);
|
|
57487
|
+
const lines2 = blocked3 === void 0 ? [] : [theme.fg("warning", truncateToWidth(blocked3, width2))];
|
|
56317
57488
|
if (text !== "") lines2.push(...wrapTextWithAnsi(theme.fg("dim", text), width2));
|
|
56318
57489
|
return lines2.slice(0, 3);
|
|
56319
57490
|
}
|
|
@@ -57356,8 +58527,8 @@ var init_config_ui = __esm({
|
|
|
57356
58527
|
const spec2 = settingSpec(key);
|
|
57357
58528
|
if (panel === void 0 || spec2 === void 0) return;
|
|
57358
58529
|
const current3 = getConfigValue(readSnapshot(this.input()), key);
|
|
57359
|
-
const
|
|
57360
|
-
if (
|
|
58530
|
+
const blocked3 = blockedReason(spec2, current3, scope);
|
|
58531
|
+
if (blocked3 !== void 0) return panel.setNotice(blocked3, "warning");
|
|
57361
58532
|
const value = current3.value;
|
|
57362
58533
|
switch (spec2.kind) {
|
|
57363
58534
|
case "bool":
|
|
@@ -57647,27 +58818,27 @@ function runEditor(command3, file) {
|
|
|
57647
58818
|
return result.status;
|
|
57648
58819
|
}
|
|
57649
58820
|
async function editExternally(text, name, deps) {
|
|
57650
|
-
const dir = (0,
|
|
58821
|
+
const dir = (0, import_node_fs74.mkdtempSync)((0, import_node_path97.join)((0, import_node_os16.tmpdir)(), "ama-edit-"));
|
|
57651
58822
|
const file = (0, import_node_path97.join)(dir, name);
|
|
57652
|
-
(0,
|
|
58823
|
+
(0, import_node_fs74.writeFileSync)(file, text);
|
|
57653
58824
|
deps.suspend();
|
|
57654
58825
|
try {
|
|
57655
58826
|
const code = (deps.run ?? runEditor)(editorCommand(deps.env, deps.platform), file);
|
|
57656
58827
|
if (code !== 0) return void 0;
|
|
57657
|
-
return (0,
|
|
58828
|
+
return (0, import_node_fs74.readFileSync)(file, "utf8");
|
|
57658
58829
|
} catch {
|
|
57659
58830
|
return void 0;
|
|
57660
58831
|
} finally {
|
|
57661
58832
|
deps.resume();
|
|
57662
|
-
(0,
|
|
58833
|
+
(0, import_node_fs74.rmSync)(dir, { recursive: true, force: true });
|
|
57663
58834
|
}
|
|
57664
58835
|
}
|
|
57665
|
-
var import_node_child_process17,
|
|
58836
|
+
var import_node_child_process17, import_node_fs74, import_node_os16, import_node_path97;
|
|
57666
58837
|
var init_external_editor = __esm({
|
|
57667
58838
|
"src/modes/interactive/external-editor.ts"() {
|
|
57668
58839
|
"use strict";
|
|
57669
58840
|
import_node_child_process17 = require("node:child_process");
|
|
57670
|
-
|
|
58841
|
+
import_node_fs74 = require("node:fs");
|
|
57671
58842
|
import_node_os16 = require("node:os");
|
|
57672
58843
|
import_node_path97 = require("node:path");
|
|
57673
58844
|
}
|
|
@@ -58631,6 +59802,10 @@ function describeRequest(request, theme, options = {}) {
|
|
|
58631
59802
|
const { shown: shown2, hidden } = lines(input2["command"], COMMAND_LINES);
|
|
58632
59803
|
out.push(...shown2.map((l, i) => theme.fg("code", (i === 0 ? "$ " : " ") + l)));
|
|
58633
59804
|
if (hidden > 0) out.push(more(hidden));
|
|
59805
|
+
} else if (request.toolName === "web_fetch" && typeof input2["url"] === "string") {
|
|
59806
|
+
const { shown: shown2, hidden } = lines(input2["url"].replace(/(.{72})/g, "$1\n"), COMMAND_LINES);
|
|
59807
|
+
out.push(...shown2.map((l) => theme.fg("code", l)));
|
|
59808
|
+
if (hidden > 0) out.push(more(hidden));
|
|
58634
59809
|
} else if (request.toolName === "write" && typeof input2["content"] === "string") {
|
|
58635
59810
|
const count2 = lines(input2["content"], Number.MAX_SAFE_INTEGER).shown.length;
|
|
58636
59811
|
out.push(
|
|
@@ -58699,8 +59874,10 @@ function approvalOutcomeText(request, outcome, taskAgent) {
|
|
|
58699
59874
|
switch (outcome) {
|
|
58700
59875
|
case "allow":
|
|
58701
59876
|
return m.allow(what);
|
|
58702
|
-
case "allow_session":
|
|
58703
|
-
|
|
59877
|
+
case "allow_session": {
|
|
59878
|
+
const host = fetchHost(request.toolName, request.input);
|
|
59879
|
+
return host === void 0 ? m.allowSession(what) : m.allowSessionHost(what, host);
|
|
59880
|
+
}
|
|
58704
59881
|
case "deny":
|
|
58705
59882
|
return m.deny(what);
|
|
58706
59883
|
case "cancelled":
|
|
@@ -58790,10 +59967,12 @@ var init_approval_dialog = __esm({
|
|
|
58790
59967
|
const { theme } = this.host;
|
|
58791
59968
|
const g = theme.glyphs;
|
|
58792
59969
|
const keyWidth = compact ? 1 : Math.max(...APPROVAL_OPTIONS.map((o) => o.keys.length));
|
|
59970
|
+
const host = fetchHost(this.request.toolName, this.request.input);
|
|
58793
59971
|
return APPROVAL_OPTIONS.map((option2, i) => {
|
|
58794
59972
|
const selected = i === this.selected;
|
|
58795
59973
|
const keys = compact ? option2.keys.slice(0, 1) : option2.keys;
|
|
58796
|
-
const
|
|
59974
|
+
const text = option2.decision === "allow_session" && host !== void 0 ? msg().approval.option.allowSessionHost(host) : option2.label;
|
|
59975
|
+
const left = `${selected ? g.prompt : " "} ${i + 1}. ${text}`;
|
|
58797
59976
|
const right = keys.padEnd(keyWidth);
|
|
58798
59977
|
const room = Math.max(1, width2 - visibleWidth(right) - 1);
|
|
58799
59978
|
const label2 = selected ? theme.fg("accent", theme.bold(left)) : left;
|
|
@@ -61212,6 +62391,9 @@ function command2(name, key) {
|
|
|
61212
62391
|
}
|
|
61213
62392
|
};
|
|
61214
62393
|
}
|
|
62394
|
+
function completionCommands(runtime, session) {
|
|
62395
|
+
return availableCommands2(runtime, session, ALL_COMMANDS);
|
|
62396
|
+
}
|
|
61215
62397
|
function keyHints() {
|
|
61216
62398
|
return msg().interactive.commands.keyHints;
|
|
61217
62399
|
}
|
|
@@ -64336,7 +65518,7 @@ var init_program_status = __esm({
|
|
|
64336
65518
|
});
|
|
64337
65519
|
|
|
64338
65520
|
// src/modes/interactive/program-status-ui.ts
|
|
64339
|
-
function
|
|
65521
|
+
function blocked2(kind, text) {
|
|
64340
65522
|
return { state: "blocked", kind, msg: text };
|
|
64341
65523
|
}
|
|
64342
65524
|
function programStatusUi(deps) {
|
|
@@ -64492,9 +65674,9 @@ var init_program_status_ui = __esm({
|
|
|
64492
65674
|
/** 当前根记录(测试也用)。 */
|
|
64493
65675
|
root() {
|
|
64494
65676
|
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
|
|
65677
|
+
if (pending !== void 0) return blocked2("permission", pending.msg);
|
|
65678
|
+
if (this.plan !== void 0) return blocked2("question", this.plan);
|
|
65679
|
+
if (this.auth !== void 0) return blocked2("auth", this.auth);
|
|
64498
65680
|
if (this.running)
|
|
64499
65681
|
return { state: "working", ...this.activity !== void 0 ? { msg: this.activity } : {} };
|
|
64500
65682
|
return this.outcome ?? { state: "idle" };
|
|
@@ -64618,7 +65800,7 @@ function runInteractiveMode(runtime, context, options = {}) {
|
|
|
64618
65800
|
const { hint, bar: status } = area;
|
|
64619
65801
|
const historyFile = options.historyFile === false ? void 0 : options.historyFile ?? (0, import_node_path101.join)(runtime.paths.dataDir, "history");
|
|
64620
65802
|
const completion = new InteractiveCompletion({
|
|
64621
|
-
commands: () =>
|
|
65803
|
+
commands: () => completionCommands(runtime, session),
|
|
64622
65804
|
prompts: () => runtime.resources.prompts,
|
|
64623
65805
|
skills: () => runtime.resources.skills,
|
|
64624
65806
|
cwd: () => session.state.cwd,
|
|
@@ -65061,7 +66243,7 @@ function choose(answer, values) {
|
|
|
65061
66243
|
}
|
|
65062
66244
|
function isDirectory3(path) {
|
|
65063
66245
|
try {
|
|
65064
|
-
return (0,
|
|
66246
|
+
return (0, import_node_fs75.statSync)(path).isDirectory();
|
|
65065
66247
|
} catch {
|
|
65066
66248
|
return false;
|
|
65067
66249
|
}
|
|
@@ -65106,7 +66288,7 @@ function createTextStartupUi(io) {
|
|
|
65106
66288
|
const answer = (await ask([m.cwdMissing(missing)], m.cwdAnswer))?.trim();
|
|
65107
66289
|
if (answer === void 0 || answer === "") return void 0;
|
|
65108
66290
|
const abs = (0, import_node_path102.resolve)(answer);
|
|
65109
|
-
if (!(0,
|
|
66291
|
+
if (!(0, import_node_fs75.existsSync)(abs) || !isDirectory3(abs)) {
|
|
65110
66292
|
io.write(m.notDirectory(abs));
|
|
65111
66293
|
return void 0;
|
|
65112
66294
|
}
|
|
@@ -65114,11 +66296,11 @@ function createTextStartupUi(io) {
|
|
|
65114
66296
|
}
|
|
65115
66297
|
};
|
|
65116
66298
|
}
|
|
65117
|
-
var
|
|
66299
|
+
var import_node_fs75, import_node_path102;
|
|
65118
66300
|
var init_startup_ui_text = __esm({
|
|
65119
66301
|
"src/modes/startup-ui-text.ts"() {
|
|
65120
66302
|
"use strict";
|
|
65121
|
-
|
|
66303
|
+
import_node_fs75 = require("node:fs");
|
|
65122
66304
|
import_node_path102 = require("node:path");
|
|
65123
66305
|
init_i18n();
|
|
65124
66306
|
}
|
|
@@ -65155,6 +66337,7 @@ function createTools(input2, options, state) {
|
|
|
65155
66337
|
};
|
|
65156
66338
|
const builtins = builtinTools({
|
|
65157
66339
|
bash,
|
|
66340
|
+
...options.webFetch !== void 0 ? { webFetch: options.webFetch } : {},
|
|
65158
66341
|
read: {
|
|
65159
66342
|
supportsImages: (ctx2) => modelAcceptsImages(state, ctx2.model),
|
|
65160
66343
|
imageOptions: (ctx2) => imageFitOptionsFor(state.providers, ctx2.model, input2.config.images)
|
|
@@ -65564,7 +66747,7 @@ var init_memory3 = __esm({
|
|
|
65564
66747
|
});
|
|
65565
66748
|
|
|
65566
66749
|
// src/cli/main.ts
|
|
65567
|
-
var
|
|
66750
|
+
var import_node_fs76 = require("node:fs");
|
|
65568
66751
|
var import_node_path104 = require("node:path");
|
|
65569
66752
|
var import_node_url3 = require("node:url");
|
|
65570
66753
|
init_version();
|
|
@@ -66101,7 +67284,7 @@ init_token_client();
|
|
|
66101
67284
|
|
|
66102
67285
|
// src/auth/chatgpt/host-id.ts
|
|
66103
67286
|
var import_node_crypto19 = require("node:crypto");
|
|
66104
|
-
var
|
|
67287
|
+
var import_node_fs49 = require("node:fs");
|
|
66105
67288
|
var import_node_path70 = require("node:path");
|
|
66106
67289
|
var HOST_ID_FILE = "chatgpt-host.json";
|
|
66107
67290
|
function hostIdPath(dataDir) {
|
|
@@ -66110,14 +67293,14 @@ function hostIdPath(dataDir) {
|
|
|
66110
67293
|
function readOrCreateHostId(dataDir) {
|
|
66111
67294
|
const path = hostIdPath(dataDir);
|
|
66112
67295
|
try {
|
|
66113
|
-
const value = JSON.parse((0,
|
|
67296
|
+
const value = JSON.parse((0, import_node_fs49.readFileSync)(path, "utf8"));
|
|
66114
67297
|
if (typeof value.hostId === "string" && /^urn:uuid:[0-9a-f-]{36}$/i.test(value.hostId))
|
|
66115
67298
|
return value.hostId;
|
|
66116
67299
|
} catch {
|
|
66117
67300
|
}
|
|
66118
67301
|
const hostId = `urn:uuid:${(0, import_node_crypto19.randomUUID)()}`;
|
|
66119
|
-
(0,
|
|
66120
|
-
(0,
|
|
67302
|
+
(0, import_node_fs49.mkdirSync)((0, import_node_path70.dirname)(path), { recursive: true, mode: 448 });
|
|
67303
|
+
(0, import_node_fs49.writeFileSync)(path, `${JSON.stringify({ version: 1, hostId }, null, 2)}
|
|
66121
67304
|
`, { mode: 384 });
|
|
66122
67305
|
return hostId;
|
|
66123
67306
|
}
|
|
@@ -66630,7 +67813,7 @@ init_merge();
|
|
|
66630
67813
|
init_key_docs();
|
|
66631
67814
|
init_paths();
|
|
66632
67815
|
var import_node_child_process14 = require("node:child_process");
|
|
66633
|
-
var
|
|
67816
|
+
var import_node_fs58 = require("node:fs");
|
|
66634
67817
|
var import_node_path79 = require("node:path");
|
|
66635
67818
|
init_models_dev_cache();
|
|
66636
67819
|
init_init();
|
|
@@ -66692,7 +67875,7 @@ init_ansi();
|
|
|
66692
67875
|
// src/cli/subcommands/config-set.ts
|
|
66693
67876
|
init_i18n();
|
|
66694
67877
|
init_edit2();
|
|
66695
|
-
var
|
|
67878
|
+
var import_node_fs57 = require("node:fs");
|
|
66696
67879
|
var import_node_path78 = require("node:path");
|
|
66697
67880
|
init_init();
|
|
66698
67881
|
init_paths();
|
|
@@ -66822,7 +68005,7 @@ async function runConfigEdit(action, argv, io, deps = {}) {
|
|
|
66822
68005
|
if (key === "permission.mode" && value === "full-auto" && scope === "user") {
|
|
66823
68006
|
if (!await confirmBypass(io, flags2.has("yes"), deps)) return ExitCode.Config;
|
|
66824
68007
|
}
|
|
66825
|
-
if (scope === "user" && !(0,
|
|
68008
|
+
if (scope === "user" && !(0, import_node_fs57.existsSync)((0, import_node_path78.join)(input2.configDir, CONFIG_FILE)))
|
|
66826
68009
|
initConfigDir(input2.configDir);
|
|
66827
68010
|
report(io, setConfigValue({ ...input2, scope, key, value }), value);
|
|
66828
68011
|
return ExitCode.Ok;
|
|
@@ -66835,7 +68018,7 @@ function showPaths(io) {
|
|
|
66835
68018
|
const configDir = resolveConfigDir({ env: io.env });
|
|
66836
68019
|
const dataDir = resolveDataDir({ env: io.env });
|
|
66837
68020
|
const m = msg().subcommands.configShow;
|
|
66838
|
-
const mark = (path) => `${path}${(0,
|
|
68021
|
+
const mark = (path) => `${path}${(0, import_node_fs58.existsSync)(path) ? "" : m.missing}`;
|
|
66839
68022
|
const width2 = Math.max(...[m.configDir, m.dataDir, m.projectLevel].map(visibleWidth)) + 2;
|
|
66840
68023
|
const label2 = (text) => padToWidth(text, width2);
|
|
66841
68024
|
const lines2 = [
|
|
@@ -66856,7 +68039,7 @@ function showPaths(io) {
|
|
|
66856
68039
|
function editConfig(io) {
|
|
66857
68040
|
const configDir = resolveConfigDir({ env: io.env });
|
|
66858
68041
|
const path = (0, import_node_path79.join)(configDir, CONFIG_FILE);
|
|
66859
|
-
if (!(0,
|
|
68042
|
+
if (!(0, import_node_fs58.existsSync)(path)) initConfigDir(configDir);
|
|
66860
68043
|
const editor = (io.env["VISUAL"] ?? io.env["EDITOR"] ?? "").trim();
|
|
66861
68044
|
if (editor === "") {
|
|
66862
68045
|
io.stdout(msg().subcommands.configShow.noEditor(path));
|
|
@@ -67148,7 +68331,7 @@ async function runConfig(argv, io, deps) {
|
|
|
67148
68331
|
}
|
|
67149
68332
|
|
|
67150
68333
|
// src/cli/subcommands/doctor.ts
|
|
67151
|
-
var
|
|
68334
|
+
var import_node_fs59 = require("node:fs");
|
|
67152
68335
|
init_blobs();
|
|
67153
68336
|
init_shadow_git();
|
|
67154
68337
|
init_gc();
|
|
@@ -67167,7 +68350,7 @@ init_args();
|
|
|
67167
68350
|
init_exit_codes();
|
|
67168
68351
|
|
|
67169
68352
|
// src/cli/proxy.ts
|
|
67170
|
-
var
|
|
68353
|
+
var http2 = __toESM(require("node:http"), 1);
|
|
67171
68354
|
init_i18n();
|
|
67172
68355
|
function pick5(env, name) {
|
|
67173
68356
|
const value = env[name.toLowerCase()] ?? env[name.toUpperCase()];
|
|
@@ -67175,18 +68358,18 @@ function pick5(env, name) {
|
|
|
67175
68358
|
}
|
|
67176
68359
|
function readProxyEnv(env) {
|
|
67177
68360
|
const out = {};
|
|
67178
|
-
const
|
|
68361
|
+
const https2 = pick5(env, "https_proxy");
|
|
67179
68362
|
const plain = pick5(env, "http_proxy");
|
|
67180
68363
|
const no = pick5(env, "no_proxy");
|
|
67181
|
-
if (
|
|
68364
|
+
if (https2 !== void 0) out.httpsProxy = https2;
|
|
67182
68365
|
if (plain !== void 0) out.httpProxy = plain;
|
|
67183
68366
|
if (no !== void 0) out.noProxy = no;
|
|
67184
68367
|
return out;
|
|
67185
68368
|
}
|
|
67186
68369
|
function defaultProxyRuntime() {
|
|
67187
|
-
const fn =
|
|
68370
|
+
const fn = http2.setGlobalProxyFromEnv;
|
|
67188
68371
|
return {
|
|
67189
|
-
setGlobalProxyFromEnv: typeof fn === "function" ? fn.bind(
|
|
68372
|
+
setGlobalProxyFromEnv: typeof fn === "function" ? fn.bind(http2) : void 0,
|
|
67190
68373
|
execArgv: process.execArgv,
|
|
67191
68374
|
version: process.versions.node
|
|
67192
68375
|
};
|
|
@@ -67521,7 +68704,7 @@ async function runDoctor(argv, io, deps) {
|
|
|
67521
68704
|
const m = msg().report.doctor;
|
|
67522
68705
|
report2.section(m.dirsTitle);
|
|
67523
68706
|
report2.item(m.configDir(level.configDir));
|
|
67524
|
-
report2.item(m.dataDir(level.dataDir, (0,
|
|
68707
|
+
report2.item(m.dataDir(level.dataDir, (0, import_node_fs59.existsSync)(level.dataDir)));
|
|
67525
68708
|
await fileHistoryLine(report2, level.dataDir);
|
|
67526
68709
|
report2.section(m.layersTitle);
|
|
67527
68710
|
report2.item(m.builtinDefaults);
|
|
@@ -67749,7 +68932,7 @@ init_discovered_cache();
|
|
|
67749
68932
|
init_catalog2();
|
|
67750
68933
|
init_models_dev_cache();
|
|
67751
68934
|
init_models_dev();
|
|
67752
|
-
var
|
|
68935
|
+
var import_node_fs60 = require("node:fs");
|
|
67753
68936
|
init_load();
|
|
67754
68937
|
init_write2();
|
|
67755
68938
|
init_args();
|
|
@@ -68112,7 +69295,7 @@ function writeEntries(ctx, provider, entries, notes) {
|
|
|
68112
69295
|
return 0;
|
|
68113
69296
|
}
|
|
68114
69297
|
models.push(...added);
|
|
68115
|
-
const backup = (0,
|
|
69298
|
+
const backup = (0, import_node_fs60.existsSync)(path);
|
|
68116
69299
|
writeConfigFile(path, config, { backup: true });
|
|
68117
69300
|
io.stdout(m.written(path, provider.id, added.length, kept, backup));
|
|
68118
69301
|
if (notes.noTools.size > 0) io.stdout(m.skippedNoTools([...notes.noTools].join(", ")));
|
|
@@ -68537,7 +69720,7 @@ async function runModels(argv, io, deps) {
|
|
|
68537
69720
|
}
|
|
68538
69721
|
|
|
68539
69722
|
// src/cli/subcommands/providers.ts
|
|
68540
|
-
var
|
|
69723
|
+
var import_node_fs61 = require("node:fs");
|
|
68541
69724
|
init_models_dev_cache();
|
|
68542
69725
|
init_models_dev();
|
|
68543
69726
|
init_auth_file();
|
|
@@ -68884,7 +70067,7 @@ function yesNo(value) {
|
|
|
68884
70067
|
const t = msg().subcommands.providersPlan;
|
|
68885
70068
|
return value === void 0 ? "?" : value ? t.yes : t.no;
|
|
68886
70069
|
}
|
|
68887
|
-
function
|
|
70070
|
+
function renderTable3(plans2) {
|
|
68888
70071
|
const h = msg().subcommands.providersPlan.head;
|
|
68889
70072
|
const head = [
|
|
68890
70073
|
h.model,
|
|
@@ -69140,7 +70323,7 @@ async function add(ctx, id, refresh) {
|
|
|
69140
70323
|
});
|
|
69141
70324
|
if (result.cancelled !== void 0) return result.cancelled;
|
|
69142
70325
|
io.stdout(`
|
|
69143
|
-
${
|
|
70326
|
+
${renderTable3(result.plans)}`);
|
|
69144
70327
|
if (refresh) {
|
|
69145
70328
|
const gone = [...existingIds].filter((m2) => !listed2.some((l) => l.id === m2));
|
|
69146
70329
|
if (gone.length > 0) io.stdout(m.goneUpstream(gone));
|
|
@@ -69194,7 +70377,7 @@ ${renderTable2(result.plans)}`);
|
|
|
69194
70377
|
const providers = config.providers ??= {};
|
|
69195
70378
|
providers[id] = merged.config;
|
|
69196
70379
|
if (defaultPick !== void 0) config.defaultModel = `${id}/${defaultPick.id}`;
|
|
69197
|
-
const backup = (0,
|
|
70380
|
+
const backup = (0, import_node_fs61.existsSync)(level.userConfigPath);
|
|
69198
70381
|
writeConfigFile(level.userConfigPath, config, { backup: true });
|
|
69199
70382
|
if (key.store !== void 0) setAuthKey(level.authFile, id, key.store);
|
|
69200
70383
|
io.stdout(m.written(level.userConfigPath, backup));
|
|
@@ -69319,7 +70502,7 @@ init_reuse();
|
|
|
69319
70502
|
init_clipboard_image();
|
|
69320
70503
|
|
|
69321
70504
|
// src/cli/subcommands/sessions-export.ts
|
|
69322
|
-
var
|
|
70505
|
+
var import_node_fs63 = require("node:fs");
|
|
69323
70506
|
var import_node_path81 = require("node:path");
|
|
69324
70507
|
init_paths();
|
|
69325
70508
|
|
|
@@ -69551,7 +70734,7 @@ async function runSessionsExport(argv, io) {
|
|
|
69551
70734
|
return ExitCode.Ok;
|
|
69552
70735
|
}
|
|
69553
70736
|
const target = (0, import_node_path81.resolve)(io.cwd, expandHome(output, { env: io.env }));
|
|
69554
|
-
(0,
|
|
70737
|
+
(0, import_node_fs63.writeFileSync)(target, text, { mode: 384 });
|
|
69555
70738
|
io.stderr(msg().subcommands.sessionsExport.exported(target));
|
|
69556
70739
|
return ExitCode.Ok;
|
|
69557
70740
|
}
|
|
@@ -69883,7 +71066,7 @@ function aggregateStats(summaries, options = {}) {
|
|
|
69883
71066
|
}
|
|
69884
71067
|
|
|
69885
71068
|
// src/session/stats-index.ts
|
|
69886
|
-
var
|
|
71069
|
+
var import_node_fs64 = require("node:fs");
|
|
69887
71070
|
var import_node_path82 = require("node:path");
|
|
69888
71071
|
|
|
69889
71072
|
// src/session/stats-scan.ts
|
|
@@ -70097,7 +71280,7 @@ function collectSummaries(files, options = {}) {
|
|
|
70097
71280
|
let index2 = { version: INDEX_VERSION, zone, files: {} };
|
|
70098
71281
|
if (options.indexFile !== void 0) {
|
|
70099
71282
|
try {
|
|
70100
|
-
const loaded = JSON.parse((0,
|
|
71283
|
+
const loaded = JSON.parse((0, import_node_fs64.readFileSync)(options.indexFile, "utf8"));
|
|
70101
71284
|
if (loaded.version === INDEX_VERSION && loaded.zone === zone && typeof loaded.files === "object")
|
|
70102
71285
|
index2 = loaded;
|
|
70103
71286
|
} catch {
|
|
@@ -70108,7 +71291,7 @@ function collectSummaries(files, options = {}) {
|
|
|
70108
71291
|
for (const file of files) {
|
|
70109
71292
|
let stat16;
|
|
70110
71293
|
try {
|
|
70111
|
-
stat16 = (0,
|
|
71294
|
+
stat16 = (0, import_node_fs64.statSync)(file);
|
|
70112
71295
|
} catch {
|
|
70113
71296
|
result.invalid++;
|
|
70114
71297
|
continue;
|
|
@@ -70138,10 +71321,10 @@ function collectSummaries(files, options = {}) {
|
|
|
70138
71321
|
}
|
|
70139
71322
|
if (dirty && options.indexFile !== void 0) {
|
|
70140
71323
|
try {
|
|
70141
|
-
(0,
|
|
71324
|
+
(0, import_node_fs64.mkdirSync)((0, import_node_path82.dirname)(options.indexFile), { recursive: true, mode: 448 });
|
|
70142
71325
|
const tmp = `${options.indexFile}.${process.pid}.tmp`;
|
|
70143
|
-
(0,
|
|
70144
|
-
(0,
|
|
71326
|
+
(0, import_node_fs64.writeFileSync)(tmp, JSON.stringify(index2), { mode: 384 });
|
|
71327
|
+
(0, import_node_fs64.renameSync)(tmp, options.indexFile);
|
|
70145
71328
|
} catch {
|
|
70146
71329
|
}
|
|
70147
71330
|
}
|
|
@@ -70427,7 +71610,7 @@ async function runSessionsSearch(argv, io) {
|
|
|
70427
71610
|
|
|
70428
71611
|
// src/cli/subcommands/sessions-trace.ts
|
|
70429
71612
|
var import_node_child_process15 = require("node:child_process");
|
|
70430
|
-
var
|
|
71613
|
+
var import_node_fs66 = require("node:fs");
|
|
70431
71614
|
var import_node_os13 = require("node:os");
|
|
70432
71615
|
var import_node_path86 = require("node:path");
|
|
70433
71616
|
init_paths();
|
|
@@ -70835,9 +72018,9 @@ function openCommand(platform, file) {
|
|
|
70835
72018
|
return { command: "xdg-open", args: [file] };
|
|
70836
72019
|
}
|
|
70837
72020
|
function spawnOpen({ command: command3, args }) {
|
|
70838
|
-
return new Promise((done,
|
|
72021
|
+
return new Promise((done, fail7) => {
|
|
70839
72022
|
const child = (0, import_node_child_process15.spawn)(command3, args, { detached: true, stdio: "ignore" });
|
|
70840
|
-
child.once("error",
|
|
72023
|
+
child.once("error", fail7);
|
|
70841
72024
|
child.once("spawn", () => {
|
|
70842
72025
|
child.unref();
|
|
70843
72026
|
done();
|
|
@@ -70866,7 +72049,7 @@ function splitHtmlFlag(argv) {
|
|
|
70866
72049
|
}
|
|
70867
72050
|
function locate(io, target, dirFlag) {
|
|
70868
72051
|
const asPath = (0, import_node_path86.resolve)(io.cwd, expandHome(target, { env: io.env }));
|
|
70869
|
-
if (/[\\/]|\.jsonl$/.test(target) && (0,
|
|
72052
|
+
if (/[\\/]|\.jsonl$/.test(target) && (0, import_node_fs66.existsSync)(asPath)) return asPath;
|
|
70870
72053
|
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
72054
|
return findSessionFileReadOnly(root, target, io.cwd);
|
|
70872
72055
|
}
|
|
@@ -70939,7 +72122,7 @@ async function runSessionsTrace(argv, io, deps = {}) {
|
|
|
70939
72122
|
io.stdout(text);
|
|
70940
72123
|
return ExitCode.Ok;
|
|
70941
72124
|
}
|
|
70942
|
-
(0,
|
|
72125
|
+
(0, import_node_fs66.writeFileSync)(outPath, text, { mode: 384 });
|
|
70943
72126
|
io.stderr(m.wrote(outPath));
|
|
70944
72127
|
if (open3) {
|
|
70945
72128
|
try {
|
|
@@ -71140,7 +72323,7 @@ function readStdinDefault() {
|
|
|
71140
72323
|
}
|
|
71141
72324
|
function stdinKindDefault() {
|
|
71142
72325
|
try {
|
|
71143
|
-
const stat16 = (0,
|
|
72326
|
+
const stat16 = (0, import_node_fs76.fstatSync)(0);
|
|
71144
72327
|
if (stat16.isFile()) return "file";
|
|
71145
72328
|
if (stat16.isFIFO()) return "fifo";
|
|
71146
72329
|
if (stat16.isSocket()) return "socket";
|
|
@@ -71200,7 +72383,7 @@ function defaultIo() {
|
|
|
71200
72383
|
}
|
|
71201
72384
|
function peekUserLanguage(env) {
|
|
71202
72385
|
try {
|
|
71203
|
-
const raw = (0,
|
|
72386
|
+
const raw = (0, import_node_fs76.readFileSync)((0, import_node_path104.join)(resolveConfigDir({ env }), "config.json"), "utf8");
|
|
71204
72387
|
const value = JSON.parse(raw).ui?.language;
|
|
71205
72388
|
return value === "auto" || value === "zh" || value === "en" ? value : void 0;
|
|
71206
72389
|
} catch {
|
|
@@ -71288,7 +72471,7 @@ function isDirectRun() {
|
|
|
71288
72471
|
const entry = process.argv[1];
|
|
71289
72472
|
if (entry === void 0) return false;
|
|
71290
72473
|
try {
|
|
71291
|
-
return (0,
|
|
72474
|
+
return (0, import_node_fs76.realpathSync)(entry) === (0, import_node_fs76.realpathSync)((0, import_node_url3.fileURLToPath)(__ama_import_meta_url));
|
|
71292
72475
|
} catch {
|
|
71293
72476
|
return false;
|
|
71294
72477
|
}
|