@oh-my-pi/pi-coding-agent 15.10.9 → 15.10.11

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 (352) hide show
  1. package/CHANGELOG.md +117 -0
  2. package/dist/cli.js +23087 -0
  3. package/dist/tokenizers.linux-x64-gnu-xcjh3jwk.node +0 -0
  4. package/dist/types/async/job-manager.d.ts +18 -0
  5. package/dist/types/cli/args.d.ts +1 -1
  6. package/dist/types/cli/dry-balance-cli.d.ts +1 -1
  7. package/dist/types/cli/gallery-cli.d.ts +1 -1
  8. package/dist/types/cli/gallery-fixtures/types.d.ts +1 -1
  9. package/dist/types/cli/usage-cli.d.ts +72 -0
  10. package/dist/types/commands/launch.d.ts +1 -1
  11. package/dist/types/commands/read.d.ts +1 -1
  12. package/dist/types/commands/usage.d.ts +25 -0
  13. package/dist/types/config/append-only-context-mode.d.ts +2 -1
  14. package/dist/types/config/model-discovery.d.ts +55 -0
  15. package/dist/types/config/model-registry.d.ts +20 -219
  16. package/dist/types/config/model-resolver.d.ts +16 -10
  17. package/dist/types/config/model-roles.d.ts +28 -0
  18. package/dist/types/config/models-config-schema.d.ts +523 -42
  19. package/dist/types/config/models-config.d.ts +385 -0
  20. package/dist/types/config/settings-schema.d.ts +12 -16
  21. package/dist/types/config/settings.d.ts +1 -1
  22. package/dist/types/debug/log-viewer.d.ts +1 -1
  23. package/dist/types/debug/raw-sse.d.ts +1 -1
  24. package/dist/types/debug/terminal-info.d.ts +0 -1
  25. package/dist/types/eval/backend.d.ts +0 -2
  26. package/dist/types/eval/idle-timeout.d.ts +0 -4
  27. package/dist/types/eval/js/shared/rewrite-imports.d.ts +6 -6
  28. package/dist/types/export/html/template.generated.d.ts +1 -1
  29. package/dist/types/extensibility/extensions/types.d.ts +3 -3
  30. package/dist/types/hindsight/mental-models.d.ts +17 -8
  31. package/dist/types/internal-urls/artifact-protocol.d.ts +2 -2
  32. package/dist/types/internal-urls/types.d.ts +1 -1
  33. package/dist/types/lsp/edits.d.ts +9 -0
  34. package/dist/types/lsp/index.d.ts +2 -2
  35. package/dist/types/lsp/types.d.ts +2 -0
  36. package/dist/types/lsp/utils.d.ts +3 -0
  37. package/dist/types/mcp/json-rpc.d.ts +5 -0
  38. package/dist/types/mnemopi/state.d.ts +11 -1
  39. package/dist/types/modes/components/agent-dashboard.d.ts +1 -1
  40. package/dist/types/modes/components/assistant-message.d.ts +3 -1
  41. package/dist/types/modes/components/bash-execution.d.ts +1 -1
  42. package/dist/types/modes/components/copy-selector.d.ts +1 -1
  43. package/dist/types/modes/components/dynamic-border.d.ts +1 -1
  44. package/dist/types/modes/components/extensions/extension-dashboard.d.ts +1 -1
  45. package/dist/types/modes/components/extensions/extension-list.d.ts +1 -1
  46. package/dist/types/modes/components/extensions/inspector-panel.d.ts +1 -1
  47. package/dist/types/modes/components/footer.d.ts +1 -1
  48. package/dist/types/modes/components/hook-editor.d.ts +5 -0
  49. package/dist/types/modes/components/hook-input.d.ts +4 -0
  50. package/dist/types/modes/components/hook-selector.d.ts +1 -1
  51. package/dist/types/modes/components/model-selector.d.ts +1 -1
  52. package/dist/types/modes/components/plan-review-overlay.d.ts +1 -1
  53. package/dist/types/modes/components/session-observer-overlay.d.ts +1 -1
  54. package/dist/types/modes/components/session-selector.d.ts +1 -1
  55. package/dist/types/modes/components/status-line/component.d.ts +1 -1
  56. package/dist/types/modes/components/tiny-title-download-progress.d.ts +1 -1
  57. package/dist/types/modes/components/transcript-container.d.ts +31 -26
  58. package/dist/types/modes/components/tree-selector.d.ts +1 -1
  59. package/dist/types/modes/components/user-message-selector.d.ts +1 -1
  60. package/dist/types/modes/components/user-message.d.ts +2 -1
  61. package/dist/types/modes/components/visual-truncate.d.ts +1 -1
  62. package/dist/types/modes/components/welcome.d.ts +19 -3
  63. package/dist/types/modes/controllers/mcp-command-controller.d.ts +1 -1
  64. package/dist/types/modes/controllers/streaming-reveal.d.ts +1 -1
  65. package/dist/types/modes/interactive-mode.d.ts +1 -1
  66. package/dist/types/modes/setup-wizard/scenes/sign-in.d.ts +1 -1
  67. package/dist/types/modes/setup-wizard/scenes/types.d.ts +1 -1
  68. package/dist/types/modes/setup-wizard/scenes/web-search.d.ts +1 -1
  69. package/dist/types/modes/setup-wizard/wizard-overlay.d.ts +1 -1
  70. package/dist/types/modes/types.d.ts +2 -1
  71. package/dist/types/session/agent-session.d.ts +1 -1
  72. package/dist/types/session/auth-broker-config.d.ts +4 -0
  73. package/dist/types/session/session-manager.d.ts +1 -1
  74. package/dist/types/slash-commands/helpers/stats-dashboard.d.ts +13 -0
  75. package/dist/types/ssh/connection-manager.d.ts +8 -0
  76. package/dist/types/task/discovery.d.ts +1 -2
  77. package/dist/types/task/parallel.d.ts +2 -2
  78. package/dist/types/task/worktree.d.ts +2 -0
  79. package/dist/types/tiny/title-client.d.ts +1 -1
  80. package/dist/types/tools/ask.d.ts +4 -0
  81. package/dist/types/tools/conflict-detect.d.ts +16 -0
  82. package/dist/types/tools/github-cache.d.ts +7 -0
  83. package/dist/types/tools/sqlite-reader.d.ts +3 -0
  84. package/dist/types/tools/todo.d.ts +2 -0
  85. package/dist/types/tui/output-block.d.ts +3 -3
  86. package/dist/types/utils/changelog.d.ts +8 -0
  87. package/dist/types/web/scrapers/readthedocs.d.ts +3 -0
  88. package/dist/types/web/scrapers/types.d.ts +12 -0
  89. package/dist/types/web/search/providers/codex.d.ts +1 -1
  90. package/dist/types/web/search/providers/gemini.d.ts +1 -1
  91. package/examples/extensions/tools.ts +5 -4
  92. package/package.json +14 -11
  93. package/scripts/build-binary.ts +18 -23
  94. package/scripts/bundle-dist.ts +81 -0
  95. package/scripts/{dev-launch → omp} +1 -1
  96. package/scripts/{dev-launch-preload.ts → omp.ts} +1 -1
  97. package/src/async/job-manager.ts +57 -3
  98. package/src/autoresearch/dashboard.ts +1 -1
  99. package/src/autoresearch/prompt-setup.md +6 -6
  100. package/src/autoresearch/prompt.md +6 -6
  101. package/src/capability/fs.ts +10 -0
  102. package/src/cli/args.ts +1 -1
  103. package/src/cli/auth-gateway-cli.ts +1 -3
  104. package/src/cli/dry-balance-cli.ts +1 -1
  105. package/src/cli/gallery-cli.ts +1 -1
  106. package/src/cli/gallery-fixtures/fs.ts +1 -1
  107. package/src/cli/gallery-fixtures/types.ts +5 -1
  108. package/src/cli/list-models.ts +7 -12
  109. package/src/cli/usage-cli.ts +603 -0
  110. package/src/cli-commands.ts +1 -0
  111. package/src/cli.ts +69 -5
  112. package/src/commands/complete.ts +1 -1
  113. package/src/commands/launch.ts +1 -1
  114. package/src/commands/read.ts +6 -3
  115. package/src/commands/usage.ts +35 -0
  116. package/src/commit/agentic/agent.ts +1 -1
  117. package/src/commit/model-selection.ts +1 -1
  118. package/src/config/append-only-context-mode.ts +6 -12
  119. package/src/config/model-discovery.ts +554 -0
  120. package/src/config/model-registry.ts +308 -1025
  121. package/src/config/model-resolver.ts +113 -156
  122. package/src/config/model-roles.ts +74 -0
  123. package/src/config/models-config-schema.ts +57 -8
  124. package/src/config/models-config.ts +129 -0
  125. package/src/config/settings-schema.ts +18 -14
  126. package/src/config/settings.ts +37 -1
  127. package/src/dap/client.ts +124 -37
  128. package/src/dap/session.ts +259 -158
  129. package/src/debug/log-viewer.ts +1 -1
  130. package/src/debug/raw-sse.ts +1 -1
  131. package/src/debug/terminal-info.ts +0 -3
  132. package/src/edit/diff.ts +95 -18
  133. package/src/edit/hashline/block-resolver.ts +20 -1
  134. package/src/edit/hashline/diff.ts +36 -1
  135. package/src/edit/hashline/execute.ts +8 -2
  136. package/src/edit/index.ts +16 -1
  137. package/src/edit/modes/patch.ts +52 -0
  138. package/src/edit/modes/replace.ts +56 -22
  139. package/src/edit/notebook.ts +22 -2
  140. package/src/edit/renderer.ts +36 -10
  141. package/src/eval/__tests__/completion-bridge.test.ts +1 -1
  142. package/src/eval/backend.ts +0 -2
  143. package/src/eval/completion-bridge.ts +2 -1
  144. package/src/eval/idle-timeout.ts +2 -9
  145. package/src/eval/js/context-manager.ts +6 -8
  146. package/src/eval/js/executor.ts +6 -2
  147. package/src/eval/js/index.ts +0 -2
  148. package/src/eval/js/shared/helpers.ts +5 -6
  149. package/src/eval/js/shared/local-module-loader.ts +1 -1
  150. package/src/eval/js/shared/prelude.txt +62 -1
  151. package/src/eval/js/shared/rewrite-imports.ts +49 -23
  152. package/src/eval/js/shared/runtime.ts +1 -1
  153. package/src/eval/py/index.ts +0 -2
  154. package/src/eval/py/kernel.ts +19 -0
  155. package/src/eval/py/runner.py +107 -3
  156. package/src/exec/bash-executor.ts +3 -1
  157. package/src/export/html/template.generated.ts +1 -1
  158. package/src/export/html/template.js +3 -1
  159. package/src/extensibility/extensions/types.ts +3 -2
  160. package/src/extensibility/plugins/legacy-pi-compat.ts +20 -3
  161. package/src/hindsight/mental-models.ts +59 -12
  162. package/src/hindsight/state.ts +6 -1
  163. package/src/internal-urls/artifact-protocol.ts +11 -2
  164. package/src/internal-urls/docs-index.generated.ts +10 -10
  165. package/src/internal-urls/issue-pr-protocol.ts +12 -5
  166. package/src/internal-urls/router.ts +1 -1
  167. package/src/internal-urls/types.ts +1 -1
  168. package/src/lib/xai-http.ts +1 -1
  169. package/src/lsp/client.ts +118 -38
  170. package/src/lsp/clients/biome-client.ts +101 -39
  171. package/src/lsp/edits.ts +143 -95
  172. package/src/lsp/index.ts +31 -22
  173. package/src/lsp/render.ts +1 -1
  174. package/src/lsp/types.ts +2 -0
  175. package/src/lsp/utils.ts +28 -10
  176. package/src/main.ts +165 -17
  177. package/src/mcp/json-rpc.ts +35 -5
  178. package/src/mcp/transports/stdio.ts +7 -1
  179. package/src/memories/index.ts +2 -1
  180. package/src/mnemopi/backend.ts +25 -3
  181. package/src/mnemopi/state.ts +38 -2
  182. package/src/modes/components/agent-dashboard.ts +10 -7
  183. package/src/modes/components/assistant-message.ts +19 -13
  184. package/src/modes/components/bash-execution.ts +1 -1
  185. package/src/modes/components/copy-selector.ts +1 -1
  186. package/src/modes/components/diff.ts +13 -2
  187. package/src/modes/components/dynamic-border.ts +12 -3
  188. package/src/modes/components/extensions/extension-dashboard.ts +8 -5
  189. package/src/modes/components/extensions/extension-list.ts +1 -1
  190. package/src/modes/components/extensions/inspector-panel.ts +1 -1
  191. package/src/modes/components/footer.ts +1 -1
  192. package/src/modes/components/history-search.ts +1 -1
  193. package/src/modes/components/hook-editor.ts +8 -0
  194. package/src/modes/components/hook-input.ts +8 -0
  195. package/src/modes/components/hook-selector.ts +2 -2
  196. package/src/modes/components/model-selector.ts +66 -54
  197. package/src/modes/components/plan-review-overlay.ts +1 -1
  198. package/src/modes/components/session-observer-overlay.ts +2 -2
  199. package/src/modes/components/session-selector.ts +1 -1
  200. package/src/modes/components/settings-selector.ts +5 -1
  201. package/src/modes/components/status-line/component.ts +1 -1
  202. package/src/modes/components/tiny-title-download-progress.ts +1 -1
  203. package/src/modes/components/transcript-container.ts +373 -141
  204. package/src/modes/components/tree-selector.ts +3 -3
  205. package/src/modes/components/user-message-selector.ts +1 -1
  206. package/src/modes/components/user-message.ts +17 -5
  207. package/src/modes/components/visual-truncate.ts +1 -1
  208. package/src/modes/components/welcome.ts +108 -26
  209. package/src/modes/controllers/command-controller.ts +10 -3
  210. package/src/modes/controllers/event-controller.ts +73 -49
  211. package/src/modes/controllers/input-controller.ts +5 -5
  212. package/src/modes/controllers/mcp-command-controller.ts +1 -1
  213. package/src/modes/controllers/selector-controller.ts +1 -5
  214. package/src/modes/controllers/streaming-reveal.ts +85 -18
  215. package/src/modes/interactive-mode.ts +5 -19
  216. package/src/modes/setup-wizard/scenes/glyph.ts +1 -1
  217. package/src/modes/setup-wizard/scenes/providers.ts +1 -1
  218. package/src/modes/setup-wizard/scenes/sign-in.ts +1 -1
  219. package/src/modes/setup-wizard/scenes/theme.ts +1 -1
  220. package/src/modes/setup-wizard/scenes/types.ts +1 -1
  221. package/src/modes/setup-wizard/scenes/web-search.ts +1 -1
  222. package/src/modes/setup-wizard/wizard-overlay.ts +1 -1
  223. package/src/modes/types.ts +2 -1
  224. package/src/prompts/agents/explore.md +2 -2
  225. package/src/prompts/agents/librarian.md +1 -2
  226. package/src/prompts/agents/oracle.md +1 -1
  227. package/src/prompts/agents/plan.md +5 -5
  228. package/src/prompts/agents/task.md +5 -5
  229. package/src/prompts/ci-green-request.md +5 -7
  230. package/src/prompts/goals/goal-budget-limit.md +2 -2
  231. package/src/prompts/goals/goal-continuation.md +4 -4
  232. package/src/prompts/goals/goal-mode-active.md +1 -1
  233. package/src/prompts/memories/read-path.md +1 -1
  234. package/src/prompts/memories/stage_one_system.md +2 -2
  235. package/src/prompts/review-custom-request.md +1 -1
  236. package/src/prompts/system/agent-creation-architect.md +2 -2
  237. package/src/prompts/system/auto-continue.md +1 -1
  238. package/src/prompts/system/background-tan-dispatch.md +1 -1
  239. package/src/prompts/system/btw-user.md +2 -2
  240. package/src/prompts/system/commit-message-system.md +13 -1
  241. package/src/prompts/system/custom-system-prompt.md +1 -1
  242. package/src/prompts/system/eager-todo.md +2 -2
  243. package/src/prompts/system/irc-incoming.md +1 -1
  244. package/src/prompts/system/manual-continue.md +1 -1
  245. package/src/prompts/system/omfg-user.md +3 -4
  246. package/src/prompts/system/orchestrate-notice.md +9 -9
  247. package/src/prompts/system/plan-mode-active.md +4 -4
  248. package/src/prompts/system/plan-mode-subagent.md +4 -5
  249. package/src/prompts/system/plan-mode-tool-decision-reminder.md +1 -1
  250. package/src/prompts/system/project-prompt.md +2 -2
  251. package/src/prompts/system/subagent-system-prompt.md +4 -4
  252. package/src/prompts/system/system-prompt.md +15 -26
  253. package/src/prompts/system/title-system.md +2 -2
  254. package/src/prompts/system/ttsr-tool-reminder.md +1 -1
  255. package/src/prompts/system/workflow-notice.md +1 -1
  256. package/src/prompts/tools/ast-edit.md +1 -1
  257. package/src/prompts/tools/ast-grep.md +2 -2
  258. package/src/prompts/tools/bash.md +8 -10
  259. package/src/prompts/tools/browser.md +7 -7
  260. package/src/prompts/tools/debug.md +1 -1
  261. package/src/prompts/tools/eval.md +3 -3
  262. package/src/prompts/tools/find.md +0 -1
  263. package/src/prompts/tools/github.md +8 -7
  264. package/src/prompts/tools/goal.md +1 -1
  265. package/src/prompts/tools/image-gen.md +1 -1
  266. package/src/prompts/tools/inspect-image-system.md +1 -1
  267. package/src/prompts/tools/irc.md +15 -15
  268. package/src/prompts/tools/lsp.md +2 -2
  269. package/src/prompts/tools/patch.md +2 -2
  270. package/src/prompts/tools/read.md +3 -4
  271. package/src/prompts/tools/recall.md +1 -1
  272. package/src/prompts/tools/reflect.md +1 -1
  273. package/src/prompts/tools/render-mermaid.md +2 -2
  274. package/src/prompts/tools/replace.md +4 -10
  275. package/src/prompts/tools/rewind.md +2 -2
  276. package/src/prompts/tools/search-tool-bm25.md +1 -9
  277. package/src/prompts/tools/search.md +0 -1
  278. package/src/prompts/tools/ssh.md +0 -4
  279. package/src/prompts/tools/task.md +2 -3
  280. package/src/prompts/tools/todo.md +6 -2
  281. package/src/sdk.ts +23 -10
  282. package/src/session/agent-session.ts +44 -10
  283. package/src/session/auth-broker-config.ts +30 -1
  284. package/src/session/session-manager.ts +2 -2
  285. package/src/session/streaming-output.ts +23 -2
  286. package/src/slash-commands/builtin-registry.ts +20 -0
  287. package/src/slash-commands/helpers/stats-dashboard.ts +85 -0
  288. package/src/ssh/connection-manager.ts +27 -0
  289. package/src/task/commands.ts +2 -1
  290. package/src/task/discovery.ts +17 -24
  291. package/src/task/executor.ts +61 -53
  292. package/src/task/index.ts +137 -60
  293. package/src/task/parallel.ts +3 -3
  294. package/src/task/render.ts +2 -2
  295. package/src/task/worktree.ts +64 -56
  296. package/src/thinking.ts +2 -1
  297. package/src/tiny/title-client.ts +32 -14
  298. package/src/tools/archive-reader.ts +30 -2
  299. package/src/tools/ask.ts +104 -21
  300. package/src/tools/ast-edit.ts +25 -5
  301. package/src/tools/auto-generated-guard.ts +20 -3
  302. package/src/tools/bash-interactive.ts +27 -7
  303. package/src/tools/bash.ts +54 -13
  304. package/src/tools/browser/launch.ts +11 -2
  305. package/src/tools/browser/readable.ts +19 -2
  306. package/src/tools/browser/registry.ts +4 -1
  307. package/src/tools/browser/render.ts +2 -2
  308. package/src/tools/browser/tab-supervisor.ts +55 -16
  309. package/src/tools/conflict-detect.ts +50 -4
  310. package/src/tools/debug.ts +1 -1
  311. package/src/tools/eval-render.ts +5 -5
  312. package/src/tools/eval.ts +0 -2
  313. package/src/tools/fetch.ts +33 -10
  314. package/src/tools/gh-cache-invalidation.ts +63 -8
  315. package/src/tools/gh-renderer.ts +1 -1
  316. package/src/tools/gh.ts +172 -29
  317. package/src/tools/github-cache.ts +70 -6
  318. package/src/tools/image-gen.ts +3 -9
  319. package/src/tools/irc.ts +5 -1
  320. package/src/tools/job.ts +1 -1
  321. package/src/tools/read.ts +202 -61
  322. package/src/tools/render-utils.ts +3 -3
  323. package/src/tools/resolve.ts +1 -1
  324. package/src/tools/search.ts +92 -29
  325. package/src/tools/sqlite-reader.ts +17 -5
  326. package/src/tools/ssh.ts +8 -8
  327. package/src/tools/todo.ts +51 -12
  328. package/src/tools/write.ts +118 -18
  329. package/src/tui/output-block.ts +4 -4
  330. package/src/utils/changelog.ts +27 -1
  331. package/src/utils/file-mentions.ts +2 -1
  332. package/src/web/scrapers/arxiv.ts +1 -1
  333. package/src/web/scrapers/go-pkg.ts +1 -1
  334. package/src/web/scrapers/iacr.ts +1 -1
  335. package/src/web/scrapers/readthedocs.ts +1 -1
  336. package/src/web/scrapers/twitter.ts +2 -1
  337. package/src/web/scrapers/types.ts +87 -8
  338. package/src/web/scrapers/wikipedia.ts +1 -1
  339. package/src/web/scrapers/youtube.ts +6 -1
  340. package/src/web/search/index.ts +1 -1
  341. package/src/web/search/providers/anthropic.ts +8 -2
  342. package/src/web/search/providers/codex.ts +2 -1
  343. package/src/web/search/providers/gemini.ts +2 -3
  344. package/src/web/search/render.ts +8 -6
  345. package/dist/types/config/model-equivalence.d.ts +0 -24
  346. package/dist/types/config/model-id-affixes.d.ts +0 -12
  347. package/dist/types/config/model-provider-priority.d.ts +0 -1
  348. package/dist/types/exec/idle-timeout-watchdog.d.ts +0 -18
  349. package/src/config/model-equivalence.ts +0 -875
  350. package/src/config/model-id-affixes.ts +0 -81
  351. package/src/config/model-provider-priority.ts +0 -56
  352. package/src/exec/idle-timeout-watchdog.ts +0 -126
@@ -455,7 +455,7 @@ function formatCellOutputLines(
455
455
  previewLines: number,
456
456
  theme: Theme,
457
457
  width: number,
458
- ): { lines: string[]; hiddenCount: number } {
458
+ ): { lines: readonly string[]; hiddenCount: number } {
459
459
  if (!cell.output) {
460
460
  return { lines: [], hiddenCount: 0 };
461
461
  }
@@ -492,7 +492,7 @@ export const evalToolRenderer = {
492
492
  let cached: { key: string; width: number; result: string[] } | undefined;
493
493
 
494
494
  return markFramedBlockComponent({
495
- render: (width: number): string[] => {
495
+ render: (width: number): readonly string[] => {
496
496
  const key = `${options.expanded ? 1 : 0}|${cells.map(c => `${c.language}:${c.title ?? ""}:${c.code.length}`).join("|")}`;
497
497
  if (cached && cached.key === key && cached.width === width) {
498
498
  return cached.result;
@@ -573,7 +573,7 @@ export const evalToolRenderer = {
573
573
  let cached: { key: string; width: number; result: string[] } | undefined;
574
574
 
575
575
  return markFramedBlockComponent({
576
- render: (width: number): string[] => {
576
+ render: (width: number): readonly string[] => {
577
577
  const expanded = options.renderContext?.expanded ?? options.expanded;
578
578
  const previewLines = options.renderContext?.previewLines ?? EVAL_DEFAULT_PREVIEW_LINES;
579
579
  const key = `${expanded}|${previewLines}|${options.spinnerFrame}`;
@@ -697,12 +697,12 @@ export const evalToolRenderer = {
697
697
  const textContent = `\n${styledOutput}`;
698
698
 
699
699
  let cachedWidth: number | undefined;
700
- let cachedLines: string[] | undefined;
700
+ let cachedLines: readonly string[] | undefined;
701
701
  let cachedSkipped: number | undefined;
702
702
  let cachedPreviewLines: number | undefined;
703
703
 
704
704
  return {
705
- render: (width: number): string[] => {
705
+ render: (width: number): readonly string[] => {
706
706
  const previewLines = options.renderContext?.previewLines ?? EVAL_DEFAULT_PREVIEW_LINES;
707
707
  if (cachedLines === undefined || cachedWidth !== width || cachedPreviewLines !== previewLines) {
708
708
  const result = truncateToVisualLines(textContent, previewLines, width);
package/src/tools/eval.ts CHANGED
@@ -358,8 +358,6 @@ export class EvalTool implements AgentTool<typeof evalSchema> {
358
358
  session,
359
359
  idleTimeoutMs,
360
360
  reset: cell.reset,
361
- artifactPath,
362
- artifactId,
363
361
  onChunk: chunk => {
364
362
  outputSink!.push(chunk);
365
363
  },
@@ -7,7 +7,6 @@ import type { FetchImpl, ImageContent, TextContent } from "@oh-my-pi/pi-ai";
7
7
  import { htmlToMarkdown } from "@oh-my-pi/pi-natives";
8
8
  import { type Component, Text } from "@oh-my-pi/pi-tui";
9
9
  import { $which, ptree, truncate } from "@oh-my-pi/pi-utils";
10
- import { parseHTML } from "linkedom";
11
10
  import { LRUCache } from "lru-cache/raw";
12
11
  import type { Settings } from "../config/settings";
13
12
  import { readEditableNotebookText } from "../edit/notebook";
@@ -23,7 +22,7 @@ import { ensureTool } from "../utils/tools-manager";
23
22
  import { extractWithParallel, findParallelApiKey, getParallelExtractContent } from "../web/parallel";
24
23
  import { specialHandlers } from "../web/scrapers";
25
24
  import type { RenderResult } from "../web/scrapers/types";
26
- import { finalizeOutput, loadPage, looksLikeHtml, MAX_OUTPUT_CHARS } from "../web/scrapers/types";
25
+ import { finalizeOutput, loadPage, looksLikeHtml, MAX_BYTES, MAX_OUTPUT_CHARS } from "../web/scrapers/types";
27
26
  import { convertWithMarkit, fetchBinary } from "../web/scrapers/utils";
28
27
  import { type ArchiveFormat, listArchiveRoot, sniffArchiveFormat } from "./archive-reader";
29
28
  import { applyListLimit } from "./list-limit";
@@ -191,7 +190,7 @@ export interface ParsedReadUrlTarget {
191
190
 
192
191
  /** Recognize a single selector token (`raw` or one/many line ranges). */
193
192
  function isUrlSelectorToken(token: string): boolean {
194
- if (token === "raw") return true;
193
+ if (token.toLowerCase() === "raw") return true;
195
194
  try {
196
195
  return parseLineRanges(token) !== null;
197
196
  } catch {
@@ -213,7 +212,7 @@ export function parseReadUrlTarget(readPath: string): ParsedReadUrlTarget | null
213
212
  let raw = false;
214
213
  let ranges: readonly LineRange[] | undefined;
215
214
  for (const sel of embedded?.sels ?? []) {
216
- if (sel === "raw") {
215
+ if (sel.toLowerCase() === "raw") {
217
216
  raw = true;
218
217
  continue;
219
218
  }
@@ -549,7 +548,8 @@ function cleanFeedText(text: string): string {
549
548
  /**
550
549
  * Parse RSS/Atom feed to markdown
551
550
  */
552
- function parseFeedToMarkdown(content: string, maxItems = 10): string {
551
+ async function parseFeedToMarkdown(content: string, maxItems = 10): Promise<string> {
552
+ const { parseHTML } = await import("linkedom");
553
553
  try {
554
554
  const doc = parseHTML(content).document;
555
555
 
@@ -805,6 +805,21 @@ function isArchiveHint(mime: string, extensionHint: string): boolean {
805
805
  return ARCHIVE_MIMES.has(mime) || ARCHIVE_EXTENSIONS.has(extensionHint);
806
806
  }
807
807
 
808
+ /**
809
+ * Content types whose payload renderUrl always re-fetches via fetchBinary.
810
+ * Skipping the initial body read for them avoids downloading and
811
+ * string-decoding huge binaries (PDFs, archives, images) twice.
812
+ */
813
+ function shouldSkipBodyDownload(contentType: string): boolean {
814
+ return (
815
+ CONVERTIBLE_MIMES.has(contentType) ||
816
+ NOTEBOOK_MIMES.has(contentType) ||
817
+ SQLITE_MIMES.has(contentType) ||
818
+ ARCHIVE_MIMES.has(contentType) ||
819
+ SUPPORTED_INLINE_IMAGE_MIME_TYPES.has(contentType)
820
+ );
821
+ }
822
+
808
823
  function getArchiveFormatHint(mime: string, extensionHint: string): ArchiveFormat | undefined {
809
824
  if (extensionHint === ".zip" || mime === "application/zip" || mime === "application/x-zip-compressed") {
810
825
  return "zip";
@@ -901,6 +916,7 @@ async function tryRenderBinaryPayload(
901
916
  mime: string,
902
917
  extHint: string,
903
918
  rawContent: string,
919
+ bodySkipped: boolean,
904
920
  timeout: number,
905
921
  signal: AbortSignal | undefined,
906
922
  fetchedAt: string,
@@ -909,7 +925,7 @@ async function tryRenderBinaryPayload(
909
925
  const hasNotebookHint = isNotebookHint(mime, extHint);
910
926
  const hasSqliteHint = isSqliteHint(mime, extHint);
911
927
  const hasArchiveHint = isArchiveHint(mime, extHint);
912
- const rawLooksBinary = sampleLooksBinary(rawContent);
928
+ const rawLooksBinary = bodySkipped || sampleLooksBinary(rawContent);
913
929
  if (!hasNotebookHint && !hasSqliteHint && !hasArchiveHint && !rawLooksBinary) {
914
930
  return null;
915
931
  }
@@ -1092,7 +1108,7 @@ async function renderUrl(
1092
1108
  }
1093
1109
 
1094
1110
  // Step 2: Fetch page
1095
- const response = await loadPage(url, { timeout, signal });
1111
+ const response = await loadPage(url, { timeout, signal, skipBodyForContentType: shouldSkipBodyDownload });
1096
1112
  if (signal?.aborted) {
1097
1113
  throw new ToolAbortError();
1098
1114
  }
@@ -1105,11 +1121,17 @@ async function renderUrl(
1105
1121
  content: "",
1106
1122
  fetchedAt,
1107
1123
  truncated: false,
1108
- notes: [response.status ? `Failed to fetch URL (HTTP ${response.status})` : "Failed to fetch URL"],
1124
+ notes: [
1125
+ response.status ? `Failed to fetch URL (HTTP ${response.status})` : "Failed to fetch URL",
1126
+ ...(response.error ? [`Cause: ${response.error}`] : []),
1127
+ ],
1109
1128
  };
1110
1129
  }
1111
1130
 
1112
1131
  const { finalUrl, content: rawContent } = response;
1132
+ if (response.truncated) {
1133
+ notes.push(`Response body exceeded ${formatBytes(MAX_BYTES)} and was cut mid-stream; content is incomplete`);
1134
+ }
1113
1135
  const mime = normalizeMime(response.contentType);
1114
1136
  const extHint = getExtensionHint(finalUrl);
1115
1137
 
@@ -1276,6 +1298,7 @@ async function renderUrl(
1276
1298
  mime,
1277
1299
  extHint,
1278
1300
  rawContent,
1301
+ response.bodySkipped === true,
1279
1302
  timeout,
1280
1303
  signal,
1281
1304
  fetchedAt,
@@ -1321,7 +1344,7 @@ async function renderUrl(
1321
1344
  }
1322
1345
 
1323
1346
  if (isFeed || (isXml && (rawContent.includes("<rss") || rawContent.includes("<feed")))) {
1324
- const parsed = parseFeedToMarkdown(rawContent);
1347
+ const parsed = await parseFeedToMarkdown(rawContent);
1325
1348
  const output = finalizeOutput(parsed);
1326
1349
  return {
1327
1350
  url,
@@ -1414,7 +1437,7 @@ async function renderUrl(
1414
1437
  const altResult = await loadPage(resolved, { timeout, signal });
1415
1438
  if (altResult.ok && altResult.content.trim().length > 200) {
1416
1439
  notes.push(`Used feed alternate: ${resolved}`);
1417
- const parsed = parseFeedToMarkdown(altResult.content);
1440
+ const parsed = await parseFeedToMarkdown(altResult.content);
1418
1441
  const output = finalizeOutput(parsed);
1419
1442
  return {
1420
1443
  url,
@@ -17,7 +17,7 @@
17
17
  * number, all auth_keys) because the upside of staleness elimination
18
18
  * dwarfs the cost of one cache miss.
19
19
  */
20
- import { invalidateAllForNumber } from "./github-cache";
20
+ import { invalidateAllForNumber, invalidateAllForRepo } from "./github-cache";
21
21
 
22
22
  const PR_URL_PATTERN = /^https:\/\/github\.com\/([^/\s]+\/[^/\s]+)\/pull\/(\d+)(?:[/?#].*)?$/i;
23
23
  const ISSUE_URL_PATTERN = /^https:\/\/github\.com\/([^/\s]+\/[^/\s]+)\/issues\/(\d+)(?:[/?#].*)?$/i;
@@ -48,13 +48,60 @@ const MUTATING_PR_SUBCMDS: Record<string, true> = {
48
48
  lock: true,
49
49
  unlock: true,
50
50
  };
51
+
52
+ /**
53
+ * Flags whose value is the next argv token (`--milestone 3`). The detector
54
+ * must skip those values so `gh pr edit --milestone 3 14` invalidates #14,
55
+ * not #3. Curated for the mutating issue/PR subcommands above; a few short
56
+ * flags are booleans for *some* subcommands (e.g. `-c` is `--comment` text
57
+ * for `pr close` but a boolean for `pr review`) — we bias toward value-taking
58
+ * because over-skipping at worst falls back to repo-wide invalidation, while
59
+ * under-skipping invalidates the wrong number.
60
+ */
61
+ const VALUE_TAKING_FLAGS: ReadonlySet<string> = new Set([
62
+ "-m",
63
+ "--milestone",
64
+ "-t",
65
+ "--title",
66
+ "-b",
67
+ "--body",
68
+ "-F",
69
+ "--body-file",
70
+ "-a",
71
+ "--assignee",
72
+ "--add-assignee",
73
+ "--remove-assignee",
74
+ "-l",
75
+ "--label",
76
+ "--add-label",
77
+ "--remove-label",
78
+ "-p",
79
+ "--project",
80
+ "--add-project",
81
+ "--remove-project",
82
+ "--add-reviewer",
83
+ "--remove-reviewer",
84
+ "-B",
85
+ "--base",
86
+ "-c",
87
+ "--comment",
88
+ "-r",
89
+ "--reason",
90
+ "--branch",
91
+ "--subject",
92
+ "--match-head-commit",
93
+ "--author-email",
94
+ ]);
51
95
  /**
52
96
  * Walk a single shell command's token stream looking for a top-level
53
- * `gh (issue|pr) <subcmd> <id-or-url>` invocation and return the
54
- * invalidation key when one is found. Returns `null` for non-matching
55
- * commands so the caller can iterate cheaply.
97
+ * `gh (issue|pr) <subcmd> [<id-or-url>]` invocation and return the
98
+ * invalidation key when one is found. `number === undefined` means the
99
+ * subcommand mutates state but names no identifier (gh defaults to the
100
+ * current branch's PR), so the caller must fall back to repo-wide
101
+ * invalidation. Returns `null` for non-matching commands so the caller can
102
+ * iterate cheaply.
56
103
  */
57
- function detectGhMutation(tokens: readonly string[]): { number: number; repo?: string } | null {
104
+ function detectGhMutation(tokens: readonly string[]): { number?: number; repo?: string } | null {
58
105
  const ghIdx = tokens.indexOf("gh");
59
106
  if (ghIdx === -1) return null;
60
107
  const subject = tokens[ghIdx + 1];
@@ -82,7 +129,9 @@ function detectGhMutation(tokens: readonly string[]): { number: number; repo?: s
82
129
  }
83
130
  for (let i = ghIdx + 3; i < tokens.length; i++) {
84
131
  const token = tokens[i];
85
- if (token === "-R" || token === "--repo") {
132
+ if (token === "-R" || token === "--repo" || VALUE_TAKING_FLAGS.has(token)) {
133
+ // Skip the flag's value so it is never mistaken for the positional
134
+ // identifier (`--milestone 3 14` must invalidate #14, not #3).
86
135
  i++;
87
136
  continue;
88
137
  }
@@ -100,7 +149,9 @@ function detectGhMutation(tokens: readonly string[]): { number: number; repo?: s
100
149
  }
101
150
  }
102
151
  }
103
- return null;
152
+ // Mutating subcommand with no identifier: gh operates on the current
153
+ // branch's PR, which we cannot resolve synchronously here.
154
+ return repo !== undefined ? { repo } : {};
104
155
  }
105
156
 
106
157
  /**
@@ -195,6 +246,10 @@ export function invalidateGithubCacheForBashCommand(command: string): void {
195
246
  for (const segment of segments) {
196
247
  const hit = detectGhMutation(segment);
197
248
  if (!hit) continue;
198
- invalidateAllForNumber(hit.number, hit.repo);
249
+ if (hit.number !== undefined) {
250
+ invalidateAllForNumber(hit.number, hit.repo);
251
+ } else {
252
+ invalidateAllForRepo(hit.repo);
253
+ }
199
254
  }
200
255
  }
@@ -163,7 +163,7 @@ function getJobStateVisual(
163
163
  ): { iconRaw: string; iconColor: ToolUIColor; textColor: ThemeColor } {
164
164
  if (job.conclusion && SUCCESS_CONCLUSIONS.has(job.conclusion)) {
165
165
  return {
166
- iconRaw: theme.symbol("tool.gh"),
166
+ iconRaw: theme.status.success,
167
167
  iconColor: "accent",
168
168
  textColor: "success",
169
169
  };