feat(rpc): add validated desktop Pi RPC command palette
This commit is contained in:
@@ -1,16 +1,73 @@
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import { legacyPreferences, removeLegacyPreferences, presentationState } from "./persistence";
|
||||
import { initialWorkspaceState, reconcileWorkspace, workspaceReducer } from "./reducer";
|
||||
import {
|
||||
legacyPreferences,
|
||||
removeLegacyPreferences,
|
||||
presentationState,
|
||||
} from "./persistence";
|
||||
import {
|
||||
initialWorkspaceState,
|
||||
reconcileWorkspace,
|
||||
workspaceReducer,
|
||||
} from "./reducer";
|
||||
import type { Workspace } from "./types";
|
||||
const workspace: Workspace = { bridgeInstanceId: "e", latestSeq: 7, directories: [{ worktreePath: "/repo", isHome: true, openCount: 1, workingCount: 0, attentionCount: 0, recoveringCount: 0, errorCount: 0, runtimes: [{ runtimeId: "r", worktreePath: "/repo", state: "idle", label: "r", attention: false, queueCount: 0, lastActivity: "now", openedAt: "now", agentId: "ephemeral" }] }] };
|
||||
const workspace: Workspace = {
|
||||
bridgeInstanceId: "e",
|
||||
latestSeq: 7,
|
||||
directories: [
|
||||
{
|
||||
worktreePath: "/repo",
|
||||
isHome: true,
|
||||
openCount: 1,
|
||||
workingCount: 0,
|
||||
attentionCount: 0,
|
||||
recoveringCount: 0,
|
||||
errorCount: 0,
|
||||
runtimes: [
|
||||
{
|
||||
runtimeId: "r",
|
||||
worktreePath: "/repo",
|
||||
state: "idle",
|
||||
label: "r",
|
||||
attention: false,
|
||||
queueCount: 0,
|
||||
lastActivity: "now",
|
||||
openedAt: "now",
|
||||
agentId: "ephemeral",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
describe("presentation persistence", () => {
|
||||
it("persists only allowlisted presentation state, never agent or session payloads", () => {
|
||||
let state = reconcileWorkspace(initialWorkspaceState, workspace); state = workspaceReducer(state, { type: "draftChanged", runtimeId: "r", draft: "safe draft" });
|
||||
const persisted = presentationState(state); const encoded = JSON.stringify(persisted);
|
||||
expect(persisted.drafts.r).toBe("safe draft"); expect(encoded).not.toContain("ephemeral"); expect(encoded).not.toContain("messages"); expect(encoded).not.toContain("extensions");
|
||||
});
|
||||
it("reads and removes legacy worktree/scale only after caller saves", () => {
|
||||
const getItem = vi.fn((key: string) => key.includes("selected") ? "/repo" : "1.2"); expect(legacyPreferences({ getItem })).toEqual({ path: "/repo", scale: 1.2 });
|
||||
const removeItem = vi.fn(); removeLegacyPreferences({ removeItem }); expect(removeItem).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
it("persists only allowlisted presentation state, never agent or session payloads", () => {
|
||||
let state = reconcileWorkspace(initialWorkspaceState, workspace);
|
||||
state = workspaceReducer(state, {
|
||||
type: "draftChanged",
|
||||
runtimeId: "r",
|
||||
draft: "safe draft",
|
||||
});
|
||||
state = workspaceReducer(state, {
|
||||
type: "setDefaultNewSessionWorktree",
|
||||
worktreePath: "/repo",
|
||||
});
|
||||
const persisted = presentationState(state);
|
||||
const encoded = JSON.stringify(persisted);
|
||||
expect(persisted.drafts.r).toBe("safe draft");
|
||||
expect(persisted.defaultNewSessionWorktree).toBe("/repo");
|
||||
expect(encoded).not.toContain("ephemeral");
|
||||
expect(encoded).not.toContain("messages");
|
||||
expect(encoded).not.toContain("extensions");
|
||||
});
|
||||
it("reads and removes legacy worktree/scale only after caller saves", () => {
|
||||
const getItem = vi.fn((key: string) =>
|
||||
key.includes("selected") ? "/repo" : "1.2",
|
||||
);
|
||||
expect(legacyPreferences({ getItem })).toEqual({
|
||||
path: "/repo",
|
||||
scale: 1.2,
|
||||
});
|
||||
const removeItem = vi.fn();
|
||||
removeLegacyPreferences({ removeItem });
|
||||
expect(removeItem).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user