@oh-my-pi/pi-coding-agent 15.7.5 → 15.8.0

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 (146) hide show
  1. package/CHANGELOG.md +159 -182
  2. package/dist/types/async/job-manager.d.ts +3 -3
  3. package/dist/types/cli/args.d.ts +1 -0
  4. package/dist/types/cli/claude-trace-cli.d.ts +54 -0
  5. package/dist/types/cli/session-picker.d.ts +10 -3
  6. package/dist/types/cli/update-cli.d.ts +17 -0
  7. package/dist/types/commands/launch.d.ts +3 -0
  8. package/dist/types/config/keybindings.d.ts +5 -0
  9. package/dist/types/config/settings-schema.d.ts +11 -2
  10. package/dist/types/config/settings.d.ts +13 -0
  11. package/dist/types/eval/__tests__/heartbeat.test.d.ts +1 -0
  12. package/dist/types/eval/concurrency-bridge.d.ts +26 -0
  13. package/dist/types/eval/heartbeat.d.ts +45 -0
  14. package/dist/types/eval/js/tool-bridge.d.ts +2 -1
  15. package/dist/types/extensibility/extensions/loader.d.ts +2 -2
  16. package/dist/types/extensibility/extensions/runner.d.ts +2 -1
  17. package/dist/types/extensibility/extensions/types.d.ts +24 -5
  18. package/dist/types/extensibility/plugins/legacy-pi-compat.d.ts +11 -0
  19. package/dist/types/lsp/diagnostics-ledger.d.ts +10 -0
  20. package/dist/types/lsp/index.d.ts +2 -0
  21. package/dist/types/lsp/utils.d.ts +4 -0
  22. package/dist/types/main.d.ts +5 -0
  23. package/dist/types/modes/acp/acp-agent.d.ts +1 -1
  24. package/dist/types/modes/components/assistant-message.d.ts +3 -1
  25. package/dist/types/modes/components/custom-editor.d.ts +3 -2
  26. package/dist/types/modes/components/hook-selector.d.ts +10 -1
  27. package/dist/types/modes/components/session-selector.d.ts +32 -5
  28. package/dist/types/modes/components/tool-execution.d.ts +8 -0
  29. package/dist/types/modes/controllers/extension-ui-controller.d.ts +3 -3
  30. package/dist/types/modes/controllers/input-controller.d.ts +1 -0
  31. package/dist/types/modes/interactive-mode.d.ts +10 -3
  32. package/dist/types/modes/rpc/rpc-mode.d.ts +1 -1
  33. package/dist/types/modes/theme/theme.d.ts +1 -1
  34. package/dist/types/modes/types.d.ts +5 -3
  35. package/dist/types/registry/agent-registry.d.ts +1 -1
  36. package/dist/types/sdk.d.ts +2 -2
  37. package/dist/types/session/agent-session.d.ts +12 -3
  38. package/dist/types/session/history-storage.d.ts +16 -1
  39. package/dist/types/session/session-manager.d.ts +4 -0
  40. package/dist/types/task/output-manager.d.ts +6 -15
  41. package/dist/types/tools/ask.d.ts +8 -6
  42. package/dist/types/tools/eval-backends.d.ts +12 -0
  43. package/dist/types/tools/eval-render.d.ts +52 -0
  44. package/dist/types/tools/eval.d.ts +2 -35
  45. package/dist/types/tools/find.d.ts +0 -9
  46. package/dist/types/tools/index.d.ts +5 -12
  47. package/dist/types/tools/path-utils.d.ts +16 -0
  48. package/dist/types/tools/sqlite-reader.d.ts +25 -8
  49. package/dist/types/tui/output-block.d.ts +4 -3
  50. package/dist/types/utils/clipboard.d.ts +4 -0
  51. package/dist/types/web/kagi.d.ts +76 -0
  52. package/dist/types/web/search/providers/exa.d.ts +7 -1
  53. package/dist/types/web/search/providers/kagi.d.ts +1 -0
  54. package/examples/extensions/README.md +1 -0
  55. package/examples/extensions/thinking-note.ts +13 -0
  56. package/package.json +9 -9
  57. package/src/async/job-manager.ts +3 -3
  58. package/src/cli/args.ts +6 -2
  59. package/src/cli/claude-trace-cli.ts +783 -0
  60. package/src/cli/session-picker.ts +36 -10
  61. package/src/cli/update-cli.ts +35 -2
  62. package/src/commands/launch.ts +3 -0
  63. package/src/config/keybindings.ts +6 -0
  64. package/src/config/model-registry.ts +33 -4
  65. package/src/config/settings-schema.ts +12 -2
  66. package/src/config/settings.ts +23 -0
  67. package/src/discovery/claude-plugins.ts +7 -9
  68. package/src/discovery/claude.ts +41 -22
  69. package/src/edit/index.ts +23 -3
  70. package/src/eval/__tests__/agent-bridge.test.ts +148 -4
  71. package/src/eval/__tests__/heartbeat.test.ts +84 -0
  72. package/src/eval/__tests__/llm-bridge.test.ts +30 -0
  73. package/src/eval/agent-bridge.ts +44 -38
  74. package/src/eval/concurrency-bridge.ts +34 -0
  75. package/src/eval/heartbeat.ts +74 -0
  76. package/src/eval/js/executor.ts +13 -9
  77. package/src/eval/js/shared/prelude.txt +20 -17
  78. package/src/eval/js/tool-bridge.ts +5 -0
  79. package/src/eval/llm-bridge.ts +20 -14
  80. package/src/eval/py/executor.ts +14 -18
  81. package/src/eval/py/prelude.py +23 -15
  82. package/src/exec/bash-executor.ts +31 -5
  83. package/src/extensibility/extensions/loader.ts +16 -18
  84. package/src/extensibility/extensions/runner.ts +22 -17
  85. package/src/extensibility/extensions/types.ts +39 -5
  86. package/src/extensibility/plugins/legacy-pi-compat.ts +115 -131
  87. package/src/extensibility/skills.ts +0 -1
  88. package/src/internal-urls/docs-index.generated.ts +14 -13
  89. package/src/lsp/diagnostics-ledger.ts +51 -0
  90. package/src/lsp/index.ts +9 -22
  91. package/src/lsp/utils.ts +21 -0
  92. package/src/main.ts +92 -24
  93. package/src/modes/acp/acp-agent.ts +8 -4
  94. package/src/modes/acp/acp-event-mapper.ts +54 -4
  95. package/src/modes/components/assistant-message.ts +28 -1
  96. package/src/modes/components/custom-editor.ts +19 -7
  97. package/src/modes/components/hook-selector.ts +229 -44
  98. package/src/modes/components/oauth-selector.ts +12 -6
  99. package/src/modes/components/session-selector.ts +179 -24
  100. package/src/modes/components/tool-execution.ts +36 -7
  101. package/src/modes/controllers/command-controller.ts +2 -11
  102. package/src/modes/controllers/event-controller.ts +5 -2
  103. package/src/modes/controllers/extension-ui-controller.ts +6 -4
  104. package/src/modes/controllers/input-controller.ts +19 -16
  105. package/src/modes/controllers/selector-controller.ts +61 -21
  106. package/src/modes/interactive-mode.ts +127 -16
  107. package/src/modes/rpc/rpc-mode.ts +17 -6
  108. package/src/modes/theme/theme-schema.json +30 -0
  109. package/src/modes/theme/theme.ts +39 -2
  110. package/src/modes/types.ts +7 -3
  111. package/src/modes/utils/ui-helpers.ts +5 -2
  112. package/src/prompts/system/orchestrate-notice.md +5 -3
  113. package/src/prompts/system/workflow-notice.md +2 -2
  114. package/src/prompts/tools/ask.md +2 -1
  115. package/src/prompts/tools/eval.md +6 -6
  116. package/src/prompts/tools/find.md +1 -1
  117. package/src/prompts/tools/irc.md +6 -6
  118. package/src/prompts/tools/search.md +1 -1
  119. package/src/prompts/tools/task.md +1 -1
  120. package/src/registry/agent-registry.ts +1 -1
  121. package/src/sdk.ts +85 -31
  122. package/src/session/agent-session.ts +127 -57
  123. package/src/session/history-storage.ts +56 -12
  124. package/src/session/session-manager.ts +34 -0
  125. package/src/task/output-manager.ts +40 -48
  126. package/src/task/render.ts +3 -8
  127. package/src/tools/ask.ts +74 -32
  128. package/src/tools/browser/tab-worker.ts +8 -5
  129. package/src/tools/eval-backends.ts +38 -0
  130. package/src/tools/eval-render.ts +750 -0
  131. package/src/tools/eval.ts +27 -754
  132. package/src/tools/find.ts +5 -29
  133. package/src/tools/index.ts +8 -38
  134. package/src/tools/path-utils.ts +144 -1
  135. package/src/tools/read.ts +47 -0
  136. package/src/tools/renderers.ts +1 -1
  137. package/src/tools/search.ts +2 -27
  138. package/src/tools/sqlite-reader.ts +92 -9
  139. package/src/tools/write.ts +9 -1
  140. package/src/tui/output-block.ts +5 -4
  141. package/src/utils/clipboard.ts +38 -1
  142. package/src/utils/open.ts +37 -2
  143. package/src/web/kagi.ts +168 -49
  144. package/src/web/search/providers/anthropic.ts +1 -1
  145. package/src/web/search/providers/exa.ts +20 -86
  146. package/src/web/search/providers/kagi.ts +4 -0
package/CHANGELOG.md CHANGED
@@ -2,34 +2,68 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
- ## [15.7.5] - 2026-06-01
6
- ### Fixed
5
+ ## [15.8.0] - 2026-06-02
7
6
 
8
- - Fixed streaming assistant responses leaving duplicated tail rows in WSL/Windows Terminal scrollback by enabling eager native-scrollback rebuilds while assistant text is actively streaming ([#1615](https://github.com/can1357/oh-my-pi/issues/1615)).
9
-
10
- ### Fixed
7
+ ### Added
11
8
 
12
- - Fixed the `task` tool mangling subagent prompts when a model double-JSON-encodes a string argument: `context` and each task's `assignment`/`description` are now repaired when they arrive uniformly double-escaped (literal `\n`, `\"`, `\uXXXX`), so the subagent receives the intended prose and the call preview renders real newlines. The repair is guarded by a JSON-string round-trip and a double-encode signature, so legitimate backslashes/quotes (Windows paths, regexes, embedded quotes) are left untouched, and it is scoped to these natural-language fields only (never code-bearing tools).
9
+ - Added an all-projects scope to the session picker (`pi --resume` / `/resume`). Press `Tab` to toggle between the current folder's sessions and every session across all projects; the all-projects list is loaded lazily and shows each session's directory. When the current folder has no sessions the picker now opens straight into all-projects scope instead of printing "No sessions found".
10
+ - Migrated the Kagi web search provider to Kagi's V1 Search API (`POST /api/v1/search`), replacing the sunset V0 endpoint while keeping the `kagi` provider id, `KAGI_API_KEY` credential, and `/login kagi` flow unchanged ([#1272](https://github.com/can1357/oh-my-pi/pull/1272) by [@thismat](https://github.com/thismat))
11
+ - Added Anthropic `anthropic-ratelimit-unified-*` response-header warming for `/usage` and the status-line usage segment, throttled to reduce direct OAuth `/usage` probes during active use.
13
12
 
14
- ### Fixed
13
+ ### Changed
15
14
 
16
- - Fixed `pr://` PR views omitting formal review submissions and approvals when comments are enabled ([#1600](https://github.com/can1357/oh-my-pi/issues/1600)).
15
+ - Changed Anthropic API request metadata `user_id.device_id` to be derived from the persistent install ID so it remains stable across Anthropic account changes on the same install
16
+ - Changed the eval `parallel()` / `pipeline()` helpers to drop their `concurrency` argument and run as wide as a `task` tool batch. The worker-pool ceiling now tracks the `task.maxConcurrency` setting (default 32; `0` = run every item at once) resolved live from the host via a new `__concurrency__` bridge, instead of the old per-call `concurrency` option that defaulted to 4 and capped at 16. This stops eval fan-outs from under-using the parallelism the session is configured for.
17
+ - Changed subagent / `agent://` output ids from a numeric prefix scheme (`0-Anna`, `1-Bob`, nested `0-Anna.1-Bob`) to a name-first scheme: the requested name is used verbatim and a `-2`/`-3`/… suffix is added only when the same name recurs within a session (`Anna`, `Anna-2`, `Anna-3`). Nested ids stay grouped under the parent (`Anna.Bob`) and the live task widget renders them as `Anna>Bob`. The main agent's IRC id is now `Main` (was `0-Main`). `AgentOutputManager` still scans existing `.md` outputs on resume so it never reuses a name that would clobber a prior output.
18
+ - Changed resuming a session that belongs to a different project to switch the process into that project's working directory. `pi --resume` and the in-session `/resume` picker now `chdir` into the resumed session's `cwd` and re-scope every cwd-derived input — project dir, **project settings** (`.claude/settings.yml`, `.omp/settings.json`, path-scoped `enabledModels`/`disabledProviders`), plugin roots, capabilities, slash commands, and the ssh tool — so tools, discovery, configuration, and commands all follow the resumed project. The `SessionManager` adopts the resumed session's own `cwd`/session directory on load (rolled back if the switch fails).
19
+ - Documented `ANTHROPIC_SEARCH_API_KEY` and `ANTHROPIC_SEARCH_BASE_URL` more thoroughly in `docs/environment-variables.md`, surfaced them in `docs/tools/web_search.md`'s Anthropic provider section, and added `ANTHROPIC_SEARCH_BASE_URL` to `omp --help`'s env-var summary so the search-only overrides are discoverable alongside `ANTHROPIC_SEARCH_API_KEY` ([#1694](https://github.com/can1357/oh-my-pi/issues/1694)).
20
+ - Migrated the Kagi web search provider to Kagi's V1 Search API (`POST /api/v1/search`), replacing the sunset V0 endpoint while keeping the `kagi` provider id, `KAGI_API_KEY` credential, and `/login kagi` flow unchanged ([#1272](https://github.com/can1357/oh-my-pi/pull/1272) by [@thismat](https://github.com/thismat))
17
21
 
18
22
  ### Fixed
19
23
 
20
- - Fixed subagent yield-reminder loop logging benign user/compaction aborts as `ERROR`. The catch around `session.prompt`/`waitForIdle` in `task/executor.ts` now demotes `ToolAbortError` and signal-aborted exits to `debug` and keeps `ERROR` for genuine prompt failures only ([#1623](https://github.com/can1357/oh-my-pi/issues/1623)).
24
+ - Fixed `read`, `search`, `find`, `ast_grep`, and `ast_edit` recovering when a model flattens multiple existing paths into one comma-, semicolon-, or space-delimited string while preserving real paths that contain delimiters.
25
+ - Fixed Exa web search reporting available without Exa credentials, which could route searches into the unauthenticated public MCP fallback and stall before trying the next provider. Availability and `searchExa()` now resolve through the standard `AuthStorage` cascade (`EXA_API_KEY` env or stored credential) ([#1695](https://github.com/can1357/oh-my-pi/issues/1695)).
26
+ - Fixed Anthropic web search ignoring `ANTHROPIC_SEARCH_BASE_URL` when credentials came from stored Anthropic auth or generic Anthropic env fallback rather than `ANTHROPIC_SEARCH_API_KEY` ([#1694](https://github.com/can1357/oh-my-pi/issues/1694)).
27
+ - Fixed `web_search` returning 401 from corporate Anthropic API gateways. `ANTHROPIC_CUSTOM_HEADERS` is now forwarded to web-search requests whenever `ANTHROPIC_BASE_URL` points to a non-Anthropic host, not only in Foundry mode ([#1693](https://github.com/can1357/oh-my-pi/issues/1693)).
28
+ - Fixed opening exported local files from WSL by sending existing paths through `wslpath -w` and launching `wslview` directly when available, avoiding `xdg-open`'s broken file-handler path translation ([#950](https://github.com/can1357/oh-my-pi/pull/950) by [@rxreyn3](https://github.com/rxreyn3)).
29
+ - Fixed `/move` (and cross-project resume) not re-scoping the live project settings to the destination directory. Changing a session's working directory now reloads the project settings layer in place (via `Settings.reloadForCwd`) so project-scoped configuration and path-scoped `enabledModels`/`disabledProviders` follow the move instead of remaining pinned to the launch directory.
30
+ - Fixed `read <db.sqlite>` freezing the TUI on large databases. Listing tables ran an unbounded `SELECT COUNT(*)` per table, and since `bun:sqlite` executes synchronously on the same JS thread that drives rendering and input, a multi-GB database's full-table scans blocked the UI for seconds. The listing now reads the planner's `sqlite_stat1` estimate for tables above a scan cap (shown as `~N rows`) and only counts exactly when a table is provably small, reading at most `cap + 1` rows (a capped table shows `N+ rows`). On an 8.4 GB stats database the listing dropped from multi-second full scans to ~2 ms.
31
+ - Fixed a module-load crash (`ReferenceError: Cannot access 'evalToolRenderer' before initialization`) triggered whenever `tools/eval` was imported before `tools/renderers`. The eval JS backend statically pulls the agent/task/sdk/extension chain, which re-enters the root barrel → `modes/components` → `tool-execution` → `renderers` while `eval.ts` was still initializing, so `renderers.ts` read `evalToolRenderer` in its TDZ. The eval TUI renderer is now split into a dependency-light `tools/eval-render.ts` that `renderers.ts` imports directly (decoupling pure rendering from the eval runtime); `eval.ts` re-exports `evalToolRenderer`/`EVAL_DEFAULT_PREVIEW_LINES` for compatibility.
32
+ - Fixed `/logout` offering providers that were only authenticated by env/config fallbacks, which made OpenCode Go/Zen appear to remain logged in after their stored credentials were removed ([#1658](https://github.com/can1357/oh-my-pi/issues/1658)).
33
+ - Fixed `omp --resume <id>` crashing with an uncaught exception when an interactive user declined the cross-project fork prompt. `createSessionManager` now returns `undefined` for that cancellation, while non-interactive invocations still fail with a diagnostic when they cannot answer the fork prompt ([#1668](https://github.com/can1357/oh-my-pi/issues/1668)).
34
+ - Fixed `history.db` never recording the originating session id: the `session_id` column documented for 15.6.0 was missing from the shipped storage layer, so the column was never created/populated on the write path and every prompt row had `session_id` `NULL`. Restored the `session_id` column, schema migration (`ALTER TABLE history ADD COLUMN session_id` for pre-existing databases), and `HistoryEntry.sessionId`; wired interactive mode to register `setSessionResolver(...)` so prompts are stamped with the session active at submission time (tracking fork/resume switches); and re-enabled prompt-history ranking in the `--resume` and in-session session pickers via `HistoryStorage.matchingSessionIds()`.
35
+ - Fixed `/quit` shutdown leaving the parent shell prompt at the top of the viewport after the final TUI teardown render on Linux terminals ([#1620](https://github.com/can1357/oh-my-pi/issues/1620)).
36
+ - Fixed `omp update` failing with `No version matching "X" found for specifier "@oh-my-pi/pi-coding-agent" (but package exists)` when bun saw an older catalog than the update check did. The version is resolved by querying `https://registry.npmjs.org/` directly, but `bun install -g` would then consult its on-disk manifest snapshot or a configured npm mirror (corporate proxy, Taobao, …) that hadn't replicated the release. The bun install step now runs with `--no-cache --registry=https://registry.npmjs.org/` so it hits exactly the registry the version check used ([#1686](https://github.com/can1357/oh-my-pi/issues/1686)).
37
+ - Fixed ACP mode resetting configured async/background job settings to disabled RPC defaults, so explicit ACP background-job opt-ins are preserved during startup ([#1324](https://github.com/can1357/oh-my-pi/issues/1324)).
38
+ - Fixed legacy Pi extensions loading their `__dirname`-relative assets as empty — e.g. `@plannotator/pi-extension` reading `plannotator.html`/`review-editor.html` via `readFileSync(join(__dirname, …))`, which left `planHtmlContent` empty and dropped the plugin into its "no UI support" auto-approve path. The compat layer previously mirrored every extension module into a flat temp directory, so `import.meta.url` (and thus `__dirname`) pointed at the mirror root and sibling asset reads `ENOENT`ed. Extensions now load in place from their real on-disk location — `import.meta.url` is the real source file, so asset reads resolve exactly as under the original Pi runtime. A `Bun.plugin()` `onLoad` hook scoped to the entry's relative-import graph (the exact set of source modules, never the host, other extensions, `node_modules` deps, or unrelated project files) rewrites only the legacy `@(scope)/pi-*` and `@sinclair/typebox` imports; relative siblings, the extension's own `node_modules` deps, and bundled assets all resolve natively, with no temp-directory mirroring and no asset copying ([#1674](https://github.com/can1357/oh-my-pi/issues/1674)).
39
+ - Fixed plan approval keep-context usage to use the execution model context window, avoid zero-usage aborted turns, and disable keeping context when preserved context exceeds 95%.
21
40
 
22
- ### Fixed
41
+ ## [15.7.6] - 2026-06-01
23
42
 
24
- - Fixed `read local://<file>` resolving to the wrong session's artifacts directory in multi-session ACP hosts (e.g. cmux). `LocalProtocolHandler.resolve` now honors `context.localProtocolOptions` supplied by the calling tool before falling back to the process-wide override or the first `main`-kind session in the global `AgentRegistry`; `read`, `find`, `search`, `ast_grep`, and `ast_edit` thread their session's options through so a `local://PLAN.md` lookup hits the calling session's `local` root instead of a sibling session's ([#1608](https://github.com/can1357/oh-my-pi/issues/1608)).
43
+ ### Added
44
+
45
+ - Added `ask` option descriptions so agents can keep short labels and render explanatory text as separate muted rows in the selector.
46
+ - Added an extension API for rendering supplemental UI below visible assistant thinking blocks.
47
+ - Added default-on `lsp.diagnosticsDeduplicate` support so post-edit LSP diagnostics already shown for a file are suppressed within the session and only new or changed diagnostics are surfaced.
25
48
 
26
49
  ### Fixed
27
50
 
28
- - Fixed `omp` segfaulting on exit on Windows after the tiny title/memory model loaded `onnxruntime-node` (issue [#1606](https://github.com/can1357/oh-my-pi/issues/1606)). The tiny model now runs in a Bun subprocess instead of a Worker thread, so the NAPI finalizer that crashes during shutdown never executes in the agent's address space; the subprocess is `SIGKILL`'d on dispose to skip every native destructor on every platform.
51
+ - Fixed a single ESC press both dismissing the @/slash autocomplete popup and aborting the running agent operation. ESC now drains the popup first; only when no popup is visible does it route to the global interrupt handler (matching the standard TUI/IDE pattern). The `shouldBypassAutocompleteOnEscape` editor hook is removed it had become the trigger for this bug ([#1655](https://github.com/can1357/oh-my-pi/issues/1655)).
52
+ - Fixed Claude Code slash command discovery to load subdirectory commands recursively while preserving basename commands (e.g. `/apply`) and adding namespace aliases (e.g. `/opsx:apply`) for tools that install colon-namespaced workflows ([#1523](https://github.com/can1357/oh-my-pi/issues/1523)).
53
+ - Fixed the `eval` tool's per-cell `timeout` killing cells that were not stalled. The timeout is now a plain wall-clock budget on the cell's **own** work that is **paused only while a host-side `agent()`/`parallel()`/`llm()` bridge call is in flight** — those calls pump a heartbeat that re-arms the watchdog, so a long fanout or a slow (e.g. reasoning-tier) completion runs to completion instead of being aborted mid-flight (a subagent's time-to-first-token, a long quiet nested tool, or an entire oneshot `llm()` request no longer trip it). Nothing else re-arms the budget: ordinary compute, `print`/stdout, `log()`/`phase()`, and non-agent tool calls all count against it, so a cell that is not delegating to an agent/llm is bounded by the regular wall-clock timeout (and the timeout message no longer says "of inactivity"). The heartbeat is a pure keepalive — never persisted or rendered.
54
+
55
+ ## [15.7.5] - 2026-06-01
29
56
 
30
57
  ### Fixed
31
58
 
59
+ - Fixed streaming assistant responses leaving duplicated tail rows in WSL/Windows Terminal scrollback by enabling eager native-scrollback rebuilds while assistant text is actively streaming ([#1615](https://github.com/can1357/oh-my-pi/issues/1615)).
60
+ - Fixed the `task` tool mangling subagent prompts when a model double-JSON-encodes a string argument: `context` and each task's `assignment`/`description` are now repaired when they arrive uniformly double-escaped (literal `\n`, `\"`, `\uXXXX`), so the subagent receives the intended prose and the call preview renders real newlines. The repair is guarded by a JSON-string round-trip and a double-encode signature, so legitimate backslashes/quotes (Windows paths, regexes, embedded quotes) are left untouched, and it is scoped to these natural-language fields only (never code-bearing tools).
61
+ - Fixed `pr://` PR views omitting formal review submissions and approvals when comments are enabled ([#1600](https://github.com/can1357/oh-my-pi/issues/1600)).
62
+ - Fixed subagent yield-reminder loop logging benign user/compaction aborts as `ERROR`. The catch around `session.prompt`/`waitForIdle` in `task/executor.ts` now demotes `ToolAbortError` and signal-aborted exits to `debug` and keeps `ERROR` for genuine prompt failures only ([#1623](https://github.com/can1357/oh-my-pi/issues/1623)).
63
+ - Fixed `read local://<file>` resolving to the wrong session's artifacts directory in multi-session ACP hosts (e.g. cmux). `LocalProtocolHandler.resolve` now honors `context.localProtocolOptions` supplied by the calling tool before falling back to the process-wide override or the first `main`-kind session in the global `AgentRegistry`; `read`, `find`, `search`, `ast_grep`, and `ast_edit` thread their session's options through so a `local://PLAN.md` lookup hits the calling session's `local` root instead of a sibling session's ([#1608](https://github.com/can1357/oh-my-pi/issues/1608)).
64
+ - Fixed `omp` segfaulting on exit on Windows after the tiny title/memory model loaded `onnxruntime-node` (issue [#1606](https://github.com/can1357/oh-my-pi/issues/1606)). The tiny model now runs in a Bun subprocess instead of a Worker thread, so the NAPI finalizer that crashes during shutdown never executes in the agent's address space; the subprocess is `SIGKILL`'d on dispose to skip every native destructor on every platform.
32
65
  - Fixed unbounded MCP reconnect loop that could fork-bomb the host when a stdio MCP server completes the `initialize`/`tools/list` handshake and then exits. `MCPManager` now enforces a per-server crash circuit breaker (5 reconnects per 30 s window) on the automatic `transport.onClose` path; manual `/mcp reconnect` resets the window so users can recover after fixing the misconfiguration ([#1592](https://github.com/can1357/oh-my-pi/issues/1592)).
66
+ - Fixed auto context maintenance to include the pending prompt in the pre-send token estimate, so large user turns compact history before the provider rejects an over-limit request ([#1618](https://github.com/can1357/oh-my-pi/issues/1618)).
33
67
 
34
68
  ## [15.7.4] - 2026-05-31
35
69
 
@@ -42,6 +76,7 @@
42
76
  - Fixed plugin install failing for sources pinned to a SHA: `git.clone()` no longer adds `--depth 1` when `options.sha` is set, so the checkout of arbitrary commits succeeds instead of bailing out with "shallow clone may not contain this commit" ([#1589](https://github.com/can1357/oh-my-pi/issues/1589)).
43
77
 
44
78
  ## [15.7.3] - 2026-05-31
79
+
45
80
  ### Added
46
81
 
47
82
  - Added support for decimal and `k`/`m` suffix turn-budget directives, enabling budgets like `+1.5k` and `+2m` in eval message parsing
@@ -75,13 +110,8 @@
75
110
  ### Fixed
76
111
 
77
112
  - Fixed Ctrl+O tool-result expansion on POSIX terminals so offscreen tool blocks rebuild native scrollback instead of leaving stale collapsed rows above the viewport.
78
-
79
- ### Removed
80
-
113
+ - Fixed auto-discovered OpenAI-compatible / Ollama / llama.cpp / new-api proxy models defaulting to `maxTokens: 8192`, which made providers drop the streaming connection mid-response on large `write`/`edit` tool calls and surfaced as Bun's opaque `socket connection was closed unexpectedly`. The discovery cap is now `32_768` (`DISCOVERY_DEFAULT_MAX_TOKENS` in `packages/coding-agent/src/config/model-registry.ts`) and `min(contextWindow, …)` still honors smaller advertised context windows ([#1528](https://github.com/can1357/oh-my-pi/issues/1528)).
81
114
  - Removed the `/drop-images` slash command; use `/shake images`, which strips every image from the session through the same `dropImages()` path.
82
-
83
- ### Fixed
84
-
85
115
  - Fixed final `agent()` completion status emissions in eval cells so the last live progress snapshot now preserves accumulated subagent metrics such as tool count and cost
86
116
  - Fixed `agent()` in eval to enforce plan-mode, spawn allowlist, and disabled-agent checks before launching subagents
87
117
  - Fixed recursive `agent()` calls from eval by enforcing the existing max subagent depth limit
@@ -96,6 +126,7 @@
96
126
  - Fixed duplicated/stale scrollback above a streaming tool result on POSIX terminals (macOS/Linux). A tool whose output grows and re-lays-out (e.g. an edit diff gaining hunks) re-renders rows that already scrolled into native scrollback; the unknown-viewport anti-yank deferral left the old copy in place while the new one rendered below, showing the block twice. The event controller now enables the TUI's eager native-scrollback rebuild while a foreground tool is executing (`setEagerNativeScrollbackRebuild`), so those offscreen re-renders rebuild history cleanly — a snap to the tail is acceptable mid-tool. Background-running tools and plain assistant-text streaming keep the no-yank deferral; the mode resets at each turn start.
97
127
 
98
128
  ## [15.7.2] - 2026-05-31
129
+
99
130
  ### Added
100
131
 
101
132
  - Added `providers.autoThinkingModel` setting so users can choose the `auto` thinking classifier backend (online smol or local tiny-memory model)
@@ -128,6 +159,7 @@
128
159
  - Added an animated pending border for `bash` and `eval` execution blocks: while a command/cell is running, a single dark segment glides clockwise around the block's outer edge (top → right → bottom → left), replacing the previous static accent border. Motion is eased per edge (decelerating into each corner) and timed against a fixed lap duration mapped onto the live perimeter, so streaming a new output line or resizing the terminal nudges the segment proportionally instead of resetting its position. Driven by the existing spinner cadence and gated on the `display.shimmer` setting (no motion when `disabled`).
129
160
  - Added `providers.tinyModelDevice` and `providers.tinyModelDtype` settings (Providers tab) controlling local tiny-model acceleration for session titles and Mnemopi memory tasks. `providers.tinyModelDevice` selects the ONNX execution provider (`default` keeps the platform pick — DirectML on Windows, CUDA on Linux x64, CPU elsewhere); `providers.tinyModelDtype` selects quantization/precision (`default` keeps each model's shipped `q4`, e.g. `fp16` trades speed for fidelity). The `PI_TINY_DEVICE` / `PI_TINY_DTYPE` env vars override the matching setting. Also added `PI_TINY_DTYPE` as the env counterpart to `PI_TINY_DEVICE`; an unrecognized device/precision fails loudly at worker startup instead of silently loading a different one.
130
161
  - Added a bundled set of default rules shipped with the agent (TypeScript/Rust convention rules registered as TTSR conditions). They load via the new lowest-priority `builtin-defaults` discovery provider, so any user/project/tool rule of the same name overrides the bundled copy. Disable the whole set with `ttsr.builtinRules: false`, or drop individual rules (bundled or your own) by name via `ttsr.disabledRules`.
162
+ - Added a `symbols.spinnerFrames` field to custom theme JSON so themes can override the loader/tool-execution spinner. Accepts either a flat `string[]` (used for both spinner types) or `{ "status"?: string[], "activity"?: string[] }` to override each independently; anything not specified falls back to the symbol preset. Documented in `docs/theme.md` and validated by `theme-schema.json`. ([#1553](https://github.com/can1357/oh-my-pi/issues/1553))
131
163
 
132
164
  ### Changed
133
165
 
@@ -152,6 +184,7 @@
152
184
  - Removed the `recipe` tool and its `recipe.enabled` setting. Task-runner targets (just/package.json/Cargo/make/Taskfile) are invoked directly through `bash`.
153
185
 
154
186
  ## [15.6.0] - 2026-05-30
187
+
155
188
  ### Added
156
189
 
157
190
  - Added prompt-mode autocomplete for supported internal URL schemes (`skill://`, `rule://`, `agent://`, `artifact://`, `local://`, `memory://`, and `omp://`) so typing those tokens now suggests existing resources as completion candidates
@@ -167,6 +200,7 @@
167
200
  - Added a Mnemopi-only `memory_edit` agent tool for updating, forgetting, or invalidating recalled memories by id, and added `/memory stats` plus `/memory diagnose` slash commands for backend maintenance visibility.
168
201
  - Added an `orchestrate` magic keyword that mirrors `ultrathink`: dropping the standalone word in a message paints it with a cool teal→violet gradient in the editor and appends a hidden system notice that switches the model into the multi-phase, parallel-subagent orchestration contract. Matching is word-bounded and case-insensitive, so `orchestrated`/`orchestrating` never trigger it.
169
202
  - Added a model-tier slider to the plan-approval prompt ("Plan mode - next step"). Left/right arrows move it from any list position to pick which configured role model (`cycleOrder`, e.g. `smol › default › slow`) executes the approved plan, with each tier colored by its role and the resolved model name shown beneath the track. The chosen tier is applied before dispatch and carries through the fresh/compacted execution session; the slider is hidden when fewer than two role models resolve.
203
+ - `omp plugin install` now accepts GitHub/GitLab/Bitbucket shorthand (`github:user/repo`, `gitlab:user/repo`, …) and full git URLs (`https://github.com/user/repo`, `git@github.com:user/repo`, …) in addition to npm specs and marketplace refs.
170
204
 
171
205
  ### Changed
172
206
 
@@ -177,12 +211,6 @@
177
211
  - Changed the system prompt to advertise `memory://root` only when the local memory backend is active.
178
212
  - Changed `todo_write` result rendering to animate completed items in place: the checkbox flips checked first, then the strikethrough reveals across the task text.
179
213
 
180
- ### Removed
181
-
182
- - Removed the standalone `ask`, `task`, and `yield` tools along with their obsolete prompts, docs, and tests; delegation now routes through persistent `delegate` agents plus IRC coordination.
183
- - Removed the `/orchestrate` slash command; orchestration is now triggered by the `orchestrate` keyword (see Added) so the contract rides alongside the user's own prompt instead of replacing it.
184
- - Removed the sticky Todos panel all-done drop/collapse animation; completed todo state now stays visible until the next explicit todo update changes it.
185
-
186
214
  ### Fixed
187
215
 
188
216
  - Fixed Mnemopi session shutdown to flush queued memory extractions before exit so the last turn’s facts are not lost
@@ -197,10 +225,14 @@
197
225
  - Fixed the bash (and `recipe`) tool result footer not rendering for failed commands. A non-zero exit threw a `ToolError`, which dropped the result details, so the styled `⟨Wall … | Timeout …⟩` footer was replaced by the raw `Wall time: … seconds` / `Command exited with code N` lines. Non-zero exits now resolve as a non-throwing error result that keeps `wallTimeMs`/`timeoutSeconds`/`exitCode`, and the footer shows `⟨Wall … | Timeout … | Exit: N⟩` with the textual notices folded out of the output pane. Aborts, timeouts, and missing-exit-status still throw as before.
198
226
  - Fixed selector-style UI components to honor `tui.select.up` and `tui.select.down` keybindings instead of hard-coding raw Up/Down arrow bytes ([#1535](https://github.com/can1357/oh-my-pi/issues/1535)).
199
227
 
200
- ### Added
228
+ ### Removed
229
+
230
+ - Removed the standalone `ask`, `task`, and `yield` tools along with their obsolete prompts, docs, and tests; delegation now routes through persistent `delegate` agents plus IRC coordination.
231
+ - Removed the `/orchestrate` slash command; orchestration is now triggered by the `orchestrate` keyword (see Added) so the contract rides alongside the user's own prompt instead of replacing it.
232
+ - Removed the sticky Todos panel all-done drop/collapse animation; completed todo state now stays visible until the next explicit todo update changes it.
201
233
 
202
- - `omp plugin install` now accepts GitHub/GitLab/Bitbucket shorthand (`github:user/repo`, `gitlab:user/repo`, …) and full git URLs (`https://github.com/user/repo`, `git@github.com:user/repo`, …) in addition to npm specs and marketplace refs.
203
234
  ## [15.5.15] - 2026-05-30
235
+
204
236
  ### Changed
205
237
 
206
238
  - Enabled the agent loop's tool-call batch cap for Anthropic Claude sessions, cutting oversized streamed tool-use bursts into runnable batches before continuing the conversation.
@@ -214,6 +246,7 @@
214
246
  - Fixed Anthropic Claude tool-call batching to clear and reapply the Claude-specific batch cap whenever the session model changes
215
247
 
216
248
  ## [15.5.14] - 2026-05-29
249
+
217
250
  ### Added
218
251
 
219
252
  - Added progress status output for `llm()` calls in `eval`, including the resolved model, tier, and returned character count
@@ -232,6 +265,7 @@
232
265
  - Reverted the sticky `Todos` panel task glyphs to the pre-15.5.12 checkbox icons: completed tasks render `theme.checkbox.checked` (not `theme.status.success`) and in-progress tasks render `theme.checkbox.unchecked` (not the running glyph). Removed the animated spinner entirely — in-progress tasks and pending tasks with a matching in-flight subagent still highlight via the `accent` colour, but the panel now paints once per state change instead of on an 80 ms timer. Subagent auto-checkmarking, the advancing window (`selectStickyTodoWindow`), `todoMatchesAnyDescription` highlighting, and the all-done close animation are unchanged.
233
266
 
234
267
  ## [15.5.13] - 2026-05-29
268
+
235
269
  ### Breaking Changes
236
270
 
237
271
  - Changed hashline edit syntax to verb-based v4: body-bearing ops are `replace N..M:`, `insert before N:`, `insert after N:`, `insert head:`, and `insert tail:`, while bodyless `delete N..M` handles deletion. Removed `>A..B` repeat rows and the old `prepend:` / `append:` virtual insert headers; `-` rows remain rejected with a teaching error.
@@ -285,9 +319,6 @@
285
319
  ### Fixed
286
320
 
287
321
  - Fixed compaction surfacing raw HTTP 401/403 envelopes (e.g. `Compaction failed: 401 {"type":"error","error":{"type":"authentication_error",…}}`) instead of routing to an authenticated fallback model. The compaction layer now attaches the provider-reported HTTP status onto the thrown error, and `AgentSession`'s auth-failure detector branches on `error.status === 401 || 403` in addition to the existing `auth_unavailable` regex. When a fallback model role (e.g. `modelRoles.smol`) is configured, compaction retries it transparently; otherwise the user sees the actionable "Compaction requires usable credentials for …" hint instead of the raw provider envelope.
288
-
289
- ### Fixed
290
-
291
322
  - Fixed compiled-binary legacy plugin loading for `@earendil-works/*` imports of bundled package roots such as `@earendil-works/pi-coding-agent`; compat now rewrites all bundled pi package roots to bunfs entrypoints and resolves fallback peer dependencies through the canonical `@oh-my-pi/*` specifier.
292
323
 
293
324
  ## [15.5.8] - 2026-05-28
@@ -343,7 +374,9 @@
343
374
  - Secured `vault://` reads and writes by validating URL paths and blocking traversal, absolute paths, and symlink escapes outside the selected vault root
344
375
 
345
376
  ## [15.5.7] - 2026-05-27
377
+
346
378
  ### Added
379
+
347
380
  - `providers.openrouterVariant` setting (Settings → Providers → "OpenRouter Routing") to default OpenRouter requests to a routing-variant suffix (`:nitro`, `:floor`, `:online`, `:exacto`). Selectors that already name a variant (e.g. `openrouter/anthropic/claude-haiku:nitro`) keep precedence.
348
381
 
349
382
  - `generate_image` supports xAI Grok Imagine via `providers.image=xai`. Supports `grok-imagine-image` (default) and `grok-imagine-image-quality` at aspect ratios `1:1`, `16:9`, `9:16`, `4:3`, `3:4`, `3:2`, `2:3`. Uses the xAI Grok OAuth credential when available, otherwise `XAI_API_KEY`.
@@ -355,6 +388,7 @@
355
388
  - Fixed `read` URL reader mode aborting after a stalled Jina request instead of falling back to trafilatura/lynx/native: Jina (and Parallel extract) now have their own per-attempt sub-budget capped at 10s, the catch handler honours only real user cancellation, and the in-process native renderer is always attempted on already-loaded HTML ([#1449](https://github.com/can1357/oh-my-pi/issues/1449))
356
389
 
357
390
  ## [15.5.6] - 2026-05-27
391
+
358
392
  ### Added
359
393
 
360
394
  - Support for multi-range line selectors on URLs (e.g., `:5-10,20-30`) to fetch and display multiple non-contiguous sections
@@ -384,6 +418,7 @@
384
418
  ## [15.5.4] - 2026-05-27
385
419
 
386
420
  ### Breaking Changes
421
+
387
422
  - Removed the package root `hashline` export so imports from the top-level entrypoint can no longer access `hashline` helpers directly
388
423
 
389
424
  ### Added
@@ -407,24 +442,13 @@
407
442
 
408
443
  - Fixed a race in `withFileLock` where a contender losing the `mkdir` race could wipe the winner's freshly-created lock directory before the winner finished writing its info file. Every lock now carries a per-process UUID token; `releaseLock(path, expectedToken)` verifies ownership before `fs.rm`, and `isLockStale` no longer returns `true` for a dir whose info file is absent but whose mtime is still inside the staleness window (or whose dir vanished mid-check).
409
444
  - Fixed `formatErrorMessage` not sanitising tabs or truncating oversized error strings before painting them through the theme. Errors that embedded raw file content (apply_patch failures, hashline mismatches, etc.) could break terminal alignment via raw `\t` chars or overflow the line width.
410
-
411
- ### Fixed
412
-
413
445
  - Fixed multi-section hashline edits to reject duplicate canonical targets and preflight write guards before any section is committed
414
-
415
- ### Fixed
416
-
417
446
  - Fixed `createAgentSession()` dropping the hidden `resolve` tool from the registry when no active tool sets `deferrable: true`, even though plan mode dispatches the plan-approval `resolve { action: "apply", ... }` call through a standing handler. Read-only plan-mode toolsets (e.g. `read`, `search`, `find`, `web_search`) silently activated plan mode without `resolve`, leaving the agent unable to submit the finalized plan and forcing the user to exit plan mode manually. `resolve` is now kept whenever `plan.enabled` is true, so the standing handler always has a callable tool ([#1428](https://github.com/can1357/oh-my-pi/issues/1428))
418
-
419
- ### Fixed
420
-
421
447
  - Fixed `omp` startup and `/changelog` reading the host project's `CHANGELOG.md` as omp's — `getPackageDir()` no longer falls back to the user's `cwd` when no owning `package.json` is locatable, preventing spurious `lastChangelogVersion` writes ([#1423](https://github.com/can1357/oh-my-pi/issues/1423))
422
-
423
- ### Fixed
424
-
425
448
  - Fixed hashline session-chain replay silently overwriting in-session edits when the model re-targeted a previously rewritten line with a stale file hash; replay now refuses unless every edit's anchor line content matches between the snapshot and the current file ([#1422](https://github.com/can1357/oh-my-pi/pull/1422))
426
449
 
427
450
  ## [15.5.3] - 2026-05-27
451
+
428
452
  ### Breaking Changes
429
453
 
430
454
  - Disallowed inline payload on hashline `↑`, `↓`, and `:` operations (including BOF/EOF inserts), requiring payload text to be supplied on standalone `+` continuation rows
@@ -438,6 +462,7 @@
438
462
  - Fixed runtime model registry refresh and cache loading so providers with authoritative dynamic catalogs, including Synthetic, do not re-add deprecated bundled model IDs after discovery ([#1417](https://github.com/can1357/oh-my-pi/issues/1417)).
439
463
 
440
464
  ## [15.5.2] - 2026-05-26
465
+
441
466
  ### Breaking Changes
442
467
 
443
468
  - Changed the hashline patch format so payload continuation lines now require a leading `+`, rejecting unprefixed multiline payload rows that were previously accepted as fallback payload text
@@ -502,10 +527,12 @@
502
527
  ## [15.4.1] - 2026-05-26
503
528
 
504
529
  ### Breaking Changes
530
+
505
531
  - The `vim` edit mode option is no longer available; configurations using `edit.mode: vim` will be automatically mapped to `hashline` mode
506
532
  - Hashline payload semantics are now strictly inline-first: the first payload line is whatever follows the sigil on the op line itself, and subsequent lines append after it. A newline immediately after `↑`/`↓`/`:` is no longer a free separator — it produces a blank first payload line. Use `LINE↓content` for a one-line insert, `LINE↓firstline\nsecondline` for two lines; bare `LINE↓` / `LINE↑` / `LINE:` (no inline payload) still insert/replace with one blank line as before.
507
533
 
508
534
  ### Added
535
+
509
536
  - Added `irc.timeoutMs` setting to configure IRC message timeout duration with a default of 120 seconds
510
537
  - Added timeout enforcement for IRC send operations to prevent indefinite hangs when recipients are unresponsive
511
538
  - Added evaluator state inheritance for `task`-spawned subagents so JavaScript and Python variables are visible between a parent agent and its child sessions
@@ -553,6 +580,7 @@
553
580
  - Updated `MCPOAuthFlow.#resolveRegistrationEndpoint` to try origin-root well-known first, then fall back to path-prefixed well-known ([1407](https://github.com/can1357/oh-my-pi/pull/1407) by [@faizhasim](https://github.com/faizhasim))
554
581
 
555
582
  ### Removed
583
+
556
584
  - Removed the `installH2Fetch()` activation from CLI startup; HTTPS fetches now use Bun's default transport
557
585
  - Removed the `vim` edit mode along with the `VimTool` module, prompt, and supporting buffer/engine/renderer stack
558
586
  - Removed per-line hash anchors (2-letter bigram hashes) from hashline format
@@ -572,6 +600,7 @@
572
600
  - Fixed JavaScript `eval` imports to preserve module-level singletons across re-imports of unchanged local files and reload them only after edits
573
601
  - Fixed concurrent Python evaluator tool calls to use per-run identifiers so tool responses and output are routed to the correct execution
574
602
  - Fixed the `search` tool argument validation to accept a single string `paths` value as a one-path search.
603
+
575
604
  ## [15.4.0] - 2026-05-26
576
605
 
577
606
  ### Breaking Changes
@@ -595,10 +624,6 @@
595
624
  - Extended `formatApprovalPrompt` with payload previews for `eval` (language + first cell's code), `task` (agent + first task's id + assignment), `ast_edit` (first op's pattern / replacement / paths), `browser` (action + tab + url + code), and `write` content (alongside path). Previously these all rendered as bare `Allow tool: <name>` lines, giving the user no signal about what they were authorizing.
596
625
  - Decoupled the per-tool approval gate from extension-loading state: `ExtensionRunner` and the `ExtensionToolWrapper` per-tool gate are now constructed unconditionally in `createAgentSession`, regardless of whether any extensions are loaded. Previously the runner was created only when `extensionsResult.extensions.length > 0`, which silently disabled the entire approval system if no extensions (including `createAutoresearchExtension`) were loaded; a regression test in `approval-mode.test.ts` now locks the invariant.
597
626
 
598
- ### Fixed
599
-
600
- - Fixed `isMcpToolName` over-matching any tool name containing `__` (an extension legally named `my__feature` or `pkg__util__do` was getting falsely labelled `Origin: MCP server tool` in the approval prompt). Restricted to the canonical `mcp__` prefix only.
601
-
602
627
  ### Changed
603
628
 
604
629
  - Updated hashline operation syntax to support inline payload text on the same op line for insert and replace (`ANCHOR↑/↓/...→`) while still accepting payload lines that follow
@@ -610,6 +635,7 @@
610
635
 
611
636
  ### Fixed
612
637
 
638
+ - Fixed `isMcpToolName` over-matching any tool name containing `__` (an extension legally named `my__feature` or `pkg__util__do` was getting falsely labelled `Origin: MCP server tool` in the approval prompt). Restricted to the canonical `mcp__` prefix only.
613
639
  - Fixed hashline inline payload parsing so same-line payloads containing whitespace, including tab-indented text, are preserved instead of being rejected
614
640
  - Fixed Bun HTTP/2 transport errors (`HTTP2StreamReset`, `HTTP2RefusedStream`, and `HTTP2EnhanceYourCalm`) to be treated as transient so the assistant now retries automatically instead of stopping on these recoverable failures
615
641
  - Fixed web search OAuth-backed providers (including Codex and Gemini) to use broker-managed token retrieval and account metadata, avoiding direct token-store refresh behavior that could cause search authentication failures
@@ -623,16 +649,10 @@
623
649
  - Fixed `adapter: "debugpy"` over-promising in the `debug` tool. `resolveAdapter("debugpy", cwd)` only checks for `python` in `PATH`; it does not verify that the `debugpy` module is importable. Both failure modes — `python` missing and `debugpy` module missing — used to collapse onto a generic `"No suitable debug adapter found"` error. The launch/attach action now throws a targeted `ToolError` naming `python` when `resolveAdapter` returns null for an explicit `adapter: "debugpy"`, and the `DapSessionManager` spawn-catch detects `"No module named debugpy"` in adapter stderr and surfaces a `pip install debugpy` hint. The Python debug tool documentation lists the install hint so the prompt and runtime diagnostics agree.
624
650
  - Fixed the LSP symbol-resolver `BARE_IDENTIFIER_RE` (`/^[A-Za-z_][\w]*$/`) rejecting `$`-prefixed identifiers (`$store`, `$count`, RxJS observables, Svelte stores, Angular signals). Without the word-boundary check, searching for `$store` on a line containing `bar$store` returned the offset inside the compound identifier rather than the standalone occurrence, feeding a wrong column to the LSP server. Pattern now `/^[$A-Za-z_][\w$]*$/`; the companion `IDENTIFIER_CHAR_RE` already contained `$`.
625
651
  - Fixed `applyWorkspaceEdit` writing all text edits before walking `documentChanges` for resource operations. LSP §3.16.2 requires clients to apply `documentChanges` in declared order, so any server emitting `{kind: "create", uri: X}` followed by a `TextDocumentEdit` for `X` (e.g. "Extract to new file" code actions, some rename responses) broke: the edit ran against a non-existent file, then the create happened. `applyWorkspaceEdit` now walks `documentChanges` once in declared order; per-URI text edits are coalesced into a pending Map and flushed immediately before any subsequent resource op for the same URI. Legacy `changes`-map-only payloads are unchanged. Folder-level `rename`/`delete` ops now flush every pending URI under the affected subtree (not just the exact target) so child-file edits queued before a parent-folder move land at the original location instead of dangling against a non-existent path on the final flush. Rename ops additionally flush pending edits queued against `renameOp.newUri` (and its descendants) **before** `fs.rename` runs, so edits intended for the pre-rename target file are applied before the rename clobbers or replaces it (relevant under `options.overwrite`/`options.ignoreIfExists`). When a `WorkspaceEdit` payload supplies both `changes` and `documentChanges`, the `documentChanges` arm is now used exclusively per LSP §3.16.2 ("if documentChanges are supplied … servers should use them in preference to changes"); previously the two were merged.
626
-
627
- ### Fixed
628
-
629
652
  - Fixed built-in `explore` agent failing every invocation with `schema_violation: files.0.ref: must not be present` on releases prior to 15.3.2 by renaming the `files[].ref` property to `files[].path` in the agent's output schema; `ref` is a JTD-reserved keyword (RFC 8927) and collides with JSON Type Definition's schema-reference form, so the converter previously dropped it from the generated JSON Schema. Defense-in-depth alongside the 15.3.2 converter fix ([#1379](https://github.com/can1357/oh-my-pi/issues/1379)).
630
653
  - Increased the `yield` tool's schema-validation retry budget from 1 to 3 so subagents whose first structured-output attempt mismatches the declared output schema get up to three retries before the parent's post-mortem `schema_violation` check hard-fails the task. The tool now also surfaces remaining retry attempts and an explicit "call yield again with the corrected shape" directive in each rejection message, giving the model the context it needs to converge — particularly helpful for models like GLM that tend to invent per-element field names instead of following the declared schema.
631
654
  - Fixed CLI PDF file arguments being decoded as raw bytes for local vision models; `.pdf` and other supported document files now go through the same Markit conversion path as the `read` tool before entering the prompt ([#1401](https://github.com/can1357/oh-my-pi/issues/1401)).
632
655
  - Fixed the `bash` tool hanging until the 305 s hard timeout when a command writes a file via heredoc on Windows (bodies > ~4 KiB) or macOS (bodies > 16-64 KiB). Root cause was in the embedded brush shell; see `@oh-my-pi/pi-natives` changelog for the underlying fix.
633
-
634
- ### Fixed
635
-
636
656
  - Fixed `/review` custom prompt orchestration text to use static prompt templates and consistently instruct reviewer task delegation.
637
657
  - Fixed `/review` custom-instructions submission on terminals that cannot distinguish Ctrl+Enter by using prompt-style input where Enter submits and Shift+Enter inserts a newline.
638
658
  - Fixed hook editor submissions sending large-paste placeholders such as `[paste #1 +27 lines]` instead of the pasted content.
@@ -645,6 +665,7 @@
645
665
  - Added `tools.approvalMode` global setting (Interaction tab in `/settings`) with values `auto` | `prompt` | `custom`. Defaults to `auto` so the agent runs every tool call without interruption — matching the `--auto-approve` / `--yolo` CLI flag. `prompt` uses built-in per-tool defaults only (read/find/search auto-allow; bash/edit/write/eval/ssh require confirmation; `tools.approval.<tool>` config is ignored). `custom` makes the `tools.approval.<tool>` config the source of truth — your settings win over built-in defaults, which fall back only for tools you haven't configured. CLI `--auto-approve` always wins. Critical safety patterns (e.g. `rm -rf /`, `curl … | bash`, fork bombs) keep prompting even when the tool is user-allowed.
646
666
 
647
667
  ## [15.3.2] - 2026-05-25
668
+
648
669
  ### Added
649
670
 
650
671
  - Added inline `|TEXT` payload support to `»` and `«` hashline insert operations, allowing single-line inserts on the op line and still supporting additional payload lines
@@ -672,8 +693,11 @@
672
693
  - Fixed append-only context mode not being recomputed after model switches — the mode was frozen at session construction time using the initial model's provider, so `provider.appendOnlyContext=auto` left append-only enabled after switching away from DeepSeek (or disabled after switching to DeepSeek) for the rest of the session
673
694
 
674
695
  ### Fixed
696
+
675
697
  - Fixed clipboard image paste (Ctrl+V) silently failing on WSL2 by routing image reads through a `powershell.exe` bridge when WSL interop is detected, since `arboard` returns `ContentNotAvailable` under WSLg ([#1280](https://github.com/can1357/oh-my-pi/issues/1280))
698
+
676
699
  ## [15.2.4] - 2026-05-22
700
+
677
701
  ### Breaking Changes
678
702
 
679
703
  - Replaced the legacy `@@` header and `+`/`<`/`=`/`-` hashline syntax with the new `§PATH` header and `«`/`»`/`≔` operation format, so existing hashline scripts and prompts using old symbols must be updated
@@ -695,6 +719,7 @@
695
719
  - Fixed hashline payload handling in parser and streaming preview to preserve blank lines as actual payload text until the next op, file header, or envelope marker
696
720
 
697
721
  ## [15.2.3] - 2026-05-22
722
+
698
723
  ### Breaking Changes
699
724
 
700
725
  - Changed PR and task-isolation worktree directory layout to hash-based `~/.omp/wt/<identifier>-<path-hash>` style paths, replacing the previous nested encoded-repo layout
@@ -732,9 +757,6 @@
732
757
  ### Fixed
733
758
 
734
759
  - Fixed compaction routing to the wrong provider when `modelRoles.default` is set to a different model than the active chat. Auto- and manual compaction now prefer the active session's model and only fall back to role-based candidates when the current model has no usable credentials. Previously, an Anthropic chat with `modelRoles.default = openai/gpt-5` would compact through OpenAI (including the remote-compaction endpoint), even though the live conversation never used OpenAI.
735
-
736
- ### Fixed
737
-
738
760
  - Fixed context overflow not being detected when the session's model (e.g. `hf:zai-org/GLM-5.1` via `synthetic` provider) returns a 400 with the upstream "400 status code (no body)" message wrapped inside a JSON envelope. The `isContextOverflow` check now matches the no-body status phrase anywhere in the error string rather than requiring it at the very start, so auto-compaction fires correctly instead of leaving the session silently stuck ([#1251](https://github.com/can1357/oh-my-pi/issues/1251)).
739
761
  - Fixed `formatCapturedHttpError` not extracting the error text from `{"error":"string"}` response bodies (only object-valued `error` fields were previously handled), resulting in raw JSON in error messages instead of the human-readable string.
740
762
 
@@ -747,60 +769,32 @@
747
769
  ### Fixed
748
770
 
749
771
  - Fixed false-positive hashline `~ TEXT` separator-padding warning firing on YAML, JSON, Python, Markdown, TOML, and other indent-sensitive file edits. The padding check is now skipped entirely for indentation-sensitive extensions (`.py`, `.yml`/`.yaml`, `.md`/`.mdx`, `.json`/`.jsonc`/`.json5`, `.toml`, `.rst`, `.tf`, `.nix`, `.coffee`, `.haml`/`.slim`/`.pug`, `.sass`/`.styl`, `.nim`, `.cr`, `.elm`, `.fs`, …), and tightened on every other extension to flag only the `~ beta` typo shape (exactly one leading space before non-space content) rather than any leading-space payload.
750
-
751
- ### Fixed
752
-
753
772
  - Fixed goal state machine: `get` now returns paused goals (was returning null for `enabled=false`), `complete` now works on paused goals after interrupts, `create` is allowed after a previous goal reaches `complete` status, and the goal tool is re-added to the active tool set on session reload when a paused goal is persisted. Added `resume` and `drop` ops to the goal tool so the agent can re-engage or discard a paused goal without requiring user slash commands. ([#1249](https://github.com/can1357/oh-my-pi/issues/1249))
754
773
 
755
774
  ## [15.1.9] - 2026-05-21
756
775
 
757
- ### Fixed
776
+ ### Added
758
777
 
759
- - Fixed `disabledProviders` still probing local discovery endpoints for Ollama, llama.cpp, and LM Studio during background model refresh. Disabled providers are now excluded before implicit and built-in discovery managers are created. ([#1232](https://github.com/can1357/oh-my-pi/issues/1232))
778
+ - Added OSC 8 terminal hyperlink support for file paths in tool output. When the terminal supports hyperlinks (kitty, Ghostty, WezTerm, iTerm2, Alacritty, VS Code) and the new `tui.hyperlinks` setting is `auto` (default) or `always`, OMP wraps file paths emitted by `read`, `find`, `search`, `edit`, `ast_grep`, and `ast_edit` renderers in `file:///abs/path` hyperlinks. `local://` and other fs-backed internal URLs resolve to their backing path. Set `tui.hyperlinks: off` to disable. ([#1244](https://github.com/can1357/oh-my-pi/issues/1244))
760
779
 
761
780
  ### Fixed
762
781
 
782
+ - Fixed `disabledProviders` still probing local discovery endpoints for Ollama, llama.cpp, and LM Studio during background model refresh. Disabled providers are now excluded before implicit and built-in discovery managers are created. ([#1232](https://github.com/can1357/oh-my-pi/issues/1232))
763
783
  - Fixed `omp acp` auto-discovering host `.mcp.json` servers in parallel with the ACP client's `session/new.mcpServers`, which shadowed client-supplied MCP tools in `search_tool_bm25` and the session tool registry. The ACP session factory now forces `enableMCP: false`, so MCP ownership stays with `AcpAgent#configureMcpServers`. Non-ACP modes keep on-disk discovery. ([#1234](https://github.com/can1357/oh-my-pi/issues/1234))
764
-
765
- ### Fixed
766
-
767
784
  - Fixed binary `omp update` rollbacks so a downloaded replacement that fails post-install version verification no longer remains installed over the previous working binary. ([#1240](https://github.com/can1357/oh-my-pi/issues/1240))
768
-
769
- ### Fixed
770
-
771
785
  - Fixed `/force <tool>` rejecting Ollama/local models before the requested tool could run; Ollama now receives a named forced choice that the provider transport narrows to the selected tool. ([#1236](https://github.com/can1357/oh-my-pi/issues/1236))
772
-
773
- ### Fixed
774
-
775
786
  - Fixed `web_search` freezing the session when an upstream provider stalled. Bun's WinHTTP backend on Windows can silently drop `AbortSignal` once a TCP/TLS connection hangs (oven-sh/bun#15275, oven-sh/bun#18536), so Esc never reached the in-flight fetch and the only recovery was Ctrl+C + `omp --resume`. Every web-search provider's outbound `fetch` (anthropic, brave, codex, exa, gemini, jina, kagi, kimi, parallel, perplexity, searxng, synthetic, tavily, z.ai) now composes the caller signal with a 60s hard timeout via a shared `withHardTimeout` helper, guaranteeing the request settles within a minute even when Bun's abort fails to propagate. Independently, `executeSearch`'s provider-fallback loop was masking real cancellations as ordinary provider errors and returning "All web search providers failed"; it now re-throws as `ToolAbortError` the moment the caller's signal aborts, so the session sees a clean cancel on every platform. ([#1221](https://github.com/can1357/oh-my-pi/issues/1221))
776
787
 
777
- ### Added
778
-
779
- - Added OSC 8 terminal hyperlink support for file paths in tool output. When the terminal supports hyperlinks (kitty, Ghostty, WezTerm, iTerm2, Alacritty, VS Code) and the new `tui.hyperlinks` setting is `auto` (default) or `always`, OMP wraps file paths emitted by `read`, `find`, `search`, `edit`, `ast_grep`, and `ast_edit` renderers in `file:///abs/path` hyperlinks. `local://` and other fs-backed internal URLs resolve to their backing path. Set `tui.hyperlinks: off` to disable. ([#1244](https://github.com/can1357/oh-my-pi/issues/1244))
780
-
781
788
  ## [15.1.8] - 2026-05-20
782
789
 
783
790
  ### Fixed
784
791
 
785
792
  - Fixed streaming edit previews for `apply_patch` and `hashline` jittering as the model typed `+added` lines. Two root causes addressed: (1) the trailing partial line of the streaming text input is now trimmed at each tick so a half-typed `+added` line no longer flickers; (2) the preview is rendered in the model's input order during streaming instead of re-deriving a unified diff via `Diff.structuredPatch`, whose coalescing previously reshuffled existing `+added` lines downward each time a new `-removed` line arrived. Existing additions now stay put and the preview only grows at the bottom while streaming. A residual trailing `-removed`/hunk-header block whose matching `+added` companion has not yet arrived is also suppressed until the additions land.
786
793
  - Fixed Perplexity web search appearing "logged out" roughly an hour after `omp auth login perplexity`. The search provider's `findOAuthToken` was honoring the bogus `expires = login_time + 1h` written by older logins (Perplexity JWTs typically omit `exp` because sessions are server-side) and silently dropping the credential. The loader now decodes the JWT's `exp` claim directly and only skips when the JWT itself is expired; tokens without an `exp` claim are treated as non-expiring.
787
-
788
- ### Fixed
789
-
790
794
  - Fixed `legacy-pi-compat` failing to load plugin extensions (e.g. `pi-schedule-prompt@0.3.0`) that import `@mariozechner/pi-ai` when running from a compiled binary. `getResolvedSpecifier` called `Bun.resolveSync` against `import.meta.dir` inside `/$bunfs/root`, where the virtual FS exposes no resolvable `node_modules` tree at runtime; the throw silently dropped the plugin. The fix lets `rewriteLegacyPiImports` fall back gracefully on resolution failure so that `rewriteBareImportsForLegacyExtension` — which already runs immediately after — can resolve the original specifier against the plugin's own installed peer deps instead. The same fallback is applied to `resolveLegacyPiSpecifier` (the Bun plugin shim's `onResolve` handler) for tool/hook files loaded directly via Bun's import system. ([#1215](https://github.com/can1357/oh-my-pi/issues/1215))
791
795
 
792
796
  ## [15.1.7] - 2026-05-19
793
797
 
794
- ### Fixed
795
-
796
- - Fixed `debug` launch/attach failures so `configurationDone` no longer masks the underlying DAP launch error, early stop-outcome watchers cannot emit unhandled rejections, and directory-valued launch programs are rejected before adapter selection. ([#1187](https://github.com/can1357/oh-my-pi/issues/1187))
797
- - Fixed hashline edit payloads that use a readability space after `~` by warning on separator-padding-shaped payload blocks and tightening the model prompt. ([#1166](https://github.com/can1357/oh-my-pi/issues/1166))
798
- - Fixed ACP bash permission requests to include execute tool metadata and command content so clients can render command approval prompts consistently. ([#1189](https://github.com/can1357/oh-my-pi/issues/1189))
799
- - Fixed the status-line fast-mode indicator (`⚡`) rendering for scoped service tiers (`openai-only`, `claude-only`) even when the active model's provider didn't realize them — e.g. `serviceTier: "openai-only"` would still show the indicator next to a Claude model the wire request couldn't apply fast mode to. The indicator now consults a new `AgentSession.isFastModeActive()` predicate that runs the configured tier through `resolveServiceTier(tier, model.provider)` and only lights up when the result is `"priority"` for the current model. `isFastModeEnabled()` keeps its scope-aware semantics so `/fast on|off|toggle` and `/fast status` continue to reflect the user's configured intent.
800
- ### Fixed
801
-
802
- - Fixed status-line context% computation freezing the UI for ~1.1 s every 2 s on long sessions (2,000+ messages). The earlier alignment fix (which uses `computeContextBreakdown` to match the `/context` slash command) was running on every agent event via `updateEditorTopBorder()` (event-controller.ts:163), and `computeContextBreakdown` walks every message through the native `countTokens` tokenizer (~0.5 ms each) — for the user's 2,312-message session this was ~1,120 ms synchronous blocking per cache miss, producing the user-visible "jittery rendering" and "status bar disappearing during streaming". `StatusLineComponent.getCachedContextBreakdown()` now uses an incremental per-message token cache: messages are walked ONCE during warm-up, and subsequent refreshes only compute tokens for the NEW messages appended since last call (typically 0–1 per refresh during streaming). The LAST message is always recomputed because its content may still be growing mid-stream; all prior messages are immutable once a newer message exists. Compaction (messages array shrinks) resets the cache. Non-message tokens (system prompt + tools + skills) are cached separately and invalidated via a cheap identity fingerprint. Result: 2,300-message warm refresh drops from ~1,120 ms to ~0.04 ms — 28,000× faster. Functional parity with the prior `computeContextBreakdown` path is preserved.
803
-
804
798
  ### Added
805
799
 
806
800
  - Added scoped service tier values to the `serviceTier` setting: `priority (OpenAI only)` and `priority (Claude only)`. They let you opt into premium processing on one provider family without paying premium costs on the other when switching models mid-session. `/fast on` continues to set the unscoped `"priority"` (active everywhere supported); `/fast status` and `isFastModeEnabled()` now report `on` for any scoped value too.
@@ -809,6 +803,14 @@
809
803
 
810
804
  - Changed `/fast` to be a single provider-agnostic toggle: enabling the command sets `serviceTier: "priority"` for every provider, and the anthropic-messages provider translates `priority` into `speed: "fast"` plus the `fast-mode-2026-02-01` beta. Anthropic fast mode is currently supported on Claude Opus 4.6 and 4.7; the server rejects other models, which triggers the provider's auto-fallback (request retried without the priority signal, `providerSessionState.fastModeDisabled` persisted for the rest of the session). The session listens for the `"priority"` marker in `AssistantMessage.disabledFeatures`, syncs `/fast` off, and emits a warning notice. Re-running `/fast on` clears the per-session disable so the next request actually re-tries priority.
811
805
 
806
+ ### Fixed
807
+
808
+ - Fixed `debug` launch/attach failures so `configurationDone` no longer masks the underlying DAP launch error, early stop-outcome watchers cannot emit unhandled rejections, and directory-valued launch programs are rejected before adapter selection. ([#1187](https://github.com/can1357/oh-my-pi/issues/1187))
809
+ - Fixed hashline edit payloads that use a readability space after `~` by warning on separator-padding-shaped payload blocks and tightening the model prompt. ([#1166](https://github.com/can1357/oh-my-pi/issues/1166))
810
+ - Fixed ACP bash permission requests to include execute tool metadata and command content so clients can render command approval prompts consistently. ([#1189](https://github.com/can1357/oh-my-pi/issues/1189))
811
+ - Fixed the status-line fast-mode indicator (`⚡`) rendering for scoped service tiers (`openai-only`, `claude-only`) even when the active model's provider didn't realize them — e.g. `serviceTier: "openai-only"` would still show the indicator next to a Claude model the wire request couldn't apply fast mode to. The indicator now consults a new `AgentSession.isFastModeActive()` predicate that runs the configured tier through `resolveServiceTier(tier, model.provider)` and only lights up when the result is `"priority"` for the current model. `isFastModeEnabled()` keeps its scope-aware semantics so `/fast on|off|toggle` and `/fast status` continue to reflect the user's configured intent.
812
+ - Fixed status-line context% computation freezing the UI for ~1.1 s every 2 s on long sessions (2,000+ messages). The earlier alignment fix (which uses `computeContextBreakdown` to match the `/context` slash command) was running on every agent event via `updateEditorTopBorder()` (event-controller.ts:163), and `computeContextBreakdown` walks every message through the native `countTokens` tokenizer (~0.5 ms each) — for the user's 2,312-message session this was ~1,120 ms synchronous blocking per cache miss, producing the user-visible "jittery rendering" and "status bar disappearing during streaming". `StatusLineComponent.getCachedContextBreakdown()` now uses an incremental per-message token cache: messages are walked ONCE during warm-up, and subsequent refreshes only compute tokens for the NEW messages appended since last call (typically 0–1 per refresh during streaming). The LAST message is always recomputed because its content may still be growing mid-stream; all prior messages are immutable once a newer message exists. Compaction (messages array shrinks) resets the cache. Non-message tokens (system prompt + tools + skills) are cached separately and invalidated via a cheap identity fingerprint. Result: 2,300-message warm refresh drops from ~1,120 ms to ~0.04 ms — 28,000× faster. Functional parity with the prior `computeContextBreakdown` path is preserved.
813
+
812
814
  ## [15.1.6] - 2026-05-19
813
815
 
814
816
  ### Fixed
@@ -837,6 +839,7 @@
837
839
  - Fixed the TUI model selector to keep provider tab labels separate from provider ids, so the human-readable Ollama Cloud tab refreshes and filters `ollama-cloud` models correctly. ([#1153](https://github.com/can1357/oh-my-pi/issues/1153))
838
840
 
839
841
  ## [15.1.3] - 2026-05-17
842
+
840
843
  ### Breaking Changes
841
844
 
842
845
  - Renamed the embedded-documentation internal URL scheme from `pi://` to `omp://`. `OmpProtocolHandler` replaces `PiProtocolHandler`; update any external references accordingly.
@@ -877,12 +880,10 @@
877
880
  - Fixed gateway usage reporting to include cached-token totals for OpenAI Chat/Responses and to serve the last good cached report during transient upstream usage fetch failures.
878
881
  - Fixed auth-gateway request cancellation for requests that are already aborted before dispatch.
879
882
  - Fixed `/login` and `/logout` provider selector overflowing tall provider lists off-screen on small terminals. The selector now scrolls a 10-item window centered on the highlighted entry, shows a `(n/total)` indicator when windowed, and accepts PageUp/PageDown for faster navigation.
880
-
881
- ### Fixed
882
-
883
883
  - Fixed `.env` loading so malformed variable names and NUL-containing values are ignored before they can poison `Bun.env` and break bash/external process execution with `nul byte found in provided data`.
884
884
 
885
885
  ## [15.1.2] - 2026-05-15
886
+
886
887
  ### Fixed
887
888
 
888
889
  - Fixed SSH host additions/removals made inside a running session not refreshing the live `ssh` tool. `/ssh add` and `/ssh remove` now update the model-visible host list immediately, while `/reload-plugins` and `/move` refresh SSH discovery for external or project-scope config changes without restart.
@@ -895,6 +896,7 @@
895
896
  - Updated MCP and theme schema metadata to reference JSON Schema draft-2020-12
896
897
 
897
898
  ## [15.1.0] - 2026-05-15
899
+
898
900
  ### Breaking Changes
899
901
 
900
902
  - Changed the extension and hook runtime API by moving schema typing from direct TypeBox imports to `TSchema` from `@oh-my-pi/pi-ai`, requiring callers who use TypeScript imports of `Type` to migrate via provided injected modules
@@ -962,7 +964,6 @@
962
964
  ### Changed
963
965
 
964
966
  - Changed the `github` tool's search ops (`search_issues`, `search_prs`, `search_code`, `search_commits`) to default the `repo` scope to the current checkout's `owner/repo` when `repo` is omitted. The auto-scope is skipped when the query already carries an explicit `repo:`/`org:`/`user:`/`owner:` qualifier or when `gh repo view` cannot resolve a github remote (in which case the search proceeds across all of GitHub as before). `search_repos` is unchanged — repository-scoping there must live in the query.
965
-
966
967
  - Changed bash command preprocessing to strip trailing `| head` and `| tail` pipelines (including `|&`) from each top-level segment in command chains separated by `;`, `&&`, `||`, or `&`
967
968
  - Changed bash fixup notices to state that stderr is already merged into stdout and to reflect that fixes were applied for multiple stripped segments when several transforms fire
968
969
  - Changed shell-minimizer per-line truncation marker from a bare `…` to `…[+N]`, where `N` is the count of dropped Unicode scalars. The bracketed tally disambiguates minimizer-driven cuts from genuine `…` characters in the source (paths, JSON, stack traces, etc.) and gives the agent an exact count so it can decide whether the missing tail is recoverable inline or warrants reading the `[raw output: artifact://<id>]` footer the bash wrapper already emits when the minimizer rewrites output. Affects pipeline Stage 5 (`truncate_lines_at` in `defs/*.toml`) and the internal callers in `filters/git.rs`, `filters/listing.rs`, and `filters/lint.rs`. ([#1046](https://github.com/can1357/oh-my-pi/issues/1046))
@@ -981,13 +982,10 @@
981
982
  - Rewrote the hashline edit prompt examples to use an ASCII-only `TITLE = "Mr"` → `"Mrs"` / `"Dr"` motif instead of the previous `" • "` and `"·"` separators. Some agents had been copying the middle-dot literal characters into real edits as if they were format scaffolding (e.g. emitting payload lines like `~ ·`), since the demo inserts were near-twins of the existing string. The new example keeps every original op shape (single-line replace, multiline replace, insert AFTER/BEFORE, append, delete, blank, plus both anti-patterns) but uses content that is obviously domain-specific and clearly distinct from any payload separator. Pure prompt change; no parser, schema, or runtime behavior is affected.
982
983
  - Fixed startup fallback-chain validation to recognize cached runtime-discovered standard provider models, including Ollama Cloud models listed by `--list-models`, so `retry.fallbackChains` no longer warns that valid `ollama-cloud/<model>` selectors are unknown. ([#1052](https://github.com/can1357/oh-my-pi/issues/1052))
983
984
  - Fixed `discoverAgents()` ignoring `disabledProviders` for the `claude-plugins` provider. Plugin roots from `~/.claude/plugins/` were scanned unconditionally, so agents from Claude Code marketplace plugins continued to appear in `/agents` and the Agent Control Center even when `disabledProviders: [claude-plugins]` was set. The discovery path now checks `isProviderEnabled("claude-plugins")` before calling `listClaudePluginRoots()`, matching how every other capability respects the disabled-providers set. ([#1075](https://github.com/can1357/oh-my-pi/issues/1075))
984
-
985
- ### Fixed
986
-
987
985
  - Fixed `$env:VAR` PowerShell variables being mangled on Windows when commands invoked PowerShell as a subprocess (e.g. `powershell -Command "Write-Host $env:SystemRoot"`). Brush-core applied POSIX parameter expansion to `$env` before spawning the child, leaving a dangling `:NAME`. The fix lives in `pi-shell` at env-var application time: every brush session now defines `env=$env` as an internal shell variable so `$env:NAME` expands to the literal `$env:NAME` token that PowerShell expects. The fallback is not exported, only influences brush's own expansion, and is shadowed by any user assignment to `env` (e.g. `env=prod; echo "$env:8080"` still prints `prod:8080`), so the POSIX bash contract is preserved. ([#1079](https://github.com/can1357/oh-my-pi/issues/1079))
988
986
 
989
-
990
987
  ## [15.0.1] - 2026-05-14
988
+
991
989
  ### Breaking Changes
992
990
 
993
991
  - Removed the dedicated `exit_plan_mode` tool and its prompt, requiring plan-mode completion to use the existing `resolve` tool path instead
@@ -1030,6 +1028,7 @@
1030
1028
  - Fixed MCP OAuth refresh failing with `HTTP 401 invalid_client` for servers that require Dynamic Client Registration (RFC 7591) and have no `oauth.clientId` configured (e.g. `mcp.linear.app`). `MCPOAuthFlow` registered a fresh public PKCE client on each authorize and discarded the issued `client_id` once the flow object went out of scope; refresh then called the provider's `/token` endpoint without a `client_id`. The flow now exposes `resolvedClientId` / `registeredClientSecret` getters, `MCPCommandController#handleOAuthFlow` returns them alongside `credentialId`, and both the initial-connect and `/mcp reauth` paths persist them into `auth.{clientId,clientSecret}` (used at refresh) and `oauth.{clientId,clientSecret}` (used by subsequent `/mcp reauth` to skip re-registration). The `MCPAddWizard` `onOAuth` callback type is now `Promise<MCPAddWizardOAuthResult>` and `#launchOAuthFlow` folds the registered credentials into wizard state. Servers with a statically-configured `oauth.clientId` (Notion, Slack, Datadog) are unaffected — `#tryRegisterClient` short-circuits and the write-back is a no-op. ([#1061](https://github.com/can1357/oh-my-pi/pull/1061) by [@ldx](https://github.com/ldx)).
1031
1029
 
1032
1030
  ## [15.0.0] - 2026-05-13
1031
+
1033
1032
  ### Breaking Changes
1034
1033
 
1035
1034
  - Removed `op: issue_view` and `op: pr_view` from the `github` tool. Read single issues/PRs via the `read` tool against `issue://<N>` / `pr://<N>` (or the long form `issue://<owner>/<repo>/<N>` / `pr://<owner>/<repo>/<N>`); append `?comments=0` to drop the comments section. The `issue` and `comments` parameters were removed from the tool schema since no remaining op consumes them. Mutating ops (`pr_create`, `pr_checkout`, `pr_push`), `repo_view`, `search_*`, and `run_watch` are unchanged.
@@ -1063,6 +1062,7 @@
1063
1062
  - Aligned prompt instruction language by defining `NEVER` and `AVOID` as strict aliases for `MUST NOT` and `SHOULD NOT` in the system prompt, and standardized agent, tool, and system prompt templates to use those terms consistently
1064
1063
  - Changed `--mode acp` to apply the same stdout-quiet overrides as `--mode rpc` so no banner or status text leaks into the JSON-RPC channel
1065
1064
  - Changed ACP startup to no longer require a configured model so registry validators and clients can complete `initialize` and `authenticate` before any model is selected
1065
+
1066
1066
  ### Fixed
1067
1067
 
1068
1068
  - Deferred flushing of buffered `credential_disabled` events during extension runner initialization to a microtask so handler failures are now routed through `onError()` registrations made immediately after `initialize()`, preserving extension error reporting
@@ -1200,6 +1200,7 @@
1200
1200
  - Fixed top-level `const`, `let`, and `class` declarations in evaluated JavaScript to persist across subsequent runs by rewriting top-level declarations
1201
1201
 
1202
1202
  ## [14.9.5] - 2026-05-12
1203
+
1203
1204
  ### Breaking Changes
1204
1205
 
1205
1206
  - Removed the `jobs://` internal URL protocol; inspect background jobs via the `job` tool's `list: true` operation instead
@@ -1224,9 +1225,6 @@
1224
1225
  - Changed `memory://` URL resolution to walk all active sessions’ memory roots and return the first matching file, so worktree-based subagents can access their own memory views as well as shared roots
1225
1226
  - Changed internal URL routing to use a shared process-global `InternalUrlRouter` and protocol handlers, so built-in tools resolve `agent://`, `artifact://`, `memory://`, `skill://`, `rule://`, `mcp://`, and `local://` URLs without requiring session-specific router wiring
1226
1227
  - Changed `mcp://` handler to use the globally registered MCP manager so MCP resource links work for agents sharing session context
1227
-
1228
- ### Changed
1229
-
1230
1228
  - Changed the `ask.timeout` default from `30` (seconds) to `0` (wait indefinitely). Auto-selecting the recommended option after a fixed delay was surprising users mid-deliberation; the timer is now strictly opt-in. The legacy auto-select behavior is preserved when `ask.timeout` is set to a non-zero value, and the `ask` tool's prompt has been updated so the model expects unlimited reply time by default.
1231
1229
 
1232
1230
  ### Fixed
@@ -1244,6 +1242,7 @@
1244
1242
  - Fixed `Timed out initializing browser tab worker` on prebuilt binaries by rewriting `spawnTabWorker` to import the worker entry with `with { type: "file" }` so Bun's `--compile` bundler statically discovers and embeds `tab-worker-entry.ts` in the single-file binary ([#1011](https://github.com/can1357/oh-my-pi/issues/1011))
1245
1243
 
1246
1244
  ## [14.9.3] - 2026-05-10
1245
+
1247
1246
  ### Breaking Changes
1248
1247
 
1249
1248
  - Changed the `eval` tool input format to canonical `*** Begin <LANG>` ... `*** End <LANG>` cells with `*** Title`, `*** Timeout`, and `*** Reset` directives, so legacy `===== ... =====` eval inputs are no longer accepted for execution
@@ -1289,6 +1288,7 @@
1289
1288
  - Fixed IRC background exchange poll loop leaking after session disposal: `#scheduleBackgroundExchangeFlush` now stops immediately when `dispose()` is called, preventing stale `setTimeout` callbacks from firing against a torn-down agent
1290
1289
 
1291
1290
  ## [14.9.2] - 2026-05-10
1291
+
1292
1292
  ### Added
1293
1293
 
1294
1294
  - Added `agentsMdFiles` to `WorkspaceTree` so AGENTS.md discovery results are returned with the workspace scan output
@@ -1304,13 +1304,18 @@
1304
1304
  - Fixed MCP HTTP streamable transport spamming `HTTP SSE stream error: ReadableStream already has a controller` after every JSON-RPC request whose response was returned as `text/event-stream`. The transport used to break out of the SSE iterator once the matching response was captured and then re-open `response.body` for a background drain, but the body had already been piped through a `TransformStream` and could not be re-read. The drain now runs from a single iterator that resolves the response promise inline and continues to dispatch piggybacked notifications on the same stream.
1305
1305
 
1306
1306
  ## [14.9.0] - 2026-05-10
1307
+
1307
1308
  ### Breaking Changes
1308
1309
 
1309
1310
  - Moved hashline APIs to the dedicated `@oh-my-pi/pi-coding-agent/hashline` module, moved hash helpers to `@oh-my-pi/pi-coding-agent/hashline/hash`, and removed the legacy `edit/modes/hashline` and `edit/line-hash` source subpaths.
1310
1311
 
1311
- ### Removed
1312
+ ### Added
1312
1313
 
1313
- - Removed hashline auto-rebase. Anchor mismatches now reject immediately so the model re-reads instead of silently relocating an edit to a hash-collision within ±5 lines, which could otherwise apply the change to the wrong region. Stale-anchor recovery via the cached read snapshot is unaffected.
1314
+ - Added a debug-panel raw SSE stream viewer so stuck model/tool-call streams can be inspected live from the TUI.
1315
+ - Added `get_login_providers` RPC command to list registered OAuth providers with their current authentication status (`id`, `name`, `available`, `authenticated`)
1316
+ - Added `login` RPC command to trigger OAuth login for a given provider; emits an `open_url` extension UI event (fire-and-forget) carrying the auth URL and optional instructions so headless clients can open the browser, then resolves when the callback-server flow completes
1317
+ - Added `open_url` variant to `RpcExtensionUIRequest` for the above
1318
+ - Added `getLoginProviders()` and `login(providerId)` methods to `RpcClient`
1314
1319
 
1315
1320
  ### Fixed
1316
1321
 
@@ -1325,23 +1330,14 @@
1325
1330
  - Fixed `metadata.user_id` lacking the authenticated `account_uuid` on Anthropic OAuth requests; sessions now install a dynamic resolver via `Agent#setMetadataResolver` that builds `{ session_id, account_uuid? }` per request, looking the live OAuth account UUID up from `AuthStorage` so it stays in sync with token refreshes and login/logout transitions instead of stranding a stale value
1326
1331
  - Fixed multi-file legacy Pi extensions failing to load when sibling `.ts` files import each other via relative paths ([#983](https://github.com/can1357/oh-my-pi/issues/983)).
1327
1332
  - Fixed sub-agent dispatch silently routing to a model whose provider has no working credentials (e.g. an unqualified `modelRoles.task` id like `qwen3.6-plus-free` resolving to a provider the user is not authenticated against). Task dispatch now falls back to the parent session's active model — which by definition has working auth — when the resolved subagent model has none ([#985](https://github.com/can1357/oh-my-pi/issues/985)).
1328
-
1329
- ### Added
1330
-
1331
- - Added a debug-panel raw SSE stream viewer so stuck model/tool-call streams can be inspected live from the TUI.
1332
-
1333
- ### Fixed
1334
-
1335
1333
  - Fixed legacy Pi plugin extensions failing to load on Windows when their entry path contains a drive letter ([#990](https://github.com/can1357/oh-my-pi/pull/990) by [@jiwangyihao](https://github.com/jiwangyihao)).
1336
1334
 
1337
- ### Added
1335
+ ### Removed
1338
1336
 
1339
- - Added `get_login_providers` RPC command to list registered OAuth providers with their current authentication status (`id`, `name`, `available`, `authenticated`)
1340
- - Added `login` RPC command to trigger OAuth login for a given provider; emits an `open_url` extension UI event (fire-and-forget) carrying the auth URL and optional instructions so headless clients can open the browser, then resolves when the callback-server flow completes
1341
- - Added `open_url` variant to `RpcExtensionUIRequest` for the above
1342
- - Added `getLoginProviders()` and `login(providerId)` methods to `RpcClient`
1337
+ - Removed hashline auto-rebase. Anchor mismatches now reject immediately so the model re-reads instead of silently relocating an edit to a hash-collision within ±5 lines, which could otherwise apply the change to the wrong region. Stale-anchor recovery via the cached read snapshot is unaffected.
1343
1338
 
1344
1339
  ## [14.8.0] - 2026-05-09
1340
+
1345
1341
  ### Added
1346
1342
 
1347
1343
  - Added hashline stale-anchor recovery by replaying edits against a session-scoped `read`/`search` snapshot and 3-way-merging them onto the current file when anchors no longer match
@@ -1361,6 +1357,7 @@
1361
1357
  - Fixed indefinite startup hang on large repos introduced in 14.7.6 ([#975](https://github.com/can1357/oh-my-pi/issues/975)) on two fronts: (1) `createAgentSession` was awaiting `buildAgentsMdSearch` and `buildWorkspaceTree` directly in its blocking `Promise.all`, bypassing the existing 5s preparation deadline that previously protected startup — both scans are now raced against a 5s deadline and fall back to the system-prompt fallback path on timeout; (2) `buildWorkspaceTree` now derives its listing from `git ls-files --cached --others --exclude-standard` when the workspace is a git worktree, which is O(index size) and avoids the per-call full-tree gitignore-aware native scan that the previous implementation triggered. Repos without git, or where the call fails / times out, transparently fall back to the previous native-glob path.
1362
1358
 
1363
1359
  ## [14.7.6] - 2026-05-07
1360
+
1364
1361
  ### Changed
1365
1362
 
1366
1363
  - Changed the "Hide Thinking Blocks" setting (Ctrl+T) to also instruct the provider to omit thinking/reasoning summaries from responses, instead of just hiding them client-side. Anthropic sees `thinking.display = "omitted"` (where supported); OpenAI Responses / Azure / Codex requests drop `reasoning.summary` entirely.
@@ -1373,6 +1370,7 @@
1373
1370
  - Fixed subagents re-running expensive workspace scans (`buildAgentsMdSearch`, `buildWorkspaceTree`) on every spawn: parents now forward their already-resolved `AGENTS.md` search and workspace tree to subagents through `createAgentSession`, matching how `contextFiles`, `skills`, and `promptTemplates` are already inherited. On large monorepos this removes seconds of redundant work per `task` invocation and prevents the per-subagent system-prompt timeout warnings.
1374
1371
 
1375
1372
  ## [14.7.5] - 2026-05-07
1373
+
1376
1374
  ### Added
1377
1375
 
1378
1376
  - Added optional `/loop` limits: `/loop 10` stops after 10 auto-iterations, while duration forms such as `/loop 10m` and `/loop 10min` stop after the time limit.
@@ -1408,6 +1406,7 @@
1408
1406
  - Fixed hashline edit streaming preview collapsing to a header-only "opaque box" when a second `@PATH` section header arrived mid-stream — earlier completed sections now stay rendered while the trailing section is still being typed.
1409
1407
 
1410
1408
  ## [14.7.2] - 2026-05-06
1409
+
1411
1410
  ### Breaking Changes
1412
1411
 
1413
1412
  - Removed the exported `BUILTIN_TOOL_METADATA` API, including `BuiltinEntry`-style metadata exports and discoverable-built-in helper exports, which will break consumers relying on those symbols
@@ -1435,6 +1434,7 @@
1435
1434
  - Changed hashline replacement and pure-insert auto-absorb to also drop a single duplicated structural-closing line (`}`, `);`, `]`, etc.) on either boundary when keeping it would unbalance brackets. The pure-insert variant fires regardless of `edit.hashlineAutoDropPureInsertDuplicates`, while the existing 2+ line generic absorb stays gated on that setting.
1436
1435
 
1437
1436
  ## [14.7.0] - 2026-05-04
1437
+
1438
1438
  ### Breaking Changes
1439
1439
 
1440
1440
  - Changed session system-prompt APIs to use ordered string block arrays by requiring `buildSystemPrompt`, `CreateAgentSessionOptions.systemPrompt`, `Session.rebuildSystemPrompt`, and extension `before_agent_start`/`getSystemPrompt` hooks to accept and return `systemPrompt: string[]` instead of a plain system-prompt string or separate `projectPrompt` field
@@ -1479,6 +1479,7 @@
1479
1479
  - Added Ctrl+D draft persistence: pressing Ctrl+D with text in the editor now exits the app and saves the unsent text as a per-session draft. Resuming the same session (e.g. via `--resume`) restores the draft into the editor (one-shot, removed after restore).
1480
1480
 
1481
1481
  ## [14.6.4] - 2026-05-03
1482
+
1482
1483
  ### Added
1483
1484
 
1484
1485
  - Added `hindsight.mentalModelsEnabled`, `hindsight.mentalModelAutoSeed`, `hindsight.mentalModelRefreshIntervalMs`, and `hindsight.mentalModelMaxRenderChars` settings to control curated Hindsight mental-model activation, seeding, refresh cadence, and prompt render budget
@@ -1656,9 +1657,6 @@
1656
1657
  ### Fixed
1657
1658
 
1658
1659
  - Fixed eval startup messaging to report `eval` as unavailable when Python is unreachable and JavaScript backend is disabled
1659
-
1660
- ### Fixed
1661
-
1662
1660
  - Stabilized MCP tool ordering so reconnects and refreshes no longer reorder the tools array sent to the model. Anthropic prompt caching is keyed on byte-identical tool definitions; previously, the order depended on connection sequence and a single MCP server reconnect could shuffle tools across servers and invalidate the tools cache breakpoint.
1663
1661
  - Skipped redundant system-prompt rebuilds in `AgentSession.refreshMCPTools` when the active tool set is unchanged. MCP transport flapping (e.g. routine 5-minute SSE reconnects) used to call `rebuildSystemPrompt` on every reconnect even though the resulting prompt was byte-identical, eating CPU and risking cache misses if the rebuild ever became non-deterministic. The applied-tool signature also covers `customWireName` so a wire-name flip with the rest of the tool metadata constant still forces a rebuild.
1664
1662
 
@@ -2312,9 +2310,6 @@
2312
2310
  - Fixed stale child selector reuse to correctly match chunks by checksum when multiple sibling chunks with the same name exist under the same parent
2313
2311
  - Fixed stale diagnostics being reused after unrelated file publishes by clearing cached diagnostics before refreshing file state
2314
2312
  - Fixed Codex search to use streamed answer text when final answer is an image placeholder or empty
2315
-
2316
- ### Fixed
2317
-
2318
2313
  - Fixed MCP config docs and schema to use `~/.omp/agent/mcp.json` for user-scoped OMP-native MCP config while keeping project config at `<cwd>/.omp/mcp.json`
2319
2314
 
2320
2315
  ## [14.0.4] - 2026-04-10
@@ -2489,6 +2484,7 @@
2489
2484
  - Chunk-mode `read` output: recursive rendering with `$XXXX` checksum suffixes, inline large-chunk previews, and normalized `#path$XXXX` selectors between read and edit
2490
2485
  - Autoresearch: `init_experiment` options `new_segment`, `from_autoresearch_md`, `abandon_unlogged_runs`; `log_experiment` options `skip_restore` and broader `force`; `run_experiment` `force` (with warnings); pre-run dirty-path tracking; `abandonUnloggedAutoresearchRuns` and `abandonedAt` on runs
2491
2486
  - LSP: diagnostic versioning (`versionSupport`, stored document version per diagnostic set), and `waitForDiagnostics` / `getDiagnosticsForFile` options (`expectedDocumentVersion`, `allowUnversioned`)
2487
+ - `/review` command now accepts inline args as custom instructions appended to the generated prompt for all structured review modes (PR-style, uncommitted, specific commit). When inline args are provided, option 4 (editor) is suppressed from the menu. The no-UI (Task tool) path forwards args as a focus hint.
2492
2488
 
2493
2489
  ### Changed
2494
2490
 
@@ -2523,17 +2519,6 @@
2523
2519
  - ACP session creation now uses a factory function to support creating new sessions for different working directories
2524
2520
  - ACP event mapping now accepts optional `getMessageId` callback for stable message ID assignment to assistant chunks
2525
2521
 
2526
- ### Removed
2527
-
2528
- - Deleted `src/utils/prompt-format.ts` module; prompt formatting logic moved to `pi-utils`
2529
- - Deleted `src/utils/frontmatter.ts` module; frontmatter parsing logic moved to `pi-utils`
2530
- - Removed `waitForChildProcess` utility (child process termination now handled by native `killTree` from pi-natives)
2531
- - `grep-chunk.md` (folded into unified grep template)
2532
- - `startMacAppearanceObserver` export (use `MacAppearanceObserver.start()`)
2533
- - `copyToClipboard` export from pi-natives
2534
- - `PI_CHUNK_SPLICES` env and `chunkSplicesEnabled()`
2535
- - Autoresearch `segmentFingerprint` and related config hashing
2536
-
2537
2522
  ### Fixed
2538
2523
 
2539
2524
  - Chunk edit parameter validation: corrected detection of chunk edit operations to check for `sel` field instead of `target`
@@ -2601,9 +2586,16 @@
2601
2586
  - `/autoresearch` toggles like `/plan` when empty; slash completion no longer suggests `off`/`clear` on an empty prefix after the command
2602
2587
  - Chunk-mode read/edit edge cases (zero-width gap replaces, stale batch diagnostics, grouped Go receivers, line-count headers, parse error locations)
2603
2588
 
2604
- ### Added
2589
+ ### Removed
2605
2590
 
2606
- - `/review` command now accepts inline args as custom instructions appended to the generated prompt for all structured review modes (PR-style, uncommitted, specific commit). When inline args are provided, option 4 (editor) is suppressed from the menu. The no-UI (Task tool) path forwards args as a focus hint.
2591
+ - Deleted `src/utils/prompt-format.ts` module; prompt formatting logic moved to `pi-utils`
2592
+ - Deleted `src/utils/frontmatter.ts` module; frontmatter parsing logic moved to `pi-utils`
2593
+ - Removed `waitForChildProcess` utility (child process termination now handled by native `killTree` from pi-natives)
2594
+ - `grep-chunk.md` (folded into unified grep template)
2595
+ - `startMacAppearanceObserver` export (use `MacAppearanceObserver.start()`)
2596
+ - `copyToClipboard` export from pi-natives
2597
+ - `PI_CHUNK_SPLICES` env and `chunkSplicesEnabled()`
2598
+ - Autoresearch `segmentFingerprint` and related config hashing
2607
2599
 
2608
2600
  ## [13.19.0] - 2026-04-05
2609
2601
 
@@ -2951,6 +2943,7 @@
2951
2943
  - Added support for Agent Client Protocol SDK integration with session management, MCP server configuration, and streaming communication
2952
2944
  - Added `ensureOnDisk()` method to SessionManager to persist sessions immediately for ACP discovery
2953
2945
  - Added multiline custom input for `ask` custom answers, using the prompt-style editor without inactivity timeout while composing ([#506](https://github.com/can1357/oh-my-pi/issues/506))
2946
+ - Session observer overlay (`Ctrl+S`): view running subagent sessions with a picker and read-only transcript showing thinking, text, tool calls, and results
2954
2947
 
2955
2948
  ### Changed
2956
2949
 
@@ -2994,13 +2987,6 @@
2994
2987
  - Changed session persistence logic to use atomic file rewrite when flushing unflushed sessions to prevent duplication
2995
2988
  - Removed hashline edit autocorrection for duplicated boundary lines; escaped-tab autocorrection remains available for leading `\\t` sequences
2996
2989
 
2997
- ### Removed
2998
-
2999
- - Removed `command-start.md` prompt template in favor of separate initialize and resume workflows
3000
- - Removed auto-correction of off-by-one range edits that duplicated closing braces or boundary lines
3001
- - Removed `shouldAutocorrect` function and related boundary line deduplication logic from hashline editor
3002
- - Removed auto-correction of off-by-one range edits that duplicated closing braces or boundary lines
3003
-
3004
2990
  ### Fixed
3005
2991
 
3006
2992
  - Fixed autoresearch resume to detect and recover pending run artifacts that were left unlogged from previous sessions
@@ -3008,14 +2994,14 @@
3008
2994
  - Fixed tab character rendering in dashboard command display and tool output summaries
3009
2995
  - Fixed autoresearch logging to require durable ASI metadata (hypothesis, rollback_reason, next_action_hint) for every run including rollback context for discarded, crashed, and checks-failed experiments
3010
2996
  - Fixed autoresearch logging to require durable ASI metadata for every run, including rollback context for discarded, crashed, and checks-failed experiments
3011
-
3012
- ### Fixed
3013
-
3014
2997
  - Fixed resumed and session-switched GitHub Copilot/OpenAI Responses conversations replaying stale assistant native history from older saved sessions by sanitizing persisted assistant replay metadata on rehydration and resetting provider session state across live session boundaries ([#505](https://github.com/can1357/oh-my-pi/issues/505))
3015
2998
 
3016
- ### Added
2999
+ ### Removed
3017
3000
 
3018
- - Session observer overlay (`Ctrl+S`): view running subagent sessions with a picker and read-only transcript showing thinking, text, tool calls, and results
3001
+ - Removed `command-start.md` prompt template in favor of separate initialize and resume workflows
3002
+ - Removed auto-correction of off-by-one range edits that duplicated closing braces or boundary lines
3003
+ - Removed `shouldAutocorrect` function and related boundary line deduplication logic from hashline editor
3004
+ - Removed auto-correction of off-by-one range edits that duplicated closing braces or boundary lines
3019
3005
 
3020
3006
  ## [13.14.0] - 2026-03-20
3021
3007
 
@@ -3242,9 +3228,6 @@
3242
3228
  ### Changed
3243
3229
 
3244
3230
  - Path resolution on Linux redirects to XDG locations when `XDG_DATA_HOME` / `XDG_STATE_HOME` / `XDG_CACHE_HOME` environment variables are set
3245
-
3246
- ### Changed
3247
-
3248
3231
  - Changed TTSR interrupt logic to respect per-rule `interruptMode` settings, falling back to global `ttsr.interruptMode` when rule-level override is not specified
3249
3232
  - Reorganized settings tabs from 12 tabs (display, agent, input, tools, config, services, bash, lsp, ttsr, status) to 8 focused tabs (appearance, model, interaction, context, editing, tools, tasks, providers) for improved discoverability
3250
3233
  - Consolidated status line settings into the Appearance tab instead of a separate Status tab
@@ -3270,10 +3253,6 @@
3270
3253
  - Changed working directory paths in system prompt to use forward slashes for consistency across platforms
3271
3254
  - Modified bash executor to fall back to one-shot shell execution after a persistent session hard timeout, preventing subsequent commands from hanging
3272
3255
 
3273
- ### Removed
3274
-
3275
- - Removed bash executor hard timeout recovery test file (functionality already documented in existing entries)
3276
-
3277
3256
  ### Fixed
3278
3257
 
3279
3258
  - Fixed bash execution to fall back to one-shot shell runs after a persistent session hard timeout, preventing later commands from hanging until restart
@@ -3281,6 +3260,10 @@
3281
3260
  - Fixed AgentSession disposal to call SessionManager's `close()` method when available, ensuring proper cleanup of persistent writers
3282
3261
  - Removed redundant `path.join()` call wrapping `getHistoryDbPath()` in history-storage.ts
3283
3262
 
3263
+ ### Removed
3264
+
3265
+ - Removed bash executor hard timeout recovery test file (functionality already documented in existing entries)
3266
+
3284
3267
  ## [13.11.1] - 2026-03-13
3285
3268
 
3286
3269
  ### Added
@@ -7358,31 +7341,6 @@
7358
7341
  - Added auto-chdir to temp directories when starting in home unless `--allow-home` is set
7359
7342
  - Added upfront diff parsing and filtering for code review command to exclude lock files, generated code, and binary assets
7360
7343
 
7361
- ### Fixed
7362
-
7363
- - Fixed auto-chdir to only use existing directories and fall back to `tmpdir()`
7364
- - Added automatic reviewer agent count recommendation based on diff weight and file count
7365
- - Added file grouping guidance for parallel review distribution across multiple agents
7366
- - Added diff preview mode for large changesets that exceed size thresholds
7367
- - Added in-memory session storage implementation for testing and ephemeral sessions
7368
- - Added `createToolUIKit` helper to consolidate common UI formatting utilities across tool renderers
7369
- - Added configurable bash interceptor rules via `bashInterceptor.patterns` setting for custom command blocking
7370
- - Added `bashInterceptor.simpleLs` setting to control interception of bare ls commands
7371
- - Added LSP server configuration via external JSON defaults file for easier customization
7372
- - Added abort signal propagation to web scrapers for improved cancellation handling
7373
- - Added `diagnosticsVersion` tracking to LSP client for more reliable diagnostic polling
7374
- - Added 80+ specialized web scrapers for structured content extraction from popular sites including GitHub, GitLab, npm, PyPI, crates.io, Wikipedia, YouTube, Stack Overflow, Hacker News, Reddit, arXiv, PubMed, and many more
7375
- - Added site-specific API integrations for package registries (npm, PyPI, crates.io, Hex, Hackage, NuGet, Maven, RubyGems, Packagist, pub.dev, Go packages)
7376
- - Added scrapers for social platforms (Mastodon, Bluesky, Lemmy, Lobsters, Dev.to, Discourse)
7377
- - Added scrapers for academic sources (arXiv, bioRxiv, PubMed, Semantic Scholar, ORCID, CrossRef, IACR)
7378
- - Added scrapers for security databases (NVD, OSV, CISA KEV)
7379
- - Added scrapers for documentation sites (MDN, Read the Docs, RFC Editor, W3C, SPDX, tldr, cheat.sh)
7380
- - Added scrapers for media platforms (YouTube, Vimeo, Spotify, Discogs, MusicBrainz)
7381
- - Added scrapers for AI/ML platforms (Hugging Face, Ollama)
7382
- - Added scrapers for app stores and marketplaces (VS Code Marketplace, JetBrains Marketplace, Firefox Add-ons, Open VSX, Flathub, F-Droid, Snapcraft)
7383
- - Added scrapers for business data (SEC EDGAR, OpenCorporates, CoinGecko)
7384
- - Added scrapers for reference sources (Wikipedia, Wikidata, OpenLibrary, Choose a License)
7385
-
7386
7344
  ### Changed
7387
7345
 
7388
7346
  - Changed `Ctrl+P` to cycle through role models (slow → default → smol) instead of all available models
@@ -7405,12 +7363,30 @@
7405
7363
  - Improved rust-analyzer diagnostic polling to use version-based stability detection
7406
7364
  - Refactored web-fetch tool to use modular scraper architecture for improved maintainability
7407
7365
 
7408
- ### Removed
7409
-
7410
- - Removed `submit_review` tool - reviewers now finish via `complete` tool with structured output
7411
-
7412
7366
  ### Fixed
7413
7367
 
7368
+ - Fixed auto-chdir to only use existing directories and fall back to `tmpdir()`
7369
+ - Added automatic reviewer agent count recommendation based on diff weight and file count
7370
+ - Added file grouping guidance for parallel review distribution across multiple agents
7371
+ - Added diff preview mode for large changesets that exceed size thresholds
7372
+ - Added in-memory session storage implementation for testing and ephemeral sessions
7373
+ - Added `createToolUIKit` helper to consolidate common UI formatting utilities across tool renderers
7374
+ - Added configurable bash interceptor rules via `bashInterceptor.patterns` setting for custom command blocking
7375
+ - Added `bashInterceptor.simpleLs` setting to control interception of bare ls commands
7376
+ - Added LSP server configuration via external JSON defaults file for easier customization
7377
+ - Added abort signal propagation to web scrapers for improved cancellation handling
7378
+ - Added `diagnosticsVersion` tracking to LSP client for more reliable diagnostic polling
7379
+ - Added 80+ specialized web scrapers for structured content extraction from popular sites including GitHub, GitLab, npm, PyPI, crates.io, Wikipedia, YouTube, Stack Overflow, Hacker News, Reddit, arXiv, PubMed, and many more
7380
+ - Added site-specific API integrations for package registries (npm, PyPI, crates.io, Hex, Hackage, NuGet, Maven, RubyGems, Packagist, pub.dev, Go packages)
7381
+ - Added scrapers for social platforms (Mastodon, Bluesky, Lemmy, Lobsters, Dev.to, Discourse)
7382
+ - Added scrapers for academic sources (arXiv, bioRxiv, PubMed, Semantic Scholar, ORCID, CrossRef, IACR)
7383
+ - Added scrapers for security databases (NVD, OSV, CISA KEV)
7384
+ - Added scrapers for documentation sites (MDN, Read the Docs, RFC Editor, W3C, SPDX, tldr, cheat.sh)
7385
+ - Added scrapers for media platforms (YouTube, Vimeo, Spotify, Discogs, MusicBrainz)
7386
+ - Added scrapers for AI/ML platforms (Hugging Face, Ollama)
7387
+ - Added scrapers for app stores and marketplaces (VS Code Marketplace, JetBrains Marketplace, Firefox Add-ons, Open VSX, Flathub, F-Droid, Snapcraft)
7388
+ - Added scrapers for business data (SEC EDGAR, OpenCorporates, CoinGecko)
7389
+ - Added scrapers for reference sources (Wikipedia, Wikidata, OpenLibrary, Choose a License)
7414
7390
  - Fixed session persistence to call fsync before renaming temp file for durability
7415
7391
  - Fixed duplicate persistence error logging by tracking whether error was already reported
7416
7392
  - Fixed byte counting in task output truncation to correctly handle multi-byte Unicode characters
@@ -7419,6 +7395,10 @@
7419
7395
  - Fixed parallel task execution to fail fast on first error instead of waiting for all workers
7420
7396
  - Fixed byte counting in task output truncation to handle multi-byte Unicode characters correctly
7421
7397
 
7398
+ ### Removed
7399
+
7400
+ - Removed `submit_review` tool - reviewers now finish via `complete` tool with structured output
7401
+
7422
7402
  ## [3.30.0] - 2026-01-07
7423
7403
 
7424
7404
  ### Added
@@ -7497,10 +7477,6 @@
7497
7477
 
7498
7478
  ## [3.21.0] - 2026-01-06
7499
7479
 
7500
- ### Changed
7501
-
7502
- - Switched from local `@oh-my-pi/pi-ai` to upstream `@oh-my-pi/pi-ai` package
7503
-
7504
7480
  ### Added
7505
7481
 
7506
7482
  - Added `webSearchProvider` setting to override auto-detection priority (Exa > Perplexity > Anthropic)
@@ -7522,6 +7498,7 @@
7522
7498
 
7523
7499
  ### Changed
7524
7500
 
7501
+ - Switched from local `@oh-my-pi/pi-ai` to upstream `@oh-my-pi/pi-ai` package
7525
7502
  - Refactored tool renderers to be co-located with their respective tool implementations for improved code organization
7526
7503
  - Changed web search to try all configured providers in sequence with fallback before reporting errors
7527
7504
  - Changed default Anthropic web search model from `claude-sonnet-4-5-20250514` to `claude-haiku-4-5`
@@ -9238,4 +9215,4 @@ Initial public release.
9238
9215
  - Git branch display in footer
9239
9216
  - Message queueing during streaming responses
9240
9217
  - OAuth integration for Gmail and Google Calendar access
9241
- - HTML export with syntax highlighting and collapsible sections
9218
+ - HTML export with syntax highlighting and collapsible sections