@oh-my-pi/pi-coding-agent 16.1.15 → 16.1.16

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 (85) hide show
  1. package/CHANGELOG.md +48 -0
  2. package/dist/cli.js +3725 -4029
  3. package/dist/types/cli/args.d.ts +2 -5
  4. package/dist/types/cli/flag-tables.d.ts +2 -2
  5. package/dist/types/cli/session-picker.d.ts +4 -2
  6. package/dist/types/commands/launch.d.ts +1 -1
  7. package/dist/types/config/settings-schema.d.ts +12 -1
  8. package/dist/types/eval/agent-bridge.d.ts +19 -0
  9. package/dist/types/eval/js/shared/helpers.d.ts +1 -13
  10. package/dist/types/eval/js/shared/types.d.ts +1 -1
  11. package/dist/types/eval/js/worker-protocol.d.ts +1 -1
  12. package/dist/types/eval/py/executor.d.ts +1 -1
  13. package/dist/types/internal-urls/local-protocol.d.ts +18 -1
  14. package/dist/types/main.d.ts +2 -0
  15. package/dist/types/modes/components/plugin-settings.d.ts +5 -0
  16. package/dist/types/modes/components/session-selector.d.ts +25 -0
  17. package/dist/types/task/isolation-runner.d.ts +128 -0
  18. package/dist/types/task/worktree.d.ts +14 -1
  19. package/dist/types/thinking.d.ts +15 -0
  20. package/dist/types/tools/eval-render.d.ts +3 -0
  21. package/dist/types/tools/eval.d.ts +11 -17
  22. package/dist/types/tools/todo.d.ts +26 -28
  23. package/dist/types/tui/output-block.d.ts +8 -0
  24. package/dist/types/utils/image-resize.d.ts +2 -0
  25. package/dist/types/web/search/providers/exa.d.ts +2 -0
  26. package/package.json +12 -12
  27. package/scripts/build-binary.ts +18 -4
  28. package/src/cli/args.ts +4 -5
  29. package/src/cli/flag-tables.ts +3 -3
  30. package/src/cli/gallery-fixtures/interaction.ts +6 -9
  31. package/src/cli/gallery-fixtures/shell.ts +15 -23
  32. package/src/cli/session-picker.ts +17 -3
  33. package/src/commands/launch.ts +3 -3
  34. package/src/config/settings-schema.ts +13 -1
  35. package/src/edit/renderer.ts +34 -12
  36. package/src/eval/__tests__/agent-bridge.test.ts +462 -3
  37. package/src/eval/__tests__/helpers-local-roots.test.ts +2 -5
  38. package/src/eval/__tests__/julia-prelude.test.ts +1 -30
  39. package/src/eval/__tests__/prelude-agent.test.ts +42 -8
  40. package/src/eval/agent-bridge.ts +301 -71
  41. package/src/eval/jl/prelude.jl +32 -227
  42. package/src/eval/jl/runner.jl +38 -12
  43. package/src/eval/js/shared/helpers.ts +1 -114
  44. package/src/eval/js/shared/prelude.txt +13 -27
  45. package/src/eval/js/shared/runtime.ts +0 -6
  46. package/src/eval/js/shared/types.ts +1 -1
  47. package/src/eval/js/worker-protocol.ts +1 -1
  48. package/src/eval/py/__tests__/prelude.test.ts +13 -0
  49. package/src/eval/py/executor.ts +1 -1
  50. package/src/eval/py/prelude.py +47 -105
  51. package/src/eval/py/runner.py +0 -6
  52. package/src/eval/rb/prelude.rb +21 -189
  53. package/src/eval/rb/runner.rb +116 -9
  54. package/src/export/html/tool-views.generated.js +29 -29
  55. package/src/internal-urls/docs-index.generated.txt +1 -1
  56. package/src/internal-urls/local-protocol.ts +100 -53
  57. package/src/main.ts +15 -4
  58. package/src/modes/acp/acp-event-mapper.ts +7 -2
  59. package/src/modes/components/plugin-settings.ts +7 -1
  60. package/src/modes/components/session-selector.ts +143 -29
  61. package/src/modes/controllers/command-controller.ts +5 -0
  62. package/src/modes/rpc/rpc-mode.ts +6 -0
  63. package/src/modes/utils/copy-targets.ts +7 -2
  64. package/src/prompts/system/system-prompt.md +3 -3
  65. package/src/prompts/system/workflow-notice.md +3 -3
  66. package/src/prompts/tools/bash.md +16 -0
  67. package/src/prompts/tools/eval.md +19 -19
  68. package/src/prompts/tools/todo.md +1 -1
  69. package/src/session/agent-session.ts +231 -50
  70. package/src/task/index.ts +61 -207
  71. package/src/task/isolation-runner.ts +354 -0
  72. package/src/task/worktree.ts +46 -9
  73. package/src/thinking.ts +20 -0
  74. package/src/tools/ask.ts +44 -38
  75. package/src/tools/bash.ts +9 -2
  76. package/src/tools/browser/tab-worker.ts +1 -1
  77. package/src/tools/eval-render.ts +34 -27
  78. package/src/tools/eval.ts +100 -103
  79. package/src/tools/index.ts +8 -1
  80. package/src/tools/read.ts +136 -60
  81. package/src/tools/todo.ts +60 -64
  82. package/src/tui/code-cell.ts +1 -1
  83. package/src/tui/output-block.ts +11 -0
  84. package/src/utils/image-resize.ts +30 -0
  85. package/src/web/search/providers/exa.ts +85 -1
package/CHANGELOG.md CHANGED
@@ -2,6 +2,54 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [16.1.16] - 2026-06-23
6
+
7
+ ### Breaking Changes
8
+
9
+ - Renamed the eval `agent()` helper parameters `agent_type` → `agent` and `return_handle` → `handle` across every workflow runtime (Python, JavaScript, Ruby, Julia), so the names are identical in every language (no camelCase/snake_case split) and the agent-selection parameter matches the `task` tool's `agent`. The `__agent__` eval bridge wire protocol was renamed to match.
10
+ - Changed the `eval` tool to take a single cell per call (`{ language, code, title?, timeout?, reset? }`) instead of a `cells` array. State still persists per language across separate eval calls, tool calls, and `task` subagents, so each call is one logical step that reuses everything earlier calls defined — the array only encouraged re-importing/re-declaring the same setup in every batch. The schema, field descriptions, examples, system `eval.md`/`workflowz` helper docs, and the `[i/n]` cell-counter (now hidden for single cells) were updated to match; the renderer, ACP start-text, copy-targets, and collab-web tool view still parse legacy multi-cell transcripts.
11
+
12
+ ### Added
13
+
14
+ - Added `isolated`, `apply`, and `merge` options to eval `agent()` across every workflow runtime (Python, JavaScript, Ruby, Julia) so `workflowz`-driven fan-outs can request the same copy-on-write worktree isolation the `task` tool offers (strict opt-in via `isolated: true`, matching the `task` tool; `apply: false` keeps captured patches/branches without merging back; `merge: false` forces patch mode). Extracted the task-isolation lifecycle into `task/isolation-runner.ts` so the eval bridge and `TaskTool` share one implementation ([#3196](https://github.com/can1357/oh-my-pi/issues/3196))
15
+
16
+ ### Changed
17
+
18
+ - Made the session picker fullscreen with mouse support for clicking rows and scrolling
19
+ - Pinned the session picker footer to the bottom of the screen to prevent layout flickering
20
+ - Simplified `eval` tool to accept a single logical step (code block) instead of an array of cells
21
+ - Updated `eval` tool documentation to emphasize incremental, single-step execution
22
+ - Restricted `bash` tool from using `ls` or `find`, requiring the use of `read` or `find` tools
23
+ - Simplified `todo` tool interface to accept a single operation directly instead of an array of ops
24
+ - Reinforced routing of fragile, multi-step shell logic to the `eval` tool over `bash`. The system-prompt tool policy, `bash.md`, and `eval.md` now treat loops, conditionals, heredocs, inline `-e`/`-c` scripts, multi-stage pipelines, and quote/JSON escaping as the signal to write an `eval` cell; bash's "compute a fact" carveout is narrowed to single short pipelines, and `eval.md` now actively claims that territory with runtime-templated examples (only enabled backends are advertised).
25
+ - Made `eval` an essential built-in tool (`loadMode: "essential"`, added to the default essential tool set) so it stays active under `tools.discoveryMode: "all"` instead of being hidden behind `search_tool_bm25`.
26
+ - Made the `--resume` session picker fullscreen on the terminal's alternate screen, so the list scrolls with the mouse wheel and a row resumes its session on left click. Rows are hit-tested against the live scroll window, and the keybinding hint + bottom border are now pinned to the screen bottom instead of drifting up and down as the visible window changes height.
27
+
28
+ ### Fixed
29
+
30
+ - Fixed `local://` URLs decoding images as corrupted text (mojibake) instead of showing the image
31
+ - Fixed `omp --resume` hanging instead of exiting when the startup session picker is cancelled (Esc) or there are no sessions to resume. Startup arms long-lived handles (theme/appearance listeners, settings save timer, model registry), so the cancel/empty paths' bare `return` left the event loop alive and the process stuck after the picker cleared the alternate screen. These paths now exit cleanly via `process.exit(0)`, matching the `--version`/`--export` early-exit convention. The in-session `/resume` picker is unaffected — it keeps its own cancel handler that just closes the overlay.
32
+ - Fixed the `/resume` session picker scrolling down after a session is deleted. The delete-confirmation dialog was mounted as a sibling below the picker's bottom border, briefly growing the picker past the terminal height; the TUI committed the picker's header rows into native scrollback to fit, and when the dialog closed `windowTop` stayed pinned at the new commit boundary, leaving the header stranded above the viewport. The picker now hosts the `SessionList` in a single content slot and swaps the dialog INTO that slot (replacing the `SessionList`) while it is open, so the dialog only competes with the `SessionList`'s rendered budget — not the `SessionList` AND the picker chrome — and the picker frame stays inside the viewport. ([#3283](https://github.com/can1357/oh-my-pi/issues/3283))
33
+ - Fixed the `eval` tool card not streaming a still-running cell's stdout: a long-running cell (e.g. a `time.sleep()` monitor loop) showed nothing until it returned or was interrupted, then dumped everything at once. The renderer draws cell output from `details.cells[i].output`, which was only populated after `backend.execute()` resolved — live stdout streamed into the transient result `content` tail (and `renderContext.output`), which the per-cell render branch ignores. Streamed chunks now append to the active cell's `output` (a dedicated per-cell tail buffer, capped like the aggregate) as they arrive, so the card shows progress live; on completion the authoritative full output overwrites the live tail. `log()`/`phase()`/`display()` and status ops were unaffected because they already stream via the status channel.
34
+ - Fixed Escape doing nothing in the Settings text-input fields (e.g. "Python Interpreter") on terminals with the kitty keyboard protocol active (ghostty/kitty). Inside the fullscreen settings overlay the protocol reports Escape as the CSI-u sequence `\x1b[27u`, which the text-input submenu's raw `\x1b` compare missed; `handleInputOrEscape` now decodes Escape via `matchesKey`, matching every other Escape-to-cancel path.
35
+ - Fixed Julia `eval` graph/plot visualization (Plots.jl, GraphRecipes, Makie, etc.) never rendering inline. Two bugs: (1) the runner's `build_mime_bundle`/`emit_error` dispatched `show`/`showable`/`showerror` directly from the long-lived `main()` loop, whose world age is frozen before any cell ran, so rich `show(::IO, ::MIME"image/png", …)` methods registered when a plotting package is `using`-ed inside a cell were invisible — `show` fell back to the default struct repr (which itself threw on Julia 1.12, aborting the whole result). These calls now route through `Base.invokelatest`, and the `text/plain` probe is guarded so a failing repr can no longer suppress the image MIME. (2) The default GR backend popped up a native `gksqt` GUI window on each plot; the runner now defaults `GKSwstype=100` (headless, overridable) so plots render only as inline PNGs, mirroring the Python runner's `MPLBACKEND=Agg` default.
36
+ - Fixed streaming output blocks incorrectly calculating preview height, preventing flickering banners
37
+ - Fixed streaming `bash`/`eval` tool output duplicating its `… (N earlier lines, showing 10 of M) (ctrl+o to expand)` preview into native scrollback. The collapsed output is a sliding tail window fixed at 10 lines, so when the box outgrew the live viewport (a tall command/output under a still-live predecessor such as a parallel tool) its mutating tail scrolled above the commit window and the renderer re-committed a fresh snapshot every frame, stacking dozens of stale preview banners and chunks. The output preview is now clamped to the viewport tail (`Math.min(10, previewWindowRows())`) and measured in visual rows at the box's inner content width (via the new `outputBlockContentWidth` helper), so on short terminals the volatile tail shrinks to stay on-screen and is never committed. Fixes the duplication introduced when scroll-off commits were made loss-free.
38
+ - Prevented `/handoff` from executing while a response is streaming to avoid session corruption
39
+ - Fixed `/handoff` cold-missing the provider prompt cache. Handoff generation now builds its request through the same pipeline a live turn uses (`convertMessagesToLlm` + `Agent.buildSideRequestContext` + `prepareSimpleStreamOptions`, via the new `generateHandoffFromContext`), so it reuses the live system prompt, normalized tools, transformed/obfuscated message history, and — critically — a stable `promptCacheKey` with a unique side `sessionId`. Previously the oneshot sent no cache-routing key and skipped the `transformContext`/`transformProviderContext` and tool/message normalization the loop applies, so its prefix never matched what the turn populated and every handoff re-read the whole context uncached. Mirrors the cache-preserving path already used by `/btw` and `/omfg`.
40
+ - Fixed `/handoff` (and the RPC `handoff` command) resetting the agent while a response was still streaming, which let the live turn keep emitting into the torn-down session. Manual handoff now refuses while a prompt is in flight (matching `/fork` and `/move`); the auto-handoff path is unaffected.
41
+ - Fixed Exa web search requests firing back-to-back with no client-side pacing by adding a configurable `exa.searchDelayMs` delay (default 1000ms) between Exa search requests. ([#3271](https://github.com/can1357/oh-my-pi/issues/3271))
42
+ - Fixed `ask` returning `(cancelled)` or aborting the tool when Escape dismissed `Other (type your own)` custom input; it now returns to the option selector so the user can pick a listed answer instead. ([#3269](https://github.com/can1357/oh-my-pi/issues/3269))
43
+ - Fixed `/goal` threshold auto-compaction skipping real sessions through three paths: per-turn supersede/drop-useless pruning no longer deflates the threshold trigger below the last provider-billed context; active-goal text stops now attempt threshold maintenance before unexpected-stop retry continuations can return from post-turn handling; and empty `toolUse` stops keep the existing cleanup pass that strips the orphan assistant from active context + session history before any compaction continuation. Active-goal compaction continuations now also resolve completed retry gates before returning, preventing `isRetrying` from staying stuck after a retry succeeds over the threshold. Added `agent_end maintenance routing` and `Auto-compaction threshold decision` debug logs so future no-start reports identify the exact early-return branch and the billed/stored/resolved/post-maintenance token counts that fed `shouldCompact`. ([#3174](https://github.com/can1357/oh-my-pi/issues/3174))
44
+ - Fixed active `/goal` runs that never reached `agent_end` because the model kept emitting tool calls inside one agent run. Threshold maintenance now runs between tool-call turns, compacts the live loop context in place, and suppresses queued continuations that would race the still-running goal loop. ([#3174](https://github.com/can1357/oh-my-pi/issues/3174))
45
+
46
+ ### Removed
47
+
48
+ - Removed `append`, `tree`, and `diff` eval helper functions from Python, JavaScript, and Ruby
49
+ - Removed `sort`, `uniq`, and `counter` text processing eval helpers from Python, JavaScript, and Ruby
50
+ - Removed the `append(path, content)`, `tree(path, max_depth?, show_hidden?)`, and `diff(a, b)` eval prelude helpers from every workflow runtime (Python, JavaScript, Ruby, Julia), along with their status renderers, icon entries, and tool/`docs` references. Use `write`/`read` for file mutation and `tool.<name>(...)` for richer filesystem operations.
51
+ - Removed the `sort(text, reverse?, unique?)`, `uniq(text, count?)`, and `counter(items, limit?, reverse?)` eval text helpers from the Python, JavaScript, and Ruby prelude surfaces (Julia never defined them), along with the JS `HelperBundle`/`HelperOptions` members and `docs` references. Sort/dedupe/count inline in cell code instead.
52
+
5
53
  ## [16.1.15] - 2026-06-22
6
54
 
7
55
  ### Added