From dad466d696d9906625e5311f8494e73181073675 Mon Sep 17 00:00:00 2001 From: Mohamed Boudra Date: Wed, 4 Nov 2026 06:30:29 +0100 Subject: [PATCH] test(plugins): a Command Center agent item reaches the composer through the real client state The command-path test now reads workspace and agent through createPluginClientStateSource over seeded session stores, so an empty lookup, which makes the Command Center return before calling the item, would fail it. Also records at the focused-agent publisher that it publishes in an effect. --- .../plugins/command-center/registration.tsx | 3 ++ .../src/plugins/composer-items/source.test.ts | 43 ++++++------------- 2 files changed, 16 insertions(+), 30 deletions(-) diff --git a/packages/app/src/plugins/command-center/registration.tsx b/packages/app/src/plugins/command-center/registration.tsx index 2e5090d88f..9686aab731 100644 --- a/packages/app/src/plugins/command-center/registration.tsx +++ b/packages/app/src/plugins/command-center/registration.tsx @@ -40,6 +40,9 @@ export function PluginCommandCenterActions() { }); const handedAgentId = agentExists ? focusedAgentId : null; // The agent a plugin's `{ focused: true }` composer names is the one handed to agent items. + // Known limit: this publishes in an effect, so a command that runs on the first commit after a + // route change can still see the previous route's agent. Publishing from a shared + // navigation/focus context would remove the gap. useEffect(() => { publishFocusedAgent(serverId && handedAgentId ? { serverId, agentId: handedAgentId } : null); return () => publishFocusedAgent(null); diff --git a/packages/app/src/plugins/composer-items/source.test.ts b/packages/app/src/plugins/composer-items/source.test.ts index 4e55fb813c..c6e1ab1cd1 100644 --- a/packages/app/src/plugins/composer-items/source.test.ts +++ b/packages/app/src/plugins/composer-items/source.test.ts @@ -1,13 +1,13 @@ import { defineRpc } from "@getpaseo/plugin"; import type { DaemonClient } from "@getpaseo/client/internal/daemon-client"; -import type { PluginAgentSnapshot, PluginWorkspaceSnapshot } from "@getpaseo/plugin"; import { PluginTranslationRuntime } from "@getpaseo/plugin/client/host"; import { QueryClient } from "@tanstack/react-query"; import { z } from "zod"; import { afterEach, beforeEach, describe, expect, it } from "vitest"; import { queryClient } from "@/data/query-client"; import { useDraftStore } from "@/stores/draft-store"; -import { useSessionStore, type Agent } from "@/stores/session-store"; +import { useSessionStore, type Agent, type WorkspaceDescriptor } from "@/stores/session-store"; +import { createPluginClientStateSource } from "../client-state/source"; import { buildPluginCommandCenterContributions } from "../command-center/contributions"; import { publishFocusedAgent } from "../focused-agent"; import type { InstalledPlugin } from "../types"; @@ -167,40 +167,26 @@ describe("a plugin's composers by reference", () => { }); describe("a Command Center item reaching an agent's composer by id", () => { - const snapshot: PluginAgentSnapshot = { - id: "agent-1", - workspaceId: "workspace-1", - provider: "claude", - status: "idle", - createdAt: "2026-08-16T10:00:00.000Z", - updatedAt: "2026-08-16T10:00:00.000Z", - lastActivityAt: "2026-08-16T10:00:00.000Z", - title: null, - cwd: "/repo", - model: null, - currentModeId: null, - thinkingOptionId: null, - requiresAttention: false, - attentionReason: null, - parentAgentId: null, - labels: {}, - metadata: {}, - }; - - const workspace: PluginWorkspaceSnapshot = { + // The real client-state source reads these stores. A lookup that came back empty would make the + // Command Center return before calling the item, and nothing would be reported. + const workspace: WorkspaceDescriptor = { + createdAt: null, + lastUserMessageAt: null, id: "workspace-1", projectId: "project-1", projectDisplayName: "Repo", projectRootPath: "/repo", - directory: "/repo", + workspaceDirectory: "/repo", projectKind: "git", - kind: "checkout", + workspaceKind: "checkout", name: "Repo", title: null, + pinnedAt: null, status: "running", statusEnteredAt: null, archivingAt: null, diffStat: null, + scripts: [], }; function markForReview(rejection?: Error) { @@ -214,6 +200,7 @@ describe("a Command Center item reaching an agent's composer by id", () => { useSessionStore.getState().clearSession(serverId); useSessionStore.getState().initializeSession(serverId, client); useSessionStore.getState().setAgents(serverId, new Map([["agent-1", agent("agent-1")]])); + useSessionStore.getState().setWorkspaces(serverId, new Map([[workspace.id, workspace]])); const installed = plugin(); installed.commandCenterItems = [ { @@ -231,11 +218,7 @@ describe("a Command Center item reaching an agent's composer by id", () => { const reported: unknown[] = []; const [item] = buildPluginCommandCenterContributions({ plugins: [installed], - state: { - subscribe: () => () => {}, - getWorkspace: () => workspace, - getAgent: () => snapshot, - }, + state: createPluginClientStateSource(serverId), workspaceId: "workspace-1", agentId: "agent-1", navigation: {