@selesai/code 0.13.3 → 0.13.5

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 (511) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/dist/cli/credential-print.js +4 -4
  3. package/dist/cli.js +0 -0
  4. package/dist/core/compaction/utils.js +2 -2
  5. package/dist/core/export-html/template.css +1066 -1066
  6. package/dist/core/export-html/template.html +55 -55
  7. package/dist/core/export-html/template.js +1864 -1864
  8. package/dist/core/export-html/vendor/highlight.min.js +1212 -1212
  9. package/dist/core/export-html/vendor/marked.min.js +78 -78
  10. package/dist/core/messages.js +7 -7
  11. package/dist/defaults/models.json +17 -1
  12. package/dist/extensions/context-compaction-reminder.test.ts +82 -82
  13. package/dist/extensions/context-compaction-reminder.ts +28 -28
  14. package/dist/extensions/cost-reconcile.test.ts +24 -5
  15. package/dist/extensions/cost-reconcile.ts +14 -7
  16. package/dist/extensions/pi-hermes-memory/scripts/check-min-sdk.mjs +0 -0
  17. package/dist/extensions/pi-hermes-memory/tests/run-all.sh +0 -0
  18. package/dist/extensions/pi-intercom/CHANGELOG.md +13 -0
  19. package/dist/extensions/pi-intercom/LICENSE +21 -21
  20. package/dist/extensions/pi-intercom/README.md +4 -5
  21. package/dist/extensions/pi-intercom/broker/client.test.ts +83 -83
  22. package/dist/extensions/pi-intercom/broker/framing.test.ts +114 -114
  23. package/dist/extensions/pi-intercom/broker/paths.ts +134 -134
  24. package/dist/extensions/pi-intercom/broker/runtime-claim.test.ts +34 -34
  25. package/dist/extensions/pi-intercom/broker/runtime-claim.ts +21 -21
  26. package/dist/extensions/pi-intercom/config.test.ts +3 -31
  27. package/dist/extensions/pi-intercom/config.ts +0 -15
  28. package/dist/extensions/pi-intercom/cwd.test.ts +40 -40
  29. package/dist/extensions/pi-intercom/cwd.ts +31 -31
  30. package/dist/extensions/pi-intercom/format-context.test.ts +31 -31
  31. package/dist/extensions/pi-intercom/format-context.ts +32 -32
  32. package/dist/extensions/pi-intercom/index.ts +9 -46
  33. package/dist/extensions/pi-intercom/intercom.integration.test.ts +49 -57
  34. package/dist/extensions/pi-intercom/package.json +1 -1
  35. package/dist/extensions/pi-intercom/reply-tracker.test.ts +20 -0
  36. package/dist/extensions/pi-intercom/reply-tracker.ts +8 -0
  37. package/dist/extensions/pi-intercom/test/overlay-width.test.ts +66 -66
  38. package/dist/extensions/pi-intercom/ui/compose.ts +143 -143
  39. package/dist/extensions/pi-intercom/ui/session-list.ts +166 -166
  40. package/dist/extensions/pi-subagents/CHANGELOG.md +27 -0
  41. package/dist/extensions/pi-subagents/docs/tool-reference.md +4 -1
  42. package/dist/extensions/pi-subagents/docs/workflows.md +2 -2
  43. package/dist/extensions/pi-subagents/install.mjs +0 -0
  44. package/dist/extensions/pi-subagents/package-lock.json +2 -2
  45. package/dist/extensions/pi-subagents/package.json +1 -1
  46. package/dist/extensions/pi-subagents/skills/council-mode/SKILL.md +48 -243
  47. package/dist/extensions/pi-subagents/skills/council-mode/references/pass-contracts.md +150 -0
  48. package/dist/extensions/pi-subagents/skills/pi-subagents/SKILL.md +87 -37
  49. package/dist/extensions/pi-subagents/skills/pi-subagents/references/constraints-and-recipes.md +29 -233
  50. package/dist/extensions/pi-subagents/skills/pi-subagents/references/execution-controls.md +49 -8
  51. package/dist/extensions/pi-subagents/skills/pi-subagents/references/management-authoring-rpc.md +2 -2
  52. package/dist/extensions/pi-subagents/skills/pi-subagents/references/multi-lane-orchestration.md +13 -1
  53. package/dist/extensions/pi-subagents/skills/pi-subagents/references/prompting-and-roles.md +34 -27
  54. package/dist/extensions/pi-subagents/skills/pi-subagents/references/review-and-validation.md +73 -0
  55. package/dist/extensions/pi-subagents/src/agents/agent-management.ts +157 -28
  56. package/dist/extensions/pi-subagents/src/api/shared-types.ts +2 -0
  57. package/dist/extensions/pi-subagents/src/extension/public-execution.ts +1 -0
  58. package/dist/extensions/pi-subagents/src/extension/schemas.ts +1 -0
  59. package/dist/extensions/pi-subagents/src/extension/tool-description.ts +4 -1
  60. package/dist/extensions/pi-subagents/src/runs/background/async-execution.ts +2 -2
  61. package/dist/extensions/pi-subagents/src/runs/background/async-job-tracker.ts +3 -0
  62. package/dist/extensions/pi-subagents/src/runs/background/async-status.ts +45 -2
  63. package/dist/extensions/pi-subagents/src/runs/background/control-channel.ts +3 -2
  64. package/dist/extensions/pi-subagents/src/runs/background/run-status.ts +13 -2
  65. package/dist/extensions/pi-subagents/src/runs/background/subagent-runner.ts +5 -1
  66. package/dist/extensions/pi-subagents/src/runs/background/subagent-wait.ts +10 -2
  67. package/dist/extensions/pi-subagents/src/runs/background/wait-completions.ts +3 -0
  68. package/dist/extensions/pi-subagents/src/runs/foreground/execution.ts +11 -2
  69. package/dist/extensions/pi-subagents/src/runs/foreground/subagent-executor.ts +98 -1
  70. package/dist/extensions/pi-subagents/src/runs/shared/async-status-projection.ts +138 -4
  71. package/dist/extensions/pi-subagents/src/runs/shared/background-process-options.ts +9 -0
  72. package/dist/extensions/pi-subagents/src/runs/shared/mcp-direct-tool-grant.ts +2 -5
  73. package/dist/extensions/pi-subagents/src/runs/shared/mutation-evidence.ts +52 -3
  74. package/dist/extensions/pi-subagents/src/runs/shared/pi-args.ts +47 -1
  75. package/dist/extensions/pi-subagents/src/runs/shared/single-output.ts +45 -18
  76. package/dist/extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.ts +21 -2
  77. package/dist/extensions/pi-subagents/src/runs/shared/workflow-graph.ts +15 -0
  78. package/dist/extensions/pi-subagents/src/shared/types.ts +34 -1
  79. package/dist/extensions/pi-subagents/src/tui/fleet-status.ts +11 -3
  80. package/dist/extensions/pi-subagents/src/tui/render-helpers.ts +31 -0
  81. package/dist/extensions/pi-subagents/src/tui/render.ts +597 -112
  82. package/dist/extensions/pi-subagents/src/watchdog/change-signature.ts +40 -1
  83. package/dist/extensions/pi-subagents/src/workflows/host-command.ts +6 -1
  84. package/dist/extensions/pi-subagents/src/workflows/scripted-workflow.ts +53 -2
  85. package/dist/extensions/pi-subagents/test/integration/async-execution.test.ts +55 -6
  86. package/dist/extensions/pi-subagents/test/integration/async-status.test.ts +111 -1
  87. package/dist/extensions/pi-subagents/test/integration/render-fork-badge.test.ts +206 -38
  88. package/dist/extensions/pi-subagents/test/integration/render-widget.test.ts +522 -31
  89. package/dist/extensions/pi-subagents/test/integration/single-execution.test.ts +123 -0
  90. package/dist/extensions/pi-subagents/test/unit/agent-management.test.ts +48 -0
  91. package/dist/extensions/pi-subagents/test/unit/async-status-projection.test.ts +57 -1
  92. package/dist/extensions/pi-subagents/test/unit/background-process-options.test.ts +17 -0
  93. package/dist/extensions/pi-subagents/test/unit/external-cli-runner.test.ts +1 -1
  94. package/dist/extensions/pi-subagents/test/unit/fleet-status.test.ts +44 -4
  95. package/dist/extensions/pi-subagents/test/unit/fork-cache-key.test.ts +91 -0
  96. package/dist/extensions/pi-subagents/test/unit/host-command.test.ts +1 -0
  97. package/dist/extensions/pi-subagents/test/unit/index-child-registration.test.ts +0 -1
  98. package/dist/extensions/pi-subagents/test/unit/mcp-direct-tool-grant.test.ts +20 -3
  99. package/dist/extensions/pi-subagents/test/unit/mutation-evidence.test.ts +27 -0
  100. package/dist/extensions/pi-subagents/test/unit/pi-args.test.ts +93 -17
  101. package/dist/extensions/pi-subagents/test/unit/public-execution.test.ts +1 -0
  102. package/dist/extensions/pi-subagents/test/unit/render-helpers.test.ts +103 -26
  103. package/dist/extensions/pi-subagents/test/unit/run-status.test.ts +58 -0
  104. package/dist/extensions/pi-subagents/test/unit/schemas.test.ts +22 -2
  105. package/dist/extensions/pi-subagents/test/unit/scripted-workflow.test.ts +21 -0
  106. package/dist/extensions/pi-subagents/test/unit/single-output.test.ts +13 -0
  107. package/dist/extensions/pi-subagents/test/unit/subagent-wait.test.ts +54 -0
  108. package/dist/extensions/pi-subagents/test/unit/tool-description.test.ts +2 -0
  109. package/dist/extensions/pi-subagents/test/unit/wait-completions.test.ts +32 -0
  110. package/dist/extensions/pi-subagents/test/unit/watchdog-change-signature.test.ts +48 -1
  111. package/dist/extensions/pi-subagents/test/unit/widget-nested-render.test.ts +21 -6
  112. package/dist/extensions/pi-subagents/test/unit/windows-hide-spawn.test.ts +11 -0
  113. package/dist/extensions/pi-web-agent/CHANGELOG.md +410 -0
  114. package/dist/extensions/pi-web-agent/README.md +131 -0
  115. package/dist/extensions/pi-web-agent/package.json +4 -2
  116. package/dist/extensions/pi-web-agent/src/backends/config.ts +62 -5
  117. package/dist/extensions/pi-web-agent/src/backends/doctor.ts +136 -0
  118. package/dist/extensions/pi-web-agent/src/backends/factory.ts +96 -6
  119. package/dist/extensions/pi-web-agent/src/backends/settings-reader.ts +25 -25
  120. package/dist/extensions/pi-web-agent/src/cache/ttl-cache.ts +28 -28
  121. package/dist/extensions/pi-web-agent/src/changelog-notice.ts +136 -136
  122. package/dist/extensions/pi-web-agent/src/commands/web-agent-config.ts +183 -47
  123. package/dist/extensions/pi-web-agent/src/extension.ts +62 -25
  124. package/dist/extensions/pi-web-agent/src/extract/readability.ts +19 -11
  125. package/dist/extensions/pi-web-agent/src/fetch/browser-resolution.ts +199 -199
  126. package/dist/extensions/pi-web-agent/src/fetch/firecrawl-fetch.ts +100 -100
  127. package/dist/extensions/pi-web-agent/src/fetch/headless-fetch.ts +117 -117
  128. package/dist/extensions/pi-web-agent/src/fetch/http-fetch.ts +67 -67
  129. package/dist/extensions/pi-web-agent/src/orchestration/answer-synthesizer.ts +60 -60
  130. package/dist/extensions/pi-web-agent/src/orchestration/candidate-selector.ts +5 -4
  131. package/dist/extensions/pi-web-agent/src/orchestration/direct-url.ts +2 -25
  132. package/dist/extensions/pi-web-agent/src/orchestration/evidence-quality.ts +5 -2
  133. package/dist/extensions/pi-web-agent/src/orchestration/evidence-ranker.ts +2 -0
  134. package/dist/extensions/pi-web-agent/src/orchestration/index.ts +28 -28
  135. package/dist/extensions/pi-web-agent/src/orchestration/query-planner.ts +47 -47
  136. package/dist/extensions/pi-web-agent/src/orchestration/research-orchestrator.ts +72 -7
  137. package/dist/extensions/pi-web-agent/src/orchestration/research-types.ts +8 -1
  138. package/dist/extensions/pi-web-agent/src/orchestration/research-worker.ts +28 -3
  139. package/dist/extensions/pi-web-agent/src/orchestration/source-profile.ts +4 -0
  140. package/dist/extensions/pi-web-agent/src/orchestration/stop-decider.ts +81 -81
  141. package/dist/extensions/pi-web-agent/src/orchestration/url.ts +35 -0
  142. package/dist/extensions/pi-web-agent/src/presentation/config-store.ts +210 -210
  143. package/dist/extensions/pi-web-agent/src/presentation/config.ts +75 -75
  144. package/dist/extensions/pi-web-agent/src/presentation/explore-presentation.ts +18 -6
  145. package/dist/extensions/pi-web-agent/src/presentation/fetch-presentation.ts +54 -54
  146. package/dist/extensions/pi-web-agent/src/presentation/search-presentation.ts +14 -2
  147. package/dist/extensions/pi-web-agent/src/presentation/select-view.ts +20 -20
  148. package/dist/extensions/pi-web-agent/src/presentation/types.ts +63 -63
  149. package/dist/extensions/pi-web-agent/src/readers/github-reader.ts +150 -0
  150. package/dist/extensions/pi-web-agent/src/readers/limits.ts +3 -0
  151. package/dist/extensions/pi-web-agent/src/readers/pdf-reader.ts +87 -0
  152. package/dist/extensions/pi-web-agent/src/readers/resolver.ts +25 -0
  153. package/dist/extensions/pi-web-agent/src/readers/types.ts +11 -0
  154. package/dist/extensions/pi-web-agent/src/readers/youtube-reader.ts +79 -0
  155. package/dist/extensions/pi-web-agent/src/search/brave.ts +114 -114
  156. package/dist/extensions/pi-web-agent/src/search/duckduckgo.ts +32 -5
  157. package/dist/extensions/pi-web-agent/src/search/exa.ts +109 -0
  158. package/dist/extensions/pi-web-agent/src/search/fanout.ts +154 -0
  159. package/dist/extensions/pi-web-agent/src/search/searxng.ts +96 -96
  160. package/dist/extensions/pi-web-agent/src/search/tavily.ts +113 -0
  161. package/dist/extensions/pi-web-agent/src/search/youcom.ts +109 -0
  162. package/dist/extensions/pi-web-agent/src/tools/web-explore.ts +71 -71
  163. package/dist/extensions/pi-web-agent/src/tools/web-fetch-headless.ts +31 -31
  164. package/dist/extensions/pi-web-agent/src/tools/web-fetch.ts +31 -31
  165. package/dist/extensions/pi-web-agent/src/tools/web-search.ts +22 -9
  166. package/dist/extensions/pi-web-agent/src/types.ts +19 -4
  167. package/dist/extensions/pi-zentui/extensions/zentui/format.ts +7 -1
  168. package/dist/extensions/ponytail/package.json +8 -8
  169. package/dist/extensions/question/constants.ts +30 -30
  170. package/dist/extensions/question/helpers.ts +58 -58
  171. package/dist/extensions/question/navigation.ts +14 -14
  172. package/dist/extensions/question/package.json +19 -19
  173. package/dist/extensions/question/selection-mode.ts +46 -46
  174. package/dist/extensions/question/shortcuts.ts +44 -44
  175. package/dist/extensions/question/types.ts +132 -132
  176. package/dist/extensions/test-resolve-hook-impl.mjs +6 -6
  177. package/dist/extensions/test-resolve-hook.mjs +6 -6
  178. package/dist/extensions/web-agent-onboarding.ts +222 -222
  179. package/dist/package-manager-cli.js +71 -71
  180. package/dist/rpc-entry.js +0 -0
  181. package/dist/skills/improve-codebase/REFERENCE.md +78 -78
  182. package/docs/compaction.md +396 -396
  183. package/docs/containerization.md +111 -111
  184. package/docs/development.md +71 -71
  185. package/docs/docs.json +164 -164
  186. package/docs/environment-variables.md +86 -86
  187. package/docs/index.md +83 -83
  188. package/docs/json.md +82 -82
  189. package/docs/models.md +502 -502
  190. package/docs/packages.md +227 -227
  191. package/docs/plans/subagent-delegation/phase-0-correctness.md +264 -264
  192. package/docs/plans/subagent-delegation/phase-1-behavioral-contract.md +485 -485
  193. package/docs/plans/subagent-delegation/phase-2-context-controls.md +281 -281
  194. package/docs/plans/subagent-delegation/phase-3-advisory-routing.md +361 -361
  195. package/docs/plans/subagent-delegation/phase-4-optional-enforcement.md +380 -380
  196. package/docs/prompt-templates.md +95 -95
  197. package/docs/providers.md +293 -293
  198. package/docs/security.md +59 -59
  199. package/docs/session-format.md +414 -414
  200. package/docs/sessions.md +145 -145
  201. package/docs/shared-host-extensions.md +109 -109
  202. package/docs/shell-aliases.md +13 -13
  203. package/docs/skills.md +231 -231
  204. package/docs/terminal-setup.md +142 -142
  205. package/docs/termux.md +127 -127
  206. package/docs/themes.md +295 -295
  207. package/docs/tmux.md +63 -63
  208. package/docs/tui.md +927 -927
  209. package/docs/windows.md +17 -17
  210. package/examples/README.md +25 -25
  211. package/examples/extensions/README.md +211 -211
  212. package/examples/extensions/auto-commit-on-exit.ts +49 -49
  213. package/examples/extensions/bash-spawn-hook.ts +30 -30
  214. package/examples/extensions/bookmark.ts +50 -50
  215. package/examples/extensions/border-status-editor.ts +150 -150
  216. package/examples/extensions/built-in-tool-renderer.ts +249 -249
  217. package/examples/extensions/claude-rules.ts +86 -86
  218. package/examples/extensions/commands.ts +72 -72
  219. package/examples/extensions/confirm-destructive.ts +59 -59
  220. package/examples/extensions/custom-compaction.ts +130 -130
  221. package/examples/extensions/custom-footer.ts +64 -64
  222. package/examples/extensions/custom-header.ts +73 -73
  223. package/examples/extensions/custom-provider-anthropic/index.ts +610 -610
  224. package/examples/extensions/custom-provider-anthropic/package-lock.json +24 -24
  225. package/examples/extensions/custom-provider-anthropic/package.json +19 -19
  226. package/examples/extensions/custom-provider-gitlab-duo/index.ts +404 -404
  227. package/examples/extensions/custom-provider-gitlab-duo/package.json +16 -16
  228. package/examples/extensions/custom-provider-gitlab-duo/test.ts +82 -82
  229. package/examples/extensions/dirty-repo-guard.ts +56 -56
  230. package/examples/extensions/doom-overlay/README.md +46 -46
  231. package/examples/extensions/doom-overlay/doom/build/doom.js +21 -21
  232. package/examples/extensions/doom-overlay/doom/build/doom.wasm +0 -0
  233. package/examples/extensions/doom-overlay/doom/build.sh +152 -152
  234. package/examples/extensions/doom-overlay/doom/doomgeneric_pi.c +72 -72
  235. package/examples/extensions/doom-overlay/doom-component.ts +132 -132
  236. package/examples/extensions/doom-overlay/doom-engine.ts +173 -173
  237. package/examples/extensions/doom-overlay/doom-keys.ts +104 -104
  238. package/examples/extensions/doom-overlay/index.ts +74 -74
  239. package/examples/extensions/doom-overlay/wad-finder.ts +51 -51
  240. package/examples/extensions/dynamic-resources/SKILL.md +8 -8
  241. package/examples/extensions/dynamic-resources/dynamic.json +79 -79
  242. package/examples/extensions/dynamic-resources/dynamic.md +5 -5
  243. package/examples/extensions/dynamic-resources/index.ts +15 -15
  244. package/examples/extensions/dynamic-tools.ts +74 -74
  245. package/examples/extensions/event-bus.ts +43 -43
  246. package/examples/extensions/file-trigger.ts +41 -41
  247. package/examples/extensions/git-checkpoint.ts +53 -53
  248. package/examples/extensions/git-merge-and-resolve.ts +115 -115
  249. package/examples/extensions/github-issue-autocomplete.ts +185 -185
  250. package/examples/extensions/gondolin/index.ts +531 -531
  251. package/examples/extensions/gondolin/package-lock.json +185 -185
  252. package/examples/extensions/gondolin/package.json +19 -19
  253. package/examples/extensions/handoff.ts +199 -199
  254. package/examples/extensions/hello.ts +26 -26
  255. package/examples/extensions/hidden-thinking-label.ts +53 -53
  256. package/examples/extensions/inline-bash.ts +94 -94
  257. package/examples/extensions/input-transform-streaming.ts +39 -39
  258. package/examples/extensions/input-transform.ts +43 -43
  259. package/examples/extensions/interactive-shell.ts +196 -196
  260. package/examples/extensions/mac-system-theme.ts +47 -47
  261. package/examples/extensions/message-renderer.ts +59 -59
  262. package/examples/extensions/minimal-mode.ts +426 -426
  263. package/examples/extensions/modal-editor.ts +85 -85
  264. package/examples/extensions/model-status.ts +31 -31
  265. package/examples/extensions/notify.ts +55 -55
  266. package/examples/extensions/overlay-qa-tests.ts +1450 -1450
  267. package/examples/extensions/overlay-test.ts +153 -153
  268. package/examples/extensions/permission-gate.ts +34 -34
  269. package/examples/extensions/pirate.ts +47 -47
  270. package/examples/extensions/plan-mode/README.md +66 -66
  271. package/examples/extensions/plan-mode/index.ts +390 -390
  272. package/examples/extensions/plan-mode/utils.ts +168 -168
  273. package/examples/extensions/preset.ts +436 -436
  274. package/examples/extensions/project-trust.ts +64 -64
  275. package/examples/extensions/prompt-customizer.ts +97 -97
  276. package/examples/extensions/protected-paths.ts +30 -30
  277. package/examples/extensions/provider-payload.ts +18 -18
  278. package/examples/extensions/qna.ts +122 -122
  279. package/examples/extensions/question.ts +285 -285
  280. package/examples/extensions/questionnaire.ts +448 -448
  281. package/examples/extensions/rainbow-editor.ts +88 -88
  282. package/examples/extensions/reload-runtime.ts +37 -37
  283. package/examples/extensions/rpc-demo.ts +118 -118
  284. package/examples/extensions/sandbox/index.ts +321 -321
  285. package/examples/extensions/sandbox/package-lock.json +92 -92
  286. package/examples/extensions/sandbox/package.json +19 -19
  287. package/examples/extensions/send-user-message.ts +97 -97
  288. package/examples/extensions/session-name.ts +27 -27
  289. package/examples/extensions/shutdown-command.ts +63 -63
  290. package/examples/extensions/snake.ts +343 -343
  291. package/examples/extensions/space-invaders.ts +560 -560
  292. package/examples/extensions/ssh.ts +220 -220
  293. package/examples/extensions/status-line.ts +32 -32
  294. package/examples/extensions/structured-output.ts +65 -65
  295. package/examples/extensions/subagent/README.md +175 -175
  296. package/examples/extensions/subagent/agents/planner.md +37 -37
  297. package/examples/extensions/subagent/agents/reviewer.md +35 -35
  298. package/examples/extensions/subagent/agents/scout.md +50 -50
  299. package/examples/extensions/subagent/agents/worker.md +24 -24
  300. package/examples/extensions/subagent/agents.ts +126 -126
  301. package/examples/extensions/subagent/index.ts +1015 -1015
  302. package/examples/extensions/subagent/prompts/implement-and-review.md +10 -10
  303. package/examples/extensions/subagent/prompts/implement.md +10 -10
  304. package/examples/extensions/subagent/prompts/scout-and-plan.md +9 -9
  305. package/examples/extensions/summarize.ts +209 -209
  306. package/examples/extensions/system-prompt-header.ts +17 -17
  307. package/examples/extensions/tic-tac-toe.ts +1008 -1008
  308. package/examples/extensions/timed-confirm.ts +70 -70
  309. package/examples/extensions/titlebar-spinner.ts +58 -58
  310. package/examples/extensions/todo.ts +297 -297
  311. package/examples/extensions/tool-override.ts +144 -144
  312. package/examples/extensions/tools.ts +146 -146
  313. package/examples/extensions/trigger-compact.ts +50 -50
  314. package/examples/extensions/truncated-tool.ts +195 -195
  315. package/examples/extensions/widget-placement.ts +9 -9
  316. package/examples/extensions/with-deps/index.ts +32 -32
  317. package/examples/extensions/with-deps/package-lock.json +31 -31
  318. package/examples/extensions/with-deps/package.json +22 -22
  319. package/examples/extensions/working-indicator.ts +123 -123
  320. package/examples/extensions/working-message-test.ts +25 -25
  321. package/examples/rpc-extension-ui.ts +632 -632
  322. package/examples/sdk/01-minimal.ts +26 -26
  323. package/examples/sdk/02-custom-model.ts +53 -53
  324. package/examples/sdk/03-custom-prompt.ts +75 -75
  325. package/examples/sdk/04-skills.ts +55 -55
  326. package/examples/sdk/05-tools.ts +48 -48
  327. package/examples/sdk/06-extensions.ts +99 -99
  328. package/examples/sdk/07-context-files.ts +47 -47
  329. package/examples/sdk/08-prompt-templates.ts +51 -51
  330. package/examples/sdk/09-api-keys-and-oauth.ts +52 -52
  331. package/examples/sdk/10-settings.ts +53 -53
  332. package/examples/sdk/11-sessions.ts +52 -52
  333. package/examples/sdk/12-full-control.ts +79 -79
  334. package/examples/sdk/13-session-runtime.ts +67 -67
  335. package/examples/sdk/README.md +144 -144
  336. package/package.json +3 -2
  337. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/bun/cli.d.ts +0 -3
  338. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/bun/register-bedrock.d.ts +0 -2
  339. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/bun/restore-sandbox-env.d.ts +0 -17
  340. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/args.d.ts +0 -57
  341. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/config-selector.d.ts +0 -16
  342. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/file-processor.d.ts +0 -15
  343. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/initial-message.d.ts +0 -18
  344. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/list-models.d.ts +0 -9
  345. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/project-trust.d.ts +0 -10
  346. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/session-picker.d.ts +0 -10
  347. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/startup-ui.d.ts +0 -20
  348. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli.d.ts +0 -3
  349. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/config.d.ts +0 -96
  350. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/agent-session-runtime.d.ts +0 -119
  351. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/agent-session-services.d.ts +0 -85
  352. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/agent-session.d.ts +0 -620
  353. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/auth-guidance.d.ts +0 -5
  354. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/auth-storage.d.ts +0 -56
  355. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/bash-executor.d.ts +0 -32
  356. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/cache-stats.d.ts +0 -49
  357. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/compaction/branch-summarization.d.ts +0 -93
  358. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/compaction/compaction.d.ts +0 -128
  359. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/compaction/index.d.ts +0 -7
  360. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/compaction/utils.d.ts +0 -38
  361. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/defaults.d.ts +0 -3
  362. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/diagnostics.d.ts +0 -15
  363. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/event-bus.d.ts +0 -9
  364. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/exec.d.ts +0 -29
  365. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/experimental.d.ts +0 -2
  366. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/export-html/ansi-to-html.d.ts +0 -22
  367. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/export-html/index.d.ts +0 -37
  368. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/export-html/tool-renderer.d.ts +0 -34
  369. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/index.d.ts +0 -12
  370. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/loader.d.ts +0 -23
  371. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/runner.d.ts +0 -171
  372. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/types.d.ts +0 -1261
  373. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/wrapper.d.ts +0 -20
  374. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/footer-data-provider.d.ts +0 -54
  375. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/http-dispatcher.d.ts +0 -22
  376. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/index.d.ts +0 -13
  377. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/keybindings.d.ts +0 -358
  378. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/messages.d.ts +0 -77
  379. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/model-config.d.ts +0 -512
  380. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/model-registry.d.ts +0 -43
  381. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/model-resolver.d.ts +0 -121
  382. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/model-runtime.d.ts +0 -82
  383. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/models-store.d.ts +0 -17
  384. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/output-guard.d.ts +0 -7
  385. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/package-manager.d.ts +0 -210
  386. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/project-trust.d.ts +0 -15
  387. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/prompt-templates.d.ts +0 -54
  388. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/provider-attribution.d.ts +0 -4
  389. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/provider-composer.d.ts +0 -55
  390. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/radius.d.ts +0 -2
  391. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/remote-catalog-provider.d.ts +0 -5
  392. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/resolve-config-value.d.ts +0 -30
  393. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/resource-loader.d.ts +0 -206
  394. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/runtime-credentials.d.ts +0 -15
  395. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/sdk.d.ts +0 -106
  396. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/session-cwd.d.ts +0 -19
  397. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/session-manager.d.ts +0 -356
  398. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/settings-manager.d.ts +0 -297
  399. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/skills.d.ts +0 -60
  400. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/slash-commands.d.ts +0 -15
  401. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/source-info.d.ts +0 -18
  402. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/system-prompt.d.ts +0 -28
  403. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/telemetry.d.ts +0 -3
  404. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/timings.d.ts +0 -10
  405. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/bash.d.ts +0 -68
  406. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/edit-diff.d.ts +0 -106
  407. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/edit.d.ts +0 -51
  408. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/file-mutation-queue.d.ts +0 -6
  409. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/find.d.ts +0 -35
  410. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/grep.d.ts +0 -37
  411. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/index.d.ts +0 -40
  412. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/ls.d.ts +0 -37
  413. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/output-accumulator.d.ts +0 -52
  414. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/path-utils.d.ts +0 -10
  415. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/read.d.ts +0 -35
  416. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/render-utils.d.ts +0 -24
  417. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/tool-definition-wrapper.d.ts +0 -14
  418. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/truncate.d.ts +0 -70
  419. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/write.d.ts +0 -26
  420. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/trust-manager.d.ts +0 -36
  421. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/usage-totals.d.ts +0 -19
  422. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/index.d.ts +0 -3
  423. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/client.d.ts +0 -61
  424. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/huggingface.d.ts +0 -23
  425. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/index.d.ts +0 -3
  426. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/provider.d.ts +0 -10
  427. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/ui.d.ts +0 -42
  428. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/index.d.ts +0 -35
  429. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/main.d.ts +0 -12
  430. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/migrations.d.ts +0 -33
  431. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/index.d.ts +0 -9
  432. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/armin.d.ts +0 -34
  433. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/assistant-message.d.ts +0 -22
  434. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/bash-execution.d.ts +0 -34
  435. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/bordered-loader.d.ts +0 -16
  436. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/branch-summary-message.d.ts +0 -16
  437. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/compaction-summary-message.d.ts +0 -16
  438. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/config-selector.d.ts +0 -102
  439. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/countdown-timer.d.ts +0 -14
  440. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/custom-editor.d.ts +0 -21
  441. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/custom-entry.d.ts +0 -19
  442. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/custom-message.d.ts +0 -20
  443. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/daxnuts.d.ts +0 -23
  444. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/diff.d.ts +0 -12
  445. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/dynamic-border.d.ts +0 -15
  446. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/earendil-announcement.d.ts +0 -5
  447. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/extension-editor.d.ts +0 -22
  448. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/extension-input.d.ts +0 -23
  449. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/extension-selector.d.ts +0 -26
  450. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/first-time-setup.d.ts +0 -25
  451. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/footer.d.ts +0 -32
  452. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/index.d.ts +0 -34
  453. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/keybinding-hints.d.ts +0 -13
  454. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/login-dialog.d.ts +0 -52
  455. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/model-selector.d.ts +0 -54
  456. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/oauth-selector.d.ts +0 -33
  457. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/scoped-models-selector.d.ts +0 -42
  458. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/session-selector-search.d.ts +0 -23
  459. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/session-selector.d.ts +0 -95
  460. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/settings-selector.d.ts +0 -77
  461. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/show-images-selector.d.ts +0 -10
  462. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/skill-invocation-message.d.ts +0 -17
  463. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/status-indicator.d.ts +0 -28
  464. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/theme-selector.d.ts +0 -11
  465. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/thinking-selector.d.ts +0 -11
  466. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/tool-execution.d.ts +0 -63
  467. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/tree-selector.d.ts +0 -94
  468. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/trust-selector.d.ts +0 -23
  469. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/user-message-selector.d.ts +0 -30
  470. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/user-message.d.ts +0 -14
  471. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/visual-truncate.d.ts +0 -24
  472. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/interactive-mode.d.ts +0 -394
  473. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/model-search.d.ts +0 -12
  474. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/theme/theme-controller.d.ts +0 -29
  475. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/theme/theme.d.ts +0 -120
  476. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/print-mode.d.ts +0 -28
  477. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/rpc/jsonl.d.ts +0 -17
  478. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/rpc/rpc-client.d.ts +0 -246
  479. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/rpc/rpc-mode.d.ts +0 -20
  480. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/rpc/rpc-types.d.ts +0 -457
  481. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/package-manager-cli.d.ts +0 -8
  482. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/rpc-entry.d.ts +0 -3
  483. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/ansi.d.ts +0 -2
  484. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/changelog.d.ts +0 -22
  485. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/child-process.d.ts +0 -18
  486. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/clipboard-image.d.ts +0 -11
  487. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/clipboard-native.d.ts +0 -11
  488. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/clipboard.d.ts +0 -4
  489. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/deprecation.d.ts +0 -4
  490. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/exif-orientation.d.ts +0 -5
  491. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/frontmatter.d.ts +0 -8
  492. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/fs-watch.d.ts +0 -5
  493. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/git.d.ts +0 -26
  494. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/html.d.ts +0 -7
  495. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-convert.d.ts +0 -10
  496. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-process.d.ts +0 -18
  497. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-resize-core.d.ts +0 -30
  498. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-resize-worker.d.ts +0 -2
  499. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-resize.d.ts +0 -16
  500. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/json.d.ts +0 -3
  501. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/mime.d.ts +0 -3
  502. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/open-browser.d.ts +0 -9
  503. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/paths.d.ts +0 -31
  504. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/photon.d.ts +0 -21
  505. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/pi-user-agent.d.ts +0 -2
  506. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/shell.d.ts +0 -31
  507. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/sleep.d.ts +0 -5
  508. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/syntax-highlight.d.ts +0 -12
  509. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/tools-manager.d.ts +0 -3
  510. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/version-check.d.ts +0 -15
  511. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/windows-self-update.d.ts +0 -3
@@ -2,16 +2,27 @@ import {
2
2
  DEFAULT_BACKEND_CONFIG,
3
3
  mergeBackendConfigLayers,
4
4
  validateBackendConfig,
5
+ usableSearchProviders,
5
6
  type BackendConfig,
6
7
  type BackendConfigOverride
7
8
  } from '../backends/config.js';
8
9
  import { checkBackendHealth } from '../backends/doctor.js';
10
+ import type { SearchProviderName } from '../types.js';
9
11
  import {
10
12
  DynamicBorder,
11
13
  getSettingsListTheme,
12
14
  type ExtensionAPI
13
15
  } from '@selesai/code';
14
- import { Container, SelectList, SettingsList, Text, type SelectItem, type SettingItem } from '@earendil-works/pi-tui';
16
+ import {
17
+ Container,
18
+ Input,
19
+ SelectList,
20
+ SettingsList,
21
+ Text,
22
+ type Component,
23
+ type SelectItem,
24
+ type SettingItem
25
+ } from '@earendil-works/pi-tui';
15
26
  import {
16
27
  DEFAULT_PRESENTATION_CONFIG,
17
28
  mergePresentationConfigLayers,
@@ -78,7 +89,10 @@ function cloneBackendConfig(config: BackendConfig): BackendConfig {
78
89
  return {
79
90
  search: {
80
91
  ...config.search,
81
- options: config.search.options ? { ...config.search.options } : undefined
92
+ options: config.search.options ? { ...config.search.options } : undefined,
93
+ fanout: config.search.fanout
94
+ ? { mode: config.search.fanout.mode, providers: config.search.fanout.providers ? [...config.search.fanout.providers] : undefined }
95
+ : undefined
82
96
  },
83
97
  fetch: {
84
98
  ...config.fetch,
@@ -115,12 +129,17 @@ async function defaultCheckTypebox(): Promise<boolean> {
115
129
  }
116
130
 
117
131
  function formatSearchOptions(config: BackendConfig['search']) {
118
- return [
132
+ const parts = [
119
133
  config.fallback ? `fallback ${config.fallback}` : undefined,
120
134
  config.options?.categories?.length ? `categories ${config.options.categories.join(',')}` : undefined,
121
135
  config.options?.language ? `language ${config.options.language}` : undefined,
122
- config.options?.safesearch !== undefined ? `safesearch ${config.options.safesearch}` : undefined
123
- ].filter(Boolean).join(' ');
136
+ config.options?.safesearch !== undefined ? `safesearch ${config.options.safesearch}` : undefined,
137
+ config.fanout && config.fanout.mode !== 'off'
138
+ ? `fanout ${config.fanout.mode} (${(config.fanout.providers || usableSearchProviders(config)).join(', ')})`
139
+ : undefined
140
+ ].filter(Boolean);
141
+
142
+ return parts.join(' ');
124
143
  }
125
144
 
126
145
  function formatFetchOptions(config: BackendConfig['fetch']) {
@@ -181,7 +200,73 @@ function buildPresentationSettingsItems(scope: PresentationScope, config: Presen
181
200
  ];
182
201
  }
183
202
 
184
- function buildBackendSettingsItems(scope: PresentationScope, backends: BackendConfig): SettingItem[] {
203
+ export function createBackendUrlEditor(
204
+ theme: any,
205
+ label: string,
206
+ placeholderUrl: string,
207
+ onOpenChange?: (open: boolean) => void
208
+ ) {
209
+ return (currentValue: string, done: (selectedValue?: string) => void): Component => {
210
+ onOpenChange?.(true);
211
+
212
+ const initialValue = currentValue && currentValue !== 'not set' ? currentValue : placeholderUrl;
213
+ const container = new Container();
214
+ const hint = new Text(theme.fg('muted', `${label} · enter to save · empty clears · esc cancels`), 1, 0);
215
+ const input = new Input();
216
+ input.setValue(initialValue);
217
+ input.handleInput('\x1b[F'); // move cursor to end; setValue leaves it at 0
218
+ input.focused = true;
219
+ const errorText = new Text('', 1, 0);
220
+
221
+ const finish = (selectedValue?: string) => {
222
+ onOpenChange?.(false);
223
+ done(selectedValue);
224
+ };
225
+
226
+ const showError = (message: string) => {
227
+ errorText.setText(theme.fg('warning', message));
228
+ container.invalidate();
229
+ };
230
+
231
+ input.onSubmit = (value: string) => {
232
+ if (!value.trim()) {
233
+ finish('');
234
+ return;
235
+ }
236
+
237
+ const validated = validateBackendUrl(value);
238
+ if (!validated.ok) {
239
+ showError(validated.message);
240
+ return;
241
+ }
242
+
243
+ finish(validated.value);
244
+ };
245
+
246
+ input.onEscape = () => finish(undefined);
247
+
248
+ container.addChild(hint);
249
+ container.addChild(input);
250
+ container.addChild(errorText);
251
+
252
+ return {
253
+ render: (width: number) => container.render(width),
254
+ invalidate: () => container.invalidate(),
255
+ handleInput: (data: string) => input.handleInput(data)
256
+ };
257
+ };
258
+ }
259
+
260
+ function buildBackendSettingsItems(
261
+ scope: PresentationScope,
262
+ backends: BackendConfig,
263
+ theme: any,
264
+ onUrlEditorOpenChange?: (open: boolean) => void
265
+ ): SettingItem[] {
266
+ const usable = usableSearchProviders(backends.search);
267
+ const fanoutMode = backends.search.fanout?.mode ?? 'off';
268
+ const fanoutProviders = backends.search.fanout?.providers ?? usable;
269
+
185
270
  return [
186
271
  {
187
272
  id: 'scope',
@@ -193,26 +278,56 @@ function buildBackendSettingsItems(scope: PresentationScope, backends: BackendCo
193
278
  id: 'backend:search:provider',
194
279
  label: 'Search backend',
195
280
  currentValue: backends.search.provider,
196
- values: ['duckduckgo', 'searxng', 'brave']
281
+ values: ['duckduckgo', 'searxng', 'brave', 'youcom', 'exa', 'tavily']
197
282
  },
198
283
  {
199
284
  id: 'backend:search:baseUrl',
200
285
  label: 'SearXNG URL',
201
286
  currentValue: backends.search.baseUrl ?? 'not set',
202
- values: ['edit']
287
+ submenu: createBackendUrlEditor(theme, 'SearXNG base URL', 'http://localhost:8080', onUrlEditorOpenChange)
203
288
  },
204
289
  {
205
290
  id: 'backend:search:fallback',
206
291
  label: 'Search fallback',
207
- currentValue: backends.search.provider === 'searxng' || backends.search.provider === 'brave' ? backends.search.fallback ?? 'off' : 'off',
208
- values: backends.search.provider === 'searxng' || backends.search.provider === 'brave' ? ['off', 'duckduckgo'] : ['off']
292
+ currentValue: backends.search.provider === 'searxng' || backends.search.provider === 'brave' || backends.search.provider === 'youcom' || backends.search.provider === 'exa' || backends.search.provider === 'tavily' ? backends.search.fallback ?? 'off' : 'off',
293
+ values: backends.search.provider === 'searxng' || backends.search.provider === 'brave' || backends.search.provider === 'youcom' || backends.search.provider === 'exa' || backends.search.provider === 'tavily' ? ['off', 'duckduckgo'] : ['off']
209
294
  },
295
+ {
296
+ id: 'backend:search:fanout:mode',
297
+ label: 'Search fanout',
298
+ currentValue: fanoutMode,
299
+ values: ['off', 'on', 'auto']
300
+ },
301
+ ...(fanoutMode !== 'off' ? usable.map((provider) => ({
302
+ id: `backend:search:fanout:provider:${provider}`,
303
+ label: ` ${provider}`,
304
+ currentValue: fanoutProviders.includes(provider) ? 'included' : 'excluded',
305
+ values: ['included', 'excluded']
306
+ })) : []),
210
307
  {
211
308
  id: 'backend:secret:brave',
212
309
  label: 'Brave API key',
213
310
  currentValue: 'env var',
214
311
  values: ['env var']
215
312
  },
313
+ {
314
+ id: 'backend:secret:youcom',
315
+ label: 'You.com API key',
316
+ currentValue: 'env var',
317
+ values: ['env var']
318
+ },
319
+ {
320
+ id: 'backend:secret:exa',
321
+ label: 'Exa API key',
322
+ currentValue: 'env var',
323
+ values: ['env var']
324
+ },
325
+ {
326
+ id: 'backend:secret:tavily',
327
+ label: 'Tavily API key',
328
+ currentValue: 'env var',
329
+ values: ['env var']
330
+ },
216
331
  {
217
332
  id: 'backend:fetch:provider',
218
333
  label: 'Fetch backend',
@@ -223,7 +338,7 @@ function buildBackendSettingsItems(scope: PresentationScope, backends: BackendCo
223
338
  id: 'backend:fetch:baseUrl',
224
339
  label: 'Firecrawl URL',
225
340
  currentValue: backends.fetch.baseUrl ?? 'not set',
226
- values: ['edit']
341
+ submenu: createBackendUrlEditor(theme, 'Firecrawl base URL', 'http://localhost:3002', onUrlEditorOpenChange)
227
342
  },
228
343
  {
229
344
  id: 'backend:fetch:fallback',
@@ -373,7 +488,7 @@ export function applySettingsValue(
373
488
  currentDraft.tools = nextTools;
374
489
  }
375
490
 
376
- if (id === 'backend:search:provider' && (newValue === 'duckduckgo' || newValue === 'searxng' || newValue === 'brave')) {
491
+ if (id === 'backend:search:provider' && (newValue === 'duckduckgo' || newValue === 'searxng' || newValue === 'brave' || newValue === 'youcom' || newValue === 'exa' || newValue === 'tavily')) {
377
492
  currentBackends.search.provider = newValue;
378
493
  if (newValue !== 'searxng') {
379
494
  delete currentBackends.search.baseUrl;
@@ -385,15 +500,53 @@ export function applySettingsValue(
385
500
  }
386
501
 
387
502
  if (id === 'backend:search:fallback') {
388
- if (newValue === 'duckduckgo' && (currentBackends.search.provider === 'searxng' || currentBackends.search.provider === 'brave')) {
503
+ if (newValue === 'duckduckgo' && (currentBackends.search.provider === 'searxng' || currentBackends.search.provider === 'brave' || currentBackends.search.provider === 'youcom' || currentBackends.search.provider === 'exa' || currentBackends.search.provider === 'tavily')) {
389
504
  currentBackends.search.fallback = 'duckduckgo';
390
505
  } else {
391
506
  delete currentBackends.search.fallback;
392
507
  }
393
508
  }
394
509
 
510
+ if (id === 'backend:search:fanout:mode') {
511
+ if (newValue === 'off') {
512
+ currentBackends.search.fanout = { mode: 'off' };
513
+ } else if (newValue === 'on' || newValue === 'auto') {
514
+ currentBackends.search.fanout = {
515
+ mode: newValue,
516
+ providers: undefined
517
+ };
518
+ }
519
+ }
520
+
521
+ if (id.startsWith('backend:search:fanout:provider:')) {
522
+ const providerName = id.slice('backend:search:fanout:provider:'.length) as SearchProviderName;
523
+ const usableProviders = usableSearchProviders(currentBackends.search);
524
+
525
+ // Ensure fanout exists
526
+ if (!currentBackends.search.fanout) {
527
+ currentBackends.search.fanout = { mode: 'on', providers: undefined };
528
+ }
529
+
530
+ // Materialize the provider list if it's currently undefined; use usable providers instead of all
531
+ const currentProviders = currentBackends.search.fanout.providers ?? usableProviders;
532
+
533
+ if (newValue === 'excluded') {
534
+ // Remove the provider from the list
535
+ const filtered: SearchProviderName[] = currentProviders.filter((p) => p !== providerName);
536
+ // never allow an empty set: keep at least one provider (empty would be read as "all")
537
+ if (filtered.length > 0) {
538
+ currentBackends.search.fanout.providers = filtered;
539
+ }
540
+ } else if (newValue === 'included') {
541
+ // Add the provider back, maintaining canonical order using usable providers
542
+ const result: SearchProviderName[] = usableProviders.filter((p) => currentProviders.includes(p) || p === providerName);
543
+ currentBackends.search.fanout.providers = result;
544
+ }
545
+ }
546
+
395
547
  if (id === 'backend:search:baseUrl') {
396
- if (currentBackends.search.provider === 'searxng' && newValue.trim()) {
548
+ if (newValue.trim()) {
549
+ currentBackends.search.provider = 'searxng';
397
550
  currentBackends.search.baseUrl = newValue.trim();
398
551
  } else {
399
552
  delete currentBackends.search.baseUrl;
@@ -417,6 +570,7 @@ export function applySettingsValue(
417
570
 
418
571
  if (id === 'backend:fetch:baseUrl') {
419
572
  if (newValue.trim()) {
573
+ currentBackends.fetch.provider = 'firecrawl';
420
574
  currentBackends.fetch.baseUrl = newValue.trim();
421
575
  } else {
422
576
  delete currentBackends.fetch.baseUrl;
@@ -474,7 +628,8 @@ export function collapseBackendConfigToOverride(
474
628
  : {
475
629
  ...(config.search.baseUrl !== inheritedConfig.search.baseUrl ? { baseUrl: config.search.baseUrl } : {}),
476
630
  ...(config.search.fallback !== inheritedConfig.search.fallback ? { fallback: config.search.fallback } : {}),
477
- ...(!sameJson(config.search.options, inheritedConfig.search.options) ? { options: config.search.options } : {})
631
+ ...(!sameJson(config.search.options, inheritedConfig.search.options) ? { options: config.search.options } : {}),
632
+ ...(!sameJson(config.search.fanout, inheritedConfig.search.fanout) ? { fanout: config.search.fanout } : {})
478
633
  };
479
634
 
480
635
  if (config.search.provider !== inheritedConfig.search.provider) {
@@ -675,9 +830,10 @@ async function openBackendSettingsUi(
675
830
  loaded: Awaited<LoadedPresentationConfig>,
676
831
  initialScope: PresentationScope
677
832
  ): Promise<SettingsUiResult | undefined> {
678
- return ctx.ui.custom((tui: any, theme: any, _kb: unknown, done: (value: SettingsUiResult) => void) => {
833
+ return ctx.ui.custom((_tui: unknown, theme: any, _kb: unknown, done: (value: SettingsUiResult) => void) => {
679
834
  let state = createSettingsDraftState(loaded, initialScope);
680
835
  let settingsList: SettingsList;
836
+ let urlEditorOpen = false;
681
837
 
682
838
  const container = new Container();
683
839
  container.addChild(new Text(theme.fg('accent', theme.bold('pi-web-agent · backends')), 1, 1));
@@ -689,46 +845,18 @@ async function openBackendSettingsUi(
689
845
  )
690
846
  );
691
847
 
692
- const editUrl = async (id: string) => {
693
- const isSearchUrl = id === 'backend:search:baseUrl';
694
- const label = isSearchUrl ? 'SearXNG base URL' : 'Firecrawl base URL';
695
- const currentValue = isSearchUrl ? state.backends.search.baseUrl : state.backends.fetch.baseUrl;
696
- const entered = await ctx.ui.input(label, currentValue ?? (isSearchUrl ? 'http://localhost:8080' : 'http://localhost:3002'));
697
- if (entered === undefined) return;
698
-
699
- if (!entered.trim()) {
700
- state = applySettingsValue(state, id, '');
701
- rebuildSettingsList();
702
- tui.requestRender?.();
703
- return;
704
- }
705
-
706
- const validated = validateBackendUrl(entered);
707
- if (!validated.ok) {
708
- ctx.ui.notify(validated.message, 'warning');
709
- return;
710
- }
711
-
712
- state = applySettingsValue(state, id, validated.value);
713
- rebuildSettingsList();
714
- tui.requestRender?.();
715
- };
716
-
717
848
  const rebuildSettingsList = () => {
718
849
  if (settingsList) {
719
850
  container.removeChild(settingsList);
720
851
  }
721
852
 
722
853
  settingsList = new SettingsList(
723
- buildBackendSettingsItems(state.scope, state.backends),
854
+ buildBackendSettingsItems(state.scope, state.backends, theme, (open) => {
855
+ urlEditorOpen = open;
856
+ }),
724
857
  12,
725
858
  getSettingsListTheme(),
726
859
  (id, newValue) => {
727
- if (id === 'backend:search:baseUrl' || id === 'backend:fetch:baseUrl') {
728
- void editUrl(id);
729
- return;
730
- }
731
-
732
860
  state = applySettingsValue(state, id, newValue);
733
861
  rebuildSettingsList();
734
862
  container.invalidate();
@@ -746,6 +874,14 @@ async function openBackendSettingsUi(
746
874
  render: (width: number) => container.render(width),
747
875
  invalidate: () => container.invalidate(),
748
876
  handleInput: (data: string) => {
877
+ // While the inline URL editor is open, let it (and its own Escape/Enter
878
+ // handling) consume input first — otherwise these shortcuts close the
879
+ // whole settings UI out from under an in-progress edit.
880
+ if (urlEditorOpen) {
881
+ settingsList.handleInput?.(data);
882
+ return;
883
+ }
884
+
749
885
  const shortcut = handleSettingsShortcut(JSON.stringify(data).slice(1, -1));
750
886
 
751
887
  if (shortcut?.action === 'cancel') {
@@ -6,18 +6,35 @@ import { DEFAULT_PRESENTATION_CONFIG, resolvePresentationMode } from './presenta
6
6
  import { createResearchWorkflow } from './orchestration/index.js';
7
7
  import { loadPresentationConfigLayers } from './presentation/config-store.js';
8
8
  import { selectPresentationView } from './presentation/select-view.js';
9
- import type {
10
- PresentationConfig,
11
- PresentationEnvelope,
12
- PresentationToolName
13
- } from './presentation/types.js';
9
+ import type { PresentationConfig } from './presentation/types.js';
14
10
  import { createWebExploreTool } from './tools/web-explore.js';
15
11
  import type { WebExploreResponse } from './types.js';
16
12
  import { getUpdateChangelogNotice } from './changelog-notice.js';
13
+ import { Text } from '@earendil-works/pi-tui';
17
14
 
18
- type ToolResultWithPresentation = {
19
- presentation?: PresentationEnvelope;
20
- };
15
+ /**
16
+ * What the model receives as the tool result: the actual synthesized findings (which for a
17
+ * direct GitHub/PDF/YouTube read is the full extracted content), plus source citations and any
18
+ * caveat. This is separate from the terminal display (see renderResult), so the model always
19
+ * gets the substance regardless of the user's compact/preview/verbose presentation setting.
20
+ */
21
+ function serializeForModel(result: WebExploreResponse): string {
22
+ if (result.status === 'error') {
23
+ return `Research failed: ${result.error?.message ?? 'Unknown research failure.'}`;
24
+ }
25
+ if (result.findings.length === 0 && result.sources.length === 0) {
26
+ return 'No usable evidence found.';
27
+ }
28
+ return [
29
+ result.findings.join('\n\n'),
30
+ result.sources.length
31
+ ? `Sources:\n${result.sources.map((source) => `- ${source.title}: ${source.url}`).join('\n')}`
32
+ : undefined,
33
+ result.caveat
34
+ ]
35
+ .filter(Boolean)
36
+ .join('\n\n');
37
+ }
21
38
 
22
39
  async function loadWebAgentConfig(pi: ExtensionAPI) {
23
40
  const store = (
@@ -49,16 +66,6 @@ async function getEffectiveBackendConfig(pi: ExtensionAPI): Promise<BackendConfi
49
66
  }
50
67
  }
51
68
 
52
- async function renderToolText(
53
- pi: ExtensionAPI,
54
- toolName: PresentationToolName,
55
- details: ToolResultWithPresentation
56
- ): Promise<string> {
57
- const config = await getEffectivePresentationConfig(pi);
58
- const mode = resolvePresentationMode(toolName, config);
59
- return selectPresentationView(details.presentation, mode) ?? JSON.stringify(details, null, 2);
60
- }
61
-
62
69
  export default function extension(pi: ExtensionAPI) {
63
70
  registerWebAgentConfigCommands(pi);
64
71
 
@@ -111,16 +118,46 @@ export default function extension(pi: ExtensionAPI) {
111
118
  async execute(_toolCallId, params) {
112
119
  const webExplore = await getConfiguredWebExplore();
113
120
  const result: WebExploreResponse = await webExplore({ query: params.query });
121
+
122
+ // Terminal display honors the user's presentation mode; the model gets the full findings.
123
+ // The fallback must stay terse: never fall back to serializeForModel here, or a missing
124
+ // presentation would dump the full findings into the terminal.
125
+ const mode = resolvePresentationMode('web_explore', await getEffectivePresentationConfig(pi));
126
+ const terseFallback = 'web_explore result';
127
+ const terminalText = selectPresentationView(result.presentation, mode) ?? terseFallback;
128
+ const terminalTextExpanded = selectPresentationView(result.presentation, 'verbose') ?? terminalText;
129
+
114
130
  return {
115
- content: [
116
- {
117
- type: 'text',
118
- text: await renderToolText(pi, 'web_explore', result)
119
- }
120
- ],
121
- details: result,
131
+ content: [{ type: 'text', text: serializeForModel(result) }],
132
+ details: { ...result, terminalText, terminalTextExpanded },
122
133
  isError: result.status === 'error'
123
134
  };
135
+ },
136
+ renderResult(toolResult, options) {
137
+ const details = toolResult.details as
138
+ | {
139
+ terminalText?: string;
140
+ terminalTextExpanded?: string;
141
+ presentation?: { views?: { compact?: string; verbose?: string } };
142
+ }
143
+ | undefined;
144
+ try {
145
+ // Legacy fallback: results persisted before this change carry `presentation` but no
146
+ // `terminalText`, so old sessions stay readable instead of rendering blank.
147
+ const legacy = options.expanded
148
+ ? details?.presentation?.views?.verbose ?? details?.presentation?.views?.compact
149
+ : details?.presentation?.views?.compact;
150
+ const text =
151
+ (options.expanded ? details?.terminalTextExpanded : details?.terminalText) ??
152
+ details?.terminalText ??
153
+ legacy ??
154
+ 'web_explore result';
155
+ return new Text(text, 0, 0);
156
+ } catch {
157
+ // Never throw: a thrown renderer makes Pi fall back to raw content, which would dump
158
+ // the full model-facing findings into the terminal.
159
+ return new Text('web_explore result', 0, 0);
160
+ }
124
161
  }
125
162
  });
126
163
  }
@@ -41,18 +41,26 @@ export function extractReadableContent(html: string, maxLength = 4000): Extracte
41
41
  };
42
42
  }
43
43
 
44
+ const NAMED_ENTITIES: Record<string, string> = {
45
+ '&nbsp;': ' ',
46
+ '&amp;': '&',
47
+ '&lt;': '<',
48
+ '&gt;': '>',
49
+ '&quot;': '"'
50
+ };
51
+
44
52
  function decodeHtmlEntities(text: string): string {
45
- return text
46
- .replace(/&nbsp;/gi, ' ')
47
- .replace(/&amp;/gi, '&')
48
- .replace(/&lt;/gi, '<')
49
- .replace(/&gt;/gi, '>')
50
- .replace(/&quot;/gi, '"')
51
- .replace(/&#39;/gi, "'")
52
- .replace(/&#x27;/gi, "'")
53
- .replace(/&#x2F;/gi, '/')
54
- .replace(/&#(\d+);/g, (_, code) => String.fromCharCode(Number(code)))
55
- .replace(/&#x([\da-f]+);/gi, (_, code) => String.fromCharCode(parseInt(code, 16)));
53
+ // Single pass so each entity is decoded exactly once. A multi-pass decode
54
+ // rescans its own output, which double-unescapes either &amp;lt; -> < or
55
+ // &#38;amp; -> & depending on the pass order. One pass avoids both.
56
+ return text.replace(
57
+ /&(?:#(\d+)|#x([\da-f]+)|nbsp|amp|lt|gt|quot);/gi,
58
+ (match, dec, hex) => {
59
+ if (dec !== undefined) return String.fromCharCode(Number(dec));
60
+ if (hex !== undefined) return String.fromCharCode(parseInt(hex, 16));
61
+ return NAMED_ENTITIES[match.toLowerCase()] ?? match;
62
+ }
63
+ );
56
64
  }
57
65
 
58
66
  function extractTitle(html: string): string | undefined {