diff --git a/.changeset/fn-9007-pi-0-84-1.md b/.changeset/fn-9007-pi-0-84-1.md new file mode 100644 index 0000000000..d0dd5c1a02 --- /dev/null +++ b/.changeset/fn-9007-pi-0-84-1.md @@ -0,0 +1,7 @@ +--- +"@runfusion/fusion": patch +--- + +summary: Upgrade the bundled Pi runtime to 0.84.1 for updated provider and model support. +category: internal +dev: Advance the exact Pi closure from 0.82.1 to 0.84.1 and guard pi-client, pi-protocol, and pi-telemetry. diff --git a/packages/cli/package.json b/packages/cli/package.json index 02e3d7a19b..b29d3a67fe 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -67,8 +67,8 @@ "dependencies": { "@agentclientprotocol/sdk": "0.24.0", "agent-browser": "0.26.0", - "@earendil-works/pi-ai": "0.82.1", - "@earendil-works/pi-coding-agent": "0.82.1", + "@earendil-works/pi-ai": "0.84.1", + "@earendil-works/pi-coding-agent": "0.84.1", "claude-code-cli-acp": "0.1.1", "dockerode": "^4.0.12", "electron": "^33.4.11", diff --git a/packages/cli/src/__tests__/package-config.test.ts b/packages/cli/src/__tests__/package-config.test.ts index 2153fd3a9c..760417dece 100644 --- a/packages/cli/src/__tests__/package-config.test.ts +++ b/packages/cli/src/__tests__/package-config.test.ts @@ -55,12 +55,12 @@ function assertRuntimeDepsAreNotOptionalPeers(pkg: any, label: string): void { ).not.toBe(true); } - // FNXC:DesktopPackaging 2026-07-26-22:55: Exact matched Pi runtime pin — keep in sync with - // pnpm-workspace.yaml overrides and check-pi-versions-pinned.mjs (currently 0.82.1). + // FNXC:DesktopPackaging 2026-08-12-20:46: Exact matched Pi runtime pin — keep in sync with + // pnpm-workspace.yaml overrides and check-pi-versions-pinned.mjs (currently 0.84.1). for (const dependencyName of ["@earendil-works/pi-coding-agent", "@earendil-works/pi-ai"]) { expect(dependencies, `${label}: ${dependencyName} must remain a required runtime dependency`).toHaveProperty( dependencyName, - "0.82.1", + "0.84.1", ); expect(dependencies[dependencyName], `${label}: ${dependencyName} must be a clean exact semver`).toMatch( EXACT_SEMVER, diff --git a/packages/cli/vitest.config.ts b/packages/cli/vitest.config.ts index a42eedf4f1..3e293ffc60 100644 --- a/packages/cli/vitest.config.ts +++ b/packages/cli/vitest.config.ts @@ -130,7 +130,7 @@ export default defineConfig({ alias: [ /* FNXC:CliTests 2026-08-11-04:50: - pnpm resolves pi-coding-agent 0.82.1 into peer-hashed instances because dashboard pins zod + pnpm resolves pi-coding-agent 0.84.1 into peer-hashed instances because dashboard pins zod ^3.25.76 while CLI/engine use zod 4.x and different ws versions. vi.mock is resolved-path scoped, so unify its exact package root here or CLI mocks silently miss dashboard/engine and run the real pi runtime plus vendored pi-claude-cli. Keep this anchored root alias after any diff --git a/packages/core/package.json b/packages/core/package.json index 51bb5b85bb..1421f4f761 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -67,7 +67,7 @@ "test:unit-gate": "vitest run src/__tests__/task-merge.test.ts src/__tests__/legacy-adoption.test.ts src/__tests__/no-hardcoded-lifecycle-columns.test.ts src/__tests__/sync-workflow-ir-callsite-allowlist.test.ts --silent=passed-only --reporter=dot" }, "devDependencies": { - "@earendil-works/pi-coding-agent": "0.82.1", + "@earendil-works/pi-coding-agent": "0.84.1", "@types/dockerode": "^3.3.41", "@types/node": "^25.5.0", "@vitest/coverage-v8": "^4.1.10", diff --git a/packages/dashboard/package.json b/packages/dashboard/package.json index 0ed9780c27..966f652fde 100644 --- a/packages/dashboard/package.json +++ b/packages/dashboard/package.json @@ -108,7 +108,7 @@ "@codemirror/state": "^6.7.1", "@codemirror/theme-one-dark": "^6.1.2", "@codemirror/view": "^6.36.4", - "@earendil-works/pi-coding-agent": "0.82.1", + "@earendil-works/pi-coding-agent": "0.84.1", "@fusion-plugin-examples/claude-runtime": "workspace:*", "@fusion-plugin-examples/cli-printing-press": "workspace:*", "@fusion-plugin-examples/compound-engineering": "workspace:*", @@ -161,7 +161,7 @@ "sherpa-onnx-node": "1.13.4" }, "devDependencies": { - "@earendil-works/pi-ai": "0.82.1", + "@earendil-works/pi-ai": "0.84.1", "@testing-library/jest-dom": "^6.9.1", "@testing-library/react": "^16.3.2", "@testing-library/user-event": "^14.5.0", diff --git a/packages/dashboard/src/routes.ts b/packages/dashboard/src/routes.ts index 554c6aa37b..bd50846c8f 100644 --- a/packages/dashboard/src/routes.ts +++ b/packages/dashboard/src/routes.ts @@ -121,8 +121,12 @@ export interface ModelRegistryLike { * FNXC:ModelCatalog 2026-07-16-17:55: * pi 0.80.8 refreshes asynchronously, so the models endpoint must wait for it * before reading getAvailable() and surface any refresh failure to the caller. + * + * FNXC:ModelCatalog 2026-08-12-20:46: + * Pi 0.84.1 returns refresh metadata instead of void. Preserve it as unknown because + * the route needs only completion while structural compatibility must track the SDK. */ - refresh(): Promise; + refresh(): Promise; /** Optional runtime passthrough lets request refreshes use the engine abort-aware path. */ modelRuntime?: { refresh: (options?: { allowNetwork?: boolean; signal?: AbortSignal; force?: boolean }) => Promise; diff --git a/packages/engine/package.json b/packages/engine/package.json index 181c590cbb..6b3fd7f353 100644 --- a/packages/engine/package.json +++ b/packages/engine/package.json @@ -38,8 +38,8 @@ "test:watch": "vitest src/__tests__/executor-*.test.ts --watch" }, "dependencies": { - "@earendil-works/pi-ai": "0.82.1", - "@earendil-works/pi-coding-agent": "0.82.1", + "@earendil-works/pi-ai": "0.84.1", + "@earendil-works/pi-coding-agent": "0.84.1", "@fusion/core": "workspace:*", "@fusion/pi-claude-cli": "workspace:*", "@modelcontextprotocol/sdk": "^1.0.0", diff --git a/packages/engine/src/__tests__/pi.test.ts b/packages/engine/src/__tests__/pi.test.ts index 21c4f39e4e..9b4801ec33 100644 --- a/packages/engine/src/__tests__/pi.test.ts +++ b/packages/engine/src/__tests__/pi.test.ts @@ -892,9 +892,12 @@ describe("session failure diagnostics", () => { it("forwards materialized MCP servers into session creation and prompt options for supported providers", async () => { const createAgentSessionMock = vi.mocked(createAgentSession); + // FNXC:SessionIdentity 2026-08-12-20:46: createFnAgent wraps session.prompt to bind the + // request principal, so retain the original spy when asserting the prompt reaches Pi. + const prompt = vi.fn(); const session = { model: { provider: "test", id: "primary-model" }, - prompt: vi.fn(), + prompt, subscribe: vi.fn(), dispose: vi.fn(), sessionFile: undefined, @@ -916,14 +919,15 @@ describe("session failure diagnostics", () => { await (created.session as any).promptWithFallback("Use docs"); expect(createAgentSessionMock.mock.calls[0]?.[0]).not.toHaveProperty("mcpServers"); - expect(session.prompt).toHaveBeenCalledWith("Use docs", expect.objectContaining({ mcpServers })); + expect(prompt).toHaveBeenCalledWith("Use docs", expect.objectContaining({ mcpServers })); }); it("skips MCP forwarding for unsupported mock provider and emits a content-free skip log", async () => { const createAgentSessionMock = vi.mocked(createAgentSession); + const prompt = vi.fn(); const session = { model: { provider: "test", id: "primary-model" }, - prompt: vi.fn(), + prompt, subscribe: vi.fn(), dispose: vi.fn(), sessionFile: undefined, @@ -944,7 +948,7 @@ describe("session failure diagnostics", () => { await (created.session as any).promptWithFallback("Use docs"); expect(createAgentSessionMock.mock.calls[0]?.[0]).not.toHaveProperty("mcpServers"); - expect(session.prompt).toHaveBeenCalledWith("Use docs"); + expect(prompt).toHaveBeenCalledWith("Use docs"); const skipLog = consoleErrorSpy.mock.calls.find(([message]) => String(message).includes("mcp.forwarding.skipped")); expect(skipLog?.[0]).toContain('"skippedCount":1'); expect(skipLog?.[0]).toContain('"provider":"mock"'); @@ -1169,10 +1173,13 @@ describe("piLog structured diagnostics", () => { it("throws a bounded fallback exhaustion error when prompt-time fallback also fails", async () => { const createAgentSessionMock = vi.mocked(createAgentSession); const onFallbackModelUsed = vi.fn(); + const primaryPrompt = vi.fn().mockRejectedValue(new Error("429 Too Many Requests")); + const fallbackPrompt = vi.fn().mockRejectedValue(new Error("401 invalid api key for fallback")); + const primaryRetryPrompt = vi.fn().mockRejectedValue(new Error("429 Too Many Requests")); const primarySession = { model: { provider: "openai", id: "gpt-4o" }, - prompt: vi.fn().mockRejectedValue(new Error("429 Too Many Requests")), + prompt: primaryPrompt, subscribe: vi.fn(), dispose: vi.fn(), setThinkingLevel: vi.fn(), @@ -1181,7 +1188,7 @@ describe("piLog structured diagnostics", () => { const fallbackSession = { model: { provider: "anthropic", id: "claude-3-5-haiku-20241022" }, - prompt: vi.fn().mockRejectedValue(new Error("401 invalid api key for fallback")), + prompt: fallbackPrompt, state: { errorMessage: "", messages: [] }, subscribe: vi.fn(), dispose: vi.fn(), @@ -1192,7 +1199,7 @@ describe("piLog structured diagnostics", () => { createAgentSessionMock.mockReset(); const primaryRetrySession = { model: { provider: "openai", id: "gpt-4o" }, - prompt: vi.fn().mockRejectedValue(new Error("429 Too Many Requests")), + prompt: primaryRetryPrompt, subscribe: vi.fn(), dispose: vi.fn(), setThinkingLevel: vi.fn(), sessionFile: undefined, } as unknown as AgentSession; createAgentSessionMock @@ -1220,9 +1227,9 @@ describe("piLog structured diagnostics", () => { }); expect(createAgentSessionMock).toHaveBeenCalledTimes(3); - expect(primarySession.prompt).toHaveBeenCalledTimes(1); - expect(fallbackSession.prompt).toHaveBeenCalledTimes(1); - expect(primaryRetrySession.prompt).toHaveBeenCalledTimes(1); + expect(primaryPrompt).toHaveBeenCalledTimes(1); + expect(fallbackPrompt).toHaveBeenCalledTimes(1); + expect(primaryRetryPrompt).toHaveBeenCalledTimes(1); expect((createAgentSessionMock.mock.calls[2]?.[0] as any).model.id).toBe("gpt-4o"); expect(onFallbackModelUsed).toHaveBeenCalledTimes(1); expect(onFallbackModelUsed).toHaveBeenCalledWith(expect.objectContaining({ @@ -1272,6 +1279,7 @@ describe("piLog structured diagnostics", () => { const createAgentSessionMock = vi.mocked(createAgentSession); const onFallbackModelUsed = vi.fn(); const primaryState = { errorMessage: "", messages: [] }; + const fallbackPrompt = vi.fn().mockResolvedValue(undefined); const modelAuthTierError = "Codex error: 400 invalid_request_error — \"The 'gpt-5.3-codex' model is not supported when using Codex with a ChatGPT account.\""; @@ -1289,7 +1297,7 @@ describe("piLog structured diagnostics", () => { const fallbackSession = { model: { provider: "test", id: "fallback-model" }, - prompt: vi.fn().mockResolvedValue(undefined), + prompt: fallbackPrompt, state: { errorMessage: "", messages: [] }, subscribe: vi.fn(), dispose: vi.fn(), @@ -1315,7 +1323,7 @@ describe("piLog structured diagnostics", () => { await (session as any).promptWithFallback("prompt text"); - expect(fallbackSession.prompt).toHaveBeenCalledWith("prompt text"); + expect(fallbackPrompt).toHaveBeenCalledWith("prompt text"); expect(createAgentSessionMock).toHaveBeenCalledTimes(2); expect(onFallbackModelUsed).toHaveBeenCalledWith( expect.objectContaining({ @@ -1330,6 +1338,10 @@ describe("piLog structured diagnostics", () => { const onFallbackModelUsed = vi.fn(); const sonnet5NotFoundError = 'Error: 404 {"type":"error","error":{"type":"not_found_error","message":"Not found"},"request_id":"req_011CcawcZ3Ra9CennJXM8oWC"}'; + const sonnetPrompt = vi.fn(async () => { + throw new Error(sonnet5NotFoundError); + }); + const fallbackPrompt = vi.fn(async (_prompt: string, _options?: unknown) => undefined); createAgentSessionMock.mockReset(); createAgentSessionMock.mockImplementation(async (options: any) => { @@ -1337,9 +1349,7 @@ describe("piLog structured diagnostics", () => { return { session: { model: { provider: "anthropic", id: "claude-sonnet-5" }, - prompt: vi.fn(async () => { - throw new Error(sonnet5NotFoundError); - }), + prompt: sonnetPrompt, state: { errorMessage: "", messages: [] }, subscribe: vi.fn(), dispose: vi.fn(), @@ -1351,7 +1361,7 @@ describe("piLog structured diagnostics", () => { return { session: { model: { provider: "zai", id: "glm-5.1" }, - prompt: vi.fn(async (_prompt: string, _options?: unknown) => undefined), + prompt: fallbackPrompt, state: { errorMessage: "", messages: [{ role: "assistant", content: "Fallback reply" }] }, subscribe: vi.fn(), dispose: vi.fn(), @@ -1374,9 +1384,8 @@ describe("piLog structured diagnostics", () => { await expect((session as any).promptWithFallback("prompt text", { temperature: 0 })).resolves.toBeUndefined(); - const fallbackPrompt = vi.mocked((session as any).prompt).mock; expect(createAgentSessionMock).toHaveBeenCalledTimes(2); - expect(fallbackPrompt.calls).toEqual([["prompt text", { temperature: 0 }]]); + expect(fallbackPrompt).toHaveBeenCalledWith("prompt text", { temperature: 0 }); expect((session as any).state.errorMessage ?? "").toBe(""); expect(onFallbackModelUsed).toHaveBeenCalledWith(expect.objectContaining({ triggerPoint: "prompt-time", diff --git a/packages/engine/src/__tests__/provider-registration.test.ts b/packages/engine/src/__tests__/provider-registration.test.ts index a5788ac112..dc81a0a313 100644 --- a/packages/engine/src/__tests__/provider-registration.test.ts +++ b/packages/engine/src/__tests__/provider-registration.test.ts @@ -123,8 +123,8 @@ describe("seedDashboardProviders", () => { }); it("keeps native Kimi K3 available through the installed pi model registry", async () => { - // FNXC:ModelCatalog 2026-07-24-12:00: FN-8564 keeps catalog coverage on Pi - // 0.82.0's real built-in registry, not a hand-written Kimi fixture. + // FNXC:ModelCatalog 2026-08-12-20:46: FN-9007 keeps catalog coverage on Pi + // 0.84.1's real built-in registry, not a hand-written Kimi fixture. const modelRegistry = await createInMemoryModelRegistry(); await modelRegistry.refresh(); diff --git a/packages/engine/src/auth/auth-storage.ts b/packages/engine/src/auth/auth-storage.ts index 8af39b9cc7..9f0b6dfe62 100644 --- a/packages/engine/src/auth/auth-storage.ts +++ b/packages/engine/src/auth/auth-storage.ts @@ -364,19 +364,15 @@ FNXC:ProviderAuth 2026-07-07-00:00: FN-7646: the cross-process ~/.fusion/agent/auth.json coordination invariant (concurrent writers merge per-provider instead of clobbering each other's credentials) depends on the vendored @earendil-works/pi-coding-agent AuthStorage backend using proper-lockfile locking -plus a per-provider read-modify-merge (FileAuthStorageBackend.persistProviderChange / -refreshOAuthTokenWithLock re-read the file under a lock and spread -{...currentData, [provider]: credential} rather than flushing a whole-file in-memory -snapshot). packages/engine/package.json already pins this at -"@earendil-works/pi-coding-agent": "0.82.1" (exact matched runtime pair; locked per-provider -merge requires >=0.80.3) — do not downgrade below 0.80.x, and re-verify this comment against -dist/core/auth-storage.js if the pin is ever lowered. See - -FNXC:ProviderAuth 2026-07-24-12:00: -FN-8564 retains Fusion's credential-store adapter on Pi 0.82.x. The release adds Kimi Code and -OpenRouter OAuth, so new upstream login providers must still use the same queued, cross-process -credential persistence contract rather than bypassing Fusion auth storage. +plus a per-provider read-modify-merge. See packages/engine/src/__tests__/auth-storage-concurrency.test.ts for the regression coverage. + +FNXC:ProviderAuth 2026-08-12-20:46: +FN-9007 re-verified pi-coding-agent@0.84.1 dist/core/auth-storage.js: FileAuthStorageBackend's +proper-lockfile-guarded withLockAsync rereads auth.json and AuthStorage.modify merges +{ ...currentData, [provider]: next } before writing. This preserves the per-provider +read-modify-merge contract rather than flushing a whole-file in-memory snapshot as the +credential-store adapter handles new upstream providers. */ /* diff --git a/packages/engine/src/pi.ts b/packages/engine/src/pi.ts index da8a66061f..7d6ba36f9e 100644 --- a/packages/engine/src/pi.ts +++ b/packages/engine/src/pi.ts @@ -2705,6 +2705,11 @@ export async function createFnAgent(options: AgentOptions): Promise provider-verified reasoning levels and adds Kimi/OpenRouter OAuth plus constrained tools; retain Fusion's ModelRuntime session construction and supplemental catalog merges rather than duplicating upstream provider behavior. + + FNXC:ModelCatalog 2026-08-12-20:46: + FN-9007 advances the exact matched Pi runtime closure from 0.82.1 to 0.84.1. + Keep constructing sessions through ModelRuntime so Fusion inherits the updated provider + catalog and SDK behavior without duplicating upstream runtime policy. */ const createSessionOptions: NonNullable[0]> = { cwd: options.cwd, diff --git a/packages/pi-claude-cli/package.json b/packages/pi-claude-cli/package.json index ced9c47e30..b58e114211 100644 --- a/packages/pi-claude-cli/package.json +++ b/packages/pi-claude-cli/package.json @@ -23,12 +23,12 @@ "@agentclientprotocol/sdk": "0.24.0" }, "peerDependencies": { - "@earendil-works/pi-ai": "0.82.1", - "@earendil-works/pi-coding-agent": "0.82.1" + "@earendil-works/pi-ai": "0.84.1", + "@earendil-works/pi-coding-agent": "0.84.1" }, "devDependencies": { - "@earendil-works/pi-ai": "0.82.1", - "@earendil-works/pi-coding-agent": "0.82.1", + "@earendil-works/pi-ai": "0.84.1", + "@earendil-works/pi-coding-agent": "0.84.1", "@types/node": "^22.0.0", "typescript": "^5.7.0", "vitest": "^4.1.10" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d4bf77306b..ad018509f4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7,10 +7,13 @@ settings: overrides: '@types/node': ^25.5.2 protobufjs: ^7.5.8 - '@earendil-works/pi-agent-core': 0.82.1 - '@earendil-works/pi-ai': 0.82.1 - '@earendil-works/pi-coding-agent': 0.82.1 - '@earendil-works/pi-tui': 0.82.1 + '@earendil-works/pi-agent-core': 0.84.1 + '@earendil-works/pi-ai': 0.84.1 + '@earendil-works/pi-client': 0.84.1 + '@earendil-works/pi-coding-agent': 0.84.1 + '@earendil-works/pi-protocol': 0.84.1 + '@earendil-works/pi-telemetry': 0.84.1 + '@earendil-works/pi-tui': 0.84.1 importers: @@ -56,11 +59,11 @@ importers: specifier: 0.24.0 version: 0.24.0(zod@4.4.3) '@earendil-works/pi-ai': - specifier: 0.82.1 - version: 0.82.1(@modelcontextprotocol/sdk@1.28.0(zod@4.4.3))(ws@8.21.1)(zod@4.4.3) + specifier: 0.84.1 + version: 0.84.1(@modelcontextprotocol/sdk@1.28.0(zod@4.4.3))(ws@8.21.1)(zod@4.4.3) '@earendil-works/pi-coding-agent': - specifier: 0.82.1 - version: 0.82.1(@modelcontextprotocol/sdk@1.28.0(zod@4.4.3))(ws@8.21.1)(zod@4.4.3) + specifier: 0.84.1 + version: 0.84.1(@modelcontextprotocol/sdk@1.28.0(zod@4.4.3))(ws@8.21.1)(zod@4.4.3) agent-browser: specifier: 0.26.0 version: 0.26.0 @@ -218,8 +221,8 @@ importers: version: 2.9.0 devDependencies: '@earendil-works/pi-coding-agent': - specifier: 0.82.1 - version: 0.82.1 + specifier: 0.84.1 + version: 0.84.1 '@types/dockerode': specifier: ^3.3.41 version: 3.3.47 @@ -267,8 +270,8 @@ importers: specifier: ^6.36.4 version: 6.40.0 '@earendil-works/pi-coding-agent': - specifier: 0.82.1 - version: 0.82.1(@modelcontextprotocol/sdk@1.28.0(zod@3.25.76))(ws@8.21.1)(zod@3.25.76) + specifier: 0.84.1 + version: 0.84.1(@modelcontextprotocol/sdk@1.28.0(zod@3.25.76))(ws@8.21.1)(zod@3.25.76) '@fusion-plugin-examples/claude-runtime': specifier: workspace:* version: link:../../plugins/fusion-plugin-claude-runtime @@ -412,8 +415,8 @@ importers: version: 3.25.76 devDependencies: '@earendil-works/pi-ai': - specifier: 0.82.1 - version: 0.82.1(@modelcontextprotocol/sdk@1.28.0(zod@3.25.76))(ws@8.21.1)(zod@3.25.76) + specifier: 0.84.1 + version: 0.84.1(@modelcontextprotocol/sdk@1.28.0(zod@3.25.76))(ws@8.21.1)(zod@3.25.76) '@testing-library/jest-dom': specifier: ^6.9.1 version: 6.9.1 @@ -540,11 +543,11 @@ importers: packages/droid-cli: dependencies: '@earendil-works/pi-ai': - specifier: 0.82.1 - version: 0.82.1(@modelcontextprotocol/sdk@1.28.0(zod@4.4.3))(ws@8.21.3)(zod@4.4.3) + specifier: 0.84.1 + version: 0.84.1(@modelcontextprotocol/sdk@1.28.0(zod@4.4.3))(ws@8.21.3)(zod@4.4.3) '@earendil-works/pi-coding-agent': - specifier: 0.82.1 - version: 0.82.1(@modelcontextprotocol/sdk@1.28.0(zod@4.4.3))(ws@8.21.3)(zod@4.4.3) + specifier: 0.84.1 + version: 0.84.1(@modelcontextprotocol/sdk@1.28.0(zod@4.4.3))(ws@8.21.3)(zod@4.4.3) '@fusion-plugin-examples/droid-runtime': specifier: workspace:* version: link:../../plugins/fusion-plugin-droid-runtime @@ -562,11 +565,11 @@ importers: packages/engine: dependencies: '@earendil-works/pi-ai': - specifier: 0.82.1 - version: 0.82.1(@modelcontextprotocol/sdk@1.28.0(zod@4.4.3))(ws@8.21.3)(zod@4.4.3) + specifier: 0.84.1 + version: 0.84.1(@modelcontextprotocol/sdk@1.28.0(zod@4.4.3))(ws@8.21.3)(zod@4.4.3) '@earendil-works/pi-coding-agent': - specifier: 0.82.1 - version: 0.82.1(@modelcontextprotocol/sdk@1.28.0(zod@4.4.3))(ws@8.21.3)(zod@4.4.3) + specifier: 0.84.1 + version: 0.84.1(@modelcontextprotocol/sdk@1.28.0(zod@4.4.3))(ws@8.21.3)(zod@4.4.3) '@fusion/core': specifier: workspace:* version: link:../core @@ -680,11 +683,11 @@ importers: version: 0.24.0(zod@4.4.3) devDependencies: '@earendil-works/pi-ai': - specifier: 0.82.1 - version: 0.82.1(@modelcontextprotocol/sdk@1.28.0(zod@4.4.3))(ws@8.21.3)(zod@4.4.3) + specifier: 0.84.1 + version: 0.84.1(@modelcontextprotocol/sdk@1.28.0(zod@4.4.3))(ws@8.21.3)(zod@4.4.3) '@earendil-works/pi-coding-agent': - specifier: 0.82.1 - version: 0.82.1(@modelcontextprotocol/sdk@1.28.0(zod@4.4.3))(ws@8.21.3)(zod@4.4.3) + specifier: 0.84.1 + version: 0.84.1(@modelcontextprotocol/sdk@1.28.0(zod@4.4.3))(ws@8.21.3)(zod@4.4.3) '@types/node': specifier: ^25.5.2 version: 25.9.5 @@ -698,8 +701,8 @@ importers: packages/pi-llama-cpp: dependencies: '@earendil-works/pi-coding-agent': - specifier: 0.82.1 - version: 0.82.1 + specifier: 0.84.1 + version: 0.84.1 devDependencies: '@types/node': specifier: ^25.5.2 @@ -797,11 +800,11 @@ importers: specifier: 0.24.0 version: 0.24.0(zod@4.4.3) '@earendil-works/pi-ai': - specifier: 0.82.1 - version: 0.82.1(@modelcontextprotocol/sdk@1.28.0(zod@4.4.3))(ws@8.21.3)(zod@4.4.3) + specifier: 0.84.1 + version: 0.84.1(@modelcontextprotocol/sdk@1.28.0(zod@4.4.3))(ws@8.21.3)(zod@4.4.3) '@earendil-works/pi-coding-agent': - specifier: 0.82.1 - version: 0.82.1(@modelcontextprotocol/sdk@1.28.0(zod@4.4.3))(ws@8.21.3)(zod@4.4.3) + specifier: 0.84.1 + version: 0.84.1(@modelcontextprotocol/sdk@1.28.0(zod@4.4.3))(ws@8.21.3)(zod@4.4.3) '@fusion/core': specifier: workspace:* version: link:../../packages/core @@ -847,11 +850,11 @@ importers: specifier: 0.24.0 version: 0.24.0(zod@4.4.3) '@earendil-works/pi-ai': - specifier: 0.82.1 - version: 0.82.1(@modelcontextprotocol/sdk@1.28.0(zod@4.4.3))(ws@8.21.3)(zod@4.4.3) + specifier: 0.84.1 + version: 0.84.1(@modelcontextprotocol/sdk@1.28.0(zod@4.4.3))(ws@8.21.3)(zod@4.4.3) '@earendil-works/pi-coding-agent': - specifier: 0.82.1 - version: 0.82.1(@modelcontextprotocol/sdk@1.28.0(zod@4.4.3))(ws@8.21.3)(zod@4.4.3) + specifier: 0.84.1 + version: 0.84.1(@modelcontextprotocol/sdk@1.28.0(zod@4.4.3))(ws@8.21.3)(zod@4.4.3) '@fusion/core': specifier: workspace:* version: link:../../packages/core @@ -970,11 +973,11 @@ importers: plugins/fusion-plugin-cursor-runtime: dependencies: '@earendil-works/pi-ai': - specifier: 0.82.1 - version: 0.82.1(@modelcontextprotocol/sdk@1.28.0(zod@4.4.3))(ws@8.21.3)(zod@4.4.3) + specifier: 0.84.1 + version: 0.84.1(@modelcontextprotocol/sdk@1.28.0(zod@4.4.3))(ws@8.21.3)(zod@4.4.3) '@earendil-works/pi-coding-agent': - specifier: 0.82.1 - version: 0.82.1(@modelcontextprotocol/sdk@1.28.0(zod@4.4.3))(ws@8.21.3)(zod@4.4.3) + specifier: 0.84.1 + version: 0.84.1(@modelcontextprotocol/sdk@1.28.0(zod@4.4.3))(ws@8.21.3)(zod@4.4.3) '@fusion/plugin-sdk': specifier: workspace:* version: link:../../packages/plugin-sdk @@ -1026,11 +1029,11 @@ importers: plugins/fusion-plugin-droid-runtime: dependencies: '@earendil-works/pi-ai': - specifier: 0.82.1 - version: 0.82.1(@modelcontextprotocol/sdk@1.28.0(zod@4.4.3))(ws@8.21.3)(zod@4.4.3) + specifier: 0.84.1 + version: 0.84.1(@modelcontextprotocol/sdk@1.28.0(zod@4.4.3))(ws@8.21.3)(zod@4.4.3) '@earendil-works/pi-coding-agent': - specifier: 0.82.1 - version: 0.82.1(@modelcontextprotocol/sdk@1.28.0(zod@4.4.3))(ws@8.21.3)(zod@4.4.3) + specifier: 0.84.1 + version: 0.84.1(@modelcontextprotocol/sdk@1.28.0(zod@4.4.3))(ws@8.21.3)(zod@4.4.3) '@fusion/plugin-sdk': specifier: workspace:* version: link:../../packages/plugin-sdk @@ -1073,11 +1076,11 @@ importers: specifier: 0.24.0 version: 0.24.0(zod@4.4.3) '@earendil-works/pi-ai': - specifier: 0.82.1 - version: 0.82.1(@modelcontextprotocol/sdk@1.28.0(zod@4.4.3))(ws@8.21.3)(zod@4.4.3) + specifier: 0.84.1 + version: 0.84.1(@modelcontextprotocol/sdk@1.28.0(zod@4.4.3))(ws@8.21.3)(zod@4.4.3) '@earendil-works/pi-coding-agent': - specifier: 0.82.1 - version: 0.82.1(@modelcontextprotocol/sdk@1.28.0(zod@4.4.3))(ws@8.21.3)(zod@4.4.3) + specifier: 0.84.1 + version: 0.84.1(@modelcontextprotocol/sdk@1.28.0(zod@4.4.3))(ws@8.21.3)(zod@4.4.3) '@fusion/core': specifier: workspace:* version: link:../../packages/core @@ -1157,11 +1160,11 @@ importers: specifier: 0.24.0 version: 0.24.0(zod@4.4.3) '@earendil-works/pi-ai': - specifier: 0.82.1 - version: 0.82.1(@modelcontextprotocol/sdk@1.28.0(zod@4.4.3))(ws@8.21.3)(zod@4.4.3) + specifier: 0.84.1 + version: 0.84.1(@modelcontextprotocol/sdk@1.28.0(zod@4.4.3))(ws@8.21.3)(zod@4.4.3) '@earendil-works/pi-coding-agent': - specifier: 0.82.1 - version: 0.82.1(@modelcontextprotocol/sdk@1.28.0(zod@4.4.3))(ws@8.21.3)(zod@4.4.3) + specifier: 0.84.1 + version: 0.84.1(@modelcontextprotocol/sdk@1.28.0(zod@4.4.3))(ws@8.21.3)(zod@4.4.3) '@fusion/core': specifier: workspace:* version: link:../../packages/core @@ -1845,22 +1848,34 @@ packages: resolution: {integrity: sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA==} engines: {node: '>=20.19.0'} - '@earendil-works/pi-agent-core@0.82.1': - resolution: {integrity: sha512-Z3kloziJIE2dmrisRckZX8zDca/gIv9/YdFAzeoqpHiLV2wsni6bL4hInNSjVKLbqT+4kqLIkph2JQLKvSepjg==} + '@earendil-works/pi-agent-core@0.84.1': + resolution: {integrity: sha512-evyzXYWCLQGmcaBYHlmSku02r8qoN4SGI60GZABo6iV+H+nqX+P9ud8fEZ4GmRq9mUSREvvfX+w9dA9ThF9C6w==} engines: {node: '>=22.19.0'} - '@earendil-works/pi-ai@0.82.1': - resolution: {integrity: sha512-3WFYRhEp3lQB3444EhPMBcM7zSaEUE3eJgHOR7s4081NLqbw/FsWilIKWXSua0Gv3sRr7m9xMidR3pPDE7jI/A==} + '@earendil-works/pi-ai@0.84.1': + resolution: {integrity: sha512-wMsAdJMxuNri08vLqTyYVI201DQQezGhPSTkzYsHdw5dYX3rCNwEmSvpaAwhi7ELKI/2tE/CEgSWg/6iRxSgdQ==} engines: {node: '>=22.19.0'} hasBin: true - '@earendil-works/pi-coding-agent@0.82.1': - resolution: {integrity: sha512-zbkAhoIuDPMF3pKuja0ajZabrMWU29FUMV9A/XMXT/XC1yXs5xt6t6t13GogQFsDrDqbFP4DkZQO1w8rWRAzYA==} + '@earendil-works/pi-client@0.84.1': + resolution: {integrity: sha512-/V5hGHE4Zq+jG0GtwIB9PyBUOGd6gBLZ7lkQYFKchKnxYHeH3rmWC5xw4kpnZKKBuBuFTdLVbU9vEjlAGMMb2A==} + engines: {node: '>=22.19.0'} + + '@earendil-works/pi-coding-agent@0.84.1': + resolution: {integrity: sha512-ncAqFrG+iybuPGOhMiZoEHkEzTpJgz3guYD32pD+M7ucc0WeHmauP6wa7qwP8V/KWvsZDVNa5XGsdZ7fkC7w7A==} engines: {node: '>=22.19.0'} hasBin: true - '@earendil-works/pi-tui@0.82.1': - resolution: {integrity: sha512-9yN8hALfKaxZq7n54EMxqhFCWnMi6LHkraMJ/1YjHiATq75XrI6XDMVppn9EDtiK7Fks8hUe1SDXUTrIvwRWfQ==} + '@earendil-works/pi-protocol@0.84.1': + resolution: {integrity: sha512-Ox1pciyeSPGEEUcxvR0/dJcrY7C6hrEGA8y71rOsvSIUlXN1Cbp/be/eoL71OGDBk5O97TeQPfWN6Ju/2Ehjww==} + engines: {node: '>=22.19.0'} + + '@earendil-works/pi-telemetry@0.84.1': + resolution: {integrity: sha512-180/xGJtsq7IoR3p9EKWjRd0e9M4DkxInhlo9xyD7prDC7Qrhqq+nhvwrW0lFjPfXcEI2FSHmGCSyvSJE9GsaQ==} + engines: {node: '>=22.19.0'} + + '@earendil-works/pi-tui@0.84.1': + resolution: {integrity: sha512-udeXFbgEhJ6JiB0uguwNVNkDy2FENfmtQwPcY+/iJ8GWeq18wkal1tKqa5YyeH0IqtX1vG0cGh8zfSYzyzVuLA==} engines: {node: '>=22.19.0'} '@electron/asar@3.4.1': @@ -5371,6 +5386,10 @@ packages: graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + grok-mermaid@0.2.2: + resolution: {integrity: sha512-XcJEP5dDC8liHBh52mlLjU18fNvu1ckFsu0QpIG3+APZ270fsj9wxpiA6cOURmbUEuoMVgjbC2+UYgTdCqqgzA==} + engines: {node: '>=18'} + hachure-fill@0.5.2: resolution: {integrity: sha512-3GKBOn+m2LX9iq+JC1064cSFprJY4jL1jCXTcpnfER5HYE2l/4EfWSGzkPa/ZDBmYI0ZOEj5VHV/eKnPGkHuOg==} @@ -7639,6 +7658,9 @@ packages: typebox@1.1.38: resolution: {integrity: sha512-pZ0aQPmMmXoUvSbeuWf/Hzsc+avNw/Zd6VeE8CFgkVGWyuHPJvqeJJDeJqLve+K70LvjYIoleGcoJHPT17cWoA==} + typebox@1.3.7: + resolution: {integrity: sha512-meKuifc33Pccx0O6PdIzYMq3Og8zvP4TIi/a+Bw3AEMZMxOD0+RHGQvpglEe6Zdy3wZ8nqn/j95h8LUZLk/6Hg==} + typedarray@0.0.6: resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} @@ -7668,8 +7690,8 @@ packages: resolution: {integrity: sha512-IDxfleLmmbSskfWSUATiN1nfn2rDuvnMOqb5CWR92iIfojA0Ud+ulOAAEQ57LPr9rWmsreUyf5lwyao+7GNNVw==} engines: {node: '>=20.18.1'} - undici@8.5.0: - resolution: {integrity: sha512-xamtWoB1EshgjpmlXd7GGm2VfdDtw1+rD8uhry8pSNW3If6S8E0m2T2+orSKeZXEn/aPJMviCpDBA65WJt8zhg==} + undici@8.9.0: + resolution: {integrity: sha512-aWZpUj7XoGonMClx4gdDRfgBjqeA+F473aDmROQQbM9n6PRfK/u1q/a0X4wMTgcHfT8H6fpbt98PFuDUwFg2YA==} engines: {node: '>=22.19.0'} unicorn-magic@0.3.0: @@ -8806,12 +8828,13 @@ snapshots: '@csstools/css-tokenizer@4.0.0': {} - '@earendil-works/pi-agent-core@0.82.1': + '@earendil-works/pi-agent-core@0.84.1': dependencies: - '@earendil-works/pi-ai': 0.82.1 + '@earendil-works/pi-ai': 0.84.1 + '@earendil-works/pi-telemetry': 0.84.1 diff: 8.0.4 ignore: 7.0.5 - typebox: 1.1.38 + typebox: 1.3.7 yaml: 2.9.0 transitivePeerDependencies: - '@modelcontextprotocol/sdk' @@ -8821,12 +8844,13 @@ snapshots: - ws - zod - '@earendil-works/pi-agent-core@0.82.1(@modelcontextprotocol/sdk@1.28.0(zod@3.25.76))(ws@8.21.1)(zod@3.25.76)': + '@earendil-works/pi-agent-core@0.84.1(@modelcontextprotocol/sdk@1.28.0(zod@3.25.76))(ws@8.21.1)(zod@3.25.76)': dependencies: - '@earendil-works/pi-ai': 0.82.1(@modelcontextprotocol/sdk@1.28.0(zod@3.25.76))(ws@8.21.1)(zod@3.25.76) + '@earendil-works/pi-ai': 0.84.1(@modelcontextprotocol/sdk@1.28.0(zod@3.25.76))(ws@8.21.1)(zod@3.25.76) + '@earendil-works/pi-telemetry': 0.84.1 diff: 8.0.4 ignore: 7.0.5 - typebox: 1.1.38 + typebox: 1.3.7 yaml: 2.9.0 transitivePeerDependencies: - '@modelcontextprotocol/sdk' @@ -8836,12 +8860,13 @@ snapshots: - ws - zod - '@earendil-works/pi-agent-core@0.82.1(@modelcontextprotocol/sdk@1.28.0(zod@4.4.3))(ws@8.21.1)(zod@4.4.3)': + '@earendil-works/pi-agent-core@0.84.1(@modelcontextprotocol/sdk@1.28.0(zod@4.4.3))(ws@8.21.1)(zod@4.4.3)': dependencies: - '@earendil-works/pi-ai': 0.82.1(@modelcontextprotocol/sdk@1.28.0(zod@4.4.3))(ws@8.21.1)(zod@4.4.3) + '@earendil-works/pi-ai': 0.84.1(@modelcontextprotocol/sdk@1.28.0(zod@4.4.3))(ws@8.21.1)(zod@4.4.3) + '@earendil-works/pi-telemetry': 0.84.1 diff: 8.0.4 ignore: 7.0.5 - typebox: 1.1.38 + typebox: 1.3.7 yaml: 2.9.0 transitivePeerDependencies: - '@modelcontextprotocol/sdk' @@ -8851,12 +8876,13 @@ snapshots: - ws - zod - '@earendil-works/pi-agent-core@0.82.1(@modelcontextprotocol/sdk@1.28.0(zod@4.4.3))(ws@8.21.3)(zod@4.4.3)': + '@earendil-works/pi-agent-core@0.84.1(@modelcontextprotocol/sdk@1.28.0(zod@4.4.3))(ws@8.21.3)(zod@4.4.3)': dependencies: - '@earendil-works/pi-ai': 0.82.1(@modelcontextprotocol/sdk@1.28.0(zod@4.4.3))(ws@8.21.3)(zod@4.4.3) + '@earendil-works/pi-ai': 0.84.1(@modelcontextprotocol/sdk@1.28.0(zod@4.4.3))(ws@8.21.3)(zod@4.4.3) + '@earendil-works/pi-telemetry': 0.84.1 diff: 8.0.4 ignore: 7.0.5 - typebox: 1.1.38 + typebox: 1.3.7 yaml: 2.9.0 transitivePeerDependencies: - '@modelcontextprotocol/sdk' @@ -8866,10 +8892,11 @@ snapshots: - ws - zod - '@earendil-works/pi-ai@0.82.1': + '@earendil-works/pi-ai@0.84.1': dependencies: '@anthropic-ai/sdk': 0.91.1 '@aws-sdk/client-bedrock-runtime': 3.1048.0 + '@earendil-works/pi-telemetry': 0.84.1 '@google/genai': 1.52.0 '@mistralai/mistralai': 2.2.6(@opentelemetry/api@1.9.0) '@opentelemetry/api': 1.9.0 @@ -8878,7 +8905,7 @@ snapshots: https-proxy-agent: 7.0.6 openai: 6.26.0 partial-json: 0.1.7 - typebox: 1.1.38 + typebox: 1.3.7 transitivePeerDependencies: - '@modelcontextprotocol/sdk' - bufferutil @@ -8887,10 +8914,11 @@ snapshots: - ws - zod - '@earendil-works/pi-ai@0.82.1(@modelcontextprotocol/sdk@1.28.0(zod@3.25.76))(ws@8.21.1)(zod@3.25.76)': + '@earendil-works/pi-ai@0.84.1(@modelcontextprotocol/sdk@1.28.0(zod@3.25.76))(ws@8.21.1)(zod@3.25.76)': dependencies: '@anthropic-ai/sdk': 0.91.1(zod@3.25.76) '@aws-sdk/client-bedrock-runtime': 3.1048.0 + '@earendil-works/pi-telemetry': 0.84.1 '@google/genai': 1.52.0(@modelcontextprotocol/sdk@1.28.0(zod@3.25.76)) '@mistralai/mistralai': 2.2.6(@opentelemetry/api@1.9.0) '@opentelemetry/api': 1.9.0 @@ -8899,7 +8927,7 @@ snapshots: https-proxy-agent: 7.0.6 openai: 6.26.0(ws@8.21.1)(zod@3.25.76) partial-json: 0.1.7 - typebox: 1.1.38 + typebox: 1.3.7 transitivePeerDependencies: - '@modelcontextprotocol/sdk' - bufferutil @@ -8908,10 +8936,11 @@ snapshots: - ws - zod - '@earendil-works/pi-ai@0.82.1(@modelcontextprotocol/sdk@1.28.0(zod@4.4.3))(ws@8.21.1)(zod@4.4.3)': + '@earendil-works/pi-ai@0.84.1(@modelcontextprotocol/sdk@1.28.0(zod@4.4.3))(ws@8.21.1)(zod@4.4.3)': dependencies: '@anthropic-ai/sdk': 0.91.1(zod@4.4.3) '@aws-sdk/client-bedrock-runtime': 3.1048.0 + '@earendil-works/pi-telemetry': 0.84.1 '@google/genai': 1.52.0(@modelcontextprotocol/sdk@1.28.0(zod@4.4.3)) '@mistralai/mistralai': 2.2.6(@opentelemetry/api@1.9.0) '@opentelemetry/api': 1.9.0 @@ -8920,7 +8949,7 @@ snapshots: https-proxy-agent: 7.0.6 openai: 6.26.0(ws@8.21.1)(zod@4.4.3) partial-json: 0.1.7 - typebox: 1.1.38 + typebox: 1.3.7 transitivePeerDependencies: - '@modelcontextprotocol/sdk' - bufferutil @@ -8929,10 +8958,11 @@ snapshots: - ws - zod - '@earendil-works/pi-ai@0.82.1(@modelcontextprotocol/sdk@1.28.0(zod@4.4.3))(ws@8.21.3)(zod@4.4.3)': + '@earendil-works/pi-ai@0.84.1(@modelcontextprotocol/sdk@1.28.0(zod@4.4.3))(ws@8.21.3)(zod@4.4.3)': dependencies: '@anthropic-ai/sdk': 0.91.1(zod@4.4.3) '@aws-sdk/client-bedrock-runtime': 3.1048.0 + '@earendil-works/pi-telemetry': 0.84.1 '@google/genai': 1.52.0(@modelcontextprotocol/sdk@1.28.0(zod@4.4.3)) '@mistralai/mistralai': 2.2.6(@opentelemetry/api@1.9.0) '@opentelemetry/api': 1.9.0 @@ -8941,7 +8971,7 @@ snapshots: https-proxy-agent: 7.0.6 openai: 6.26.0(ws@8.21.3)(zod@4.4.3) partial-json: 0.1.7 - typebox: 1.1.38 + typebox: 1.3.7 transitivePeerDependencies: - '@modelcontextprotocol/sdk' - bufferutil @@ -8950,16 +8980,23 @@ snapshots: - ws - zod - '@earendil-works/pi-coding-agent@0.82.1': + '@earendil-works/pi-client@0.84.1': dependencies: - '@earendil-works/pi-agent-core': 0.82.1 - '@earendil-works/pi-ai': 0.82.1 - '@earendil-works/pi-tui': 0.82.1 + '@earendil-works/pi-protocol': 0.84.1 + + '@earendil-works/pi-coding-agent@0.84.1': + dependencies: + '@earendil-works/pi-agent-core': 0.84.1 + '@earendil-works/pi-ai': 0.84.1 + '@earendil-works/pi-client': 0.84.1 + '@earendil-works/pi-protocol': 0.84.1 + '@earendil-works/pi-tui': 0.84.1 '@silvia-odwyer/photon-node': 0.3.4 chalk: 5.6.2 cross-spawn: 7.0.6 diff: 8.0.4 glob: 13.0.6 + grok-mermaid: 0.2.2 highlight.js: 10.7.3 hosted-git-info: 9.0.3 ignore: 7.0.5 @@ -8967,8 +9004,8 @@ snapshots: minimatch: 10.2.5 proper-lockfile: 4.1.2 semver: 7.8.0 - typebox: 1.1.38 - undici: 8.5.0 + typebox: 1.3.7 + undici: 8.9.0 yaml: 2.9.0 optionalDependencies: '@mariozechner/clipboard': 0.3.9 @@ -8980,16 +9017,19 @@ snapshots: - ws - zod - '@earendil-works/pi-coding-agent@0.82.1(@modelcontextprotocol/sdk@1.28.0(zod@3.25.76))(ws@8.21.1)(zod@3.25.76)': + '@earendil-works/pi-coding-agent@0.84.1(@modelcontextprotocol/sdk@1.28.0(zod@3.25.76))(ws@8.21.1)(zod@3.25.76)': dependencies: - '@earendil-works/pi-agent-core': 0.82.1(@modelcontextprotocol/sdk@1.28.0(zod@3.25.76))(ws@8.21.1)(zod@3.25.76) - '@earendil-works/pi-ai': 0.82.1(@modelcontextprotocol/sdk@1.28.0(zod@3.25.76))(ws@8.21.1)(zod@3.25.76) - '@earendil-works/pi-tui': 0.82.1 + '@earendil-works/pi-agent-core': 0.84.1(@modelcontextprotocol/sdk@1.28.0(zod@3.25.76))(ws@8.21.1)(zod@3.25.76) + '@earendil-works/pi-ai': 0.84.1(@modelcontextprotocol/sdk@1.28.0(zod@3.25.76))(ws@8.21.1)(zod@3.25.76) + '@earendil-works/pi-client': 0.84.1 + '@earendil-works/pi-protocol': 0.84.1 + '@earendil-works/pi-tui': 0.84.1 '@silvia-odwyer/photon-node': 0.3.4 chalk: 5.6.2 cross-spawn: 7.0.6 diff: 8.0.4 glob: 13.0.6 + grok-mermaid: 0.2.2 highlight.js: 10.7.3 hosted-git-info: 9.0.3 ignore: 7.0.5 @@ -8997,8 +9037,8 @@ snapshots: minimatch: 10.2.5 proper-lockfile: 4.1.2 semver: 7.8.0 - typebox: 1.1.38 - undici: 8.5.0 + typebox: 1.3.7 + undici: 8.9.0 yaml: 2.9.0 optionalDependencies: '@mariozechner/clipboard': 0.3.9 @@ -9010,16 +9050,19 @@ snapshots: - ws - zod - '@earendil-works/pi-coding-agent@0.82.1(@modelcontextprotocol/sdk@1.28.0(zod@4.4.3))(ws@8.21.1)(zod@4.4.3)': + '@earendil-works/pi-coding-agent@0.84.1(@modelcontextprotocol/sdk@1.28.0(zod@4.4.3))(ws@8.21.1)(zod@4.4.3)': dependencies: - '@earendil-works/pi-agent-core': 0.82.1(@modelcontextprotocol/sdk@1.28.0(zod@4.4.3))(ws@8.21.1)(zod@4.4.3) - '@earendil-works/pi-ai': 0.82.1(@modelcontextprotocol/sdk@1.28.0(zod@4.4.3))(ws@8.21.1)(zod@4.4.3) - '@earendil-works/pi-tui': 0.82.1 + '@earendil-works/pi-agent-core': 0.84.1(@modelcontextprotocol/sdk@1.28.0(zod@4.4.3))(ws@8.21.1)(zod@4.4.3) + '@earendil-works/pi-ai': 0.84.1(@modelcontextprotocol/sdk@1.28.0(zod@4.4.3))(ws@8.21.1)(zod@4.4.3) + '@earendil-works/pi-client': 0.84.1 + '@earendil-works/pi-protocol': 0.84.1 + '@earendil-works/pi-tui': 0.84.1 '@silvia-odwyer/photon-node': 0.3.4 chalk: 5.6.2 cross-spawn: 7.0.6 diff: 8.0.4 glob: 13.0.6 + grok-mermaid: 0.2.2 highlight.js: 10.7.3 hosted-git-info: 9.0.3 ignore: 7.0.5 @@ -9027,8 +9070,8 @@ snapshots: minimatch: 10.2.5 proper-lockfile: 4.1.2 semver: 7.8.0 - typebox: 1.1.38 - undici: 8.5.0 + typebox: 1.3.7 + undici: 8.9.0 yaml: 2.9.0 optionalDependencies: '@mariozechner/clipboard': 0.3.9 @@ -9040,16 +9083,19 @@ snapshots: - ws - zod - '@earendil-works/pi-coding-agent@0.82.1(@modelcontextprotocol/sdk@1.28.0(zod@4.4.3))(ws@8.21.3)(zod@4.4.3)': + '@earendil-works/pi-coding-agent@0.84.1(@modelcontextprotocol/sdk@1.28.0(zod@4.4.3))(ws@8.21.3)(zod@4.4.3)': dependencies: - '@earendil-works/pi-agent-core': 0.82.1(@modelcontextprotocol/sdk@1.28.0(zod@4.4.3))(ws@8.21.3)(zod@4.4.3) - '@earendil-works/pi-ai': 0.82.1(@modelcontextprotocol/sdk@1.28.0(zod@4.4.3))(ws@8.21.3)(zod@4.4.3) - '@earendil-works/pi-tui': 0.82.1 + '@earendil-works/pi-agent-core': 0.84.1(@modelcontextprotocol/sdk@1.28.0(zod@4.4.3))(ws@8.21.3)(zod@4.4.3) + '@earendil-works/pi-ai': 0.84.1(@modelcontextprotocol/sdk@1.28.0(zod@4.4.3))(ws@8.21.3)(zod@4.4.3) + '@earendil-works/pi-client': 0.84.1 + '@earendil-works/pi-protocol': 0.84.1 + '@earendil-works/pi-tui': 0.84.1 '@silvia-odwyer/photon-node': 0.3.4 chalk: 5.6.2 cross-spawn: 7.0.6 diff: 8.0.4 glob: 13.0.6 + grok-mermaid: 0.2.2 highlight.js: 10.7.3 hosted-git-info: 9.0.3 ignore: 7.0.5 @@ -9057,8 +9103,8 @@ snapshots: minimatch: 10.2.5 proper-lockfile: 4.1.2 semver: 7.8.0 - typebox: 1.1.38 - undici: 8.5.0 + typebox: 1.3.7 + undici: 8.9.0 yaml: 2.9.0 optionalDependencies: '@mariozechner/clipboard': 0.3.9 @@ -9070,7 +9116,13 @@ snapshots: - ws - zod - '@earendil-works/pi-tui@0.82.1': + '@earendil-works/pi-protocol@0.84.1': + dependencies: + typebox: 1.3.7 + + '@earendil-works/pi-telemetry@0.84.1': {} + + '@earendil-works/pi-tui@0.84.1': dependencies: get-east-asian-width: 1.6.0 marked: 18.0.5 @@ -9415,7 +9467,7 @@ snapshots: google-auth-library: 10.9.0 p-retry: 4.6.2 protobufjs: 7.6.5 - ws: 8.21.1 + ws: 8.21.3 transitivePeerDependencies: - bufferutil - supports-color @@ -9426,7 +9478,7 @@ snapshots: google-auth-library: 10.9.0 p-retry: 4.6.2 protobufjs: 7.6.5 - ws: 8.21.1 + ws: 8.21.3 optionalDependencies: '@modelcontextprotocol/sdk': 1.28.0(zod@3.25.76) transitivePeerDependencies: @@ -9439,7 +9491,7 @@ snapshots: google-auth-library: 10.9.0 p-retry: 4.6.2 protobufjs: 7.6.5 - ws: 8.21.1 + ws: 8.21.3 optionalDependencies: '@modelcontextprotocol/sdk': 1.28.0(zod@4.4.3) transitivePeerDependencies: @@ -9944,7 +9996,7 @@ snapshots: '@mistralai/mistralai@2.2.6(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/semantic-conventions': 1.43.0 - ws: 8.21.1 + ws: 8.21.3 zod: 3.25.76 zod-to-json-schema: 3.25.2(zod@3.25.76) optionalDependencies: @@ -12683,6 +12735,8 @@ snapshots: graceful-fs@4.2.11: {} + grok-mermaid@0.2.2: {} + hachure-fill@0.5.2: {} happy-dom@20.10.1: @@ -15322,6 +15376,8 @@ snapshots: typebox@1.1.38: {} + typebox@1.3.7: {} + typedarray@0.0.6: {} typescript-eslint@8.66.0(eslint@9.39.4(jiti@2.7.0))(typescript@5.9.3): @@ -15345,7 +15401,7 @@ snapshots: undici@7.29.0: {} - undici@8.5.0: {} + undici@8.9.0: {} unicorn-magic@0.3.0: {} @@ -15598,8 +15654,7 @@ snapshots: ws@8.21.1: {} - ws@8.21.3: - optional: true + ws@8.21.3: {} xml-name-validator@5.0.0: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index e5ec639e65..de64fcfce9 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -31,10 +31,16 @@ overrides: # FNXC:DesktopPackaging 2026-07-26-22:55: Advance the matched closure 0.82.0 → 0.82.1 so # electron-builder's production-dependency walk accepts pi-agent-core's pi-ai@^0.82.1 requirement # (Desktop packaging PR-lane failure when deploy resolved a newer agent-core patch beside 0.82.0 ai). - '@earendil-works/pi-agent-core': 0.82.1 - '@earendil-works/pi-ai': 0.82.1 - '@earendil-works/pi-coding-agent': 0.82.1 - '@earendil-works/pi-tui': 0.82.1 + # FNXC:DesktopPackaging 2026-08-12-20:46: Advance the matched closure 0.82.1 → 0.84.1. + # pi-coding-agent@0.84.1 adds pi-client and pi-protocol while pi-ai@0.84.1 adds pi-telemetry; + # none were in the pre-bump lockfile, so pin every sibling for electron-builder's lockfile-free walk. + '@earendil-works/pi-agent-core': 0.84.1 + '@earendil-works/pi-ai': 0.84.1 + '@earendil-works/pi-client': 0.84.1 + '@earendil-works/pi-coding-agent': 0.84.1 + '@earendil-works/pi-protocol': 0.84.1 + '@earendil-works/pi-telemetry': 0.84.1 + '@earendil-works/pi-tui': 0.84.1 # FNXC:DesktopEmbeddedPostgres 2026-07-14-09:30: # Desktop release jobs cross-build Intel and ARM64 artifacts on one host. Install # optional native payloads for both CPU families on the current OS so each diff --git a/scripts/__tests__/check-pi-versions-pinned.test.mjs b/scripts/__tests__/check-pi-versions-pinned.test.mjs index fb9293e396..098fbd7526 100644 --- a/scripts/__tests__/check-pi-versions-pinned.test.mjs +++ b/scripts/__tests__/check-pi-versions-pinned.test.mjs @@ -9,12 +9,12 @@ import { /* FNXC:DesktopPackaging 2026-07-26-22:55: -Fixture versions track the workspace's exact matched Pi runtime pin (currently 0.82.1). +Fixture versions track the workspace's exact matched Pi runtime pin (currently 0.84.1). Keep these in sync when advancing overrides/manifests so the policy guard still exercises matched-set and range rejection against the live pin surface. */ -const PINNED_VERSION = "0.82.1"; -const OTHER_VERSION = "0.82.0"; +const PINNED_VERSION = "0.84.1"; +const OTHER_VERSION = "0.84.0"; const pinnedManifest = { dependencies: { @@ -33,7 +33,7 @@ describe("check-pi-versions-pinned", () => { }); it("rejects caret, tilde, wildcard, x, and comparator ranges", () => { - for (const version of [`^${PINNED_VERSION}`, `~${PINNED_VERSION}`, "*", "0.82.x", `>=${PINNED_VERSION}`]) { + for (const version of [`^${PINNED_VERSION}`, `~${PINNED_VERSION}`, "*", "0.84.x", `>=${PINNED_VERSION}`]) { const violations = validate({ ...pinnedManifest, dependencies: { ...pinnedManifest.dependencies, "@earendil-works/pi-ai": version }, @@ -80,5 +80,24 @@ describe("check-pi-versions-pinned", () => { .some((violation) => violation.includes("one exact version")), true, ); + + for (const packageName of [ + "@earendil-works/pi-client", + "@earendil-works/pi-protocol", + "@earendil-works/pi-telemetry", + ]) { + assert.equal( + validateWorkspaceOverrides({ ...coherentOverrides, [packageName]: undefined }) + .some((violation) => violation.includes(packageName) && violation.includes("must be pinned")), + true, + `${packageName} must remain in the desktop closure`, + ); + assert.equal( + validateWorkspaceOverrides({ ...coherentOverrides, [packageName]: OTHER_VERSION }) + .some((violation) => violation.includes("one exact version")), + true, + `${packageName} must share the desktop closure pin`, + ); + } }); }); diff --git a/scripts/check-pi-versions-pinned.mjs b/scripts/check-pi-versions-pinned.mjs index a003d60056..3a482429f2 100644 --- a/scripts/check-pi-versions-pinned.mjs +++ b/scripts/check-pi-versions-pinned.mjs @@ -22,11 +22,19 @@ The legacy desktop deploy resolves pi-coding-agent's transitive pi-mono ranges without the workspace lockfile. Keep every Pi package in that staged runtime closure on one exact override so a new agent-core or tui patch cannot be hoisted beside older direct ai/coding-agent dependencies. + +FNXC:DesktopPackaging 2026-08-12-20:46: +pi-coding-agent@0.84.1 transitively adds pi-client and pi-protocol while pi-ai +adds pi-telemetry. Guard these siblings too so electron-builder's lockfile-free +production walk cannot hoist them into a split Pi runtime closure. */ export const PI_RUNTIME_PACKAGES = [ "@earendil-works/pi-agent-core", "@earendil-works/pi-ai", + "@earendil-works/pi-client", "@earendil-works/pi-coding-agent", + "@earendil-works/pi-protocol", + "@earendil-works/pi-telemetry", "@earendil-works/pi-tui", ];