thincoder 0.12.62 → 0.12.63

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 (228) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/README.md +13 -12
  3. package/bin/thincoder.mjs +53 -27
  4. package/package.json +6 -5
  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 +240 -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 +59 -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 +25 -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-reindex.mjs +1 -1
  31. package/src/tui/cmd-restore.mjs +2 -2
  32. package/src/tui/cmd-session.mjs +24 -1
  33. package/src/tui/cmd-skills.mjs +1 -1
  34. package/src/tui/cmd-think.mjs +22 -9
  35. package/src/tui/config-helpers.mjs +1 -1
  36. package/src/tui/display-budget.mjs +33 -11
  37. package/src/tui/index.mjs +9 -9
  38. package/src/tui/interaction.mjs +16 -7
  39. package/src/tui/key-modes.mjs +9 -4
  40. package/src/tui/ledger-surface.mjs +26 -10
  41. package/src/tui/model-catalog.mjs +4 -4
  42. package/src/tui/model-picker.mjs +8 -7
  43. package/src/tui/mouse.mjs +11 -6
  44. package/src/tui/pickers.mjs +15 -2
  45. package/src/tui/render-conversation.mjs +1 -1
  46. package/src/tui/render-frame.mjs +10 -5
  47. package/src/tui/render-loop.mjs +1 -1
  48. package/src/tui/render-segments.mjs +3 -1
  49. package/src/tui/slash-commands.mjs +1 -1
  50. package/src/tui/startup.mjs +14 -14
  51. package/src/tui/subagent-blocks.mjs +20 -3
  52. package/src/tui/subagent-freeze.mjs +73 -2
  53. package/src/tui/suspension-drive.mjs +46 -22
  54. package/src/tui/tool-events.mjs +11 -8
  55. package/src/tui/wizard.mjs +3 -3
  56. package/src/abort-provenance.mjs +0 -116
  57. package/src/advisor/citations.mjs +0 -139
  58. package/src/advisor/compaction.mjs +0 -174
  59. package/src/advisor/convergence.mjs +0 -80
  60. package/src/advisor/history.mjs +0 -77
  61. package/src/advisor/loop.mjs +0 -293
  62. package/src/advisor/messages.mjs +0 -299
  63. package/src/advisor/project-context.mjs +0 -194
  64. package/src/advisor/repos.mjs +0 -150
  65. package/src/advisor/run.mjs +0 -293
  66. package/src/advisor/truncate.mjs +0 -57
  67. package/src/advisor.mjs +0 -290
  68. package/src/agent/completion.mjs +0 -146
  69. package/src/agent/dispatch.mjs +0 -489
  70. package/src/agent/helpers.mjs +0 -384
  71. package/src/agent/post-turn.mjs +0 -70
  72. package/src/agent/record-results.mjs +0 -174
  73. package/src/agent/relay-prefix.mjs +0 -39
  74. package/src/agent/run-stages.mjs +0 -244
  75. package/src/agent/setup-reminders.mjs +0 -69
  76. package/src/agent/setup.mjs +0 -354
  77. package/src/agent/spawn-child.mjs +0 -243
  78. package/src/agent-tools/advisor-async.mjs +0 -346
  79. package/src/agent-tools/advisor-settle.mjs +0 -231
  80. package/src/agent-tools/advisor.mjs +0 -260
  81. package/src/agent-tools/async-settle.mjs +0 -204
  82. package/src/agent-tools/batch-segment.mjs +0 -195
  83. package/src/agent-tools/consult.mjs +0 -473
  84. package/src/agent-tools/design-token.mjs +0 -117
  85. package/src/agent-tools/digest-budget.mjs +0 -76
  86. package/src/agent-tools/eng.mjs +0 -67
  87. package/src/agent-tools/escalate-async.mjs +0 -295
  88. package/src/agent-tools/goal.mjs +0 -119
  89. package/src/agent-tools/plan.mjs +0 -81
  90. package/src/agent-tools/read-history.mjs +0 -309
  91. package/src/agent-tools/recent-changes.mjs +0 -24
  92. package/src/agent-tools/review-streak.mjs +0 -93
  93. package/src/agent-tools/settings.mjs +0 -265
  94. package/src/agent-tools/skill.mjs +0 -47
  95. package/src/agent-tools/subagent-actions.mjs +0 -482
  96. package/src/agent-tools/subagent-async.mjs +0 -434
  97. package/src/agent-tools/subagent-panel.mjs +0 -160
  98. package/src/agent-tools/subagent-run.mjs +0 -205
  99. package/src/agent-tools/subagent-scheduler.mjs +0 -392
  100. package/src/agent-tools/subagent-spawn.mjs +0 -459
  101. package/src/agent-tools/subagent.mjs +0 -404
  102. package/src/agent-tools/task.mjs +0 -87
  103. package/src/agent-tools/timer.mjs +0 -46
  104. package/src/agent-tools/verify.mjs +0 -271
  105. package/src/agent-tools.mjs +0 -17
  106. package/src/agent.mjs +0 -417
  107. package/src/auto-think.mjs +0 -115
  108. package/src/config-migrate.mjs +0 -70
  109. package/src/config.mjs +0 -496
  110. package/src/context.mjs +0 -392
  111. package/src/conventions.mjs +0 -223
  112. package/src/embedding.mjs +0 -120
  113. package/src/escape.mjs +0 -152
  114. package/src/expand-home.mjs +0 -16
  115. package/src/explore-distill.mjs +0 -155
  116. package/src/generate-title.mjs +0 -88
  117. package/src/git/checkpoint.mjs +0 -448
  118. package/src/git/gitmem.mjs +0 -100
  119. package/src/hooks.mjs +0 -97
  120. package/src/ledger.mjs +0 -227
  121. package/src/log.mjs +0 -195
  122. package/src/markdown.mjs +0 -106
  123. package/src/mcp/helpers.mjs +0 -51
  124. package/src/mcp/transport-http.mjs +0 -248
  125. package/src/mcp/transport-stdio.mjs +0 -140
  126. package/src/mcp/transport-ws.mjs +0 -122
  127. package/src/mcp.mjs +0 -295
  128. package/src/memory/code-index.mjs +0 -219
  129. package/src/memory/code-sync.mjs +0 -415
  130. package/src/memory/core.mjs +0 -299
  131. package/src/memory/delete.mjs +0 -236
  132. package/src/memory/docs.mjs +0 -419
  133. package/src/memory/file-walk.mjs +0 -109
  134. package/src/memory/scan.mjs +0 -95
  135. package/src/memory/schema.mjs +0 -452
  136. package/src/memory.mjs +0 -21
  137. package/src/model-ref.mjs +0 -66
  138. package/src/model-specs.mjs +0 -179
  139. package/src/peer-domains.mjs +0 -265
  140. package/src/peer-instances.mjs +0 -231
  141. package/src/prompt-overlays.mjs +0 -82
  142. package/src/prompts/advisor-design.md +0 -41
  143. package/src/prompts/advisor-round1.md +0 -41
  144. package/src/prompts/advisor-round2.md +0 -46
  145. package/src/prompts/advisor-round3.md +0 -42
  146. package/src/prompts/common.md +0 -115
  147. package/src/prompts/consult-base.md +0 -19
  148. package/src/prompts/discipline-engineering.md +0 -258
  149. package/src/prompts/discipline-normal.md +0 -185
  150. package/src/prompts/persona-coder.md +0 -21
  151. package/src/prompts/persona-eng-coder.md +0 -37
  152. package/src/prompts/persona-eng-designer.md +0 -60
  153. package/src/prompts/persona-engineering.md +0 -55
  154. package/src/prompts/persona-explore.md +0 -15
  155. package/src/prompts/persona-normal.md +0 -27
  156. package/src/prompts/persona-plan.md +0 -26
  157. package/src/provider/anthropic.mjs +0 -225
  158. package/src/provider/core.mjs +0 -476
  159. package/src/provider/errors.mjs +0 -101
  160. package/src/provider/google.mjs +0 -257
  161. package/src/provider/index.mjs +0 -7
  162. package/src/provider/list-models.mjs +0 -93
  163. package/src/provider/normalize.mjs +0 -81
  164. package/src/provider/rate.mjs +0 -108
  165. package/src/provider/responses.mjs +0 -495
  166. package/src/provider/retry.mjs +0 -88
  167. package/src/provider/sse.mjs +0 -264
  168. package/src/proxy.mjs +0 -261
  169. package/src/rules.mjs +0 -53
  170. package/src/session-gc.mjs +0 -221
  171. package/src/session-guard.mjs +0 -59
  172. package/src/session-migrate.mjs +0 -48
  173. package/src/session-rename.mjs +0 -38
  174. package/src/session-segments.mjs +0 -100
  175. package/src/session-slots.mjs +0 -492
  176. package/src/session-store.mjs +0 -441
  177. package/src/session.mjs +0 -492
  178. package/src/skills.mjs +0 -153
  179. package/src/text-budget.mjs +0 -46
  180. package/src/token-ttl.mjs +0 -274
  181. package/src/tools/apply_patch.md +0 -15
  182. package/src/tools/bash.md +0 -37
  183. package/src/tools/bash.mjs +0 -268
  184. package/src/tools/checklist-sync.mjs +0 -181
  185. package/src/tools/checklist.md +0 -13
  186. package/src/tools/checklist.mjs +0 -299
  187. package/src/tools/delete.md +0 -13
  188. package/src/tools/edit-batch.mjs +0 -191
  189. package/src/tools/edit-diff.mjs +0 -348
  190. package/src/tools/edit.md +0 -30
  191. package/src/tools/execute.md +0 -21
  192. package/src/tools/execute.mjs +0 -228
  193. package/src/tools/fetch.md +0 -12
  194. package/src/tools/file.mjs +0 -469
  195. package/src/tools/file_ops.md +0 -17
  196. package/src/tools/get_current_time.md +0 -8
  197. package/src/tools/git-checkpoint.mjs +0 -143
  198. package/src/tools/git-ext.mjs +0 -173
  199. package/src/tools/git.md +0 -54
  200. package/src/tools/git.mjs +0 -356
  201. package/src/tools/glob-dialect.mjs +0 -130
  202. package/src/tools/glob.md +0 -11
  203. package/src/tools/grep.md +0 -19
  204. package/src/tools/hashline_edit.md +0 -14
  205. package/src/tools/index.mjs +0 -36
  206. package/src/tools/insert_after.md +0 -15
  207. package/src/tools/lint.md +0 -10
  208. package/src/tools/linter.mjs +0 -128
  209. package/src/tools/ls.md +0 -12
  210. package/src/tools/lsp.md +0 -10
  211. package/src/tools/lsp.mjs +0 -316
  212. package/src/tools/ops.mjs +0 -299
  213. package/src/tools/patch.mjs +0 -282
  214. package/src/tools/process.md +0 -10
  215. package/src/tools/question.md +0 -16
  216. package/src/tools/question.mjs +0 -26
  217. package/src/tools/read.md +0 -20
  218. package/src/tools/read_image.md +0 -8
  219. package/src/tools/repomap.mjs +0 -314
  220. package/src/tools/search.mjs +0 -236
  221. package/src/tools/shared.mjs +0 -446
  222. package/src/tools/tree.md +0 -14
  223. package/src/tools/tree.mjs +0 -66
  224. package/src/tools/wait_for.md +0 -22
  225. package/src/tools/web.mjs +0 -224
  226. package/src/tools/websearch.md +0 -16
  227. package/src/tools/write.md +0 -11
  228. 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