Files
pi-auto-reinject/test/commands-no-ui.test.ts
T
grayhook 502ca39b3e Phase 12: RPC no-ui command safety — SPEC §11.
Slash commands persist state changes in hasUI=false mode without calling notify; export handler for regression tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-17 13:13:42 +07:00

84 lines
2.3 KiB
TypeScript

import { describe, expect, it, vi } from "vitest";
import { handleSkillReinjectCommand } from "../src/commands";
import { createInitialState, createRuntimeFlags } from "../src/state";
function createNoUiCommandContext() {
const notify = vi.fn();
return {
hasUI: false,
mode: "rpc" as const,
ui: { notify, setStatus: vi.fn() },
cwd: process.cwd(),
isProjectTrusted: () => true,
isIdle: () => true,
};
}
function createDeps() {
const state = createInitialState();
const persistState = vi.fn();
const pi = {
sendUserMessage: vi.fn(),
registerCommand: vi.fn(),
appendEntry: vi.fn(),
};
return {
state,
persistState,
pi,
runtime: createRuntimeFlags(),
getRegisteredSkills: () => [],
};
}
describe("handleSkillReinjectCommand without UI", () => {
it("does not throw on status", async () => {
const ctx = createNoUiCommandContext();
const deps = createDeps();
await expect(handleSkillReinjectCommand("", ctx as never, deps as never)).resolves.toBeUndefined();
expect(ctx.ui.notify).not.toHaveBeenCalled();
});
it("persists session toggle without notify", async () => {
const ctx = createNoUiCommandContext();
const deps = createDeps();
await handleSkillReinjectCommand("on", ctx as never, deps as never);
expect(deps.state.sessionOverride).toBe(true);
expect(deps.persistState).toHaveBeenCalledTimes(1);
expect(ctx.ui.notify).not.toHaveBeenCalled();
});
it("clears tracked skills without notify", async () => {
const ctx = createNoUiCommandContext();
const deps = createDeps();
deps.state.skills.push({
name: "alpha",
filePath: "/a/SKILL.md",
baseDir: "/a",
firstSeenAt: 1,
lastSeenAt: 1,
sources: ["slash"],
});
await handleSkillReinjectCommand("clear", ctx as never, deps as never);
expect(deps.state.skills).toEqual([]);
expect(deps.persistState).toHaveBeenCalledTimes(1);
expect(ctx.ui.notify).not.toHaveBeenCalled();
});
it("persists integration override without notify", async () => {
const ctx = createNoUiCommandContext();
const deps = createDeps();
await handleSkillReinjectCommand("integration defer", ctx as never, deps as never);
expect(deps.state.sessionIntegrationOverride).toBe("defer");
expect(deps.persistState).toHaveBeenCalledTimes(1);
expect(ctx.ui.notify).not.toHaveBeenCalled();
});
});