reasonix 0.33.2 → 0.34.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/dashboard/dist/app.js +1 -21
  2. package/dashboard/dist/app.js.map +1 -1
  3. package/dist/cli/{chat-ZMSAXE77.js → chat-TD6GR3QK.js} +14 -13
  4. package/dist/cli/chunk-2EBODRRO.js +149 -0
  5. package/dist/cli/chunk-2EBODRRO.js.map +1 -0
  6. package/dist/cli/{chunk-DULSP7JH.js → chunk-5JXXEPDM.js} +34 -1
  7. package/dist/cli/chunk-5JXXEPDM.js.map +1 -0
  8. package/dist/cli/{chunk-OW7IHE6M.js → chunk-EINEIIIW.js} +693 -364
  9. package/dist/cli/chunk-EINEIIIW.js.map +1 -0
  10. package/dist/cli/{chunk-WVJL7ZO2.js → chunk-F3ILWP2L.js} +4 -4
  11. package/dist/cli/{chunk-SDE5U32Z.js → chunk-KZHMKOJH.js} +13 -8
  12. package/dist/cli/{chunk-SDE5U32Z.js.map → chunk-KZHMKOJH.js.map} +1 -1
  13. package/dist/cli/{chunk-G7M3QWEN.js → chunk-LNTORE5K.js} +225 -132
  14. package/dist/cli/chunk-LNTORE5K.js.map +1 -0
  15. package/dist/cli/chunk-MRLXEMZ7.js +26 -0
  16. package/dist/cli/chunk-MRLXEMZ7.js.map +1 -0
  17. package/dist/cli/{chunk-WBDE4IRI.js → chunk-OERAGRJX.js} +2 -2
  18. package/dist/cli/{chunk-QGE6AF76.js → chunk-Q36KBLSU.js} +207 -8
  19. package/dist/cli/chunk-Q36KBLSU.js.map +1 -0
  20. package/dist/cli/{chunk-RZILUXUC.js → chunk-RXGEGA7K.js} +2 -2
  21. package/dist/cli/{chunk-FXGQ5NHE.js → chunk-SA4UGZPG.js} +21 -1
  22. package/dist/cli/chunk-SA4UGZPG.js.map +1 -0
  23. package/dist/cli/{chunk-J5VLP23S.js → chunk-SW3CCXEV.js} +2 -2
  24. package/dist/cli/{chunk-W4LDFAZ6.js → chunk-SX6L4HZZ.js} +2 -2
  25. package/dist/cli/chunk-WUI3P4RA.js +319 -0
  26. package/dist/cli/chunk-WUI3P4RA.js.map +1 -0
  27. package/dist/cli/{code-R4TXQQEE.js → code-TGUOQBRJ.js} +15 -14
  28. package/dist/cli/{code-R4TXQQEE.js.map → code-TGUOQBRJ.js.map} +1 -1
  29. package/dist/cli/{commands-JWT2MWVH.js → commands-MEZPSEHV.js} +4 -3
  30. package/dist/cli/{commands-JWT2MWVH.js.map → commands-MEZPSEHV.js.map} +1 -1
  31. package/dist/cli/{commit-RPZBOZS2.js → commit-CE4EFTUQ.js} +3 -2
  32. package/dist/cli/{commit-RPZBOZS2.js.map → commit-CE4EFTUQ.js.map} +1 -1
  33. package/dist/cli/{doctor-V5HLCMSQ.js → doctor-YASM64X6.js} +7 -6
  34. package/dist/cli/index.js +22 -21
  35. package/dist/cli/index.js.map +1 -1
  36. package/dist/cli/{mcp-ARTNQ24O.js → mcp-LDFK5QJI.js} +3 -2
  37. package/dist/cli/{mcp-ARTNQ24O.js.map → mcp-LDFK5QJI.js.map} +1 -1
  38. package/dist/cli/{mcp-browse-HLO2ENDL.js → mcp-browse-FYHEITCM.js} +3 -2
  39. package/dist/cli/{mcp-browse-HLO2ENDL.js.map → mcp-browse-FYHEITCM.js.map} +1 -1
  40. package/dist/cli/{replay-Q43DSMG6.js → replay-JEDLU7F2.js} +8 -6
  41. package/dist/cli/{replay-Q43DSMG6.js.map → replay-JEDLU7F2.js.map} +1 -1
  42. package/dist/cli/{run-HK3FP266.js → run-NHD2RSTD.js} +7 -6
  43. package/dist/cli/{run-HK3FP266.js.map → run-NHD2RSTD.js.map} +1 -1
  44. package/dist/cli/{server-SYC3OVOP.js → server-MC4A4WAJ.js} +9 -8
  45. package/dist/cli/{server-SYC3OVOP.js.map → server-MC4A4WAJ.js.map} +1 -1
  46. package/dist/cli/{sessions-3XU2GGHX.js → sessions-ZHWJEW4L.js} +7 -6
  47. package/dist/cli/{sessions-3XU2GGHX.js.map → sessions-ZHWJEW4L.js.map} +1 -1
  48. package/dist/cli/{setup-CCJZAWTY.js → setup-DK43MT47.js} +6 -5
  49. package/dist/cli/{setup-CCJZAWTY.js.map → setup-DK43MT47.js.map} +1 -1
  50. package/dist/cli/{version-5SGI2SEE.js → version-O362UKPM.js} +7 -6
  51. package/dist/cli/{version-5SGI2SEE.js.map → version-O362UKPM.js.map} +1 -1
  52. package/dist/index.d.ts +45 -1
  53. package/dist/index.js +569 -27
  54. package/dist/index.js.map +1 -1
  55. package/package.json +1 -1
  56. package/dist/cli/chunk-63KAV5DX.js +0 -106
  57. package/dist/cli/chunk-63KAV5DX.js.map +0 -1
  58. package/dist/cli/chunk-DULSP7JH.js.map +0 -1
  59. package/dist/cli/chunk-FXGQ5NHE.js.map +0 -1
  60. package/dist/cli/chunk-G7M3QWEN.js.map +0 -1
  61. package/dist/cli/chunk-OW7IHE6M.js.map +0 -1
  62. package/dist/cli/chunk-QGE6AF76.js.map +0 -1
  63. package/dist/cli/chunk-ZPTSJGX5.js +0 -88
  64. package/dist/cli/chunk-ZPTSJGX5.js.map +0 -1
  65. /package/dist/cli/{chat-ZMSAXE77.js.map → chat-TD6GR3QK.js.map} +0 -0
  66. /package/dist/cli/{chunk-WVJL7ZO2.js.map → chunk-F3ILWP2L.js.map} +0 -0
  67. /package/dist/cli/{chunk-WBDE4IRI.js.map → chunk-OERAGRJX.js.map} +0 -0
  68. /package/dist/cli/{chunk-RZILUXUC.js.map → chunk-RXGEGA7K.js.map} +0 -0
  69. /package/dist/cli/{chunk-J5VLP23S.js.map → chunk-SW3CCXEV.js.map} +0 -0
  70. /package/dist/cli/{chunk-W4LDFAZ6.js.map → chunk-SX6L4HZZ.js.map} +0 -0
  71. /package/dist/cli/{doctor-V5HLCMSQ.js.map → doctor-YASM64X6.js.map} +0 -0
@@ -13,7 +13,7 @@ import {
13
13
  } from "./chunk-KMWKGPFZ.js";
14
14
  import {
15
15
  pauseGate
16
- } from "./chunk-W4LDFAZ6.js";
16
+ } from "./chunk-SX6L4HZZ.js";
17
17
  import {
18
18
  ESCALATION_CONTRACT,
19
19
  NEGATIVE_CLAIM_RULE,
@@ -22,7 +22,7 @@ import {
22
22
  import {
23
23
  formatHookOutcomeMessage,
24
24
  runHooks
25
- } from "./chunk-WBDE4IRI.js";
25
+ } from "./chunk-OERAGRJX.js";
26
26
  import {
27
27
  ignoredByLayers,
28
28
  loadGitignoreAt,
@@ -36,12 +36,12 @@ import {
36
36
  } from "./chunk-DFP4YSVM.js";
37
37
  import {
38
38
  t
39
- } from "./chunk-QGE6AF76.js";
39
+ } from "./chunk-Q36KBLSU.js";
40
40
  import {
41
41
  DEFAULT_INDEX_EXCLUDES,
42
42
  webSearchEndpoint,
43
43
  webSearchEngine
44
- } from "./chunk-DULSP7JH.js";
44
+ } from "./chunk-5JXXEPDM.js";
45
45
  import {
46
46
  DEEPSEEK_CONTEXT_TOKENS,
47
47
  DEFAULT_CONTEXT_TOKENS,
@@ -3839,6 +3839,112 @@ ${i + 1}. ${r.title}`);
3839
3839
  import { existsSync, readFileSync, readdirSync, statSync } from "fs";
3840
3840
  import { readdir, stat } from "fs/promises";
3841
3841
  import { isAbsolute as isAbsolute2, join as join4, relative as relative5, resolve as resolve2 } from "path";
3842
+
3843
+ // src/at-mentions-url.ts
3844
+ var AT_URL_PATTERN = /(?<=^|\s)@(https?:\/\/\S+)/g;
3845
+ var DEFAULT_AT_URL_MAX_CHARS = 32e3;
3846
+ async function expandAtUrls(text, opts = {}) {
3847
+ const maxChars = opts.maxChars ?? DEFAULT_AT_URL_MAX_CHARS;
3848
+ const fetcher = opts.fetcher;
3849
+ if (!fetcher) {
3850
+ throw new Error("expandAtUrls: fetcher option is required (wire src/tools/web.ts:webFetch)");
3851
+ }
3852
+ const seen = /* @__PURE__ */ new Map();
3853
+ const bodies = /* @__PURE__ */ new Map();
3854
+ const order = [];
3855
+ for (const match of text.matchAll(AT_URL_PATTERN)) {
3856
+ const rawUrl = match[1] ?? "";
3857
+ const url = stripUrlTail(rawUrl);
3858
+ if (!url) continue;
3859
+ if (seen.has(url)) continue;
3860
+ const cached = opts.cache?.get(url);
3861
+ if (cached) {
3862
+ seen.set(url, cached);
3863
+ if (cached.body) bodies.set(url, cached.body);
3864
+ order.push(url);
3865
+ continue;
3866
+ }
3867
+ let expansion;
3868
+ let body = "";
3869
+ try {
3870
+ const page = await fetcher(url, {
3871
+ maxChars,
3872
+ timeoutMs: opts.timeoutMs,
3873
+ signal: opts.signal
3874
+ });
3875
+ body = page.text;
3876
+ expansion = {
3877
+ token: `@${url}`,
3878
+ url,
3879
+ ok: true,
3880
+ title: page.title,
3881
+ chars: body.length,
3882
+ truncated: page.truncated
3883
+ };
3884
+ } catch (err) {
3885
+ const message = err.message ?? String(err);
3886
+ let skip = "fetch-error";
3887
+ if (/aborted|timeout/i.test(message)) skip = "timeout";
3888
+ else if (/40\d|forbidden|access denied|captcha/i.test(message)) skip = "blocked";
3889
+ expansion = {
3890
+ token: `@${url}`,
3891
+ url,
3892
+ ok: false,
3893
+ skip,
3894
+ error: message
3895
+ };
3896
+ }
3897
+ seen.set(url, expansion);
3898
+ if (body) bodies.set(url, body);
3899
+ if (opts.cache) opts.cache.set(url, { ...expansion, body });
3900
+ order.push(url);
3901
+ }
3902
+ if (seen.size === 0) return { text, expansions: [] };
3903
+ const expansions = order.map((u) => seen.get(u)).filter(Boolean);
3904
+ const blocks = [];
3905
+ for (const ex of expansions) {
3906
+ if (ex.ok) {
3907
+ const titleAttr = ex.title ? ` title="${escapeAttr(ex.title)}"` : "";
3908
+ const truncTag = ex.truncated ? ' truncated="true"' : "";
3909
+ const body = bodies.get(ex.url) ?? "";
3910
+ blocks.push(`<url href="${ex.url}"${titleAttr}${truncTag}>
3911
+ ${body}
3912
+ </url>`);
3913
+ } else {
3914
+ const reasonAttr = ex.skip ?? "fetch-error";
3915
+ blocks.push(`<url href="${ex.url}" skipped="${reasonAttr}" />`);
3916
+ }
3917
+ }
3918
+ const augmented = `${text}
3919
+
3920
+ [Referenced URLs]
3921
+ ${blocks.join("\n\n")}`;
3922
+ return { text: augmented, expansions };
3923
+ }
3924
+ function stripUrlTail(raw) {
3925
+ let s = raw;
3926
+ while (s.length > 0) {
3927
+ const last = s[s.length - 1];
3928
+ if (".,;:!?".includes(last)) {
3929
+ s = s.slice(0, -1);
3930
+ continue;
3931
+ }
3932
+ if (")]}>".includes(last)) {
3933
+ const open = { ")": "(", "]": "[", "}": "{", ">": "<" }[last];
3934
+ if (!s.includes(open)) {
3935
+ s = s.slice(0, -1);
3936
+ continue;
3937
+ }
3938
+ }
3939
+ break;
3940
+ }
3941
+ return s;
3942
+ }
3943
+ function escapeAttr(s) {
3944
+ return s.replace(/"/g, "&quot;").replace(/[\r\n]+/g, " ").trim();
3945
+ }
3946
+
3947
+ // src/at-mentions.ts
3842
3948
  var DEFAULT_AT_MENTION_MAX_BYTES = 64 * 1024;
3843
3949
  var DEFAULT_AT_DIR_MAX_ENTRIES = 200;
3844
3950
  var DEFAULT_PICKER_IGNORE_DIRS = [
@@ -3912,14 +4018,30 @@ function listFilesWithStatsSync(root, opts = {}) {
3912
4018
  walk2(rootAbs, "", []);
3913
4019
  return out;
3914
4020
  }
3915
- async function listFilesWithStatsAsync(root, opts = {}) {
3916
- const maxResults = Math.max(1, opts.maxResults ?? 2e3);
4021
+ async function walkFilesStream(root, opts) {
3917
4022
  const ignoreDirs = new Set(opts.ignoreDirs ?? DEFAULT_PICKER_IGNORE_DIRS);
3918
- const rootAbs = resolve2(root);
3919
4023
  const respectGi = opts.respectGitignore !== false;
3920
- const out = [];
4024
+ const rootAbs = resolve2(root);
4025
+ const progressGap = Math.max(0, opts.progressIntervalMs ?? 100);
4026
+ let scanned = 0;
4027
+ let halted = false;
4028
+ let lastProgress = 0;
4029
+ const reportProgress = (force) => {
4030
+ if (!opts.onProgress) return;
4031
+ const now = Date.now();
4032
+ if (force || now - lastProgress >= progressGap) {
4033
+ lastProgress = now;
4034
+ opts.onProgress(scanned);
4035
+ }
4036
+ };
4037
+ const emit = (entry) => {
4038
+ scanned++;
4039
+ if (halted) return;
4040
+ if (opts.onEntry(entry) === false) halted = true;
4041
+ reportProgress(false);
4042
+ };
3921
4043
  const walk2 = async (dirAbs, dirRel, layers) => {
3922
- if (out.length >= maxResults) return;
4044
+ if (halted || opts.signal?.aborted) return;
3923
4045
  let effectiveLayers = layers;
3924
4046
  if (respectGi) {
3925
4047
  const ig = await loadGitignoreAt(dirAbs);
@@ -3934,36 +4056,31 @@ async function listFilesWithStatsAsync(root, opts = {}) {
3934
4056
  entries.sort((a, b) => a.name.localeCompare(b.name));
3935
4057
  const fileEnts = [];
3936
4058
  for (const ent of entries) {
3937
- if (out.length >= maxResults) break;
3938
- const relPath = dirRel ? `${dirRel}/${ent.name}` : ent.name;
4059
+ if (halted || opts.signal?.aborted) break;
3939
4060
  const absPath = join4(dirAbs, ent.name);
3940
4061
  if (ent.isDirectory()) {
3941
4062
  if (ent.name.startsWith(".") || ignoreDirs.has(ent.name)) continue;
3942
4063
  if (ignoredByLayers(effectiveLayers, absPath, true)) continue;
3943
4064
  if (fileEnts.length > 0) {
3944
- await statBatch(fileEnts, dirAbs, dirRel, out, maxResults, effectiveLayers);
4065
+ await flushFiles(fileEnts, dirAbs, dirRel, effectiveLayers, emit);
3945
4066
  fileEnts.length = 0;
3946
- if (out.length >= maxResults) return;
4067
+ if (halted || opts.signal?.aborted) return;
3947
4068
  }
3948
- await walk2(absPath, relPath, effectiveLayers);
4069
+ await walk2(absPath, dirRel ? `${dirRel}/${ent.name}` : ent.name, effectiveLayers);
3949
4070
  } else if (ent.isFile() || ent.isSymbolicLink()) {
3950
4071
  fileEnts.push(ent);
3951
4072
  }
3952
4073
  }
3953
- if (fileEnts.length > 0 && out.length < maxResults) {
3954
- await statBatch(fileEnts, dirAbs, dirRel, out, maxResults, effectiveLayers);
4074
+ if (fileEnts.length > 0 && !halted && !opts.signal?.aborted) {
4075
+ await flushFiles(fileEnts, dirAbs, dirRel, effectiveLayers, emit);
3955
4076
  }
3956
4077
  };
3957
4078
  await walk2(rootAbs, "", []);
3958
- return out;
4079
+ reportProgress(true);
4080
+ return { scanned, cancelled: !!opts.signal?.aborted };
3959
4081
  }
3960
- async function statBatch(ents, dirAbs, dirRel, out, maxResults, layers) {
3961
- const accepted = [];
3962
- for (const e of ents) {
3963
- if (out.length + accepted.length >= maxResults) break;
3964
- if (ignoredByLayers(layers, join4(dirAbs, e.name), false)) continue;
3965
- accepted.push(e);
3966
- }
4082
+ async function flushFiles(ents, dirAbs, dirRel, layers, emit) {
4083
+ const accepted = ents.filter((e) => !ignoredByLayers(layers, join4(dirAbs, e.name), false));
3967
4084
  const stats = await Promise.all(
3968
4085
  accepted.map(
3969
4086
  (e) => stat(join4(dirAbs, e.name)).then((s) => ({ mtimeMs: s.mtimeMs, isFile: s.isFile() })).catch(() => null)
@@ -3972,14 +4089,90 @@ async function statBatch(ents, dirAbs, dirRel, out, maxResults, layers) {
3972
4089
  for (let i = 0; i < accepted.length; i++) {
3973
4090
  const ent = accepted[i];
3974
4091
  const s = stats[i];
3975
- if (ent.isSymbolicLink()) {
3976
- if (!s || !s.isFile) continue;
4092
+ if (ent.isSymbolicLink() && (!s || !s.isFile)) continue;
4093
+ emit({
4094
+ path: dirRel ? `${dirRel}/${ent.name}` : ent.name,
4095
+ mtimeMs: s?.mtimeMs ?? 0
4096
+ });
4097
+ }
4098
+ }
4099
+ async function listDirectory(root, relDir, opts = {}) {
4100
+ const ignoreDirs = new Set(opts.ignoreDirs ?? DEFAULT_PICKER_IGNORE_DIRS);
4101
+ const respectGi = opts.respectGitignore !== false;
4102
+ const rootAbs = resolve2(root);
4103
+ const dirAbs = resolve2(rootAbs, relDir);
4104
+ const rel = relative5(rootAbs, dirAbs);
4105
+ if (rel.startsWith("..") || isAbsolute2(rel)) return [];
4106
+ const layers = [];
4107
+ if (respectGi) {
4108
+ const segs = rel ? rel.split(/[\\/]/) : [];
4109
+ let cursor = rootAbs;
4110
+ const ig = await loadGitignoreAt(cursor);
4111
+ if (ig) layers.push({ dirAbs: cursor, ig });
4112
+ for (const seg of segs) {
4113
+ cursor = join4(cursor, seg);
4114
+ const igSeg = await loadGitignoreAt(cursor);
4115
+ if (igSeg) layers.push({ dirAbs: cursor, ig: igSeg });
4116
+ }
4117
+ }
4118
+ let raw;
4119
+ try {
4120
+ raw = await readdir(dirAbs, { withFileTypes: true });
4121
+ } catch {
4122
+ return [];
4123
+ }
4124
+ const dirRel = rel.split(/[\\/]/).join("/");
4125
+ const dirs = [];
4126
+ const files = [];
4127
+ for (const ent of raw) {
4128
+ const absPath = join4(dirAbs, ent.name);
4129
+ if (ent.isDirectory()) {
4130
+ if (ent.name.startsWith(".") || ignoreDirs.has(ent.name)) continue;
4131
+ if (ignoredByLayers(layers, absPath, true)) continue;
4132
+ dirs.push({
4133
+ name: ent.name,
4134
+ path: dirRel ? `${dirRel}/${ent.name}` : ent.name,
4135
+ isDir: true,
4136
+ mtimeMs: 0
4137
+ });
4138
+ } else if (ent.isFile() || ent.isSymbolicLink()) {
4139
+ if (ignoredByLayers(layers, absPath, false)) continue;
4140
+ files.push(ent);
3977
4141
  }
3978
- out.push({
4142
+ }
4143
+ const stats = await Promise.all(
4144
+ files.map(
4145
+ (e) => stat(join4(dirAbs, e.name)).then((s) => ({ mtimeMs: s.mtimeMs, isFile: s.isFile() })).catch(() => null)
4146
+ )
4147
+ );
4148
+ const fileEntries = [];
4149
+ for (let i = 0; i < files.length; i++) {
4150
+ const ent = files[i];
4151
+ const s = stats[i];
4152
+ if (ent.isSymbolicLink() && (!s || !s.isFile)) continue;
4153
+ fileEntries.push({
4154
+ name: ent.name,
3979
4155
  path: dirRel ? `${dirRel}/${ent.name}` : ent.name,
4156
+ isDir: false,
3980
4157
  mtimeMs: s?.mtimeMs ?? 0
3981
4158
  });
3982
4159
  }
4160
+ dirs.sort((a, b) => a.name.localeCompare(b.name));
4161
+ fileEntries.sort((a, b) => a.name.localeCompare(b.name));
4162
+ return [...dirs, ...fileEntries];
4163
+ }
4164
+ function parseAtQuery(query) {
4165
+ const normalized = query.replace(/\\/g, "/");
4166
+ const trailingSlash = normalized.endsWith("/");
4167
+ const trimmed = trailingSlash ? normalized.slice(0, -1) : normalized;
4168
+ const lastSlash = trimmed.lastIndexOf("/");
4169
+ if (trailingSlash) return { dir: trimmed, filter: "", trailingSlash: true };
4170
+ if (lastSlash < 0) return { dir: "", filter: trimmed, trailingSlash: false };
4171
+ return {
4172
+ dir: trimmed.slice(0, lastSlash),
4173
+ filter: trimmed.slice(lastSlash + 1),
4174
+ trailingSlash: false
4175
+ };
3983
4176
  }
3984
4177
  var AT_PICKER_PREFIX = /(?:^|\s)@([a-zA-Z0-9_./\\-]*)$/;
3985
4178
  function detectAtPicker(input) {
@@ -4192,108 +4385,6 @@ var defaultFs = {
4192
4385
  },
4193
4386
  read: (p) => readFileSync(p, "utf8")
4194
4387
  };
4195
- var AT_URL_PATTERN = /(?<=^|\s)@(https?:\/\/\S+)/g;
4196
- var DEFAULT_AT_URL_MAX_CHARS = 32e3;
4197
- async function expandAtUrls(text, opts = {}) {
4198
- const maxChars = opts.maxChars ?? DEFAULT_AT_URL_MAX_CHARS;
4199
- const fetcher = opts.fetcher;
4200
- if (!fetcher) {
4201
- throw new Error("expandAtUrls: fetcher option is required (wire src/tools/web.ts:webFetch)");
4202
- }
4203
- const seen = /* @__PURE__ */ new Map();
4204
- const bodies = /* @__PURE__ */ new Map();
4205
- const order = [];
4206
- for (const match of text.matchAll(AT_URL_PATTERN)) {
4207
- const rawUrl = match[1] ?? "";
4208
- const url = stripUrlTail(rawUrl);
4209
- if (!url) continue;
4210
- if (seen.has(url)) continue;
4211
- const cached = opts.cache?.get(url);
4212
- if (cached) {
4213
- seen.set(url, cached);
4214
- if (cached.body) bodies.set(url, cached.body);
4215
- order.push(url);
4216
- continue;
4217
- }
4218
- let expansion;
4219
- let body = "";
4220
- try {
4221
- const page = await fetcher(url, {
4222
- maxChars,
4223
- timeoutMs: opts.timeoutMs,
4224
- signal: opts.signal
4225
- });
4226
- body = page.text;
4227
- expansion = {
4228
- token: `@${url}`,
4229
- url,
4230
- ok: true,
4231
- title: page.title,
4232
- chars: body.length,
4233
- truncated: page.truncated
4234
- };
4235
- } catch (err) {
4236
- const message = err.message ?? String(err);
4237
- let skip = "fetch-error";
4238
- if (/aborted|timeout/i.test(message)) skip = "timeout";
4239
- else if (/40\d|forbidden|access denied|captcha/i.test(message)) skip = "blocked";
4240
- expansion = {
4241
- token: `@${url}`,
4242
- url,
4243
- ok: false,
4244
- skip,
4245
- error: message
4246
- };
4247
- }
4248
- seen.set(url, expansion);
4249
- if (body) bodies.set(url, body);
4250
- if (opts.cache) opts.cache.set(url, { ...expansion, body });
4251
- order.push(url);
4252
- }
4253
- if (seen.size === 0) return { text, expansions: [] };
4254
- const expansions = order.map((u) => seen.get(u)).filter(Boolean);
4255
- const blocks = [];
4256
- for (const ex of expansions) {
4257
- if (ex.ok) {
4258
- const titleAttr = ex.title ? ` title="${escapeAttr(ex.title)}"` : "";
4259
- const truncTag = ex.truncated ? ' truncated="true"' : "";
4260
- const body = bodies.get(ex.url) ?? "";
4261
- blocks.push(`<url href="${ex.url}"${titleAttr}${truncTag}>
4262
- ${body}
4263
- </url>`);
4264
- } else {
4265
- const reasonAttr = ex.skip ?? "fetch-error";
4266
- blocks.push(`<url href="${ex.url}" skipped="${reasonAttr}" />`);
4267
- }
4268
- }
4269
- const augmented = `${text}
4270
-
4271
- [Referenced URLs]
4272
- ${blocks.join("\n\n")}`;
4273
- return { text: augmented, expansions };
4274
- }
4275
- function stripUrlTail(raw) {
4276
- let s = raw;
4277
- while (s.length > 0) {
4278
- const last = s[s.length - 1];
4279
- if (".,;:!?".includes(last)) {
4280
- s = s.slice(0, -1);
4281
- continue;
4282
- }
4283
- if (")]}>".includes(last)) {
4284
- const open = { ")": "(", "]": "[", "}": "{", ">": "<" }[last];
4285
- if (!s.includes(open)) {
4286
- s = s.slice(0, -1);
4287
- continue;
4288
- }
4289
- }
4290
- break;
4291
- }
4292
- return s;
4293
- }
4294
- function escapeAttr(s) {
4295
- return s.replace(/"/g, "&quot;").replace(/[\r\n]+/g, " ").trim();
4296
- }
4297
4388
 
4298
4389
  // src/tools/subagent-types.ts
4299
4390
  var EXPLORE_SYSTEM = `You are an exploration subagent. Wide-net read-only investigation; return one distilled answer.
@@ -4777,11 +4868,13 @@ export {
4777
4868
  bridgeMcpTools,
4778
4869
  ImmutablePrefix,
4779
4870
  CacheFirstLoop,
4780
- listFilesWithStatsAsync,
4871
+ expandAtUrls,
4872
+ walkFilesStream,
4873
+ listDirectory,
4874
+ parseAtQuery,
4781
4875
  detectAtPicker,
4782
4876
  rankPickerCandidates,
4783
4877
  expandAtMentions,
4784
- expandAtUrls,
4785
4878
  registerFilesystemTools,
4786
4879
  registerMemoryTools,
4787
4880
  registerChoiceTool,
@@ -4797,4 +4890,4 @@ export {
4797
4890
  snapshotBeforeEdits,
4798
4891
  restoreSnapshots
4799
4892
  };
4800
- //# sourceMappingURL=chunk-G7M3QWEN.js.map
4893
+ //# sourceMappingURL=chunk-LNTORE5K.js.map