From 727d5eed59bc434fdf916e8115ea9a2ca1d1f0e8 Mon Sep 17 00:00:00 2001 From: Mohamed Boudra Date: Mon, 19 Oct 2026 10:01:18 +0700 Subject: [PATCH] fix(protocol): preserve the published tool detail import (#7357) The presentation module move removed a subpath shipped in 0.11.4. Forward its original runtime export and types so plugins retain their imports when upgrading to 0.12. --- .../protocol/src/paseo-tool-call-detail.ts | 6 ++ .../detail-sections.test.ts | 77 +++++++++++++++++++ 2 files changed, 83 insertions(+) create mode 100644 packages/protocol/src/paseo-tool-call-detail.ts diff --git a/packages/protocol/src/paseo-tool-call-detail.ts b/packages/protocol/src/paseo-tool-call-detail.ts new file mode 100644 index 0000000000..2fd856cee3 --- /dev/null +++ b/packages/protocol/src/paseo-tool-call-detail.ts @@ -0,0 +1,6 @@ +// COMPAT(paseoToolCallDetail): added in v0.12.0, remove after 2027-04-19 once plugins have migrated to paseo-tool-presentation/index. +export { + buildPaseoToolDetailSections, + type PaseoToolDetailField, + type PaseoToolDetailSection, +} from "./paseo-tool-presentation/index.js"; diff --git a/packages/protocol/src/paseo-tool-presentation/detail-sections.test.ts b/packages/protocol/src/paseo-tool-presentation/detail-sections.test.ts index ab3c123e17..c99e46248e 100644 --- a/packages/protocol/src/paseo-tool-presentation/detail-sections.test.ts +++ b/packages/protocol/src/paseo-tool-presentation/detail-sections.test.ts @@ -1,3 +1,8 @@ +import { execFileSync } from "node:child_process"; +import { copyFileSync, mkdtempSync, rmSync, symlinkSync, writeFileSync } from "node:fs"; +import { tmpdir } from "node:os"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; import { describe, expect, it } from "vitest"; import { buildPaseoToolDetailSections } from "./index.js"; @@ -147,3 +152,75 @@ describe("Paseo tool-call detail presentation", () => { expect(buildPaseoToolDetailSections("mcp__github__create_issue", {}, {})).toBeNull(); }); }); + +describe("published Paseo tool-call detail entry", () => { + it("preserves the 0.11.4 runtime export and types at the old subpath", () => { + const packageRoot = fileURLToPath(new URL("../../", import.meta.url)); + const compiler = fileURLToPath( + new URL("../../../../node_modules/typescript/bin/tsc", import.meta.url), + ); + const fixture = mkdtempSync(path.join(tmpdir(), "paseo-tool-call-detail-")); + try { + copyFileSync(path.join(packageRoot, "package.json"), path.join(fixture, "package.json")); + symlinkSync( + path.join(packageRoot, "../../node_modules"), + path.join(fixture, "node_modules"), + "junction", + ); + execFileSync( + process.execPath, + [ + compiler, + "-p", + path.join(packageRoot, "tsconfig.json"), + "--outDir", + path.join(fixture, "dist"), + "--incremental", + "false", + ], + { stdio: "pipe" }, + ); + writeFileSync( + path.join(fixture, "consumer.mts"), + ` +import { strict as assert } from "node:assert"; +import { + buildPaseoToolDetailSections, + type PaseoToolDetailField, + type PaseoToolDetailSection, +} from "@getpaseo/protocol/paseo-tool-call-detail"; +import { buildPaseoToolDetailSections as current } from "@getpaseo/protocol/paseo-tool-presentation/index"; +const field: PaseoToolDetailField = { label: "Agent", value: "agt_123" }; +const sections: PaseoToolDetailSection[] = [ + { kind: "prose", title: "Prompt", text: "Hello" }, + { kind: "fields", title: "Details", fields: [field] }, +]; +const build: (toolName: string, input: unknown, output: unknown) => PaseoToolDetailSection[] | null = buildPaseoToolDetailSections; +assert.equal(build, current); +assert.deepEqual(build("mcp__paseo__send_agent_prompt", { prompt: "Hello", agentId: "agt_123" }, undefined), sections); +`, + ); + execFileSync( + process.execPath, + [ + compiler, + path.join(fixture, "consumer.mts"), + "--module", + "NodeNext", + "--moduleResolution", + "NodeNext", + "--target", + "ES2020", + "--strict", + "--skipLibCheck", + ], + { stdio: "inherit" }, + ); + expect( + execFileSync(process.execPath, [path.join(fixture, "consumer.mjs")], { encoding: "utf8" }), + ).toBe(""); + } finally { + rmSync(fixture, { recursive: true, force: true }); + } + }, 30_000); +});