Files
tutti/packages/agent/gui/agent-gui/agentGuiNode/model/agentSlashCommandProviderPolicy.spec.ts
agent-radar 2ed3415fb7
Publish Claude Code Binaries / Stage and publish binaries (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-arm64 (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build linux-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build windows-amd64 (push) Canceled after 0s
Sync Tutti Agent Skills / sync (push) Canceled after 0s
Windows Agent Adapters / Test Windows agent adapters (push) Canceled after 0s
Windows Daemon Adapters / Test Windows daemon adapters (push) Canceled after 0s
Publish Tutti App Runtime / Publish runtime catalog (push) Canceled after 0s
源码快照 @ 2026-09-01 (source-only, 剔除非源码素材)
2026-09-01 20:17:27 +08:00

849 lines
24 KiB
TypeScript

import { describe, expect, it } from "vitest";
import {
resolveSlashCommandsForProvider,
resolveSlashCommandSelectionEffect,
resolveSlashCommandSubmitEffect
} from "./agentSlashCommandProviderPolicy";
import type { AgentSlashCommandPolicy } from "./agentSlashCommandProviderPolicy";
const CODEX_POLICY = {
fallbackCommands: ["compact", "status", "fast", "goal", "review"],
commandEffects: [
{ command: "init", effect: "submitImmediate" },
{ command: "compact", effect: "submitImmediate" },
{ command: "review", effect: "showReviewPicker" },
{ command: "goal", effect: "activateGoalMode" },
{ command: "plan", effect: "togglePlanMode" },
{ command: "status", effect: "showStatus" },
{ command: "fast", effect: "toggleSpeed" }
]
} as const;
const CLAUDE_POLICY = {
fallbackCommands: ["compact", "status", "fast", "goal", "review"],
commandCatalogAuthoritative: true,
commandEffects: [
{ command: "compact", effect: "submitImmediate" },
{ command: "context", effect: "submitImmediate" },
{ command: "usage", effect: "submitImmediate" },
{ command: "review", effect: "showReviewPicker" },
{ command: "goal", effect: "activateGoalMode" },
{ command: "plan", effect: "togglePlanMode" },
{ command: "status", effect: "showStatus" },
{ command: "fast", effect: "toggleSpeed" }
]
} as const;
const CURSOR_POLICY = {
fallbackCommands: ["plan"],
commandCatalogAuthoritative: true,
commandEffects: [{ command: "plan", effect: "togglePlanMode" }]
} as const;
const OPENCODE_POLICY = {
fallbackCommands: ["compact", "goal", "review"],
commandEffects: [
{ command: "compact", effect: "submitImmediate" },
{ command: "review", effect: "showReviewPicker" },
{ command: "goal", effect: "activateGoalMode" },
{ command: "plan", effect: "togglePlanMode" }
]
} as const;
describe("agentSlashCommandProviderPolicy", () => {
const reviewPickerProviders = ["codex", "claude-code"] as const;
it("surfaces compatible Plan and Tutti modifiers as independent slash entries", () => {
const commands = resolveSlashCommandsForProvider({
provider: "codex",
policy: CODEX_POLICY,
commands: [],
planSupported: true,
tuttiSupported: true
});
expect(commands.map((command) => command.name)).toEqual([
"compact",
"status",
"fast",
"goal",
"review",
"plan",
"tutti"
]);
expect(
resolveSlashCommandSelectionEffect({
provider: "codex",
policy: CODEX_POLICY,
command: commands.find((command) => command.name === "plan")!,
currentDraft: "/plan"
})
).toEqual({ kind: "enablePlanMode" });
expect(
resolveSlashCommandSelectionEffect({
provider: "codex",
policy: CODEX_POLICY,
command: commands.find((command) => command.name === "tutti")!,
currentDraft: "/tutti"
})
).toEqual({ kind: "activateTuttiMode" });
});
it("activates Tutti mode independently without synthesizing a capability reference or agent prompt", () => {
const commands = resolveSlashCommandsForProvider({
provider: "claude-code",
policy: CLAUDE_POLICY,
commands: [],
tuttiSupported: true
});
expect(
resolveSlashCommandSubmitEffect({
provider: "claude-code",
policy: CLAUDE_POLICY,
commands,
draft: "/tutti",
tuttiSupported: true
})
).toEqual({ kind: "activateTuttiMode" });
});
it("keeps /tutti arguments in the draft for normal agent submission", () => {
const commands = resolveSlashCommandsForProvider({
provider: "codex",
policy: CODEX_POLICY,
commands: [],
tuttiSupported: true
});
expect(
resolveSlashCommandSubmitEffect({
provider: "codex",
policy: CODEX_POLICY,
commands,
draft: "/tutti inspect the failing tests",
tuttiSupported: true
})
).toBeNull();
});
it("reserves the local Tutti command when a provider advertises the same name", () => {
const commands = resolveSlashCommandsForProvider({
provider: "extension-provider",
commands: [{ name: "tutti" }, { name: "provider-status" }],
tuttiSupported: true
});
expect(commands.map((command) => command.name)).toEqual([
"provider-status",
"tutti"
]);
const tutti = commands.find((command) => command.name === "tutti")!;
expect("kind" in tutti && tutti.kind).toBe("capability");
expect(
resolveSlashCommandSubmitEffect({
provider: "extension-provider",
commands,
draft: "/tutti",
tuttiSupported: true
})
).toEqual({ kind: "activateTuttiMode" });
});
it("reserves the local Plan command when Plan is supported", () => {
const commands = resolveSlashCommandsForProvider({
provider: "codex",
policy: CODEX_POLICY,
commands: [{ name: "plan" }],
planSupported: true
});
expect(commands.filter((command) => command.name === "plan")).toEqual([
{ name: "plan" }
]);
});
it("adds browser-use as a composer capability when browser use is supported", () => {
const commands = resolveSlashCommandsForProvider({
provider: "codex",
policy: CODEX_POLICY,
commands: [],
browserSupported: true
});
expect(
commands.find(
(command) => "kind" in command && command.kind === "capability"
)
).toEqual({
kind: "capability",
capability: "browserUse",
name: "browser",
aliases: ["浏览器"]
});
});
it("keeps OpenCode descriptor commands beside browser capability entries", () => {
expect(
resolveSlashCommandsForProvider({
provider: "opencode",
policy: OPENCODE_POLICY,
commands: [],
planSupported: true,
browserSupported: true
}).map((command) => command.name)
).toEqual(["compact", "goal", "review", "plan", "browser"]);
});
it("fills a canonical browser token from Chinese and English slash capability names", () => {
const commands = resolveSlashCommandsForProvider({
provider: "codex",
policy: CODEX_POLICY,
commands: [],
browserSupported: true
});
expect(
resolveSlashCommandSelectionEffect({
provider: "codex",
policy: CODEX_POLICY,
command: commands.find((command) => command.name === "browser")!,
currentDraft: "/浏览"
})
).toEqual({ kind: "enableBrowserUse", draft: "/browser " });
expect(
resolveSlashCommandSubmitEffect({
provider: "codex",
policy: CODEX_POLICY,
commands,
draft: "/浏览器",
browserSupported: true
})
).toEqual({
kind: "submitPrompt",
prompt: expect.stringContaining("browser-use"),
displayPrompt: "/browser",
requiredSettingsPatch: { browserUse: true }
});
expect(
resolveSlashCommandSubmitEffect({
provider: "extension-provider",
browserSupported: true,
commands,
draft: "/browser打开百度"
})
).toEqual({
kind: "submitPrompt",
prompt: expect.stringMatching(/browser-use[\s\S]*打开百度/),
displayPrompt: "/browser 打开百度",
requiredSettingsPatch: { browserUse: true }
});
expect(
resolveSlashCommandSubmitEffect({
provider: "codex",
policy: CODEX_POLICY,
browserSupported: true,
commands,
draft: "$browser 帮我访问下 google.com"
})
).toEqual({
kind: "submitPrompt",
prompt: expect.stringContaining("帮我访问下 google.com"),
displayPrompt: "/browser 帮我访问下 google.com",
requiredSettingsPatch: { browserUse: true }
});
expect(
resolveSlashCommandSubmitEffect({
provider: "codex",
policy: CODEX_POLICY,
browserSupported: false,
commands,
draft: "$browser test"
})
).toBeNull();
});
it("routes computer capability invocations through the local computer-use handoff", () => {
const commands = resolveSlashCommandsForProvider({
provider: "claude-code",
policy: CLAUDE_POLICY,
commands: [],
computerSupported: true
});
expect(
resolveSlashCommandSelectionEffect({
provider: "claude-code",
policy: CLAUDE_POLICY,
command: commands.find((command) => command.name === "computer")!,
currentDraft: "/comp"
})
).toEqual({ kind: "enableComputerUse", draft: "/computer " });
expect(
resolveSlashCommandSubmitEffect({
provider: "claude-code",
policy: CLAUDE_POLICY,
computerSupported: true,
commands,
draft: "/computer 你好"
})
).toEqual({
kind: "submitPrompt",
prompt: expect.stringMatching(/computer-use[\s\S]*你好/),
displayPrompt: "/computer 你好",
requiredSettingsPatch: { computerUse: true }
});
expect(
resolveSlashCommandSubmitEffect({
provider: "claude-code",
policy: CLAUDE_POLICY,
computerSupported: true,
commands,
draft: "$电脑 点击确认"
})
).toEqual({
kind: "submitPrompt",
prompt: expect.stringMatching(/computer-use[\s\S]*点击确认/),
displayPrompt: "/computer 点击确认",
requiredSettingsPatch: { computerUse: true }
});
expect(
resolveSlashCommandSubmitEffect({
provider: "claude-code",
policy: CLAUDE_POLICY,
computerSupported: false,
commands,
draft: "/computer test"
})
).toBeNull();
});
it("adds Codex compact, status, fast, goal, and review fallback commands after provider commands", () => {
expect(
resolveSlashCommandsForProvider({
provider: "codex",
policy: CODEX_POLICY,
commands: [{ name: "web" }, { name: "compact", description: "ACP" }]
})
).toEqual([
{ name: "web" },
{ name: "compact", description: "ACP" },
{ name: "status" },
{ name: "fast" },
{ name: "goal" },
{ name: "review" }
]);
});
it("adds Claude Code fallback commands including goal when SDK commands are empty", () => {
expect(
resolveSlashCommandsForProvider({
provider: "claude-code",
policy: CLAUDE_POLICY,
commands: []
}).map((command) => command.name)
).toEqual(["compact", "status", "fast", "goal", "review"]);
});
it("keeps noisy Claude Code discovered commands out of the slash palette", () => {
expect(
resolveSlashCommandsForProvider({
provider: "claude-code",
policy: CLAUDE_POLICY,
commands: [
{ name: "browser-use-tutti-10" },
{ name: "lark-mail" },
{ name: "context", description: "Show context" },
{ name: "goal" },
{ name: "security-review" },
{ name: "usage" }
]
}).map((command) => command.name)
).toEqual([
"context",
"goal",
"usage",
"compact",
"status",
"fast",
"review"
]);
});
it("trusts typed Claude Code policy commands instead of the legacy allowlist", () => {
expect(
resolveSlashCommandsForProvider({
provider: "claude-code",
policy: {
fallbackCommands: ["custom-command"],
commandCatalogAuthoritative: true,
commandEffects: []
},
commands: [{ name: "descriptor-command" }]
}).map((command) => command.name)
).toEqual(["custom-command"]);
});
it("filters compact when the session has no compactable context", () => {
expect(
resolveSlashCommandsForProvider({
provider: "codex",
policy: CODEX_POLICY,
commands: [{ name: "compact", description: "from provider" }],
hasCompactableContext: false
})
).toEqual([
{ name: "status" },
{ name: "fast" },
{ name: "goal" },
{ name: "review" }
]);
});
it("filters Claude Code plan commands from provider and fallback commands", () => {
expect(
resolveSlashCommandsForProvider({
provider: "claude-code",
policy: CLAUDE_POLICY,
commands: [{ name: "plan", description: "provider plan" }]
})
).toEqual([
{ name: "compact" },
{ name: "status" },
{ name: "fast" },
{ name: "goal" },
{ name: "review" }
]);
});
it("submits Codex init and compact commands immediately", () => {
expect(
resolveSlashCommandSelectionEffect({
provider: "codex",
policy: CODEX_POLICY,
command: { name: "init" },
currentDraft: "/"
})
).toEqual({ kind: "submitPrompt", prompt: "/init" });
expect(
resolveSlashCommandSelectionEffect({
provider: "codex",
policy: CODEX_POLICY,
command: { name: " compact " },
currentDraft: "/"
})
).toEqual({ kind: "submitPrompt", prompt: "/compact" });
});
it("does not apply legacy immediate-command behavior over a typed policy", () => {
expect(
resolveSlashCommandSelectionEffect({
provider: "codex",
policy: { fallbackCommands: ["compact"], commandEffects: [] },
command: { name: "compact" },
currentDraft: "/"
})
).toEqual({ kind: "fillDraft", draft: "/compact " });
});
it("activates goal mode instead of filling a raw /goal draft", () => {
expect(
resolveSlashCommandSelectionEffect({
provider: "codex",
policy: CODEX_POLICY,
command: { name: "web" },
currentDraft: "/"
})
).toEqual({ kind: "fillDraft", draft: "/web " });
expect(
resolveSlashCommandSelectionEffect({
provider: "codex",
policy: CODEX_POLICY,
command: { name: "goal" },
currentDraft: "/"
})
).toEqual({ kind: "activateGoalMode" });
});
it("does not infer Codex goal behavior when the typed policy omits it", () => {
expect(
resolveSlashCommandSelectionEffect({
provider: "codex",
policy: { fallbackCommands: ["goal"], commandEffects: [] },
command: { name: "goal" },
currentDraft: "/"
})
).toEqual({ kind: "fillDraft", draft: "/goal " });
});
it("handles Codex local status without provider prompts", () => {
expect(
resolveSlashCommandSelectionEffect({
provider: "codex",
policy: CODEX_POLICY,
command: { name: "status" },
currentDraft: "/sta"
})
).toEqual({ kind: "showStatus" });
expect(
resolveSlashCommandSelectionEffect({
provider: "codex",
policy: CODEX_POLICY,
command: { name: "plan" },
currentDraft: "/pla"
})
).toEqual({ kind: "enablePlanMode" });
});
it("handles Claude Code local status without provider prompts", () => {
expect(
resolveSlashCommandSelectionEffect({
provider: "claude-code",
policy: CLAUDE_POLICY,
command: { name: "status" },
currentDraft: "/sta"
})
).toEqual({ kind: "showStatus" });
expect(
resolveSlashCommandSelectionEffect({
provider: "claude-code",
policy: CLAUDE_POLICY,
command: { name: "plan" },
currentDraft: "/pla"
})
).toEqual({ kind: "enablePlanMode" });
});
it("submits advertised Claude Code compact command as provider-native prompt", () => {
expect(
resolveSlashCommandSelectionEffect({
provider: "claude-code",
policy: CLAUDE_POLICY,
command: { name: "compact" },
currentDraft: "/"
})
).toEqual({ kind: "submitPrompt", prompt: "/compact" });
});
it("activates goal mode for Claude Code goal command selection", () => {
expect(
resolveSlashCommandSelectionEffect({
provider: "claude-code",
policy: CLAUDE_POLICY,
command: { name: "goal" },
currentDraft: "/"
})
).toEqual({ kind: "activateGoalMode" });
});
it("parses manual Codex status and toggles plan mode on submit", () => {
const commands = resolveSlashCommandsForProvider({
provider: "codex",
policy: CODEX_POLICY,
commands: [],
planSupported: true
});
expect(
resolveSlashCommandSubmitEffect({
provider: "codex",
policy: CODEX_POLICY,
commands,
draft: "/status"
})
).toEqual({ kind: "showStatus" });
expect(
resolveSlashCommandSubmitEffect({
provider: "codex",
policy: CODEX_POLICY,
commands,
draft: "/plan"
})
).toEqual({ kind: "enablePlanMode" });
expect(
resolveSlashCommandSubmitEffect({
provider: "codex",
policy: CODEX_POLICY,
commands,
draft: "/goal"
})
).toEqual({ kind: "activateGoalMode" });
});
it("parses manual Claude Code status and toggles plan mode on submit", () => {
const commands = resolveSlashCommandsForProvider({
provider: "claude-code",
policy: CLAUDE_POLICY,
commands: [],
planSupported: true
});
expect(
resolveSlashCommandSubmitEffect({
provider: "claude-code",
policy: CLAUDE_POLICY,
commands,
draft: "/status"
})
).toEqual({ kind: "showStatus" });
expect(
resolveSlashCommandSubmitEffect({
provider: "claude-code",
policy: CLAUDE_POLICY,
commands,
draft: "/plan"
})
).toEqual({ kind: "enablePlanMode" });
expect(
resolveSlashCommandSubmitEffect({
provider: "claude-code",
policy: CLAUDE_POLICY,
commands,
draft: "/plan refactor auth"
})
).toBeNull();
});
it("surfaces /plan only when plan mode is supported", () => {
expect(
resolveSlashCommandsForProvider({
provider: "codex",
policy: CODEX_POLICY,
commands: [{ name: "plan" }],
planSupported: false
}).some((command) => command.name === "plan")
).toBe(false);
expect(
resolveSlashCommandsForProvider({
provider: "codex",
policy: CODEX_POLICY,
commands: [],
planSupported: true
}).filter((command) => command.name === "plan")
).toHaveLength(1);
});
it("surfaces only /plan for Cursor and hides agent-advertised slash commands", () => {
expect(
resolveSlashCommandsForProvider({
provider: "cursor",
policy: CURSOR_POLICY,
commands: [
{ name: "compact" },
{ name: "goal" },
{ name: "review" },
{ name: "browser-use-tutti-10" }
],
planSupported: true
}).map((command) => command.name)
).toEqual(["plan"]);
expect(
resolveSlashCommandsForProvider({
provider: "cursor",
policy: CURSOR_POLICY,
commands: [{ name: "plan", description: "provider plan" }],
planSupported: false
})
).toEqual([]);
});
it("keeps runtime commands provider-native when a descriptor policy is missing", () => {
expect(
resolveSlashCommandsForProvider({
provider: "cursor",
commands: [{ name: "plan" }, { name: "compact" }],
planSupported: true
})
).toEqual([{ name: "plan" }, { name: "compact" }]);
expect(
resolveSlashCommandSelectionEffect({
provider: "cursor",
command: { name: "plan" },
currentDraft: "/"
})
).toEqual({ kind: "fillDraft", draft: "/plan " });
});
it("shows open-provider runtime commands without a descriptor policy", () => {
expect(
resolveSlashCommandsForProvider({
provider: "other-provider",
commands: [{ name: "compact" }]
})
).toEqual([{ name: "compact" }]);
});
it("shows extension fallback commands when command effects are absent", () => {
const policy = {
fallbackCommands: ["compact", "status"],
commandCatalogAuthoritative: true
} as unknown as AgentSlashCommandPolicy;
expect(
resolveSlashCommandsForProvider({
provider: "acp:hermes",
policy,
commands: []
})
).toEqual([{ name: "compact" }, { name: "status" }]);
});
it("keeps non-plan advertised Claude Code controls provider-native", () => {
expect(
resolveSlashCommandSubmitEffect({
provider: "claude-code",
policy: CLAUDE_POLICY,
commands: resolveSlashCommandsForProvider({
provider: "claude-code",
policy: CLAUDE_POLICY,
commands: [{ name: "context", description: "provider context" }]
}),
draft: "/context"
})
).toEqual({ kind: "submitPrompt", prompt: "/context" });
});
it("does not intercept unknown slash text", () => {
expect(
resolveSlashCommandSubmitEffect({
provider: "codex",
policy: CODEX_POLICY,
commands: resolveSlashCommandsForProvider({
provider: "codex",
policy: CODEX_POLICY,
commands: []
}),
draft: "/unknown"
})
).toBeNull();
});
it.each(reviewPickerProviders)(
"opens the review picker when picking %s /review from the palette",
(provider) => {
expect(
resolveSlashCommandSelectionEffect({
provider,
policy: provider === "codex" ? CODEX_POLICY : CLAUDE_POLICY,
command: { name: "review", description: "Review code changes" },
currentDraft: "/rev"
})
).toEqual({ kind: "showReviewPicker" });
}
);
it.each(reviewPickerProviders)(
"opens the review picker when submitting bare /review on %s",
(provider) => {
const commands = resolveSlashCommandsForProvider({
provider,
policy: provider === "codex" ? CODEX_POLICY : CLAUDE_POLICY,
commands: [{ name: "review", description: "Review code changes" }]
});
expect(
resolveSlashCommandSubmitEffect({
provider,
policy: provider === "codex" ? CODEX_POLICY : CLAUDE_POLICY,
commands,
draft: "/review"
})
).toEqual({ kind: "showReviewPicker" });
}
);
it.each(reviewPickerProviders)(
"opens the review picker from %s fallback /review before provider commands arrive",
(provider) => {
const commands = resolveSlashCommandsForProvider({
provider,
policy: provider === "codex" ? CODEX_POLICY : CLAUDE_POLICY,
commands: [],
hasCompactableContext: false
});
expect(commands.map((command) => command.name)).toContain("review");
expect(
resolveSlashCommandSubmitEffect({
provider,
policy: provider === "codex" ? CODEX_POLICY : CLAUDE_POLICY,
commands,
draft: "/review"
})
).toEqual({ kind: "showReviewPicker" });
}
);
it.each(reviewPickerProviders)(
"submits /review <text> straight through as a %s custom review",
(provider) => {
const commands = resolveSlashCommandsForProvider({
provider,
policy: provider === "codex" ? CODEX_POLICY : CLAUDE_POLICY,
commands: [{ name: "review", description: "Review code changes" }]
});
expect(
resolveSlashCommandSubmitEffect({
provider,
policy: provider === "codex" ? CODEX_POLICY : CLAUDE_POLICY,
commands,
draft: "/review check the auth flow"
})
).toBeNull();
}
);
it("keeps review provider-native for unknown providers", () => {
expect(
resolveSlashCommandSelectionEffect({
provider: "other-provider",
command: { name: "review", description: "Review" },
currentDraft: "/rev"
})
).toEqual({ kind: "fillDraft", draft: "/review " });
});
});
describe("compact capability gating", () => {
const policy = {
commandCatalogAuthoritative: true,
commandEffects: [],
fallbackCommands: ["compact", "status"]
};
it("keeps descriptor compact when capability is unknown", () => {
const commands = resolveSlashCommandsForProvider({
provider: "codex",
commands: [{ name: "compact" }, { name: "status" }],
policy
});
expect(commands.some((command) => command.name === "compact")).toBe(true);
});
it("keeps compact when capability resolves true", () => {
const commands = resolveSlashCommandsForProvider({
provider: "codex",
commands: [{ name: "compact" }],
compactSupported: true,
policy
});
expect(commands.some((command) => command.name === "compact")).toBe(true);
});
it("drops compact (including fallback) when capability resolves false", () => {
const commands = resolveSlashCommandsForProvider({
provider: "codex",
commands: [{ name: "compact" }, { name: "status" }],
compactSupported: false,
policy
});
expect(commands.some((command) => command.name === "compact")).toBe(false);
expect(commands.some((command) => command.name === "status")).toBe(true);
});
});