@oh-my-pi/pi-coding-agent 15.10.8 → 15.10.10
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.
- package/CHANGELOG.md +41 -1
- package/dist/types/config/model-registry.d.ts +13 -0
- package/dist/types/config/settings-schema.d.ts +0 -9
- package/dist/types/debug/terminal-info.d.ts +0 -1
- package/dist/types/extensibility/custom-tools/loader.d.ts +22 -3
- package/dist/types/extensibility/extensions/index.d.ts +1 -1
- package/dist/types/extensibility/extensions/loader.d.ts +17 -1
- package/dist/types/extensibility/plugins/legacy-pi-compat.d.ts +8 -0
- package/dist/types/mcp/transports/stdio.d.ts +12 -0
- package/dist/types/modes/components/custom-editor.d.ts +3 -2
- package/dist/types/modes/components/transcript-container.d.ts +12 -26
- package/dist/types/sdk.d.ts +42 -2
- package/dist/types/task/discovery.d.ts +1 -2
- package/dist/types/task/executor.d.ts +16 -0
- package/dist/types/tiny/title-client.d.ts +1 -1
- package/dist/types/tools/index.d.ts +17 -0
- package/dist/types/tools/todo.d.ts +2 -0
- package/dist/types/tui/hyperlink.d.ts +8 -0
- package/package.json +9 -9
- package/src/cli/list-models.ts +5 -11
- package/src/config/model-registry.ts +91 -20
- package/src/config/settings-schema.ts +0 -10
- package/src/debug/terminal-info.ts +0 -3
- package/src/edit/diff.ts +48 -15
- package/src/eval/js/shared/rewrite-imports.ts +9 -1
- package/src/extensibility/custom-tools/loader.ts +43 -19
- package/src/extensibility/extensions/index.ts +1 -0
- package/src/extensibility/extensions/loader.ts +29 -6
- package/src/extensibility/plugins/legacy-pi-compat.ts +30 -6
- package/src/internal-urls/docs-index.generated.ts +4 -4
- package/src/mcp/transports/stdio.ts +139 -3
- package/src/modes/components/custom-editor.ts +69 -9
- package/src/modes/components/model-selector.ts +62 -52
- package/src/modes/components/transcript-container.ts +204 -125
- package/src/modes/controllers/event-controller.ts +0 -45
- package/src/modes/controllers/input-controller.ts +5 -5
- package/src/modes/controllers/mcp-command-controller.ts +2 -2
- package/src/modes/controllers/selector-controller.ts +0 -4
- package/src/modes/interactive-mode.ts +2 -10
- package/src/prompts/system/system-prompt.md +3 -3
- package/src/prompts/tools/bash.md +3 -3
- package/src/prompts/tools/todo.md +5 -1
- package/src/sdk.ts +138 -56
- package/src/ssh/ssh-executor.ts +60 -4
- package/src/task/discovery.ts +17 -24
- package/src/task/executor.ts +19 -0
- package/src/task/index.ts +4 -0
- package/src/tiny/title-client.ts +6 -3
- package/src/tools/index.ts +17 -0
- package/src/tools/todo.ts +16 -7
- package/src/tui/hyperlink.ts +27 -3
- package/src/web/search/providers/anthropic.ts +8 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,46 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [15.10.10] - 2026-06-09
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Added a read-only `view` op to the `todo` tool that echoes the current list without mutating state, so the agent can recover exact task text instead of guessing it from memory.
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
|
|
13
|
+
- Rewrote the bash tool's coreutils guidance (tool prompt and system prompt) around an explicit litmus: pipelines that compute a new fact (`wc -l`, `sort | uniq -c`, `comm`, `diff`) are legitimate bash, while commands that merely move, page, or trim bytes a dedicated tool can fetch remain banned — output trimming destroys data the `artifact://` capture would have saved.
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
|
|
17
|
+
- Fixed the model selector dropping an immediate Enter when cached models were available but the selector's offline refresh was still pending.
|
|
18
|
+
- Fixed dynamic `import(...)` inside functions passed to the browser tool's `tab.evaluate`/`page.evaluate` failing with `__omp_import__ is not defined`. The eval/browser JS runtime rewrites dynamic-import callees to the worker-injected `__omp_import__` helper, but puppeteer serializes evaluate callbacks with `Function.prototype.toString()` and re-runs them inside the page, where the helper does not exist. The rewriter now substitutes a guarded shim that falls back to native dynamic import when the helper is absent, so serialized code works in the page realm while in-worker imports keep resolving against the session cwd.
|
|
19
|
+
- Transcript block freezing is now unconditional instead of gated on ED3-risk terminal detection: every finalized block replays its frozen snapshot once it crosses out of the live region, on all terminals including Windows, because the rewritten renderer's committed scrollback is immutable everywhere. Still-mutating blocks (pending tools, streaming messages, async thinking renderers) anchor the live region and keep repainting until they finalize, which structurally fixes stale/duplicated output from late async expansions ([#1823](https://github.com/can1357/oh-my-pi/issues/1823)).
|
|
20
|
+
- Fixed the edit tool's post-edit diff preview occasionally echoing a context line twice with out-of-order numbering. Block-boundary context injection classified space-prefixed diff rows as old-file-only, so an unchanged line sitting in a net-offset region (old N / new N+k) was missing from the new file's visibility window; `findBlockContextLines` then re-surfaced it under its post-edit number and the row was spliced in after the adjacent change run. New-file boundary lines are now translated back to pre-edit numbers (the compact-preview renumbering contract) and merged into a single old-numbered insertion pass — also fixing closers below a net-offset edit being dropped or renumbered incorrectly.
|
|
21
|
+
- Fixed the Anthropic web-search provider claiming the Claude Code identity on API-key requests: the CC billing header + system instruction were injected whenever the model wasn't Haiku 3.5, regardless of auth mode. Injection is now OAuth-gated like the streaming path, and OAuth search requests patch the billing header's `cch` attestation (via `wrapFetchForCch`) instead of shipping the `cch=00000` placeholder.
|
|
22
|
+
- Fixed long streamed content appearing cut off mid-run: scrolled-off rows were erased from the viewport without ever being appended to terminal history. The transcript's commit boundary (`deriveLiveCommitState`) was all-or-nothing per block — one perpetually rewriting row (a task tool's ticking progress tree, per-agent cost/tool counters, spinner stats) suspended scrollback commits for the entire block, so once the block outgrew the viewport its static head (e.g. a task's prompt/context markdown) was neither committed nor on screen until the tool sealed, and was lost outright if the session ended mid-run. A stable-prefix ratchet now promotes leading rows that stayed visibly identical for a full 30-frame window as commit-safe, so the settled head reaches native scrollback while only the genuinely volatile tail stays deferred; a rewrite above the promoted run retreats the boundary and the engine audit recommits (duplication, never loss).
|
|
23
|
+
- Fixed local tiny-title worker stdout/stderr leaking raw native model output such as `</title>` and cache/status lines into the interactive TUI scrollback ([#2206](https://github.com/can1357/oh-my-pi/issues/2206)).
|
|
24
|
+
- Fixed task-agent discovery advertising Claude Code custom agents from `.claude/agents/*.md` as OMP subagents; direct task-agent discovery now only loads OMP-native `.omp` agent roots, while Claude marketplace plugin agents keep their existing provider path ([#2209](https://github.com/can1357/oh-my-pi/issues/2209)).
|
|
25
|
+
|
|
26
|
+
### Removed
|
|
27
|
+
|
|
28
|
+
- Removed the `clearOnShrink` setting and its `PI_CLEAR_ON_SHRINK` environment variable: the rewritten renderer always clears shrunken rows exactly, so the flicker/perf tradeoff the setting controlled no longer exists. Existing config entries are ignored.
|
|
29
|
+
- Removed the prompt-submit native-scrollback reconciliation checkpoint and the eager streaming render mode from the interactive controllers — the renderer's append-only contract made both obsolete.
|
|
30
|
+
|
|
31
|
+
## [15.10.9] - 2026-06-09
|
|
32
|
+
|
|
33
|
+
### Fixed
|
|
34
|
+
|
|
35
|
+
- Fixed streaming thinking (and other styled assistant content) vanishing from native scrollback once it scrolled past the viewport top during a foreground turn. The transcript's append-only commit detector compared raw row bytes, so a styled paragraph wrapping onto a new row (the span-closing SGR and width padding move while the visible cells stay identical) or a streamed token pushing the last word down a line flagged the block as permanently volatile — the commit boundary froze and every later row that crossed the viewport top was committed nowhere. Rows are now compared by visible content, a wrap-shrink of the in-flight bottom line counts as append-only, and a genuine one-off interior rewrite only suspends commits until the block re-earns append-only (30 clean frames), after which the pinned emitter backfills the stalled gap contiguously. Periodically rewriting blocks (spinners, collapsing tool previews) never re-earn and stay deferred.
|
|
36
|
+
|
|
37
|
+
- Fixed bracketed pastes containing multiple image file paths so each image is attached in order instead of treating the whole paste as one unreadable path.
|
|
38
|
+
|
|
39
|
+
- Fixed MCP OAuth fallback prompts so the "Click here to authorize" label emits an auth-safe terminal hyperlink even when hyperlink auto-detection is unavailable, keeping non-browser MCP setup usable ([#2196](https://github.com/can1357/oh-my-pi/issues/2196)).
|
|
40
|
+
- Fixed `task`-spawned subagents repeating filesystem scans the parent had already completed. `ExecutorOptions` and the `createAgentSession()` call inside `runSubprocess()` did not forward `rules`, the discovered extension paths, or the discovered `.omp/tools/` paths, so each subagent re-ran `loadCapability<Rule>()`, `discoverAndLoadExtensions()`, and the full `.omp/tools/` walk. The toolsession now caches `session.rules`, `session.extensionPaths`, and `session.customToolPaths`; `runSubprocess()` threads them through; and `createAgentSession()` accepts new `preloadedExtensionPaths` and `preloadedCustomToolPaths` options backed by new exported `discoverExtensionPaths()` and `discoverCustomToolPaths()` helpers. Crucially, only path lists are forwarded — never loaded instances. Each session rebuilds its own `Extension` and `LoadedCustomTool` objects so the per-session `ExtensionAPI`/`CustomToolAPI` (cwd, eventBus, runtime, exec, pushPendingAction, UI) targets the right session; forwarding loaded instances would have routed extension handlers and custom-tool execution back through the parent. The CLI's `preloadedExtensions` short-circuit is preserved for same-process reuse and now shallow-clones the caller's `extensions` array so inline-extension augmentation (autoresearch + custom-tools wrapper) cannot bleed back into it ([#2190](https://github.com/can1357/oh-my-pi/issues/2190)).
|
|
41
|
+
- Fixed SSH tool cancellation hanging behind OpenSSH ControlMaster streams that stayed open after an Esc/user interrupt ([#2180](https://github.com/can1357/oh-my-pi/issues/2180)).
|
|
42
|
+
- Fixed Windows stdio MCP servers launched through PATH shims such as `codegraph.cmd` so bare commands like `codegraph` resolve via `PATHEXT` before spawn ([#2174](https://github.com/can1357/oh-my-pi/issues/2174)).
|
|
43
|
+
- Fixed compiled-binary extensions failing to load `@oh-my-pi/pi-*` packages when `bun --compile` quietly dropped one of the extra entrypoints (observed on macOS arm64 release builds): the legacy-pi compat shim's package-root override branch returned the bunfs path without checking the target was present, so the rewrite emitted a `file://` URL to a missing module and the #1216 fallback (scoped to the throwing `getResolvedSpecifier` path) never ran. Override targets are now validated against the on-disk filesystem at module init, missing entries are dropped, and resolution falls through to canonical lookup so Bun resolves the import from the extension's own `node_modules` ([#2168](https://github.com/can1357/oh-my-pi/issues/2168)).
|
|
44
|
+
|
|
5
45
|
## [15.10.8] - 2026-06-09
|
|
6
46
|
|
|
7
47
|
### Added
|
|
@@ -9796,4 +9836,4 @@ Initial public release.
|
|
|
9796
9836
|
- Git branch display in footer
|
|
9797
9837
|
- Message queueing during streaming responses
|
|
9798
9838
|
- OAuth integration for Gmail and Google Calendar access
|
|
9799
|
-
- HTML export with syntax highlighting and collapsible sections
|
|
9839
|
+
- HTML export with syntax highlighting and collapsible sections
|
|
@@ -262,6 +262,11 @@ export interface CanonicalModelQueryOptions {
|
|
|
262
262
|
availableOnly?: boolean;
|
|
263
263
|
candidates?: readonly Model<Api>[];
|
|
264
264
|
}
|
|
265
|
+
/** A canonical record (with query-filtered variants) plus the variant model selected for it. */
|
|
266
|
+
export interface CanonicalModelSelection {
|
|
267
|
+
record: CanonicalModelRecord;
|
|
268
|
+
model: Model<Api>;
|
|
269
|
+
}
|
|
265
270
|
/**
|
|
266
271
|
* Model registry - loads and manages models, resolves API keys via AuthStorage.
|
|
267
272
|
*/
|
|
@@ -306,6 +311,14 @@ export declare class ModelRegistry {
|
|
|
306
311
|
*/
|
|
307
312
|
getAll(): Model<Api>[];
|
|
308
313
|
getCanonicalModels(options?: CanonicalModelQueryOptions): CanonicalModelRecord[];
|
|
314
|
+
/**
|
|
315
|
+
* One-pass equivalent of `getCanonicalModels` + `resolveCanonicalModel` per
|
|
316
|
+
* record. The per-query state (candidate-selector set, availability memo,
|
|
317
|
+
* provider rank, candidate order) is built once, so the whole catalog
|
|
318
|
+
* resolves in O(records + candidates) instead of O(records × candidates).
|
|
319
|
+
* This is the path the model selector hydrates from synchronously on open.
|
|
320
|
+
*/
|
|
321
|
+
getCanonicalModelSelections(options?: CanonicalModelQueryOptions): CanonicalModelSelection[];
|
|
309
322
|
getCanonicalVariants(canonicalId: string, options?: CanonicalModelQueryOptions): CanonicalModelVariant[];
|
|
310
323
|
resolveCanonicalModel(canonicalId: string, options?: CanonicalModelQueryOptions): Model<Api> | undefined;
|
|
311
324
|
getCanonicalId(model: Model<Api>): string | undefined;
|
|
@@ -716,15 +716,6 @@ export declare const SETTINGS_SCHEMA: {
|
|
|
716
716
|
readonly description: "Show terminal cursor for IME support";
|
|
717
717
|
};
|
|
718
718
|
};
|
|
719
|
-
readonly clearOnShrink: {
|
|
720
|
-
readonly type: "boolean";
|
|
721
|
-
readonly default: false;
|
|
722
|
-
readonly ui: {
|
|
723
|
-
readonly tab: "appearance";
|
|
724
|
-
readonly label: "Clear on Shrink";
|
|
725
|
-
readonly description: "Clear empty rows when content shrinks (may cause flicker)";
|
|
726
|
-
};
|
|
727
|
-
};
|
|
728
719
|
readonly defaultThinkingLevel: {
|
|
729
720
|
readonly type: "enum";
|
|
730
721
|
readonly values: readonly [...import("@oh-my-pi/pi-ai").Effort[], "auto"];
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import type { AgentToolResult } from "@oh-my-pi/pi-agent-core";
|
|
2
2
|
import type { HookUIContext } from "../../extensibility/hooks/types";
|
|
3
3
|
import type { LoadedCustomTool, ToolLoadError } from "./types";
|
|
4
|
-
/** Tool path with optional source metadata
|
|
5
|
-
|
|
4
|
+
/** Tool path with optional source metadata, suitable for forwarding from a
|
|
5
|
+
* parent session to a subagent so the subagent can re-bind tools to its own
|
|
6
|
+
* `CustomToolAPI` without redoing the filesystem scan. */
|
|
7
|
+
export interface ToolPathWithSource {
|
|
6
8
|
path: string;
|
|
7
9
|
source?: {
|
|
8
10
|
provider: string;
|
|
@@ -46,12 +48,30 @@ export declare function loadCustomTools(pathsWithSources: ToolPathWithSource[],
|
|
|
46
48
|
errors: ToolLoadError[];
|
|
47
49
|
setUIContext: (uiContext: HookUIContext, hasUI: boolean) => void;
|
|
48
50
|
}>;
|
|
51
|
+
/**
|
|
52
|
+
* Collect the absolute tool-source paths to load, without importing or
|
|
53
|
+
* binding factories. Hot path on session startup — the scan walks
|
|
54
|
+
* `.omp/tools/`, `.claude/tools/`, the plugin tree, and any configured paths.
|
|
55
|
+
*
|
|
56
|
+
* Subagents reuse the parent's collected paths via the SDK's
|
|
57
|
+
* `preloadedCustomToolPaths` option, then call `loadCustomTools` themselves
|
|
58
|
+
* so each session re-binds factories with its own session-scoped
|
|
59
|
+
* `CustomToolAPI` (cwd, exec, pushPendingAction, UI).
|
|
60
|
+
*
|
|
61
|
+
* @param configuredPaths - Explicit paths from settings.json and CLI --tool flags
|
|
62
|
+
* @param cwd - Current working directory
|
|
63
|
+
*/
|
|
64
|
+
export declare function discoverCustomToolPaths(configuredPaths: string[], cwd: string): Promise<ToolPathWithSource[]>;
|
|
49
65
|
/**
|
|
50
66
|
* Discover and load tools from standard locations via capability system:
|
|
51
67
|
* 1. User and project tools discovered by capability providers
|
|
52
68
|
* 2. Installed plugins (~/.omp/plugins/node_modules/*)
|
|
53
69
|
* 3. Explicitly configured paths from settings or CLI
|
|
54
70
|
*
|
|
71
|
+
* Composed of {@link discoverCustomToolPaths} (FS scan) + {@link loadCustomTools}
|
|
72
|
+
* (per-session binding). Subagents skip the first step and just call
|
|
73
|
+
* `loadCustomTools` against the parent's collected paths.
|
|
74
|
+
*
|
|
55
75
|
* @param configuredPaths - Explicit paths from settings.json and CLI --tool flags
|
|
56
76
|
* @param cwd - Current working directory
|
|
57
77
|
* @param builtInToolNames - Names of built-in tools to check for conflicts
|
|
@@ -66,4 +86,3 @@ export declare function discoverAndLoadCustomTools(configuredPaths: string[], cw
|
|
|
66
86
|
errors: ToolLoadError[];
|
|
67
87
|
setUIContext: (uiContext: HookUIContext, hasUI: boolean) => void;
|
|
68
88
|
}>;
|
|
69
|
-
export {};
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Extension system for lifecycle events and custom tools.
|
|
3
3
|
*/
|
|
4
4
|
export type { SlashCommandInfo, SlashCommandLocation, SlashCommandSource } from "../slash-commands";
|
|
5
|
-
export { discoverAndLoadExtensions, ExtensionRuntimeNotInitializedError, loadExtensionFromFactory, loadExtensions, } from "./loader";
|
|
5
|
+
export { discoverAndLoadExtensions, discoverExtensionPaths, ExtensionRuntimeNotInitializedError, loadExtensionFromFactory, loadExtensions, } from "./loader";
|
|
6
6
|
export * from "./runner";
|
|
7
7
|
export * from "./types";
|
|
8
8
|
export * from "./wrapper";
|
|
@@ -38,6 +38,22 @@ export declare function loadExtensionFromFactory(factory: ExtensionFactory, cwd:
|
|
|
38
38
|
*/
|
|
39
39
|
export declare function loadExtensions(paths: string[], cwd: string, eventBus?: EventBus): Promise<LoadExtensionsResult>;
|
|
40
40
|
/**
|
|
41
|
-
* Discover
|
|
41
|
+
* Discover absolute paths of extensions to load, without importing or
|
|
42
|
+
* binding factories. Hot path on session startup — the scan walks native
|
|
43
|
+
* `.omp`/`.pi` extension capabilities, the installed-plugin tree, and any
|
|
44
|
+
* configured paths.
|
|
45
|
+
*
|
|
46
|
+
* Subagents reuse the parent's collected paths via the SDK's
|
|
47
|
+
* `preloadedExtensionPaths` option, then call {@link loadExtensions} themselves
|
|
48
|
+
* so each session rebuilds Extension instances bound to its OWN
|
|
49
|
+
* `ExtensionAPI` (cwd, eventBus, runtime). Forwarding the parent's
|
|
50
|
+
* `LoadExtensionsResult` directly would reuse handlers/tools/commands that
|
|
51
|
+
* closed over the parent's `cwd` and event bus.
|
|
52
|
+
*/
|
|
53
|
+
export declare function discoverExtensionPaths(configuredPaths: string[], cwd: string, disabledExtensionIds?: string[]): Promise<string[]>;
|
|
54
|
+
/**
|
|
55
|
+
* Discover and load extensions from standard locations. Composed of
|
|
56
|
+
* {@link discoverExtensionPaths} (FS scan) + {@link loadExtensions}
|
|
57
|
+
* (per-session binding).
|
|
42
58
|
*/
|
|
43
59
|
export declare function discoverAndLoadExtensions(configuredPaths: string[], cwd: string, eventBus?: EventBus, disabledExtensionIds?: string[]): Promise<LoadExtensionsResult>;
|
|
@@ -13,6 +13,14 @@ import * as path from "node:path";
|
|
|
13
13
|
* Exported for tests; production callers use `BUNFS_PACKAGE_ROOT` below.
|
|
14
14
|
*/
|
|
15
15
|
export declare function __computeBunfsPackageRoot(metaDir: string, pathImpl?: typeof path): string;
|
|
16
|
+
/**
|
|
17
|
+
* Drop overrides whose targets are missing on disk so they can fall through to
|
|
18
|
+
* the canonical-resolution path. Exported for the test seam in #2168.
|
|
19
|
+
*
|
|
20
|
+
* `pathExistsSync` defaults to `fs.existsSync`; the tests inject a stub to
|
|
21
|
+
* simulate the missing-entrypoint failure mode without touching the real FS.
|
|
22
|
+
*/
|
|
23
|
+
export declare function __validateLegacyPiPackageRootOverrides(candidates: Record<string, string>, pathExistsSync?: (p: string) => boolean): Record<string, string>;
|
|
16
24
|
/**
|
|
17
25
|
* Load a legacy Pi extension module from its real on-disk location.
|
|
18
26
|
*
|
|
@@ -5,6 +5,18 @@
|
|
|
5
5
|
* Messages are newline-delimited JSON.
|
|
6
6
|
*/
|
|
7
7
|
import type { MCPRequestOptions, MCPStdioServerConfig, MCPTransport } from "../../mcp/types";
|
|
8
|
+
/** Subprocess argv for launching an MCP stdio server. */
|
|
9
|
+
export interface StdioSpawnCommand {
|
|
10
|
+
cmd: string[];
|
|
11
|
+
}
|
|
12
|
+
/** Inputs used to resolve platform-specific stdio spawn behavior. */
|
|
13
|
+
export interface ResolveStdioSpawnOptions {
|
|
14
|
+
cwd: string;
|
|
15
|
+
env: Record<string, string | undefined>;
|
|
16
|
+
platform?: NodeJS.Platform;
|
|
17
|
+
}
|
|
18
|
+
/** Resolve the subprocess argv used to launch an MCP stdio server. */
|
|
19
|
+
export declare function resolveStdioSpawnCommand(config: MCPStdioServerConfig, options: ResolveStdioSpawnOptions): Promise<StdioSpawnCommand>;
|
|
8
20
|
/** Minimal write surface of `Subprocess.stdin` we need for framed sends. */
|
|
9
21
|
interface FrameSink {
|
|
10
22
|
write(chunk: string): unknown;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Editor, type KeyId } from "@oh-my-pi/pi-tui";
|
|
2
2
|
import type { AppKeybinding } from "../../config/keybindings";
|
|
3
3
|
type ConfigurableEditorAction = Extract<AppKeybinding, "app.interrupt" | "app.clear" | "app.exit" | "app.suspend" | "app.display.reset" | "app.thinking.cycle" | "app.model.cycleForward" | "app.model.cycleBackward" | "app.model.select" | "app.model.selectTemporary" | "app.tools.expand" | "app.thinking.toggle" | "app.editor.external" | "app.history.search" | "app.message.dequeue" | "app.clipboard.pasteImage" | "app.clipboard.pasteTextRaw" | "app.clipboard.copyPrompt">;
|
|
4
|
+
export declare function extractBracketedImagePastePaths(data: string): string[] | undefined;
|
|
4
5
|
export declare function extractBracketedImagePastePath(data: string): string | undefined;
|
|
5
6
|
/**
|
|
6
7
|
* Custom editor that handles configurable app-level shortcuts for coding-agent.
|
|
@@ -33,8 +34,8 @@ export declare class CustomEditor extends Editor {
|
|
|
33
34
|
onCopyPrompt?: () => void;
|
|
34
35
|
/** Called when the configured image-paste shortcut is pressed. */
|
|
35
36
|
onPasteImage?: () => Promise<boolean>;
|
|
36
|
-
/** Called when a bracketed paste contains
|
|
37
|
-
onPasteImagePath?: (path: string) => void
|
|
37
|
+
/** Called when a bracketed paste contains one or more image-file paths. */
|
|
38
|
+
onPasteImagePath?: (path: string) => void | Promise<void>;
|
|
38
39
|
/** Called when the configured raw text-paste shortcut is pressed. */
|
|
39
40
|
onPasteTextRaw?: () => void;
|
|
40
41
|
/** Called when the configured dequeue shortcut is pressed. */
|
|
@@ -1,25 +1,18 @@
|
|
|
1
1
|
import { Container, type NativeScrollbackLiveRegion } from "@oh-my-pi/pi-tui";
|
|
2
2
|
/**
|
|
3
|
-
* Transcript container that
|
|
4
|
-
* the
|
|
5
|
-
*
|
|
3
|
+
* Transcript container that always renders every block's current content and
|
|
4
|
+
* reports the live-region seam (`NativeScrollbackLiveRegion`) that gates the
|
|
5
|
+
* engine's append-only scrollback commits.
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
* the
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* This container provides that guarantee: a block's render is snapshotted while
|
|
17
|
-
* it is the live (bottom-most) block, and once a newer block is appended it
|
|
18
|
-
* replays the snapshot instead of recomputing. Mutations after a block leaves
|
|
19
|
-
* live are intentionally deferred until the next checkpoint {@link thaw} (prompt
|
|
20
|
-
* submit → native-scrollback rebuild), where the whole transcript is replayed
|
|
21
|
-
* and any drift reconciles safely. On terminals that can rebuild history this
|
|
22
|
-
* freezing is unnecessary, so it renders every block live for full fidelity.
|
|
7
|
+
* The engine never rewrites committed history: rows above the seam that have
|
|
8
|
+
* entered the tape keep whatever bytes they were committed with ("let the
|
|
9
|
+
* history be"), while the visible window always repaints from each block's
|
|
10
|
+
* latest render — a late tool result, a post-finalize error pin, or an expand
|
|
11
|
+
* toggle is always reflected on screen. Blocks that are still mutating (an
|
|
12
|
+
* unfinalized tool, a streaming assistant message) stay below the seam so
|
|
13
|
+
* their rows do not enter history while they can still change; a streaming
|
|
14
|
+
* block whose render grows append-only deepens the seam through its settled
|
|
15
|
+
* head so a long reply's scrolled-off rows still reach scrollback mid-stream.
|
|
23
16
|
*/
|
|
24
17
|
export declare class TranscriptContainer extends Container implements NativeScrollbackLiveRegion {
|
|
25
18
|
#private;
|
|
@@ -27,13 +20,6 @@ export declare class TranscriptContainer extends Container implements NativeScro
|
|
|
27
20
|
clear(): void;
|
|
28
21
|
getNativeScrollbackLiveRegionStart(): number | undefined;
|
|
29
22
|
getNativeScrollbackCommitSafeEnd(): number | undefined;
|
|
30
|
-
/**
|
|
31
|
-
* Retire all frozen snapshots so the next render reflects each block's current
|
|
32
|
-
* state. Call at reconciliation checkpoints (prompt submit) where the whole
|
|
33
|
-
* transcript is replayed into native scrollback and any drift a frozen block
|
|
34
|
-
* accumulated is reconciled.
|
|
35
|
-
*/
|
|
36
|
-
thaw(): void;
|
|
37
23
|
render(width: number): string[];
|
|
38
24
|
}
|
|
39
25
|
/**
|
package/dist/types/sdk.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ import { type PromptTemplate } from "./config/prompt-templates";
|
|
|
6
6
|
import { Settings, type SkillsSettings } from "./config/settings";
|
|
7
7
|
import "./discovery";
|
|
8
8
|
import { type CustomCommandsLoadResult } from "./extensibility/custom-commands";
|
|
9
|
+
import { type ToolPathWithSource } from "./extensibility/custom-tools";
|
|
9
10
|
import type { CustomTool } from "./extensibility/custom-tools/types";
|
|
10
11
|
import { type ExtensionFactory, type ExtensionUIContext, type LoadExtensionsResult, type ToolDefinition } from "./extensibility/extensions";
|
|
11
12
|
import { type Skill, type SkillWarning } from "./extensibility/skills";
|
|
@@ -62,10 +63,41 @@ export interface CreateAgentSessionOptions {
|
|
|
62
63
|
/** Disable extension discovery (explicit paths still load). */
|
|
63
64
|
disableExtensionDiscovery?: boolean;
|
|
64
65
|
/**
|
|
65
|
-
* Pre-loaded extensions (skips file discovery
|
|
66
|
-
*
|
|
66
|
+
* Pre-loaded extensions (skips file discovery and the per-session factory
|
|
67
|
+
* call). Used by the CLI when extensions are loaded early to parse custom
|
|
68
|
+
* flags — the same process owns the returned instances, so reusing them is
|
|
69
|
+
* safe.
|
|
70
|
+
*
|
|
71
|
+
* NEVER pass this across session boundaries (e.g. parent → subagent).
|
|
72
|
+
* `Extension` instances close over a parent-bound `ExtensionAPI` (cwd,
|
|
73
|
+
* eventBus, runtime), and reusing them would route tools/handlers/commands
|
|
74
|
+
* back through the parent. For subagents, forward
|
|
75
|
+
* {@link preloadedExtensionPaths} instead.
|
|
76
|
+
*
|
|
77
|
+
* @internal
|
|
67
78
|
*/
|
|
68
79
|
preloadedExtensions?: LoadExtensionsResult;
|
|
80
|
+
/**
|
|
81
|
+
* Pre-discovered extension source paths. When provided, the filesystem-scan
|
|
82
|
+
* inside `discoverExtensionPaths()` is skipped — the session still calls
|
|
83
|
+
* `loadExtensions()` itself so each `Extension` is bound to THIS session's
|
|
84
|
+
* `ExtensionAPI` (cwd, eventBus, runtime).
|
|
85
|
+
*
|
|
86
|
+
* This is the safe pass-through for parent → subagent forwarding.
|
|
87
|
+
*/
|
|
88
|
+
preloadedExtensionPaths?: string[];
|
|
89
|
+
/**
|
|
90
|
+
* Pre-discovered custom-tool source paths from `.omp/tools/`, `.claude/tools/`,
|
|
91
|
+
* plugins, etc. When provided, the filesystem-scan inside
|
|
92
|
+
* `discoverCustomToolPaths()` is skipped — subagents inherit the parent's
|
|
93
|
+
* scan result and call `loadCustomTools()` themselves so each session binds
|
|
94
|
+
* tools to its OWN `CustomToolAPI` (cwd, exec, pushPendingAction, UI).
|
|
95
|
+
*
|
|
96
|
+
* Forwarding the loaded `LoadedCustomTool[]` instances directly would reuse
|
|
97
|
+
* the parent's session-bound API and route tool execution back through the
|
|
98
|
+
* parent — wrong for isolated tasks and for pending-action routing.
|
|
99
|
+
*/
|
|
100
|
+
preloadedCustomToolPaths?: ToolPathWithSource[];
|
|
69
101
|
/** Shared event bus for tool/extension communication. Default: creates new bus. */
|
|
70
102
|
eventBus?: EventBus;
|
|
71
103
|
/** Skills. Default: discovered from multiple locations */
|
|
@@ -178,6 +210,14 @@ export declare function discoverAuthStorage(agentDir?: string): Promise<AuthStor
|
|
|
178
210
|
* Discover extensions from cwd.
|
|
179
211
|
*/
|
|
180
212
|
export declare function discoverExtensions(cwd?: string): Promise<LoadExtensionsResult>;
|
|
213
|
+
/**
|
|
214
|
+
* Path-only counterpart of {@link loadSessionExtensions}: the FS-heavy scan
|
|
215
|
+
* without the per-session module load. Subagents reuse the parent's path list
|
|
216
|
+
* (cached on {@link ToolSession.extensionPaths}) and rebuild Extension
|
|
217
|
+
* instances themselves so each session's `ExtensionAPI` (cwd, eventBus,
|
|
218
|
+
* runtime) is its own.
|
|
219
|
+
*/
|
|
220
|
+
export declare function discoverSessionExtensionPaths(options: Pick<CreateAgentSessionOptions, "disableExtensionDiscovery" | "additionalExtensionPaths">, cwd: string, settings: Settings): Promise<string[]>;
|
|
181
221
|
/**
|
|
182
222
|
* Load the discovered/configured extensions for a session — everything {@link
|
|
183
223
|
* createAgentSession} would load except the inline factory extensions it appends
|
|
@@ -7,8 +7,7 @@ export interface DiscoveryResult {
|
|
|
7
7
|
/**
|
|
8
8
|
* Discover agents from filesystem and merge with bundled agents.
|
|
9
9
|
*
|
|
10
|
-
* Precedence (highest wins): .omp
|
|
11
|
-
*
|
|
10
|
+
* Precedence (highest wins): project .omp, user .omp, Claude plugin agents, then bundled
|
|
12
11
|
* @param cwd - Current working directory for project agent discovery
|
|
13
12
|
*/
|
|
14
13
|
export declare function discoverAgents(cwd: string, home?: string): Promise<DiscoveryResult>;
|
|
@@ -4,10 +4,12 @@
|
|
|
4
4
|
* Runs each subagent on the main thread and forwards AgentEvents for progress tracking.
|
|
5
5
|
*/
|
|
6
6
|
import type { AgentTelemetryConfig, ThinkingLevel } from "@oh-my-pi/pi-agent-core";
|
|
7
|
+
import type { Rule } from "../capability/rule";
|
|
7
8
|
import { ModelRegistry } from "../config/model-registry";
|
|
8
9
|
import type { PromptTemplate } from "../config/prompt-templates";
|
|
9
10
|
import { Settings } from "../config/settings";
|
|
10
11
|
import { type SettingPath } from "../config/settings-schema";
|
|
12
|
+
import type { ToolPathWithSource } from "../extensibility/custom-tools";
|
|
11
13
|
import type { CustomTool } from "../extensibility/custom-tools/types";
|
|
12
14
|
import { type Skill } from "../extensibility/skills";
|
|
13
15
|
import type { HindsightSessionState } from "../hindsight/state";
|
|
@@ -70,6 +72,20 @@ export interface ExecutorOptions {
|
|
|
70
72
|
skills?: Skill[];
|
|
71
73
|
promptTemplates?: PromptTemplate[];
|
|
72
74
|
workspaceTree?: WorkspaceTree;
|
|
75
|
+
/** Parent-discovered rules, forwarded to skip rule discovery in the subagent. */
|
|
76
|
+
rules?: Rule[];
|
|
77
|
+
/**
|
|
78
|
+
* Parent's discovered extension source paths. Forwarded to skip the
|
|
79
|
+
* extension FS scan in the subagent; the subagent then re-binds each
|
|
80
|
+
* extension against its own `ExtensionAPI` (cwd, eventBus, runtime).
|
|
81
|
+
*/
|
|
82
|
+
preloadedExtensionPaths?: string[];
|
|
83
|
+
/**
|
|
84
|
+
* Parent's discovered custom-tool source paths. Forwarded to skip the
|
|
85
|
+
* `.omp/tools/` FS scan in the subagent; the subagent then re-binds each
|
|
86
|
+
* tool against its own `CustomToolAPI` (cwd, exec, pushPendingAction, UI).
|
|
87
|
+
*/
|
|
88
|
+
preloadedCustomToolPaths?: ToolPathWithSource[];
|
|
73
89
|
mcpManager?: MCPManager;
|
|
74
90
|
authStorage?: AuthStorage;
|
|
75
91
|
modelRegistry?: ModelRegistry;
|
|
@@ -32,7 +32,7 @@ export declare const TINY_WORKER_ARG = "--tiny-worker";
|
|
|
32
32
|
*/
|
|
33
33
|
export declare function tinyWorkerEnvOverlay(env: Record<string, string | undefined>, deviceSetting: string | undefined, dtypeSetting: string | undefined): Record<string, string>;
|
|
34
34
|
interface SpawnedSubprocess {
|
|
35
|
-
proc: Subprocess<"ignore", "
|
|
35
|
+
proc: Subprocess<"ignore", "ignore", "ignore">;
|
|
36
36
|
inbound: Set<(message: TinyTitleWorkerOutbound) => void>;
|
|
37
37
|
errors: Set<(error: Error) => void>;
|
|
38
38
|
/**
|
|
@@ -2,8 +2,10 @@ import type { InMemorySnapshotStore } from "@oh-my-pi/hashline";
|
|
|
2
2
|
import type { AgentTelemetryConfig, AgentTool } from "@oh-my-pi/pi-agent-core";
|
|
3
3
|
import type { FetchImpl, ToolChoice } from "@oh-my-pi/pi-ai";
|
|
4
4
|
import type { AsyncJobManager } from "../async/job-manager";
|
|
5
|
+
import type { Rule } from "../capability/rule";
|
|
5
6
|
import type { PromptTemplate } from "../config/prompt-templates";
|
|
6
7
|
import type { Settings } from "../config/settings";
|
|
8
|
+
import type { ToolPathWithSource } from "../extensibility/custom-tools";
|
|
7
9
|
import type { Skill } from "../extensibility/skills";
|
|
8
10
|
import type { GoalModeState, GoalRuntime } from "../goals";
|
|
9
11
|
import type { HindsightSessionState } from "../hindsight/state";
|
|
@@ -107,6 +109,21 @@ export interface ToolSession {
|
|
|
107
109
|
skills?: Skill[];
|
|
108
110
|
/** Pre-loaded prompt templates */
|
|
109
111
|
promptTemplates?: PromptTemplate[];
|
|
112
|
+
/** Pre-loaded rules (forwarded to subagents to skip re-discovery). */
|
|
113
|
+
rules?: Rule[];
|
|
114
|
+
/**
|
|
115
|
+
* Pre-discovered extension source paths. Forwarded to subagents so they
|
|
116
|
+
* skip the FS scan but still re-bind extensions to their own session-scoped
|
|
117
|
+
* `ExtensionAPI` (cwd, eventBus, runtime). Inline extension factories
|
|
118
|
+
* (`<inline-N>`) are NOT included — those are session-local.
|
|
119
|
+
*/
|
|
120
|
+
extensionPaths?: string[];
|
|
121
|
+
/**
|
|
122
|
+
* Pre-discovered custom-tool source paths from `.omp/tools/`, `.claude/tools/`,
|
|
123
|
+
* plugins, etc. Forwarded to subagents so they skip the FS scan but still
|
|
124
|
+
* re-bind tools to their own session-scoped `CustomToolAPI`.
|
|
125
|
+
*/
|
|
126
|
+
customToolPaths?: ToolPathWithSource[];
|
|
110
127
|
/** Whether LSP integrations are enabled */
|
|
111
128
|
enableLsp?: boolean;
|
|
112
129
|
/** Whether an edit-capable tool is available in this session (controls hashline output) */
|
|
@@ -40,6 +40,7 @@ declare const todoSchema: z.ZodObject<{
|
|
|
40
40
|
note: "note";
|
|
41
41
|
rm: "rm";
|
|
42
42
|
start: "start";
|
|
43
|
+
view: "view";
|
|
43
44
|
}>;
|
|
44
45
|
list: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
45
46
|
phase: z.ZodString;
|
|
@@ -113,6 +114,7 @@ export declare class TodoTool implements AgentTool<typeof todoSchema, TodoToolDe
|
|
|
113
114
|
note: "note";
|
|
114
115
|
rm: "rm";
|
|
115
116
|
start: "start";
|
|
117
|
+
view: "view";
|
|
116
118
|
}>;
|
|
117
119
|
list: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
118
120
|
phase: z.ZodString;
|
|
@@ -19,6 +19,14 @@ export declare function uriHyperlink(uri: string, displayText: string): string;
|
|
|
19
19
|
* `www.example.com` inputs are linked as `https://www.example.com`.
|
|
20
20
|
*/
|
|
21
21
|
export declare function urlHyperlink(url: string, displayText: string): string;
|
|
22
|
+
/**
|
|
23
|
+
* Wrap `displayText` in an OSC 8 hyperlink pointing at an HTTP(S) URL,
|
|
24
|
+
* bypassing terminal capability auto-detection. Used for auth prompts where
|
|
25
|
+
* an inert "click" label blocks login on terminals whose capabilities are
|
|
26
|
+
* not advertised. Still returns plain text when the user has explicitly
|
|
27
|
+
* opted out via `tui.hyperlinks=off`.
|
|
28
|
+
*/
|
|
29
|
+
export declare function urlHyperlinkAlways(url: string, displayText: string): string;
|
|
22
30
|
/**
|
|
23
31
|
* Wrap `displayText` in an OSC 8 hyperlink pointing at a filesystem path.
|
|
24
32
|
*
|
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.
|
|
4
|
+
"version": "15.10.10",
|
|
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.
|
|
51
|
-
"@oh-my-pi/omp-stats": "15.10.
|
|
52
|
-
"@oh-my-pi/pi-agent-core": "15.10.
|
|
53
|
-
"@oh-my-pi/pi-ai": "15.10.
|
|
54
|
-
"@oh-my-pi/pi-mnemopi": "15.10.
|
|
55
|
-
"@oh-my-pi/pi-natives": "15.10.
|
|
56
|
-
"@oh-my-pi/pi-tui": "15.10.
|
|
57
|
-
"@oh-my-pi/pi-utils": "15.10.
|
|
50
|
+
"@oh-my-pi/hashline": "15.10.10",
|
|
51
|
+
"@oh-my-pi/omp-stats": "15.10.10",
|
|
52
|
+
"@oh-my-pi/pi-agent-core": "15.10.10",
|
|
53
|
+
"@oh-my-pi/pi-ai": "15.10.10",
|
|
54
|
+
"@oh-my-pi/pi-mnemopi": "15.10.10",
|
|
55
|
+
"@oh-my-pi/pi-natives": "15.10.10",
|
|
56
|
+
"@oh-my-pi/pi-tui": "15.10.10",
|
|
57
|
+
"@oh-my-pi/pi-utils": "15.10.10",
|
|
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",
|
package/src/cli/list-models.ts
CHANGED
|
@@ -64,22 +64,16 @@ export async function listModels(modelRegistry: ModelRegistry, searchPattern?: s
|
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
const filteredCanonical = modelRegistry
|
|
67
|
-
.
|
|
68
|
-
.map(
|
|
69
|
-
|
|
70
|
-
availableOnly: true,
|
|
71
|
-
candidates: filteredModels,
|
|
72
|
-
});
|
|
73
|
-
if (!selected) return undefined;
|
|
74
|
-
return {
|
|
67
|
+
.getCanonicalModelSelections({ availableOnly: true, candidates: filteredModels })
|
|
68
|
+
.map(
|
|
69
|
+
({ record, model: selected }): CanonicalRow => ({
|
|
75
70
|
canonical: record.id,
|
|
76
71
|
selected: `${selected.provider}/${selected.id}`,
|
|
77
72
|
variants: String(record.variants.length),
|
|
78
73
|
context: formatNumber(selected.contextWindow),
|
|
79
74
|
maxOut: formatNumber(selected.maxTokens),
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
.filter((row): row is CanonicalRow => row !== undefined)
|
|
75
|
+
}),
|
|
76
|
+
)
|
|
83
77
|
.sort((left, right) => left.canonical.localeCompare(right.canonical));
|
|
84
78
|
|
|
85
79
|
if (filteredModels.length === 0 && filteredCanonical.length === 0) {
|