thincoder 0.12.62 → 0.12.64

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 (231) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/README.md +46 -49
  3. package/bin/thincoder.mjs +68 -34
  4. package/package.json +7 -6
  5. package/src/acp/bridge.mjs +35 -15
  6. package/src/acp/client-caps.mjs +86 -0
  7. package/src/acp/ext.mjs +86 -0
  8. package/src/acp/handlers-session.mjs +257 -0
  9. package/src/acp/handlers-slots.mjs +196 -0
  10. package/src/acp/login.mjs +48 -0
  11. package/src/acp/session.mjs +6 -4
  12. package/src/acp.mjs +67 -379
  13. package/src/cli/distill-command.mjs +3 -3
  14. package/src/cli/make-agent.mjs +60 -17
  15. package/src/cli/memory-command.mjs +3 -3
  16. package/src/cli/permission.mjs +4 -48
  17. package/src/cli/setup-wizard.mjs +1 -1
  18. package/src/completions.mjs +3 -1
  19. package/src/crash-reports.mjs +1 -1
  20. package/src/distill.mjs +4 -4
  21. package/src/heap-watch.mjs +1 -1
  22. package/src/prompt-injections.mjs +20 -0
  23. package/src/tui/agent-turn.mjs +40 -9
  24. package/src/tui/cmd-advisor.mjs +5 -5
  25. package/src/tui/cmd-config.mjs +8 -8
  26. package/src/tui/cmd-eng.mjs +35 -9
  27. package/src/tui/cmd-mcp.mjs +9 -8
  28. package/src/tui/cmd-model.mjs +1 -1
  29. package/src/tui/cmd-new.mjs +6 -5
  30. package/src/tui/cmd-plan.mjs +9 -0
  31. package/src/tui/cmd-reindex.mjs +1 -1
  32. package/src/tui/cmd-restore.mjs +2 -2
  33. package/src/tui/cmd-session.mjs +24 -1
  34. package/src/tui/cmd-skills.mjs +1 -1
  35. package/src/tui/cmd-think.mjs +22 -9
  36. package/src/tui/config-helpers.mjs +1 -1
  37. package/src/tui/display-budget.mjs +33 -11
  38. package/src/tui/index.mjs +18 -10
  39. package/src/tui/interaction.mjs +16 -7
  40. package/src/tui/key-modes.mjs +9 -4
  41. package/src/tui/ledger-surface.mjs +22 -59
  42. package/src/tui/model-catalog.mjs +4 -4
  43. package/src/tui/model-picker.mjs +8 -7
  44. package/src/tui/mouse.mjs +11 -6
  45. package/src/tui/pickers.mjs +15 -2
  46. package/src/tui/render-conversation.mjs +1 -1
  47. package/src/tui/render-frame.mjs +15 -6
  48. package/src/tui/render-loop.mjs +1 -1
  49. package/src/tui/render-segments.mjs +3 -1
  50. package/src/tui/slash-commands.mjs +1 -1
  51. package/src/tui/startup.mjs +14 -14
  52. package/src/tui/subagent-blocks.mjs +20 -3
  53. package/src/tui/subagent-freeze.mjs +73 -2
  54. package/src/tui/suspension-drive.mjs +57 -23
  55. package/src/tui/tool-events.mjs +11 -8
  56. package/src/tui/tui-lifecycle.mjs +9 -0
  57. package/src/tui/wizard.mjs +3 -3
  58. package/src/tui/wrapped-spawn.mjs +6 -2
  59. package/src/abort-provenance.mjs +0 -116
  60. package/src/advisor/citations.mjs +0 -139
  61. package/src/advisor/compaction.mjs +0 -174
  62. package/src/advisor/convergence.mjs +0 -80
  63. package/src/advisor/history.mjs +0 -77
  64. package/src/advisor/loop.mjs +0 -293
  65. package/src/advisor/messages.mjs +0 -299
  66. package/src/advisor/project-context.mjs +0 -194
  67. package/src/advisor/repos.mjs +0 -150
  68. package/src/advisor/run.mjs +0 -293
  69. package/src/advisor/truncate.mjs +0 -57
  70. package/src/advisor.mjs +0 -290
  71. package/src/agent/completion.mjs +0 -146
  72. package/src/agent/dispatch.mjs +0 -489
  73. package/src/agent/helpers.mjs +0 -384
  74. package/src/agent/post-turn.mjs +0 -70
  75. package/src/agent/record-results.mjs +0 -174
  76. package/src/agent/relay-prefix.mjs +0 -39
  77. package/src/agent/run-stages.mjs +0 -244
  78. package/src/agent/setup-reminders.mjs +0 -69
  79. package/src/agent/setup.mjs +0 -354
  80. package/src/agent/spawn-child.mjs +0 -243
  81. package/src/agent-tools/advisor-async.mjs +0 -346
  82. package/src/agent-tools/advisor-settle.mjs +0 -231
  83. package/src/agent-tools/advisor.mjs +0 -260
  84. package/src/agent-tools/async-settle.mjs +0 -204
  85. package/src/agent-tools/batch-segment.mjs +0 -195
  86. package/src/agent-tools/consult.mjs +0 -473
  87. package/src/agent-tools/design-token.mjs +0 -117
  88. package/src/agent-tools/digest-budget.mjs +0 -76
  89. package/src/agent-tools/eng.mjs +0 -67
  90. package/src/agent-tools/escalate-async.mjs +0 -295
  91. package/src/agent-tools/goal.mjs +0 -119
  92. package/src/agent-tools/plan.mjs +0 -81
  93. package/src/agent-tools/read-history.mjs +0 -309
  94. package/src/agent-tools/recent-changes.mjs +0 -24
  95. package/src/agent-tools/review-streak.mjs +0 -93
  96. package/src/agent-tools/settings.mjs +0 -265
  97. package/src/agent-tools/skill.mjs +0 -47
  98. package/src/agent-tools/subagent-actions.mjs +0 -482
  99. package/src/agent-tools/subagent-async.mjs +0 -434
  100. package/src/agent-tools/subagent-panel.mjs +0 -160
  101. package/src/agent-tools/subagent-run.mjs +0 -205
  102. package/src/agent-tools/subagent-scheduler.mjs +0 -392
  103. package/src/agent-tools/subagent-spawn.mjs +0 -459
  104. package/src/agent-tools/subagent.mjs +0 -404
  105. package/src/agent-tools/task.mjs +0 -87
  106. package/src/agent-tools/timer.mjs +0 -46
  107. package/src/agent-tools/verify.mjs +0 -271
  108. package/src/agent-tools.mjs +0 -17
  109. package/src/agent.mjs +0 -417
  110. package/src/auto-think.mjs +0 -115
  111. package/src/config-migrate.mjs +0 -70
  112. package/src/config.mjs +0 -496
  113. package/src/context.mjs +0 -392
  114. package/src/conventions.mjs +0 -223
  115. package/src/embedding.mjs +0 -120
  116. package/src/escape.mjs +0 -152
  117. package/src/expand-home.mjs +0 -16
  118. package/src/explore-distill.mjs +0 -155
  119. package/src/generate-title.mjs +0 -88
  120. package/src/git/checkpoint.mjs +0 -448
  121. package/src/git/gitmem.mjs +0 -100
  122. package/src/hooks.mjs +0 -97
  123. package/src/ledger.mjs +0 -227
  124. package/src/log.mjs +0 -195
  125. package/src/markdown.mjs +0 -106
  126. package/src/mcp/helpers.mjs +0 -51
  127. package/src/mcp/transport-http.mjs +0 -248
  128. package/src/mcp/transport-stdio.mjs +0 -140
  129. package/src/mcp/transport-ws.mjs +0 -122
  130. package/src/mcp.mjs +0 -295
  131. package/src/memory/code-index.mjs +0 -219
  132. package/src/memory/code-sync.mjs +0 -415
  133. package/src/memory/core.mjs +0 -299
  134. package/src/memory/delete.mjs +0 -236
  135. package/src/memory/docs.mjs +0 -419
  136. package/src/memory/file-walk.mjs +0 -109
  137. package/src/memory/scan.mjs +0 -95
  138. package/src/memory/schema.mjs +0 -452
  139. package/src/memory.mjs +0 -21
  140. package/src/model-ref.mjs +0 -66
  141. package/src/model-specs.mjs +0 -179
  142. package/src/peer-domains.mjs +0 -265
  143. package/src/peer-instances.mjs +0 -231
  144. package/src/prompt-overlays.mjs +0 -82
  145. package/src/prompts/advisor-design.md +0 -41
  146. package/src/prompts/advisor-round1.md +0 -41
  147. package/src/prompts/advisor-round2.md +0 -46
  148. package/src/prompts/advisor-round3.md +0 -42
  149. package/src/prompts/common.md +0 -115
  150. package/src/prompts/consult-base.md +0 -19
  151. package/src/prompts/discipline-engineering.md +0 -258
  152. package/src/prompts/discipline-normal.md +0 -185
  153. package/src/prompts/persona-coder.md +0 -21
  154. package/src/prompts/persona-eng-coder.md +0 -37
  155. package/src/prompts/persona-eng-designer.md +0 -60
  156. package/src/prompts/persona-engineering.md +0 -55
  157. package/src/prompts/persona-explore.md +0 -15
  158. package/src/prompts/persona-normal.md +0 -27
  159. package/src/prompts/persona-plan.md +0 -26
  160. package/src/provider/anthropic.mjs +0 -225
  161. package/src/provider/core.mjs +0 -476
  162. package/src/provider/errors.mjs +0 -101
  163. package/src/provider/google.mjs +0 -257
  164. package/src/provider/index.mjs +0 -7
  165. package/src/provider/list-models.mjs +0 -93
  166. package/src/provider/normalize.mjs +0 -81
  167. package/src/provider/rate.mjs +0 -108
  168. package/src/provider/responses.mjs +0 -495
  169. package/src/provider/retry.mjs +0 -88
  170. package/src/provider/sse.mjs +0 -264
  171. package/src/proxy.mjs +0 -261
  172. package/src/rules.mjs +0 -53
  173. package/src/session-gc.mjs +0 -221
  174. package/src/session-guard.mjs +0 -59
  175. package/src/session-migrate.mjs +0 -48
  176. package/src/session-rename.mjs +0 -38
  177. package/src/session-segments.mjs +0 -100
  178. package/src/session-slots.mjs +0 -492
  179. package/src/session-store.mjs +0 -441
  180. package/src/session.mjs +0 -492
  181. package/src/skills.mjs +0 -153
  182. package/src/text-budget.mjs +0 -46
  183. package/src/token-ttl.mjs +0 -274
  184. package/src/tools/apply_patch.md +0 -15
  185. package/src/tools/bash.md +0 -37
  186. package/src/tools/bash.mjs +0 -268
  187. package/src/tools/checklist-sync.mjs +0 -181
  188. package/src/tools/checklist.md +0 -13
  189. package/src/tools/checklist.mjs +0 -299
  190. package/src/tools/delete.md +0 -13
  191. package/src/tools/edit-batch.mjs +0 -191
  192. package/src/tools/edit-diff.mjs +0 -348
  193. package/src/tools/edit.md +0 -30
  194. package/src/tools/execute.md +0 -21
  195. package/src/tools/execute.mjs +0 -228
  196. package/src/tools/fetch.md +0 -12
  197. package/src/tools/file.mjs +0 -469
  198. package/src/tools/file_ops.md +0 -17
  199. package/src/tools/get_current_time.md +0 -8
  200. package/src/tools/git-checkpoint.mjs +0 -143
  201. package/src/tools/git-ext.mjs +0 -173
  202. package/src/tools/git.md +0 -54
  203. package/src/tools/git.mjs +0 -356
  204. package/src/tools/glob-dialect.mjs +0 -130
  205. package/src/tools/glob.md +0 -11
  206. package/src/tools/grep.md +0 -19
  207. package/src/tools/hashline_edit.md +0 -14
  208. package/src/tools/index.mjs +0 -36
  209. package/src/tools/insert_after.md +0 -15
  210. package/src/tools/lint.md +0 -10
  211. package/src/tools/linter.mjs +0 -128
  212. package/src/tools/ls.md +0 -12
  213. package/src/tools/lsp.md +0 -10
  214. package/src/tools/lsp.mjs +0 -316
  215. package/src/tools/ops.mjs +0 -299
  216. package/src/tools/patch.mjs +0 -282
  217. package/src/tools/process.md +0 -10
  218. package/src/tools/question.md +0 -16
  219. package/src/tools/question.mjs +0 -26
  220. package/src/tools/read.md +0 -20
  221. package/src/tools/read_image.md +0 -8
  222. package/src/tools/repomap.mjs +0 -314
  223. package/src/tools/search.mjs +0 -236
  224. package/src/tools/shared.mjs +0 -446
  225. package/src/tools/tree.md +0 -14
  226. package/src/tools/tree.mjs +0 -66
  227. package/src/tools/wait_for.md +0 -22
  228. package/src/tools/web.mjs +0 -224
  229. package/src/tools/websearch.md +0 -16
  230. package/src/tools/write.md +0 -11
  231. package/src/traces/trace-store.mjs +0 -355
@@ -1,228 +0,0 @@
1
- /**
2
- * tools/execute.mjs — JavaScript execution tool
3
- *
4
- * Gives the model an `execute` tool that runs JS in a child `node
5
- * --input-type=module --eval` process — NOT the in-process vm sandbox it used
6
- * to be. The vm route could not support dynamic `import()` (needs the
7
- * --experimental-vm-modules flag) or await it, which pushed every real JS run
8
- * back to `bash node -e`. A child node process gives top-level await, dynamic
9
- * `import()` of the project's own .mjs modules, native `console`/`fetch`, AND a
10
- * killable timeout (an in-process infinite loop would freeze the CLI; a child
11
- * process is killed like bash).
12
- *
13
- * The child runs PURE node ESM — no helpers are injected (exec-prelude.mjs
14
- * retired 2026-09-03, TOOLS.md §12: preloaded readFile/writeFile/glob/grep/log
15
- * helpers made execute look like a file tool, bypassing the dedicated
16
- * read/ls/glob/grep/write/edit tools). Scripts that need fs/path import the
17
- * node: modules themselves — same boundary as bash, no fake sandbox.
18
- *
19
- * Parameters:
20
- * code — JS to run inline (top-level await and import() supported). Use this OR scriptFile.
21
- * scriptFile — run a .mjs/.js file with node (self-contained, imports what it needs). Use this OR code.
22
- * nodeArgs — (scriptFile) extra node flags before the script (e.g. --test, --check); eval-like flags rejected
23
- * workdir — run in this sub-directory (no directory restriction)
24
- * filter — return only output lines matching this regex (case-insensitive)
25
- * timeoutMs — timeout (default 30s, max 600000ms)
26
- */
27
- import { spawn, execFileSync } from "node:child_process"
28
- import { resolve } from "node:path"
29
- import { DESC } from "./shared.mjs"
30
-
31
- const MAX_SCRIPT = 50_000
32
- const MAX_OUTPUT = 50_000
33
- const DEFAULT_TIMEOUT = 30_000
34
-
35
- /**
36
- * 超时错误文本——带重试引导(TOOLS.md §14.1 D14.1.2——"下一跳"):数字 = 实际生效的
37
- * timeoutMs(Math.min(t, 600_000) 或默认 30s)——上限 600000 与 schema/头注/execute.md 一致。
38
- */
39
- const timeoutErrorText = (timeoutMs) =>
40
- `Error: script timed out after ${timeoutMs}ms — retry with a larger timeoutMs (up to 600000) for long scripts, or use bash (default 120s) for shell commands`
41
-
42
- /** Resolve workdir relative to cwd — no boundary assertion
43
- * (§10.1 2026-09-02: workspace confinement removed; the child node process is
44
- * not directory-limited — same boundary as bash). */
45
- function resolveBaseDir(cwd, workdir) {
46
- if (!workdir || typeof workdir !== "string") return cwd
47
- return resolve(cwd, workdir)
48
- }
49
-
50
- /** Keep only output lines matching a regex (execute filter, case-insensitive). */
51
- function applyFilter(output, filter) {
52
- try {
53
- const re = new RegExp(filter, "i")
54
- const lines = output.split("\n").filter((l) => re.test(l))
55
- return lines.length ? lines.join("\n") : `(no output lines matched filter "${filter}")`
56
- } catch (e) {
57
- return `Error: filter regex invalid: ${e.message}`
58
- }
59
- }
60
-
61
- /** Platform-aware process tree kill — mirror of system.mjs/verify.mjs killProcessTree.
62
- * Timeout/abort must reach grandchildren: a script that spawned children keeps the
63
- * pipes open otherwise — "close" never fires and the tool stalls until the 3s kick
64
- * while the orphan keeps running (2026-09-05 advisor 🟡#4). */
65
- function killProcessTree(child) {
66
- if (process.platform === "win32") {
67
- try { execFileSync("taskkill", ["/PID", String(child.pid), "/T", "/F"], { stdio: "ignore" }) } catch {}
68
- } else {
69
- try { process.kill(-child.pid, "SIGKILL") } catch {}
70
- try { child.kill("SIGKILL") } catch {}
71
- }
72
- }
73
-
74
- /** Spawn node with the given args, capture stdout/stderr, enforce timeout/abort.
75
- * Resolves { text, ok } — ok=false on non-zero exit / timeout / abort. */
76
- function runNode(childArgs, baseDir, timeoutMs, signal) {
77
- return new Promise((resolvePromise) => {
78
- const child = spawn(process.execPath, childArgs, {
79
- cwd: baseDir,
80
- stdio: ["ignore", "pipe", "pipe"],
81
- windowsHide: true,
82
- // POSIX detached → 子进程为组首——killProcessTree 的 -pid 组杀可达孙进程(win 用
83
- // taskkill /T 不需 detached)——2026-09-05 advisor 🟡#4
84
- detached: process.platform !== "win32",
85
- // 双保险(2026-09-05——裸 spawn 无 signal 教训——system.mjs 同款):abort 时
86
- // Node 自动杀直接子进程(第一道)——onAbort 手动 kill 兜底(SIGKILL 防信号陷阱
87
- // 脚本——见 kill 注释)——AbortError 在 error 分支让路(close 必随——走 mode 收尾)
88
- ...(signal ? { signal } : {}),
89
- })
90
-
91
- let outBuf = "", errBuf = "", truncated = false, settled = false, mode = null
92
- let timer = null, kickTimer = null
93
-
94
- const settle = (text, ok) => {
95
- if (settled) return
96
- settled = true
97
- clearTimeout(timer)
98
- clearTimeout(kickTimer)
99
- if (signal) signal.removeEventListener("abort", onAbort)
100
- resolvePromise({ text, ok })
101
- }
102
- // Tree kill(SIGKILL/taskkill /T——signal-trapping 脚本躲不开 watchdog;孙进程持管道
103
- // 时直接 kill 不达——close 不触发拖到 kick——2026-09-05 advisor 🟡#4 对齐 bash/verify)
104
- const kill = () => { killProcessTree(child) }
105
- // After kill, wait for "close" (child fully reaped) before settling — settling
106
- // early races the caller deleting the cwd dir while the child still holds it.
107
- const armKick = () => { kickTimer = setTimeout(() => settle(mode === "abort" ? "(stopped)" : timeoutErrorText(timeoutMs), false), 3000) }
108
- const onAbort = () => { if (mode) return; mode = "abort"; kill(); armKick() }
109
-
110
- timer = setTimeout(() => { if (!mode) { mode = "timeout"; kill(); armKick() } }, timeoutMs)
111
-
112
- if (signal) {
113
- if (signal.aborted) onAbort()
114
- else signal.addEventListener("abort", onAbort, { once: true })
115
- }
116
-
117
- const cap = (buf, d) => {
118
- if (buf.length < MAX_OUTPUT) return buf + d
119
- if (!truncated) { truncated = true; return buf + "\n...[output truncated]" }
120
- return buf
121
- }
122
- child.stdout.on("data", (d) => { outBuf = cap(outBuf, d.toString()) })
123
- child.stderr.on("data", (d) => { errBuf = cap(errBuf, d.toString()) })
124
- child.on("error", (e) => {
125
- // signal 双保险(2026-09-05):abort 时 Node signal option 杀子进程 → 本事件以
126
- // AbortError 先触发——让路(close 必随——close 分支 mode==="abort" →
127
- // settle("(stopped)"))——不把中止误报为启动失败
128
- if (e.name === "AbortError") return
129
- settle(`Error: failed to start node: ${e.message}`, false)
130
- })
131
- child.on("close", (code) => {
132
- if (mode === "abort") return settle("(stopped)", false)
133
- if (mode === "timeout") return settle(timeoutErrorText(timeoutMs), false)
134
- const out = outBuf.trimEnd()
135
- const err = errBuf.trim()
136
- if (code === 0) {
137
- settle(out || "(no output)", true)
138
- } else {
139
- settle(err ? (out ? `${out}\n\n[stderr]:\n${err}` : err) : `${out}\n(exit code ${code})`.trim(), false)
140
- }
141
- })
142
- })
143
- }
144
-
145
- /** Validate nodeArgs (extra node flags for scriptFile mode, e.g. --test / --check). Forbids
146
- * eval-like flags that would conflict with scriptFile mode or re-open inline injection. */
147
- function validateNodeArgs(nodeArgs) {
148
- if (!nodeArgs) return []
149
- const arr = Array.isArray(nodeArgs) ? nodeArgs : String(nodeArgs).split(/\s+/).filter(Boolean)
150
- const forbidden = /^(--eval|-e|--input-type|--print|-p|--inspect|--inspect-brk)(=|$)/i
151
- for (const a of arr) {
152
- if (forbidden.test(a)) throw new Error(`nodeArgs flag not allowed: ${a}`)
153
- }
154
- return arr
155
- }
156
-
157
- export const executeTool = {
158
- name: "execute",
159
- description: DESC("execute"),
160
- parameters: {
161
- type: "object",
162
- properties: {
163
- code: {
164
- type: "string",
165
- description: "JavaScript code to execute (top-level await and dynamic import() supported). Pure node ESM — no preloaded globals; import node: modules (fs/path) yourself when needed. File reads/writes go through the dedicated read/ls/glob/grep/write/edit tools. Use this OR scriptFile.",
166
- },
167
- scriptFile: {
168
- type: "string",
169
- description: "Run a .mjs/.js file with node (self-contained — the file imports what it needs). Path relative to workdir — no directory restriction. Use this OR code. For `node <script>` / `node --test <file>` / `node --check <file>`.",
170
- },
171
- nodeArgs: {
172
- type: "array",
173
- items: { type: "string" },
174
- description: "(scriptFile) Extra node flags before the script, e.g. [\"--test\"], [\"--check\"]. Eval-like flags (--eval/--input-type/--inspect) are rejected.",
175
- },
176
- workdir: {
177
- type: "string",
178
- description: "Run in this directory (relative to cwd — no directory restriction; default cwd)",
179
- },
180
- filter: {
181
- type: "string",
182
- description: "Optional: only return output lines matching this regex (case-insensitive)",
183
- },
184
- timeoutMs: {
185
- type: "integer",
186
- minimum: 1,
187
- maximum: 600000,
188
- description: `Timeout in milliseconds (default ${DEFAULT_TIMEOUT}, max 600000)`,
189
- },
190
- },
191
- required: [],
192
- },
193
- readonly: false,
194
-
195
- async execute(args, ctx) {
196
- let baseDir
197
- try { baseDir = resolveBaseDir(ctx.cwd, args.workdir) }
198
- catch (e) { return `Error: ${e.message}` }
199
-
200
- const t = Number(args.timeoutMs)
201
- const timeoutMs = Number.isFinite(t) && t > 0 ? Math.min(t, 600_000) : DEFAULT_TIMEOUT
202
-
203
- let childArgs
204
- if (args.scriptFile) {
205
- if (args.code?.trim()) return "Error: pass code OR scriptFile, not both"
206
- // scriptFile mode: run a .mjs/.js file with node [nodeArgs...]. Self-contained —
207
- // a real node process imports what it needs. No directory restriction.
208
- const scriptAbs = resolve(baseDir, args.scriptFile)
209
- let nodeArgs
210
- try { nodeArgs = validateNodeArgs(args.nodeArgs) }
211
- catch (e) { return `Error: ${e.message}` }
212
- childArgs = [...nodeArgs, scriptAbs]
213
- } else {
214
- const code = args.code ?? ""
215
- if (!code.trim()) return "Error: either code or scriptFile is required"
216
- if (code.length > MAX_SCRIPT) {
217
- return `Error: script too large (${code.length} > ${MAX_SCRIPT} bytes). Split into smaller scripts or use individual tools.`
218
- }
219
- // inline mode: pure node ESM — no prelude, nothing injected (TOOLS.md §12).
220
- childArgs = ["--input-type=module", "--eval", code]
221
- }
222
-
223
- const { text, ok } = await runNode(childArgs, baseDir, timeoutMs, ctx.signal)
224
- // Only filter successful output — never swallow an error report behind a filter.
225
- if (!ok) return text
226
- return args.filter ? applyFilter(text, args.filter) : text
227
- },
228
- }
@@ -1,12 +0,0 @@
1
- Fetch a URL and return its content as text. HTML pages are stripped to readable text. Use after websearch to read full documents.
2
-
3
- Parameters:
4
- - url (required): http/https URL
5
- - proxy: http://host:port explicit proxy (optional) — use ONLY when passed; no proxy = direct. config.json proxy is NOT auto-applied (2026-08-31 ruling); pick per target (github/foreign sites need a proxy, gitee/domestic don't)
6
-
7
- Notes:
8
- - Follows redirects automatically
9
- - Timeout: 15 seconds
10
- - HTML pages are converted to plain text (scripts, styles, navigation stripped)
11
- - Non-HTML responses are returned as-is (truncated at ~50000 chars)
12
- - Proxy support: set `"proxy": {"uri": "http://host:port", "web": true}` in config.json or `HTTPS_PROXY` env var