1
>
/*---------------------------------------------------------------------------------------------
claudeBuiltinCommands.ts
2
>
* Copyright (c) Microsoft Corporation. All rights reserved.
3
>
* Licensed under the MIT License. See License.txt in the project root for license information.
4
>
*--------------------------------------------------------------------------------------------*/
5
>
6
>
import { URI } from '../../../../../base/common/uri.js';
7
>
import { localize } from '../../../../../nls.js';
8
>
import { CustomizationType } from '../../../common/state/protocol/channels-session/state.js';
9
>
import { CustomizationLoadStatus, customizationId, type DirectoryCustomization, type SkillCustomization } from '../../../common/state/sessionState.js';
10
>
11
>
/**
12
>
* URI scheme for synthetic "built-in" customizations that have no editable
13
>
* file on disk. These entries appear in the customization list purely for
14
>
* discovery (their name and description); they carry no openable content.
15
>
*/
16
>
const AGENT_BUILTIN_SCHEME = 'agent-builtin';
17
>
18
>
/**
19
>
* A Claude built-in slash command backed by the Skill tool, used to seed the
20
>
* **pre-materialize** built-in list. These ship compiled into the Claude
21
>
* CLI/SDK — they have no editable file on disk and, before a live session
22
>
* exists, the SDK can't tell us its real command set, so we show a curated
23
>
* best-guess list for discoverability.
24
>
*
25
>
* Once a session materializes, {@link buildSdkBuiltinSkillsContainer} replaces
26
>
* this list with the runtime's actual built-ins (the SDK commands we don't
27
>
* discover on disk), so this list only matters pre-session and may safely
28
>
* drift from the CLI over time.
29
>
*
30
>
* This list covers the Skill-tool built-ins only. The CLI-level built-ins
31
>
* typed directly in the terminal (`/help`, `/clear`, `/compact`, `/config`,
32
>
* `/fast`, `/model`, `/tasks`, `/workflows`) are intentionally excluded —
33
>
* they are not skills and would be mislabeled in a Skills container.
34
>
*/
35
>
interface IClaudeBuiltinCommand {
36
>
readonly name: string;
37
>
/**
38
>
* User-facing description, resolved lazily so `localize()` runs at call
39
>
* time rather than module-init (which would freeze the bundle locale).
40
>
*/
41
>
readonly description: () => string;
42
>
}
43
>
44
>
const CLAUDE_BUILTIN_COMMANDS: readonly IClaudeBuiltinCommand[] = [
45
>
{ name: 'init', description: () => localize('claude.builtin.init', "(Built-In) Scan the codebase and generate a `CLAUDE.md` file with project structure, conventions, and instructions for future sessions.") },
46
>
{ name: 'review', description: () => localize('claude.builtin.review', "(Built-In) Review a pull request or set of changes.") },
47
>
{ name: 'security-review', description: () => localize('claude.builtin.securityReview', "(Built-In) Complete a security review of the pending changes on the current branch.") },
48
>
{ name: 'code-review', description: () => localize('claude.builtin.codeReview', "(Built-In) Review the current diff for correctness bugs and reuse/simplification/efficiency cleanups at a chosen effort level (low→max). Pass `--comment` to post findings as inline PR comments, or `--fix` to apply them to the working tree.") },
49
>
{ name: 'simplify', description: () => localize('claude.builtin.simplify', "(Built-In) Review changed code for reuse, simplification, efficiency, and altitude cleanups, then apply the fixes. Quality only — it doesn't hunt for bugs (use `/code-review` for that).") },
50
>
{ name: 'verify', description: () => localize('claude.builtin.verify', "(Built-In) Run the app and observe behavior to confirm a code change actually does what it's supposed to. Use to verify a PR, confirm a fix, or validate local changes before pushing.") },
51
>
{ name: 'run', description: () => localize('claude.builtin.run', "(Built-In) Launch and drive the project's app to see a change working — run, start, or screenshot the app, or confirm a change works in the real app (not just tests).") },
52
>
{ name: 'loop', description: () => localize('claude.builtin.loop', "(Built-In) Run a prompt or slash command on a recurring interval (e.g. `/loop 5m /foo`, defaults to 10m). For recurring tasks or polling status — not one-off work.") },
53
>
{ name: 'claude-api', description: () => localize('claude.builtin.claudeApi', "(Built-In) Reference for the Claude API / Anthropic SDK: model IDs, pricing, params, streaming, tool use, MCP, agents, caching, token counting, migration.") },
54
>
{ name: 'fewer-permission-prompts', description: () => localize('claude.builtin.fewerPermissionPrompts', "(Built-In) Scan transcripts for common read-only Bash/MCP calls and add a prioritized allowlist to project `.claude/settings.json` to reduce permission prompts.") },
55
>
{ name: 'update-config', description: () => localize('claude.builtin.updateConfig', "(Built-In) Configure the Claude Code harness via `settings.json`: hooks for automated behaviors, permissions, env vars, and hook troubleshooting.") },
56
>
{ name: 'keybindings-help', description: () => localize('claude.builtin.keybindingsHelp', "(Built-In) Customize keyboard shortcuts, rebind keys, add chord bindings, or modify `~/.claude/keybindings.json`.") },
57
>
{ name: 'write-a-skill', description: () => localize('claude.builtin.writeASkill', "(Built-In) Author a new skill.") },
58
>
];
59
>
60
>
/**
61
>
* A Claude built-in subagent, used to seed the **pre-materialize** agent list.
62
>
* These ship compiled into the Claude CLI/SDK (no editable file on disk), so
63
>
* before a live session exists we surface a curated best-guess set for
64
>
* discovery and selection. Once a session materializes, the live
65
>
* `supportedAgents()` set supersedes this (see the SDK fallback in
66
>
* `buildDiscoveredCustomizations`), so the list may safely drift over time.
67
>
*
68
>
* Includes the SDK default (`general-purpose`) for completeness; the discovery
69
>
* layer hides it (selecting it is equivalent to "no selection"). The model
70
>
* each agent runs on is folded into the description since the customization
71
>
* surface has no model field.
72
>
*/
73
>
export interface IClaudeBuiltinAgent {
74
>
readonly name: string;
75
>
/** User-facing description, resolved lazily (see {@link IClaudeBuiltinCommand.description}). */
76
>
readonly description: () => string;
77
>
}
78
>
79
>
export const CLAUDE_BUILTIN_AGENTS: readonly IClaudeBuiltinAgent[] = [
80
>
{ name: 'claude', description: () => localize('claude.builtinAgent.claude', "(Built-In) Catch-all for any task that doesn't fit a more specific agent — the default when no agent name is typed.") },
81
>
{ name: 'claude-code-guide', description: () => localize('claude.builtinAgent.claudeCodeGuide', "(Built-In) Answers questions about the Claude Agent SDK, and the Claude/Anthropic API — features, hooks, slash commands, MCP servers, settings, IDE integrations, SDK agent-building, and API usage. Model: Haiku.") },
82
>
{ name: 'Explore', description: () => localize('claude.builtinAgent.explore', "(Built-In) Read-only search agent for broad fan-out searches across many files when you only need the conclusion; it locates code rather than reviewing it. Model: Haiku.") },
83
>
{ name: 'general-purpose', description: () => localize('claude.builtinAgent.generalPurpose', "(Built-In) General-purpose agent for researching complex questions, searching for code, and executing multi-step tasks.") },
84
>
{ name: 'Plan', description: () => localize('claude.builtinAgent.plan', "(Built-In) Software architect agent for designing implementation plans — step-by-step plans, critical files, and architectural trade-offs.") },
85
>
];
86
>
87
>
/**
88
>
* A resolved built-in skill entry ready to become a read-only customization.
89
>
* Structurally matches the SDK's `SlashCommand` (`{ name, description }`), so
90
>
* the live command set can be passed straight through.
91
>
*/
92
>
interface IBuiltinSkillEntry {
93
>
readonly name: string;
94
>
readonly description: string;
95
>
}
96
>
97
>
/**
98
>
* Builds the read-only "Built-in" skills container from resolved
99
>
* `{ name, description }` entries. Each child is a {@link CustomizationType.Skill}
100
>
* on the {@link AGENT_BUILTIN_SCHEME}; the name and description shown in the
101
>
* list are the discovery information it carries (the entries have no openable
102
>
* content). Returns `undefined` when there are no entries.
103
>
*/
104
function buildBuiltinSkillsContainer(entries: readonly IBuiltinSkillEntry[]): DirectoryCustomization | undefined {
105
if (entries.length === 0) {