@oh-my-pi/pi-coding-agent 15.10.1 → 15.10.2

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 (102) hide show
  1. package/CHANGELOG.md +67 -0
  2. package/dist/types/cli/startup-cwd.d.ts +2 -0
  3. package/dist/types/commands/launch.d.ts +3 -0
  4. package/dist/types/config/keybindings.d.ts +2 -2
  5. package/dist/types/config/model-provider-priority.d.ts +1 -0
  6. package/dist/types/config/model-resolver.d.ts +4 -1
  7. package/dist/types/config/settings.d.ts +7 -2
  8. package/dist/types/debug/report-bundle.d.ts +3 -0
  9. package/dist/types/edit/file-snapshot-store.d.ts +18 -10
  10. package/dist/types/eval/py/__tests__/prelude.test.d.ts +1 -0
  11. package/dist/types/extensibility/extensions/types.d.ts +4 -1
  12. package/dist/types/lsp/client.d.ts +10 -0
  13. package/dist/types/main.d.ts +3 -9
  14. package/dist/types/mcp/tool-bridge.d.ts +2 -0
  15. package/dist/types/modes/components/custom-editor.d.ts +1 -1
  16. package/dist/types/modes/components/status-line.d.ts +2 -0
  17. package/dist/types/modes/controllers/event-controller.d.ts +17 -0
  18. package/dist/types/modes/interactive-mode.d.ts +1 -0
  19. package/dist/types/modes/magic-keywords.d.ts +1 -1
  20. package/dist/types/modes/markdown-prose.d.ts +1 -1
  21. package/dist/types/modes/types.d.ts +3 -0
  22. package/dist/types/modes/workflow.d.ts +3 -3
  23. package/dist/types/session/auth-storage.d.ts +1 -1
  24. package/dist/types/session/session-manager.d.ts +5 -2
  25. package/dist/types/task/executor.d.ts +10 -0
  26. package/dist/types/tools/eval.d.ts +8 -0
  27. package/dist/types/tools/gh-cache-invalidation.d.ts +6 -0
  28. package/dist/types/tools/github-cache.d.ts +12 -0
  29. package/dist/types/tools/path-utils.d.ts +8 -0
  30. package/dist/types/tools/search.d.ts +2 -2
  31. package/dist/types/tools/yield.d.ts +8 -0
  32. package/package.json +9 -9
  33. package/src/cli/args.ts +3 -1
  34. package/src/cli/dry-balance-cli.ts +2 -4
  35. package/src/cli/startup-cwd.ts +68 -0
  36. package/src/commands/launch.ts +3 -0
  37. package/src/commit/model-selection.ts +3 -2
  38. package/src/config/model-provider-priority.ts +55 -0
  39. package/src/config/model-registry.ts +4 -22
  40. package/src/config/model-resolver.ts +39 -7
  41. package/src/config/settings.ts +86 -41
  42. package/src/debug/index.ts +8 -0
  43. package/src/debug/raw-sse-buffer.ts +7 -4
  44. package/src/debug/report-bundle.ts +9 -0
  45. package/src/edit/file-snapshot-store.ts +33 -1
  46. package/src/edit/hashline/filesystem.ts +2 -1
  47. package/src/eval/__tests__/llm-bridge.test.ts +20 -0
  48. package/src/eval/js/context-manager.ts +32 -15
  49. package/src/eval/llm-bridge.ts +14 -3
  50. package/src/eval/py/__tests__/prelude.test.ts +19 -0
  51. package/src/eval/py/executor.ts +23 -11
  52. package/src/eval/py/prelude.py +1 -1
  53. package/src/extensibility/extensions/types.ts +10 -1
  54. package/src/internal-urls/docs-index.generated.ts +3 -3
  55. package/src/lsp/client.ts +23 -11
  56. package/src/lsp/config.ts +11 -1
  57. package/src/lsp/index.ts +61 -9
  58. package/src/main.ts +91 -65
  59. package/src/mcp/tool-bridge.ts +2 -0
  60. package/src/memories/index.ts +2 -2
  61. package/src/modes/components/custom-editor.ts +143 -111
  62. package/src/modes/components/model-selector.ts +59 -13
  63. package/src/modes/components/oauth-selector.ts +33 -7
  64. package/src/modes/components/status-line.ts +19 -4
  65. package/src/modes/components/tips.txt +1 -1
  66. package/src/modes/components/user-message.ts +1 -1
  67. package/src/modes/controllers/event-controller.ts +26 -0
  68. package/src/modes/controllers/input-controller.ts +46 -7
  69. package/src/modes/interactive-mode.ts +107 -20
  70. package/src/modes/magic-keywords.ts +1 -1
  71. package/src/modes/markdown-prose.ts +1 -1
  72. package/src/modes/theme/shimmer.ts +20 -9
  73. package/src/modes/types.ts +3 -0
  74. package/src/modes/workflow.ts +10 -10
  75. package/src/prompts/system/workflow-notice.md +1 -1
  76. package/src/prompts/tools/bash.md +9 -0
  77. package/src/prompts/tools/browser.md +1 -1
  78. package/src/prompts/tools/eval.md +2 -1
  79. package/src/prompts/tools/read.md +2 -2
  80. package/src/sdk.ts +26 -9
  81. package/src/session/agent-session.ts +37 -12
  82. package/src/session/auth-storage.ts +2 -0
  83. package/src/session/session-manager.ts +96 -23
  84. package/src/task/executor.ts +71 -36
  85. package/src/task/render.ts +3 -4
  86. package/src/tools/bash.ts +7 -0
  87. package/src/tools/browser/tab-supervisor.ts +13 -1
  88. package/src/tools/browser/tab-worker.ts +33 -4
  89. package/src/tools/eval.ts +13 -2
  90. package/src/tools/find.ts +7 -0
  91. package/src/tools/gh-cache-invalidation.ts +200 -0
  92. package/src/tools/github-cache.ts +25 -0
  93. package/src/tools/inspect-image.ts +2 -2
  94. package/src/tools/path-utils.ts +28 -2
  95. package/src/tools/plan-mode-guard.ts +52 -7
  96. package/src/tools/read.ts +25 -12
  97. package/src/tools/search.ts +38 -3
  98. package/src/tools/write.ts +2 -2
  99. package/src/tools/yield.ts +10 -1
  100. package/src/utils/commit-message-generator.ts +2 -2
  101. package/src/utils/enhanced-paste.ts +30 -2
  102. package/src/web/search/providers/codex.ts +37 -8
package/CHANGELOG.md CHANGED
@@ -2,6 +2,73 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [15.10.2] - 2026-06-08
6
+ ### Added
7
+
8
+ - Added `raw-sse.txt` to debug report bundles, exporting recent raw provider SSE diagnostics when captured
9
+ - Added `/model` visibility for auto-selected role defaults: inferred `pi/smol`/`pi/slow`/designer choices now show as compact `[ROLE auto]` badges, while explicitly configured roles keep the existing solid badges and thinking labels.
10
+ - Added credential provenance to the `/login` and `/logout` provider picker: each authenticated provider now shows where its credential comes from — `(login)`, `(api key)`, `(env: VAR_NAME)`, `(config)`, `(--api-key)`, or `(custom provider)` — so a real OAuth login is distinguishable from an env var that merely aliases the provider (e.g. `COPILOT_GITHUB_TOKEN`). The origin is also matched by the picker's type-to-search filter.
11
+
12
+ ### Changed
13
+
14
+ - Changed raw SSE debug export output to prepend dropped-record metadata so truncated sessions in debug bundles now report dropped record and character counts
15
+ - Changed settings reads to cache pre-split schema paths and resolved values, with coarse invalidation on source/cwd changes.
16
+ - Changed status-line rendering to cache merged effective settings until `updateSettings()` changes the configuration.
17
+ - Changed `CustomEditor` app shortcut dispatch to parse each input packet once and match against precomputed canonical key sets, preserving the existing shortcut precedence while avoiding repeated key reparses.
18
+ - Changed `lsp references` to retry only when no references or only the queried declaration are returned, using two fixed 250ms retries for project-aware servers
19
+ - Changed `read` handling of `https://github.com/<owner>/<repo>:raw` to use raw page rendering only, removing the GitHub API README fallback
20
+ - Changed model resolution to apply provider-priority ordering when selecting models for roles and ambiguous patterns, using `modelProviderOrder` settings and built-in provider priority so first-party providers are preferred over relays in tie cases
21
+ - Changed model canonical variant selection to use the same provider-priority ordering instead of candidate order when deduplicating equivalent upstream models
22
+ - Changed the working-message shimmer to sweep at a fixed velocity (cells/second) instead of a fixed sweep duration divided by the message length. The band now advances ≤1 cell per 30fps redraw frame and stays equally smooth on short and long messages — previously a longer message swept proportionally faster and stepped visibly because it outran the redraw cadence. Sweep/round-trip duration now scales with length. Additionally, when `display.shimmer = disabled` the working line is static, so the loader no longer schedules 30fps redraws for it and falls back to the spinner-only ~12.5fps cadence.
23
+ - Changed the eval fan-out trigger keyword from `workflow`/`workflows` to `workflowz`.
24
+
25
+ ### Fixed
26
+
27
+ - Fixed working-message loader session accents so spinner/message color math is cached per session name, session-accent setting, and theme luminance while still updating immediately on renames, setting toggles, and theme changes.
28
+ - Fixed startup model fallback selection so sessions now prefer each provider’s configured default model before choosing the first available authenticated model
29
+ - Fixed implicit model selection path for tools and sessions by honoring persisted model-provider order when no explicit pattern is provided
30
+ - Fixed the working spinner appearing to ignore Esc for 2-3 seconds when an interrupt lands mid-tool. Esc fires the abort synchronously, but the agent loop only stops the loader at `agent_end`, which it cannot reach until every in-flight tool settles in `executeToolCalls`' `await Promise.allSettled(...)` — and process/subagent/kernel-owning tools tear down gracefully (SIGTERM, 2-3s grace, SIGKILL), so the loader kept showing the unchanged "Working…/<intent>" line and read as a dropped keypress. The loader now switches to "Interrupting…" the instant Esc requests the abort and freezes intent-driven label updates until the turn unwinds (`EventController.notifyInterrupting`), so the interrupt is acknowledged immediately even while teardown completes.
31
+ - Fixed a flaky JS eval worker startup that intermittently failed unrelated CI runs. The worker-ready wait reused Bun's 5s default per-test timeout as its floor, so a slow cold-start under `--isolate` + high concurrency was aborted mid-init; terminating a still-initializing Bun worker is the documented SIGILL/SIGTRAP crash trigger, which took down the whole test file. Worker init now floors at a fixed 15s infrastructure budget (independent of, and still dominated by, a larger per-cell `timeout`), and the JS eval test suites set a 20s file-local timeout so cold starts complete instead of being torn down.
32
+ - Fixed reviewer-style subagent yields crashing the calling eval cell when a caller-supplied output schema declares `additionalProperties: false` without a `findings` property. `normalizeCompleteData` now consults the active validator before splicing collected `report_finding` entries onto the yielded payload, so injection is suppressed when the schema would reject it — keeping the executor's post-mortem validation in lockstep with the in-tool `yield` validation that already accepted the same raw payload ([#2070](https://github.com/can1357/oh-my-pi/issues/2070))
33
+ - Fixed Anthropic empty `toolUse` stops without tool calls corrupting session history by retrying them and removing orphaned turns even at the retry cap.
34
+ - Fixed MCP tools hanging in non-yolo modes by declaring `approval = "write"` on `MCPTool` and `DeferredMCPTool`, and propagating the `approval` property through `customToolToDefinition()` in `sdk.ts`
35
+ - Fixed session resumption after a working directory is moved/renamed (e.g. `git worktree move`): `--continue` now re-roots the terminal's last session into the new directory when its original directory no longer exists, explicit `--resume <id> --session-dir <dir>` local matches re-root instead of reopening with the stale cwd, and cross-project `--resume <id>` offers to move (re-root) the session rather than only forking a duplicate copy when the source directory is gone
36
+ - Fixed Kitty OSC 5522 paste rejecting plain text as "no supported text or image data": the listing parser now decodes the `mime="."` DATA payload (whitespace-separated MIME list) Kitty actually sends, in addition to the per-type DATA packets described by the ancillary 5522-mode spec, and per-type spec listings now request the selected payload with `type=read:mime=...` instead of Kitty's dot-payload request shape ([#2051](https://github.com/can1357/oh-my-pi/issues/2051))
37
+ - Fixed follow-up shortcut submission of builtin slash commands so `/goal set ...` applies goal mode instead of queueing as plain text.
38
+ - Fixed Ctrl+Z crashing the agent on Windows with `TypeError: Unknown signal: SIGTSTP`. `InputController.handleCtrlZ` called `process.kill(0, "SIGTSTP")` unconditionally, but `SIGTSTP` is POSIX job-control and Bun/Node on Windows rejects the signal name from the JS side; the throw propagated out of the TUI input dispatcher as an uncaught exception. The handler now no-ops with a "Suspend (Ctrl+Z) is not supported on this platform" status on Windows, and on POSIX wraps `process.kill` in a try/catch that detaches the registered SIGCONT resume hook and re-`start()`s the TUI on failure so a rejected signal can never leave the UI stranded with a leaked listener ([#2036](https://github.com/can1357/oh-my-pi/issues/2036)).
39
+ - Fixed a relative `--cwd` target (e.g. `omp --cwd repo` launched from `/tmp`) leaking the raw relative string into the session config. `applyStartupCwd` chdired into the resolved directory via `setProjectDir` but left `parsed.cwd` as `"repo"`, so `buildSessionOptions` (which prefers `parsed.cwd` over `getProjectDir()`) handed downstream settings/discovery/session creation a value that re-resolved against the new process cwd (`/tmp/repo/repo`) or persisted a relative session cwd. `parsed.cwd` is now re-synced to the resolved absolute project dir after the chdir.
40
+ - Fixed the `--cwd` launch flag so it is parsed and can override the startup directory instead of always falling back to the current process directory or home auto-switch target.
41
+ - Fixed session auto-retry for generic `upstream_error: Upstream request failed` gateway failures.
42
+ - Stripped read-output line-number prefixes (`N:`) from auto-piped bare body rows in the hashline edit parser, so pasting `3:text` without a `+` prefix no longer injects `3:` as literal content. Uses single-pass stripping to avoid corrupting content whose own text starts with `digits:` ([#1492](https://github.com/can1357/oh-my-pi/issues/1492)).
43
+ - Fixed `eval` `llm()` returning HTTP 400 "Instructions are required" when called without a `system` prompt against providers (notably `openai-codex`) whose Responses transformer drops the `instructions` field on an empty system prompt. `runEvalLlm` now sends a minimal default system prompt ("You are a helpful assistant.") when no `system` is supplied, so `llm("question")` works against every provider; an explicit `system=` still wins.
44
+ - Fixed the Python `read(path, offset, limit)` prelude helper rejecting documented positional arguments with `TypeError: read() takes 1 positional argument but 3 were given`. The signature was keyword-only (`def read(path, *, offset=1, limit=None)`) while the eval helper table advertises positional optional args; agents that called `read("file.py", 10, 20)` literally crashed. The `*` is removed so both `read("f", 10, 20)` and `read("f", offset=10, limit=20)` work.
45
+ - Fixed `eval` reset cells failing with `"Python kernel reset already in progress"` / `"JS context reset already in progress"` when two cells happened to overlap on the same session (e.g. a rapid resubmit, or a parallel-cell race). The executor now coalesces concurrent resets — additional callers wait for the in-flight reset to finish and then run on the freshly restarted kernel — instead of throwing a user-visible error for what is purely an internal coordination state.
46
+ - Fixed the `eval` tool description advertising the `agent()` helper unconditionally even in subagent sessions whose parent forbids spawning. When `getSessionSpawns()` returns `""`, the prelude doc now omits `agent()` so the model is not promised a helper that can only ever throw "Cannot spawn 'task'. Allowed: none (spawns disabled for this agent)".
47
+ - Fixed plan mode rejecting `local://` plan-artifact edits when addressed via the absolute path the `read` tool echoes back in the `[path#tag]` header. `enforcePlanModeWrite` previously only matched the literal `local://` scheme; it now also accepts any absolute path whose realpath resolves inside the session's local sandbox root, so the absolute spelling and the `local://` spelling are interchangeable in plan mode.
48
+ - Fixed snapshot tags freshly minted by `read` being rejected as stale by a subsequent `edit` against the same file when the two sides reached the file via symlink-equivalent spellings (e.g. macOS `/tmp/…` vs `/private/tmp/…`, or `read local://foo.md` recording under the file's `fs.realpath` while `edit local://foo.md` looked up under the raw `path.resolve(localRoot, …)` form). The file snapshot store now keys every record/lookup through a `realpath`-canonicalized key (`canonicalSnapshotKey`), fusing all spellings of the same on-disk file onto one snapshot entry.
49
+ - Fixed `read` of a `github.com/<owner>/<repo>` URL with `:raw` returning the full JS-rendered HTML shell. Repo roots now resolve to the decoded README via the GitHub API (`/repos/<owner>/<repo>/readme`), falling back to the raw HTML only when the API returns no usable payload.
50
+ - Fixed `issue://` and `pr://` reads returning stale OPEN/CLOSED state after a successful `gh issue close` / `gh pr merge` (or any other state-changing `gh` invocation) in the same session. The `bash` tool now invalidates the matching `github-cache` rows before executing any `gh (issue|pr) <close|reopen|merge|delete|edit|comment|lock|unlock|pin|unpin|transfer|develop|ready|review>` command.
51
+ - Fixed line-range selectors on PDF/DOCX/PPTX/XLSX/RTF/EPUB reads being ignored. The markit-converted markdown body now flows through the same in-memory range slicer used for plain text, so `file.pdf:50-100` and `file.pdf:5-16,40-80` slice the converted body instead of returning the whole document.
52
+ - Fixed the `read` selector cheatsheet incorrectly promising "exactly one line" for `:N+1` while the implementation pads single-line reads with ≤1 leading and ≤3 trailing context; documented that multi-range selectors do not pad, giving callers a way to request exact bounds.
53
+ - Documented the `bash.autoBackground.enabled` behavior in the `bash` tool prompt so the `Background job <id> started: …` notice for foreground commands that exceed `autoBackgroundThresholdSeconds` no longer reads as a tool malfunction.
54
+ - Fixed `task` subagents whose in-tool `yield` validator had already accepted a payload after exhausting `MAX_SCHEMA_RETRIES` being rejected a second time by the post-mortem executor validator. The override now propagates through the yield tool's `details.schemaOverridden` flag, and the executor surfaces a `SUBAGENT_WARNING_SCHEMA_OVERRIDDEN` stderr line instead of re-emitting `schema_violation` for data the subagent already had to ship. Finalize also degrades to no validation (matching the yield tool's `looseRecordSchema` fallback) when the caller-supplied output schema fails to normalize.
55
+ - Fixed the `web_search` `codex` provider returning `(see attached image)` / `[Attached image]` / `See image above` and similar non-informational image-placeholder strings as the answer. Detection broadened to a small regex set, and when annotations did produce sources we now drop the placeholder prose from `answer` (returning sources only); when neither annotations nor a real answer materialize, we throw 502 to advance the provider chain.
56
+ - Fixed `search`, `find`, `ast_grep`, and `ast_edit` rejecting bracket-containing file paths (Next.js routes like `apps/[id]/page.tsx`) as glob patterns when the literal path exists on disk. `parseSearchPathPreferringLiteral` now prefers the literal interpretation for paths that resolve on disk and only falls back to glob expansion when the literal does not exist.
57
+ - Fixed `search` with an external `http(s)/ftp/ws/file://` URL in `paths` surfacing a misleading "Path not found" error. The tool now rejects external URLs with a clear "use `read` for URLs" message.
58
+ - Fixed `search` rejecting `skip: null` at the schema layer; `null` now normalizes to `0` alongside the omitted case, matching how callers serialize default pagination state.
59
+ - Fixed `search` returning zero matches with no explanation when explicit file targets exceed the native grep cap (4 MB). The tool now surfaces a `Skipped oversized files (>4MB grep limit; …)` notice listing the truncated paths.
60
+ - Fixed the archive-extraction error message in `search` recommending `grep` — which the system prompt forbids — instead of pointing to `read <archive>:<member>`.
61
+ - Fixed `browser` `tab.open(name, { viewport })` on an existing tab not applying the new viewport: `acquireTab`'s reuse path now resizes the page in addition to navigating.
62
+ - Fixed `browser` tab metadata leaking `user:pass@` basic-auth credentials in the URL surfaced to transcripts and observe snapshots; URLs are now redacted via `redactUrlCredentials()`.
63
+ - Fixed `browser` `tab.extract(format)` returning a `ReadableResult | null` shape that the tool prompt advertised as plain content. The helper now returns the markdown/text string directly (or throws a clear `ToolError` when extraction is empty), and the prompt matches.
64
+ - Fixed `lsp` requests timing out at a hard-coded 30 s ceiling when the caller supplied an explicit abort signal (e.g. the tool wall-clock). The signal is now the deadline; the 30 s default still applies when neither a signal nor an explicit `timeoutMs` is provided.
65
+ - Fixed `lsp status` reporting servers as `Active language servers: …` when the binary resolves on PATH but never spawns (rustup wrapper, missing toolchain component, etc.). Status now labels each entry as `(ready)` or `(configured, not started)`.
66
+ - Fixed `lsp rename_file` fanning `willRenameFiles` requests across every configured server (including ones with no jurisdiction over the file type) and burning the wall-clock timeout. The action now pre-filters configured LSPs to those whose `fileTypes` cover the source or destination path, falling back to a plain filesystem rename when no server claims the type.
67
+ - Fixed `lsp references` returning only the queried declaration (or only in-file results) on project-aware servers that had not finished indexing. The retry budget is raised from 2 → 3 with 250 / 500 / 1000 ms backoff, and the retry trigger now also fires when all results live in the queried file.
68
+ - Fixed `lsp config` accepting `fileTypes` entries with or without a leading dot inconsistently across actions; both `.ts` and `ts` are now normalized so a missing-dot entry no longer silently excludes a server from extension-based routing.
69
+ - Fixed `lsp request` error path swallowing the params that were sent, making shape/coercion bugs on raw LSP calls impossible to diagnose in one round-trip; the error now echoes a truncated copy of the request params.
70
+ - Fixed `find` with a single-star segment like `dir/*` recursing into subdirectories and returning nested matches. `parseFindPattern` already prepends `**/` for top-level globs (`*.ts` → `**/*.ts`), so anything reaching native without `**/` was deliberately scoped by the user; `recursive: false` is now passed to `natives.glob` to honor that scope.
71
+
5
72
  ## [15.10.1] - 2026-06-07
6
73
 
7
74
  ### Added
@@ -0,0 +1,2 @@
1
+ import type { Args } from "./args";
2
+ export declare function applyStartupCwd(parsed: Args): Promise<void>;
@@ -40,6 +40,9 @@ export default class Index extends Command {
40
40
  "allow-home": import("@oh-my-pi/pi-utils/cli").FlagDescriptor<"boolean"> & {
41
41
  description: string;
42
42
  };
43
+ cwd: import("@oh-my-pi/pi-utils/cli").FlagDescriptor<"string"> & {
44
+ description: string;
45
+ };
43
46
  mode: import("@oh-my-pi/pi-utils/cli").FlagDescriptor<"string"> & {
44
47
  description: string;
45
48
  options: string[];
@@ -109,11 +109,11 @@ export declare const KEYBINDINGS: {
109
109
  readonly description: "Delete character forward";
110
110
  };
111
111
  readonly "tui.editor.deleteWordBackward": {
112
- readonly defaultKeys: ["ctrl+w", "alt+backspace", "ctrl+backspace"];
112
+ readonly defaultKeys: ["ctrl+w", "alt+backspace", "ctrl+backspace", "super+alt+backspace"];
113
113
  readonly description: "Delete word backward";
114
114
  };
115
115
  readonly "tui.editor.deleteWordForward": {
116
- readonly defaultKeys: ["alt+delete", "alt+d"];
116
+ readonly defaultKeys: ["alt+delete", "alt+d", "super+alt+delete", "super+alt+d"];
117
117
  readonly description: "Delete word forward";
118
118
  };
119
119
  readonly "tui.editor.deleteToLineStart": {
@@ -0,0 +1 @@
1
+ export declare function buildModelProviderPriorityRank(configuredProviderOrder?: readonly string[]): Map<string, number>;
@@ -30,7 +30,9 @@ export declare function resolveProviderModelReference(provider: string, modelId:
30
30
  export interface ModelMatchPreferences {
31
31
  /** Most-recently-used model keys (provider/modelId) to prefer when ambiguous. */
32
32
  usageOrder?: string[];
33
- /** Providers to deprioritize when no recent usage is available. */
33
+ /** Provider precedence used for ambiguous unqualified model patterns. */
34
+ providerOrder?: readonly string[];
35
+ /** Providers to deprioritize when no recent usage or provider priority is available. */
34
36
  deprioritizeProviders?: string[];
35
37
  }
36
38
  export type CanonicalModelRegistry = Partial<Pick<ModelRegistry, "resolveCanonicalModel" | "getCanonicalVariants" | "getCanonicalId">>;
@@ -38,6 +40,7 @@ export type ModelLookupRegistry = Pick<ModelRegistry, "getAvailable"> & Partial<
38
40
  type CliModelRegistry = Pick<ModelRegistry, "getAll"> & Partial<CanonicalModelRegistry>;
39
41
  type InitialModelRegistry = Pick<ModelRegistry, "getAvailable" | "find">;
40
42
  type RestorableModelRegistry = Pick<ModelRegistry, "getAvailable" | "find" | "getApiKey">;
43
+ export declare function getModelMatchPreferences(settings?: Partial<Pick<Settings, "get" | "getStorage">>): ModelMatchPreferences;
41
44
  /**
42
45
  * Find an exact explicit provider/model match.
43
46
  * Bare model ids are handled separately so canonical ids can coalesce variants.
@@ -131,7 +131,12 @@ export declare class Settings {
131
131
  * Returns an unsubscribe function. Multiple sessions (main + subagents)
132
132
  * can register independently without overwriting each other.
133
133
  */
134
- export declare function onAppendOnlyModeChanged(cb: (value: string) => void): () => void;
134
+ export declare const onAppendOnlyModeChanged: (cb: (value: string) => void) => () => void;
135
+ /**
136
+ * Subscribe to session-accent setting changes.
137
+ * Returns an unsubscribe function. Callers should re-read settings in the callback.
138
+ */
139
+ export declare const onStatusLineSessionAccentChanged: (cb: () => void) => () => void;
135
140
  /**
136
141
  * Subscribe to changes in the Hindsight bank-scoping settings. Lets the
137
142
  * Hindsight backend rebuild the active `HindsightSessionState` when the
@@ -142,7 +147,7 @@ export declare function onAppendOnlyModeChanged(cb: (value: string) => void): ()
142
147
  * Returns an unsubscribe function. The callback receives no arguments — the
143
148
  * caller is expected to re-read the relevant settings via `Settings.get`.
144
149
  */
145
- export declare function onHindsightScopeChanged(cb: () => void): () => void;
150
+ export declare const onHindsightScopeChanged: (cb: () => void) => () => void;
146
151
  export declare function isSettingsInitialized(): boolean;
147
152
  /**
148
153
  * Reset the global singleton for testing.
@@ -11,6 +11,8 @@ export interface ReportBundleOptions {
11
11
  heapSnapshot?: HeapSnapshot;
12
12
  /** Work profile (for work scheduling reports) */
13
13
  workProfile?: WorkProfile;
14
+ /** Raw provider SSE diagnostics captured by the session buffer */
15
+ rawSseText?: string;
14
16
  }
15
17
  export interface ReportBundleResult {
16
18
  path: string;
@@ -33,6 +35,7 @@ export interface DebugLogSource {
33
35
  * - env.json: Sanitized environment variables
34
36
  * - config.json: Resolved settings
35
37
  * - profile.cpuprofile: CPU profile (performance report only)
38
+ * - raw-sse.txt: Recent raw provider SSE diagnostics (when captured)
36
39
  * - profile.md: Markdown CPU profile (performance report only)
37
40
  * - heap.heapsnapshot: Heap snapshot (memory report only)
38
41
  * - work.folded: Work profile folded stacks (work report only)
@@ -1,13 +1,3 @@
1
- /**
2
- * Session-bound file snapshot store.
3
- *
4
- * Used by `read` and `search` to record exactly what the model saw, and by
5
- * the hashline patcher to verify or recover from stale section tags (file
6
- * changed externally between read and edit, or a prior in-session edit
7
- * advanced the tag). The store is the {@link InMemorySnapshotStore}
8
- * from `@oh-my-pi/hashline`; the only coding-agent-specific concern here
9
- * is wiring it onto the per-session owner object.
10
- */
11
1
  import { InMemorySnapshotStore } from "@oh-my-pi/hashline";
12
2
  /**
13
3
  * Upper bound on the file size we snapshot. A section tag is a content hash of
@@ -25,6 +15,24 @@ interface FileSnapshotStoreOwner {
25
15
  * the session itself.
26
16
  */
27
17
  export declare function getFileSnapshotStore(session: FileSnapshotStoreOwner): InMemorySnapshotStore;
18
+ /**
19
+ * Canonicalize an absolute path into the stable key the snapshot store uses.
20
+ *
21
+ * Different code paths reach the snapshot store via different path forms:
22
+ * `read local://foo.md` records under the file's `fs.realpath` (the local
23
+ * protocol handler resolves symlinks); a subsequent `edit` may address the
24
+ * same artifact via `local://foo.md`, whose resolver does NOT realpath, or
25
+ * via the absolute path returned in the `[path#tag]` header. macOS adds the
26
+ * same hazard at the working-tree level (`/tmp/...` vs `/private/tmp/...`).
27
+ * Collapsing every key through `realpath` makes those forms fuse onto one
28
+ * snapshot entry, so a freshly-minted tag is never rejected as stale just
29
+ * because the lookup spelled the same file differently.
30
+ *
31
+ * Non-existent paths (new-file writes) fall back to a realpath of the parent
32
+ * directory + basename, then to the input. This keeps creates and updates on
33
+ * the same canonical key.
34
+ */
35
+ export declare function canonicalSnapshotKey(absolutePath: string): string;
28
36
  /**
29
37
  * Read the full text of `absolutePath` (within {@link SNAPSHOT_MAX_BYTES}),
30
38
  * record it as a version snapshot, and return its content-hash tag. Returns
@@ -0,0 +1 @@
1
+ export {};
@@ -7,7 +7,7 @@
7
7
  * - Register commands, keyboard shortcuts, and CLI flags
8
8
  * - Interact with the user via UI primitives
9
9
  */
10
- import type { AgentMessage, AgentToolResult, AgentToolUpdateCallback, ThinkingLevel } from "@oh-my-pi/pi-agent-core";
10
+ import type { AgentMessage, AgentToolResult, AgentToolUpdateCallback, ThinkingLevel, ToolApproval } from "@oh-my-pi/pi-agent-core";
11
11
  import type { CompactionResult } from "@oh-my-pi/pi-agent-core/compaction";
12
12
  import type { Api, AssistantMessageEvent, AssistantMessageEventStream, Context, ImageContent, Model, ProviderResponseMetadata, SimpleStreamOptions, Static, TextContent, TSchema } from "@oh-my-pi/pi-ai";
13
13
  import type { OAuthCredentials, OAuthLoginCallbacks } from "@oh-my-pi/pi-ai/utils/oauth/types";
@@ -270,6 +270,9 @@ export interface ToolDefinition<TParams extends TSchema = TSchema, TDetails = un
270
270
  defaultInactive?: boolean;
271
271
  /** If true, tool may stage deferred changes that require explicit resolve/discard. */
272
272
  deferrable?: boolean;
273
+ /** Tool approval tier. Defaults to `"exec"` when omitted.
274
+ * `"read"`: read-only operations. `"write"`: mutations. `"exec"`: code execution. */
275
+ approval?: ToolApproval;
273
276
  /** MCP server name for discovery/search metadata when this tool fronts an MCP server. */
274
277
  mcpServerName?: string;
275
278
  /** Original MCP tool name for discovery/search metadata. */
@@ -45,6 +45,16 @@ export declare function refreshFile(client: LspClient, filePath: string, signal?
45
45
  export declare function shutdownClient(key: string): Promise<void>;
46
46
  /**
47
47
  * Send an LSP request and wait for response.
48
+ *
49
+ * Timeout policy:
50
+ * - If `timeoutMs` is explicitly provided, that value is used.
51
+ * - Else, if `signal` is provided, no internal timer is installed (the caller
52
+ * owns the deadline via the signal — typically a wall-clock `AbortSignal.timeout`
53
+ * from the LSP tool). Installing a second hard-coded 30s timer here used to
54
+ * cause "timed out after 30000ms" errors even when the caller had requested
55
+ * `timeout: 60`.
56
+ * - Else (no signal, no explicit timeout), fall back to `DEFAULT_REQUEST_TIMEOUT_MS`
57
+ * to avoid leaking pending requests forever.
48
58
  */
49
59
  export declare function sendRequest(client: LspClient, method: string, params: unknown, signal?: AbortSignal, timeoutMs?: number): Promise<unknown>;
50
60
  /**
@@ -1,9 +1,3 @@
1
- /**
2
- * Main entry point for the coding agent CLI.
3
- *
4
- * This file handles CLI argument parsing and translates them into
5
- * createAgentSession() options. The SDK does the heavy lifting.
6
- */
7
1
  import type { Args } from "./cli/args";
8
2
  import { ModelRegistry } from "./config/model-registry";
9
3
  import { Settings } from "./config/settings";
@@ -41,10 +35,10 @@ export interface AcpSessionFactoryOptions {
41
35
  * tool registry and shadow the client-supplied servers (issue #1234).
42
36
  */
43
37
  export declare function createAcpSessionFactory(args: AcpSessionFactoryOptions): AcpSessionFactory;
44
- type ForkSessionPromptResult = "accepted" | "declined" | "unavailable";
45
- type ForkSessionPrompt = (session: SessionInfo) => Promise<ForkSessionPromptResult>;
38
+ type SessionPromptResult = "accepted" | "declined" | "unavailable";
39
+ type SessionPrompt = (session: SessionInfo) => Promise<SessionPromptResult>;
46
40
  /** Resolves CLI session flags into an existing, forked, in-memory, or cancelled session manager. */
47
- export declare function createSessionManager(parsed: Args, cwd: string, activeSettings?: Settings, askToForkSession?: ForkSessionPrompt): Promise<SessionManager | undefined>;
41
+ export declare function createSessionManager(parsed: Args, cwd: string, activeSettings?: Settings, askToForkSession?: SessionPrompt, askToMoveSession?: SessionPrompt): Promise<SessionManager | undefined>;
48
42
  interface RunRootCommandDependencies {
49
43
  createAgentSession?: typeof createAgentSession;
50
44
  discoverAuthStorage?: typeof discoverAuthStorage;
@@ -53,6 +53,7 @@ export declare class MCPTool implements CustomTool<TSchema, MCPToolDetails> {
53
53
  readonly mcpToolName: string;
54
54
  /** Server name */
55
55
  readonly mcpServerName: string;
56
+ readonly approval: "write";
56
57
  /** Render completed MCP calls with the result header replacing the pending call header. */
57
58
  readonly mergeCallAndResult = true;
58
59
  /** Create MCPTool instances for all tools from an MCP server connection */
@@ -79,6 +80,7 @@ export declare class DeferredMCPTool implements CustomTool<TSchema, MCPToolDetai
79
80
  readonly mcpToolName: string;
80
81
  /** Server name */
81
82
  readonly mcpServerName: string;
83
+ readonly approval: "write";
82
84
  /** Render completed MCP calls with the result header replacing the pending call header. */
83
85
  readonly mergeCallAndResult = true;
84
86
  /** Create DeferredMCPTool instances for all tools from an MCP server */
@@ -8,7 +8,7 @@ export declare function extractBracketedImagePastePath(data: string): string | u
8
8
  export declare class CustomEditor extends Editor {
9
9
  #private;
10
10
  imageLinks?: readonly (string | undefined)[];
11
- /** Gradient-highlight the "ultrathink" / "orchestrate" / "workflow" keywords as the user types
11
+ /** Gradient-highlight the "ultrathink" / "orchestrate" / "workflowz" keywords as the user types
12
12
  * them, skipping any occurrence inside code spans, fenced blocks, or XML sections. Also make
13
13
  * pasted image placeholders visually distinct and hyperlink them once their blob file exists. */
14
14
  decorateText: (text: string) => string;
@@ -30,11 +30,13 @@ export interface StatusLineSettings {
30
30
  showHookStatus?: boolean;
31
31
  sessionAccent?: boolean;
32
32
  }
33
+ export type EffectiveStatusLineSettings = Required<Pick<StatusLineSettings, "leftSegments" | "rightSegments" | "separator" | "segmentOptions">> & StatusLineSettings;
33
34
  export declare class StatusLineComponent implements Component {
34
35
  #private;
35
36
  private readonly session;
36
37
  constructor(session: AgentSession);
37
38
  updateSettings(settings: StatusLineSettings): void;
39
+ getEffectiveSettingsForTest(): EffectiveStatusLineSettings;
38
40
  setAutoCompactEnabled(enabled: boolean): void;
39
41
  setSubagentCount(count: number): void;
40
42
  setSessionStartTime(time: number): void;
@@ -1,10 +1,27 @@
1
1
  import type { InteractiveModeContext } from "../../modes/types";
2
2
  import type { AgentSessionEvent } from "../../session/agent-session";
3
+ /**
4
+ * Loader label shown the instant a user interrupt (Esc) is requested, kept until
5
+ * the agent turn fully unwinds. Esc fires the abort synchronously, but the loop
6
+ * only stops the spinner at `agent_end`, which it cannot reach until every
7
+ * in-flight tool settles its abort in `executeToolCalls` (`Promise.allSettled`).
8
+ * Swapping the steady "Working…" for this acknowledges the keypress instead of
9
+ * reading as an ignored Esc for the seconds a slow tool takes to tear down.
10
+ */
11
+ export declare const INTERRUPTING_WORKING_MESSAGE = "Interrupting\u2026";
3
12
  export declare class EventController {
4
13
  #private;
5
14
  private ctx;
6
15
  constructor(ctx: InteractiveModeContext);
7
16
  dispose(): void;
17
+ /**
18
+ * Acknowledge a user interrupt (Esc) immediately: switch the loader to
19
+ * `INTERRUPTING_WORKING_MESSAGE` and freeze intent-driven working-message
20
+ * updates for the rest of the turn so a late `tool_execution_start` intent
21
+ * cannot repaint a "Working…/<intent>" line over the acknowledgment. Reset at
22
+ * the next `agent_start`. No-op outside an active turn or if already set.
23
+ */
24
+ notifyInterrupting(): void;
8
25
  subscribeToAgent(): void;
9
26
  handleEvent(event: AgentSessionEvent): Promise<void>;
10
27
  sendCompletionNotification(): void;
@@ -180,6 +180,7 @@ export declare class InteractiveMode implements InteractiveModeContext {
180
180
  ensureLoadingAnimation(): void;
181
181
  setWorkingMessage(message?: string): void;
182
182
  applyPendingWorkingMessage(): void;
183
+ notifyInterrupting(): void;
183
184
  showNewVersionNotification(newVersion: string): void;
184
185
  clearEditor(): void;
185
186
  updatePendingMessagesDisplay(): void;
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Gradient-highlight every magic keyword ("ultrathink", "orchestrate",
3
- * "workflow") that appears as standalone prose, skipping any occurrence inside a
3
+ * "workflowz") that appears as standalone prose, skipping any occurrence inside a
4
4
  * code block, inline code span, or XML/HTML section. Each highlighter paints its
5
5
  * own keyword with its own gradient, so chaining is order-independent — the
6
6
  * earlier passes only inject zero-width SGR escapes (no backticks or angle
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Markdown structure awareness for the magic-keyword affordances
3
- * ("ultrathink"/"orchestrate"/"workflow").
3
+ * ("ultrathink"/"orchestrate"/"workflowz").
4
4
  *
5
5
  * Keyword detection and editor/transcript highlighting must fire only on prose
6
6
  * the user is actually addressing to the model — never on a word that happens to
@@ -159,6 +159,9 @@ export interface InteractiveModeContext {
159
159
  flushPendingModelSwitch(): Promise<void>;
160
160
  setWorkingMessage(message?: string): void;
161
161
  applyPendingWorkingMessage(): void;
162
+ /** Acknowledge a user interrupt (Esc) by switching the loader to an
163
+ * "Interrupting…" label until the agent turn unwinds. */
164
+ notifyInterrupting(): void;
162
165
  ensureLoadingAnimation(): void;
163
166
  startPendingSubmission(input: {
164
167
  text: string;
@@ -1,14 +1,14 @@
1
1
  import { type KeywordHighlighter } from "./gradient-highlight";
2
- /** Hidden system notice appended after a user message that mentions "workflow". */
2
+ /** Hidden system notice appended after a user message that mentions "workflowz". */
3
3
  export declare const WORKFLOW_NOTICE: string;
4
4
  /**
5
- * Whether `text` contains the standalone keyword "workflow"/"workflows"
5
+ * Whether `text` contains the standalone keyword "workflowz"
6
6
  * (lowercase, whitespace-delimited) in prose — never inside a code block, inline
7
7
  * code span, or XML/HTML section.
8
8
  */
9
9
  export declare function containsWorkflow(text: string): boolean;
10
10
  /**
11
- * Highlight every standalone "workflow"/"workflows" in `text` for editor display
11
+ * Highlight every standalone "workflowz" in `text` for editor display
12
12
  * with a warm amber→green gradient (hue 30..150), visually distinct from
13
13
  * ultrathink's rainbow and orchestrate's teal→violet.
14
14
  */
@@ -2,5 +2,5 @@
2
2
  * Re-exports from @oh-my-pi/pi-ai.
3
3
  * All credential storage types and the AuthStorage class now live in the ai package.
4
4
  */
5
- export type { ApiKeyCredential, AuthCredential, AuthCredentialEntry, AuthCredentialStore, AuthStorageData, AuthStorageOptions, OAuthCredential, SerializedAuthStorage, SnapshotResponse, StoredAuthCredential, } from "@oh-my-pi/pi-ai";
5
+ export type { ApiKeyCredential, AuthCredential, AuthCredentialEntry, AuthCredentialStore, AuthStorageData, AuthStorageOptions, CredentialOrigin, CredentialOriginKind, OAuthCredential, SerializedAuthStorage, SnapshotResponse, StoredAuthCredential, } from "@oh-my-pi/pi-ai";
6
6
  export { AuthBrokerClient, AuthStorage, DEFAULT_SNAPSHOT_CACHE_TTL_MS, REMOTE_REFRESH_SENTINEL, RemoteAuthCredentialStore, readAuthBrokerSnapshotCache, SqliteAuthCredentialStore, writeAuthBrokerSnapshotCache, } from "@oh-my-pi/pi-ai";
@@ -317,9 +317,11 @@ export declare class SessionManager {
317
317
  /**
318
318
  * Move the session to a new working directory.
319
319
  * Moves session files and artifacts on disk, updates all internal references,
320
- * and rewrites the session header with the new cwd.
320
+ * and rewrites the session header with the new cwd. When provided,
321
+ * `targetSessionDir` is used instead of deriving the default directory for
322
+ * the new cwd (for `--continue --session-dir` / `--resume --session-dir`).
321
323
  */
322
- moveTo(newCwd: string): Promise<void>;
324
+ moveTo(newCwd: string, targetSessionDir?: string): Promise<void>;
323
325
  isPersisted(): boolean;
324
326
  /**
325
327
  * Force-persist all current entries to disk, even when no assistant message exists yet.
@@ -407,6 +409,7 @@ export declare class SessionManager {
407
409
  /** The source that set the session name: "user" (manual /rename or RPC) or "auto" (generated title). */
408
410
  get titleSource(): "auto" | "user" | undefined;
409
411
  getSessionName(): string | undefined;
412
+ onSessionNameChanged(cb: () => void): () => void;
410
413
  /**
411
414
  * Set the session display name.
412
415
  * @param source - "user" for explicit renames (/rename command, RPC); "auto" for generated titles.
@@ -102,6 +102,15 @@ export interface YieldItem {
102
102
  data?: unknown;
103
103
  status?: "success" | "aborted";
104
104
  error?: string;
105
+ /**
106
+ * Set by the in-tool yield validator when it exhausted its retry budget
107
+ * (MAX_SCHEMA_RETRIES) and accepted a schema-invalid payload anyway.
108
+ * `finalizeSubprocessOutput` honors this by serializing the payload and
109
+ * surfacing a stderr warning, instead of re-emitting `schema_violation`
110
+ * — which would silently swap the subagent's "accepted" view for a
111
+ * different, opaque error blob in the parent's view of the result.
112
+ */
113
+ schemaOverridden?: boolean;
105
114
  }
106
115
  interface FinalizeSubprocessOutputArgs {
107
116
  rawOutput: string;
@@ -120,6 +129,7 @@ interface FinalizeSubprocessOutputResult {
120
129
  abortedViaYield: boolean;
121
130
  hasYield: boolean;
122
131
  }
132
+ export declare const SUBAGENT_WARNING_SCHEMA_OVERRIDDEN = "SYSTEM WARNING: Subagent exhausted schema-retry budget; result was accepted despite failing the output schema.";
123
133
  export declare const SUBAGENT_WARNING_NULL_YIELD = "SYSTEM WARNING: Subagent called yield with null data.";
124
134
  export declare const SUBAGENT_WARNING_MISSING_YIELD = "SYSTEM WARNING: Subagent exited without calling yield tool after 3 reminders.";
125
135
  export declare function finalizeSubprocessOutput(args: FinalizeSubprocessOutputArgs): FinalizeSubprocessOutputResult;
@@ -42,6 +42,14 @@ export type EvalProxyExecutor = (params: EvalToolParams, signal?: AbortSignal) =
42
42
  export interface EvalToolDescriptionOptions {
43
43
  py?: boolean;
44
44
  js?: boolean;
45
+ /**
46
+ * Whether `agent()` is allowed in this session. Driven by the parent's
47
+ * spawn policy (`getSessionSpawns`). Defaults to `true` for backward
48
+ * compatibility — when the session forbids spawning, the prelude doc
49
+ * omits the `agent()` entry so the model does not promise itself a
50
+ * helper that will only ever throw "spawns disabled".
51
+ */
52
+ spawns?: boolean;
45
53
  }
46
54
  export declare function getEvalToolDescription(options?: EvalToolDescriptionOptions): string;
47
55
  export interface EvalToolOptions {
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Drop `github-cache` rows for any `gh issue|pr <mutating-subcmd>` call
3
+ * embedded in `command`. Safe to invoke unconditionally; no-op when the
4
+ * command does not touch GitHub state.
5
+ */
6
+ export declare function invalidateGithubCacheForBashCommand(command: string): void;
@@ -55,6 +55,18 @@ export interface PutCachedInput<T = unknown> {
55
55
  export declare function putCached<T = unknown>(input: PutCachedInput<T>): void;
56
56
  /** Drop a specific cache entry. */
57
57
  export declare function invalidate(repo: string, kind: CacheKind, number: number, includeComments?: boolean, authKey?: string): void;
58
+ /**
59
+ * Drop every cached row for a given issue/PR number, regardless of repo,
60
+ * auth key, include_comments flag, or row kind ({@link CacheKind}). Best-effort:
61
+ * swallows DB failures the same way {@link invalidate} does.
62
+ *
63
+ * Used by the bash-side detector that reacts to `gh issue close` / `gh pr merge`
64
+ * style mutations. Repo + auth-key narrowing is intentionally skipped because
65
+ * the bash command often does not name the repo (defaults to cwd's `gh`
66
+ * config) and resolving the *current* repo from `cwd` for every bash call would
67
+ * be far more expensive than a write-amplified DELETE.
68
+ */
69
+ export declare function invalidateAllForNumber(number: number, repo?: string): void;
58
70
  /** Drop every cached row. Test helper. */
59
71
  export declare function clearAll(): void;
60
72
  /**
@@ -125,6 +125,14 @@ export interface ResolvedMultiFindPattern {
125
125
  * APIs accepting separate `path` and `glob` arguments.
126
126
  */
127
127
  export declare function parseSearchPath(filePath: string): ParsedSearchPath;
128
+ /**
129
+ * Async sibling of {@link parseSearchPath} that prefers literal interpretation
130
+ * when a path containing glob metacharacters resolves to an existing entry on
131
+ * disk. Disambiguates Next.js/SvelteKit routes like `apps/[id]/page.tsx` —
132
+ * without this, `[id]` is parsed as a glob character class and silently
133
+ * matches nothing.
134
+ */
135
+ export declare function parseSearchPathPreferringLiteral(filePath: string, cwd: string): Promise<ParsedSearchPath>;
128
136
  export declare function parseFindPattern(pattern: string): ParsedFindPattern;
129
137
  export declare function combineSearchGlobs(prefixGlob?: string, suffixGlob?: string): string | undefined;
130
138
  export declare function resolveExplicitSearchPaths(pathItems: string[], cwd: string, suffixGlob?: string): Promise<ResolvedMultiSearchPath | undefined>;
@@ -11,7 +11,7 @@ declare const searchSchema: z.ZodObject<{
11
11
  paths: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
12
12
  i: z.ZodOptional<z.ZodBoolean>;
13
13
  gitignore: z.ZodOptional<z.ZodBoolean>;
14
- skip: z.ZodOptional<z.ZodNumber>;
14
+ skip: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
15
15
  }, z.core.$strict>;
16
16
  export type SearchToolInput = z.infer<typeof searchSchema>;
17
17
  export declare function toPathList(input: string | string[] | undefined): string[];
@@ -70,7 +70,7 @@ export declare class SearchTool implements AgentTool<typeof searchSchema, Search
70
70
  paths: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
71
71
  i: z.ZodOptional<z.ZodBoolean>;
72
72
  gitignore: z.ZodOptional<z.ZodBoolean>;
73
- skip: z.ZodOptional<z.ZodNumber>;
73
+ skip: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
74
74
  }, z.core.$strict>;
75
75
  readonly strict = true;
76
76
  constructor(session: ToolSession);
@@ -10,6 +10,14 @@ export interface YieldDetails {
10
10
  data: unknown;
11
11
  status: "success" | "aborted";
12
12
  error?: string;
13
+ /**
14
+ * Set when the yield tool exhausted its in-tool schema-retry budget
15
+ * (MAX_SCHEMA_RETRIES) and accepted the data anyway. Surfaced so the
16
+ * executor's post-mortem finalizer can honor the override instead of
17
+ * re-rejecting the same payload with `schema_violation` — keeping the
18
+ * subagent's acceptance and the parent's view of the result in lockstep.
19
+ */
20
+ schemaOverridden?: boolean;
13
21
  }
14
22
  export declare class YieldTool implements AgentTool<TSchema, YieldDetails> {
15
23
  #private;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@oh-my-pi/pi-coding-agent",
4
- "version": "15.10.1",
4
+ "version": "15.10.2",
5
5
  "description": "Coding agent CLI with read, bash, edit, write tools and session management",
6
6
  "homepage": "https://omp.sh",
7
7
  "author": "Can Boluk",
@@ -47,14 +47,14 @@
47
47
  "@agentclientprotocol/sdk": "0.22.1",
48
48
  "@babel/parser": "^7.29.7",
49
49
  "@mozilla/readability": "^0.6.0",
50
- "@oh-my-pi/hashline": "15.10.1",
51
- "@oh-my-pi/omp-stats": "15.10.1",
52
- "@oh-my-pi/pi-agent-core": "15.10.1",
53
- "@oh-my-pi/pi-ai": "15.10.1",
54
- "@oh-my-pi/pi-mnemopi": "15.10.1",
55
- "@oh-my-pi/pi-natives": "15.10.1",
56
- "@oh-my-pi/pi-tui": "15.10.1",
57
- "@oh-my-pi/pi-utils": "15.10.1",
50
+ "@oh-my-pi/hashline": "15.10.2",
51
+ "@oh-my-pi/omp-stats": "15.10.2",
52
+ "@oh-my-pi/pi-agent-core": "15.10.2",
53
+ "@oh-my-pi/pi-ai": "15.10.2",
54
+ "@oh-my-pi/pi-mnemopi": "15.10.2",
55
+ "@oh-my-pi/pi-natives": "15.10.2",
56
+ "@oh-my-pi/pi-tui": "15.10.2",
57
+ "@oh-my-pi/pi-utils": "15.10.2",
58
58
  "@opentelemetry/api": "^1.9.1",
59
59
  "@opentelemetry/context-async-hooks": "^2.7.1",
60
60
  "@opentelemetry/exporter-trace-otlp-proto": "^0.218.0",