mirror of
https://github.com/getpaseo/paseo.git
synced 2026-07-29 12:01:31 +00:00
Show Claude skills in inline autocomplete
This commit is contained in:
@@ -999,6 +999,88 @@ describe("ClaudeAgentSession context window usage", () => {
|
||||
expect(persistedQueryFactory.mock.calls[0]?.[0].options.persistSession).toBe(true);
|
||||
});
|
||||
|
||||
test("classifies Claude root-only commands separately from inline skills", async () => {
|
||||
const queryFactory = vi.fn(({ prompt }: { prompt: AsyncIterable<unknown> }) => {
|
||||
void prompt;
|
||||
return {
|
||||
next: async () => ({ done: true, value: undefined }),
|
||||
interrupt: async () => undefined,
|
||||
return: async () => undefined,
|
||||
close: () => undefined,
|
||||
setPermissionMode: async () => undefined,
|
||||
setModel: async () => undefined,
|
||||
supportedModels: async () => [],
|
||||
supportedCommands: async () => [
|
||||
{
|
||||
name: "taste",
|
||||
description: "Use when another skill needs the shared standard. (user)",
|
||||
argumentHint: "",
|
||||
},
|
||||
{
|
||||
name: "claude-api",
|
||||
description: "Build, debug, and optimize Claude API apps with this skill.",
|
||||
argumentHint: "",
|
||||
},
|
||||
{
|
||||
name: "usage",
|
||||
description: "Show the total cost and duration of the current session",
|
||||
argumentHint: "",
|
||||
},
|
||||
{
|
||||
name: "clear",
|
||||
description: "Start a new session with empty context",
|
||||
argumentHint: "",
|
||||
},
|
||||
],
|
||||
rewindFiles: async () => ({ canRewind: true }),
|
||||
[Symbol.asyncIterator]() {
|
||||
return this;
|
||||
},
|
||||
};
|
||||
});
|
||||
const client = new ClaudeAgentClient({
|
||||
logger,
|
||||
queryFactory,
|
||||
resolveBinary: async () => "/test/claude/bin",
|
||||
});
|
||||
const session = await client.createSession({ provider: "claude", cwd: process.cwd() });
|
||||
|
||||
const commands = await session.listCommands();
|
||||
await session.close();
|
||||
|
||||
expect(commands).toEqual([
|
||||
{
|
||||
name: "claude-api",
|
||||
description: "Build, debug, and optimize Claude API apps with this skill.",
|
||||
argumentHint: "",
|
||||
kind: "skill",
|
||||
},
|
||||
{
|
||||
name: "clear",
|
||||
description: "Start a new session with empty context",
|
||||
argumentHint: "",
|
||||
kind: "command",
|
||||
},
|
||||
{
|
||||
name: "rewind",
|
||||
description: "Rewind tracked files to a previous user message",
|
||||
argumentHint: "[user_message_uuid]",
|
||||
},
|
||||
{
|
||||
name: "taste",
|
||||
description: "Use when another skill needs the shared standard. (user)",
|
||||
argumentHint: "",
|
||||
kind: "skill",
|
||||
},
|
||||
{
|
||||
name: "usage",
|
||||
description: "Show the total cost and duration of the current session",
|
||||
argumentHint: "",
|
||||
kind: "command",
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
test("deletes the persisted session jsonl on close when persistSession=false", async () => {
|
||||
const tmpConfigDir = await fs.mkdtemp(path.join(os.tmpdir(), "paseo-claude-persist-"));
|
||||
const previousConfigDir = process.env.CLAUDE_CONFIG_DIR;
|
||||
|
||||
@@ -302,6 +302,18 @@ const REWIND_COMMAND: AgentSlashCommand = {
|
||||
description: "Rewind tracked files to a previous user message",
|
||||
argumentHint: "[user_message_uuid]",
|
||||
};
|
||||
const CLAUDE_ROOT_ONLY_COMMANDS = new Set([
|
||||
"clear",
|
||||
"compact",
|
||||
"context",
|
||||
"debug",
|
||||
"extra-usage",
|
||||
"heapdump",
|
||||
"init",
|
||||
"loop",
|
||||
"schedule",
|
||||
"usage",
|
||||
]);
|
||||
const INTERRUPT_TOOL_USE_PLACEHOLDER = "[Request interrupted by user for tool use]";
|
||||
const INTERRUPT_PLACEHOLDER_PATTERN = /^\[Request interrupted by user(?:[^\]]*)\]$/;
|
||||
const NO_RESPONSE_REQUESTED_PLACEHOLDER = "No response requested.";
|
||||
@@ -313,6 +325,13 @@ interface SlashCommandInvocation {
|
||||
rawInput: string;
|
||||
}
|
||||
|
||||
function classifyClaudeSlashCommand(commandName: string): AgentSlashCommand["kind"] {
|
||||
// Claude exposes commands and skills as one flat SDK list, without structured source
|
||||
// metadata. Keep obvious root-only/session controls out of inline autocomplete and
|
||||
// treat the rest as skills; the worst failure mode is an inert inline suggestion.
|
||||
return CLAUDE_ROOT_ONLY_COMMANDS.has(commandName) ? "command" : "skill";
|
||||
}
|
||||
|
||||
type ClaudeAgentConfig = AgentSessionConfig & { provider: "claude" };
|
||||
|
||||
export interface ClaudeContentChunk {
|
||||
@@ -2137,7 +2156,7 @@ class ClaudeAgentSession implements AgentSession {
|
||||
name: cmd.name,
|
||||
description: cmd.description,
|
||||
argumentHint: cmd.argumentHint,
|
||||
kind: "command",
|
||||
kind: classifyClaudeSlashCommand(cmd.name),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user