diff --git a/packages/coding-agent/CHANGELOG.md b/packages/coding-agent/CHANGELOG.md index 72dd04126..436e88777 100644 --- a/packages/coding-agent/CHANGELOG.md +++ b/packages/coding-agent/CHANGELOG.md @@ -112,6 +112,7 @@ - Fixed the `/ssh add` inline hint omitting the `--scope project|user` option. - Fixed `omp://` throwing `ENOENT` for npm/SDK consumers: `@oh-my-pi/pi-coding-agent`'s `exports` resolve to TypeScript source where the build-time `PI_DOCS_EMBED` is empty, and the dev-tree fallback pointed at an unreachable `node_modules/docs`, so `OmpProtocolHandler.complete()`/`.resolve()` crashed for any consumer importing the package from npm. `gen:bundle` now also ships the docs corpus as `dist/docs-index.generated.txt`, the source path reads it when the env embed is empty and the on-disk `docs/` is absent, and a missing corpus degrades to an empty index (with a warning) instead of propagating `ENOENT` ([#8134](https://github.com/can1357/oh-my-pi/issues/8134)). - Fixed the legacy TypeBox facade rejecting `Type.Optional(Type.Unsafe(...))`, losing optional object properties when raw schemas were present, dropping JSON-Schema-only keywords (e.g. `patternProperties`) from nested `Type.Unsafe` wire schemas, and plugin installs accepting extension factories that fail during initialization ([#8143](https://github.com/can1357/oh-my-pi/issues/8143)). +- Fixed `omp install` failing extension validation for pi extensions that import the `isToolResult` event guards from `@earendil-works/pi-coding-agent` (e.g. `pi-lean-ctx@3.9.18`, which uses `isEditToolResult`/`isWriteToolResult`). The legacy shim's `export * from "../index"` never forwarded the guard family (dropped from the public API in 10.2.3), so a named import threw Bun's static "Export named 'isEditToolResult' not found" error. Restored `isBashToolResult`, `isReadToolResult`, `isEditToolResult`, `isWriteToolResult`, `isGrepToolResult`, `isFindToolResult`, and `isLsToolResult` on the shim to match the upstream pi surface ([#8161](https://github.com/can1357/oh-my-pi/issues/8161)). ## [17.2.12] - 2026-08-08 diff --git a/packages/coding-agent/src/extensibility/legacy-pi-coding-agent-shim.ts b/packages/coding-agent/src/extensibility/legacy-pi-coding-agent-shim.ts index 30f483184..3df2e2730 100644 --- a/packages/coding-agent/src/extensibility/legacy-pi-coding-agent-shim.ts +++ b/packages/coding-agent/src/extensibility/legacy-pi-coding-agent-shim.ts @@ -57,7 +57,16 @@ import { EventBus } from "../utils/event-bus"; import { convertImageToPng } from "../utils/image-loading"; import { discoverExtensionPaths, loadExtensionFromFactory, loadExtensions } from "./extensions"; import { ExtensionRuntime } from "./extensions/loader"; -import type { ExtensionFactory, ToolDefinition } from "./extensions/types"; +import type { + BashToolResultEvent, + EditToolResultEvent, + ExtensionFactory, + GrepToolResultEvent, + ReadToolResultEvent, + ToolDefinition, + ToolResultEvent, + WriteToolResultEvent, +} from "./extensions/types"; import { Type } from "./legacy-typebox"; import { getEnabledPlugins, resolvePluginExtensionPaths, type ScopedInstalledPlugin } from "./plugins/loader"; import type { Skill } from "./skills"; @@ -1458,3 +1467,54 @@ export * from "../index"; export { formatBytes as formatSize } from "../tools/render-utils"; export { copyToClipboard } from "../utils/clipboard"; export { Type } from "./legacy-typebox"; + +// Legacy pi's `@earendil-works/pi-coding-agent` root exported an `isToolResult` +// family of type guards that narrow a `tool_result` event (`ToolResultEvent`) by +// tool name. omp removed them from the public API in 10.2.3, and the barrel above +// does not forward them, so legacy extensions importing them (e.g. +// `pi-lean-ctx@3.9.18`, which uses `isEditToolResult`/`isWriteToolResult` to +// invalidate its read cache after a native edit/write) fail Bun's static export +// check during validation (issue #8161). Restore the full guard family; legacy +// `find`/`ls` tool results arrive through omp's custom-event branch, so those +// guards narrow the tool name while leaving their details unknown. + +/** Narrow a `tool_result` event to the `bash` tool. */ +export function isBashToolResult(e: ToolResultEvent): e is BashToolResultEvent { + return e.toolName === "bash"; +} + +/** Narrow a `tool_result` event to the `read` tool. */ +export function isReadToolResult(e: ToolResultEvent): e is ReadToolResultEvent { + return e.toolName === "read"; +} + +/** Narrow a `tool_result` event to the `edit` tool. */ +export function isEditToolResult(e: ToolResultEvent): e is EditToolResultEvent { + return e.toolName === "edit"; +} + +/** Narrow a `tool_result` event to the `write` tool. */ +export function isWriteToolResult(e: ToolResultEvent): e is WriteToolResultEvent { + return e.toolName === "write"; +} + +/** Narrow a `tool_result` event to the `grep` tool. */ +export function isGrepToolResult(e: ToolResultEvent): e is GrepToolResultEvent { + return e.toolName === "grep"; +} + +/** Legacy `find` result event represented by omp's custom-event branch. */ +export type FindToolResultEvent = ToolResultEvent & { toolName: "find" }; + +/** Narrow a `tool_result` event to the legacy `find` tool. */ +export function isFindToolResult(e: ToolResultEvent): e is FindToolResultEvent { + return e.toolName === "find"; +} + +/** Legacy `ls` result event represented by omp's custom-event branch. */ +export type LsToolResultEvent = ToolResultEvent & { toolName: "ls" }; + +/** Narrow a `tool_result` event to the legacy `ls` tool. */ +export function isLsToolResult(e: ToolResultEvent): e is LsToolResultEvent { + return e.toolName === "ls"; +} diff --git a/packages/coding-agent/test/extensibility/legacy-pi-tool-result-guards.test.ts b/packages/coding-agent/test/extensibility/legacy-pi-tool-result-guards.test.ts new file mode 100644 index 000000000..b24346fae --- /dev/null +++ b/packages/coding-agent/test/extensibility/legacy-pi-tool-result-guards.test.ts @@ -0,0 +1,59 @@ +import { describe, expect, it } from "bun:test"; +import { + isBashToolResult, + isEditToolResult, + isFindToolResult, + isGrepToolResult, + isLsToolResult, + isReadToolResult, + isWriteToolResult, + type ToolResultEvent, +} from "@oh-my-pi/pi-coding-agent/extensibility/legacy-pi-coding-agent-shim"; + +// Issue #8161: pi-lean-ctx@3.9.18 imports `isEditToolResult`/`isWriteToolResult` +// from `@earendil-works/pi-coding-agent`, which aliases to this shim. The shim's +// `export * from "../index"` never forwarded the `isToolResult` guard +// family (dropped from the public API in 10.2.3), so a named import threw Bun's +// static "Export named X not found" error and aborted `omp install`. + +function resultEvent(toolName: string): ToolResultEvent { + return { + type: "tool_result", + toolCallId: "call-1", + input: {}, + content: [], + isError: false, + toolName, + details: undefined, + }; +} + +describe("legacy shim tool-result guards", () => { + it("exports the guard family as callable functions", () => { + expect(typeof isBashToolResult).toBe("function"); + expect(typeof isReadToolResult).toBe("function"); + expect(typeof isEditToolResult).toBe("function"); + expect(typeof isWriteToolResult).toBe("function"); + expect(typeof isGrepToolResult).toBe("function"); + expect(typeof isFindToolResult).toBe("function"); + expect(typeof isLsToolResult).toBe("function"); + }); + + it("narrows a tool_result event by tool name", () => { + expect(isEditToolResult(resultEvent("edit"))).toBe(true); + expect(isEditToolResult(resultEvent("write"))).toBe(false); + + expect(isWriteToolResult(resultEvent("write"))).toBe(true); + expect(isWriteToolResult(resultEvent("edit"))).toBe(false); + + expect(isBashToolResult(resultEvent("bash"))).toBe(true); + expect(isReadToolResult(resultEvent("read"))).toBe(true); + expect(isGrepToolResult(resultEvent("grep"))).toBe(true); + expect(isFindToolResult(resultEvent("find"))).toBe(true); + expect(isLsToolResult(resultEvent("ls"))).toBe(true); + expect(isFindToolResult(resultEvent("ls"))).toBe(false); + expect(isLsToolResult(resultEvent("find"))).toBe(false); + + expect(isBashToolResult(resultEvent("read"))).toBe(false); + }); +});