Claude Code 源码分析第 13 课 · 第 04
第 13 课

命令系统

如何在 REPL 内键入、注册、组装成管道、在输入时处理以及分派斜杠命令

1. 什么是命令?

Every /something 您输入的 Claude Code 是 Command — 一个 TypeScript 对象,它携带元数据(名称、描述、可用性)以及三种执行策略之一(本地、本地 jsx 或提示)。 命令位于 src/commands.tssrc/commands/ 目录树。

顶级类型是受歧视联合:

src/types/command.ts — 核心联合
export type Command = CommandBase &
  (PromptCommand | LocalCommand | LocalJSXCommand)

判别式是 type 字段 — 每个命令对象必须准确声明三个字符串文字之一: "local", "local-jsx", 或者 "prompt".

注册了 80 多个内置命令 COMMANDS(),加上从技能目录、插件、工作流程和 MCP 服务器加载的任意数量的动态 — 所有这些都在运行时通过 getCommands(cwd).

2. 三种命令类型

local

Local

纯 TypeScript 函数。 在当前进程中同步运行。 返回一个 LocalCommandResult - 任何一个 {type:'text'}, {type:'compact'}, 或者 {type:'skip'}.

/清除、/紧凑、/成本
local-jsx

JSX 位置

将 React/Ink 组件渲染到终端 TUI 中。 返回一个 ReactNode 通过 call(onDone, context, args) 签名。 阻止桥接/远程模式。

/帮助、/模型、/配置、/内存
prompt

Prompt

扩展到发送到模型的文本内容块。 声明 getPromptForCommand(args, context) 返回 ContentBlockParam[]。 为技能、工作流程和内置代理流程提供支持。

/提交、/审查、/init、/安全审查

类型决策树

flowchart TD A[User types /cmd] --> B{Does it need\nto render UI?} B -- Yes --> C[local-jsx\ne.g. /model, /help] B -- No --> D{Does it call\nthe AI model?} D -- Yes --> E[prompt\ne.g. /commit, /review] D -- No --> F[local\ne.g. /clear, /compact, /cost] style C fill:#1f1249,stroke:#8e82ad,color:#b8b0a4 style E fill:#2a1900,stroke:#c47a50,color:#b8b0a4 style F fill:#0a2a16,stroke:#6e9468,color:#b8b0a4
深潜: local - 这 /compact command

注册于 src/commands/compact/index.ts:

const compact = {
  type: 'local',
  name: 'compact',
  description: 'Clear conversation history but keep a summary in context',
  isEnabled: () => !isEnvTruthy(process.env.DISABLE_COMPACT),
  supportsNonInteractive: true,
  argumentHint: '<optional custom summarization instructions>',
  load: () => import('./compact.js'),
} satisfies Command

The load() 模式对于本地命令来说是通用的——它将繁重的实现模块推迟到实际调用命令之前,从而保持快速启动。 该模块必须导出 { call: LocalCommandCall }:

export const call: LocalCommandCall = async (args, context) => {
  // args = trimmed string after "/compact"
  // context = ToolUseContext + REPL state
  const customInstructions = args.trim()
  // ... runs compaction, returns:
  return { type: 'compact', compactionResult, displayText }
}

The LocalCommandCall 签名总是收到 (args: string, context: LocalJSXCommandContext) — 一个原始参数字符串(命令名称后面的所有内容)和一个丰富的上下文对象,其中包括消息、setMessages、选项和中止控制器。

深潜: local-jsx - 这 /help command

注册于 src/commands/help/index.ts:

const help = {
  type: 'local-jsx',
  name: 'help',
  description: 'Show help and available commands',
  load: () => import('./help.js'),
} satisfies Command

加载的模块导出 { call: LocalJSXCommandCall }:

export const call: LocalJSXCommandCall = async (
  onDone,
  { options: { commands } },
) => {
  return <HelpV2 commands={commands} onClose={onDone} />
}

请注意 颠倒论证顺序 与本地命令相比: (onDone, context, args)。 这 onDone 回调接受可选的字符串结果加上选项,例如 shouldQuery, display, 和 nextInput。 什么时候 onDone() 触发后,REPL 会拆除组件并恢复正常输入。

The /model 命令使用相同的模式,但为其描述添加了一个计算的 getter,因此它始终反映当前选定的模型名称:

export default {
  type: 'local-jsx',
  name: 'model',
  get description() {
    return `Set the AI model (currently ${renderModelName(getMainLoopModel())})`
  },
  argumentHint: '[model]',
  get immediate() {
    return shouldInferenceConfigCommandBeImmediate()
  },
  load: () => import('./model.js'),
}
深潜: prompt - 这 /commit command

提示命令定义 getPromptForCommand 而不是 load。 他们返回一个数组 ContentBlockParam 命令触发时成为第一个用户转动的对象:

const command = {
  type: 'prompt',
  name: 'commit',
  description: 'Create a git commit',
  allowedTools: ['Bash(git add:*)', 'Bash(git status:*)', 'Bash(git commit:*)'],
  contentLength: 0,  // 0 = dynamic (computed at call time)
  progressMessage: 'creating commit',
  source: 'builtin',
  async getPromptForCommand(_args, context) {
    const promptContent = getPromptContent()
    const finalContent = await executeShellCommandsInPrompt(
      promptContent, context, '/commit'
    )
    return [{ type: 'text', text: finalContent }]
  },
} satisfies Command

The executeShellCommandsInPrompt 助手扫描提示 !`shell cmd` 反引号模式并在文本到达模型之前将其替换为实时 shell 输出。 就是这样 /commit 内联当前 git status, git diff HEAD,最近登录会自动提示。

allowedTools 限制模型在此命令执行期间可以调用哪些工具 - 一个安全层,可防止模型调用声明列表之外的任何内容。

3. CommandBase 合约

所有这三种类型都有一个共同的基础。 最重要的领域:

Field Type Description
namestring斜杠命令名称,例如 "compact"。 用户类型 /compact.
descriptionstring显示在预先输入和 /help。 可以是动态描述的吸气剂。
aliasesstring[]?替代名称。 /clear 也回应 /reset and /new.
isEnabled() => boolean功能标志或环境变量保护。 每一次都被称为新鲜 getCommands() pass.
isHiddenboolean?隐藏预输入和帮助 UI,同时仍允许调用。
availabilityCommandAvailability[]?授权门: 'claude-ai' (订阅者)或 'console' (API 密钥用户)。
argumentHintstring?预先输入命令名称后显示的灰色提示,例如 [model].
immediateboolean?If true,命令运行时无需等待任何正在进行的 AI 请求停止。
loadedFromstring?来源标签: 'skills', 'plugin', 'bundled', 'commands_DEPRECATED', 'mcp'.
whenToUsestring?面向模型的使用提示(来自 SKILL.md frontmatter)。 控制技能工具的可见性。
isSensitiveboolean?如果为真,则从对话历史记录中编辑命令参数。
isEnabled 与可用性: availability 是在功能标志之前运行的静态身份验证提供程序检查 - 它控制 谁能看到 命令。 isEnabled() 是对功能标志和环境变量的运行时检查 - 它控制 该命令现在是否处于活动状态。 两者都必须通过命令才能出现在 getCommands().

4. 注册流程

命令通过多级汇编管道到达 REPL src/commands.ts:

静态命令()
+
技能目录
+
Plugins
+
Workflows
loadAllCommands(cwd)
过滤器(可用性+ isEnabled)
getCommands(cwd)

第 1 阶段:静态核心命令 (COMMANDS())

记忆函数返回约 80 个内置命令的规范列表 - /help, /model, /clear, /compact, /commit, /review等等。它被声明为函数(而不是常量),以便在启动时配置可读后执行:

src/commands.ts
const COMMANDS = memoize((): Command[] => [
  addDir, advisor, agents, branch, btw,
  clear, compact, config, cost, diff, ...
  // feature-flagged commands are spread conditionally:
  ...(ultraplan ? [ultraplan] : []),
  ...(!isUsing3PServices() ? [logout, login()] : []),
])

第 2 阶段:动态命令源 (loadAllCommands)

所有非静态源都是并行加载和合并的。 合并顺序是确定性的,对于重复数据删除很重要:

src/commands.ts — loadAllCommands
const loadAllCommands = memoize(async (cwd: string) => {
  const [
    { skillDirCommands, pluginSkills, bundledSkills, builtinPluginSkills },
    pluginCommands,
    workflowCommands,
  ] = await Promise.all([
    getSkills(cwd),
    getPluginCommands(),
    getWorkflowCommands ? getWorkflowCommands(cwd) : Promise.resolve([]),
  ])

  return [
    ...bundledSkills,         // lowest index → highest priority in dedup
    ...builtinPluginSkills,
    ...skillDirCommands,
    ...workflowCommands,
    ...pluginCommands,
    ...pluginSkills,
    ...COMMANDS(),            // built-ins last
  ]
})

第三阶段:过滤和动态技能插入(getCommands)

每次致电 getCommands(cwd) 重新运行可用性并针对记忆的命令池进行 isEnabled 检查。 动态技能(在文件操作期间发现)插入到内置命令块之前:

src/commands.ts — getCommands
export async function getCommands(cwd: string): Promise<Command[]> {
  const allCommands = await loadAllCommands(cwd)
  const dynamicSkills = getDynamicSkills()

  const baseCommands = allCommands.filter(
    _ => meetsAvailabilityRequirement(_) && isCommandEnabled(_)
  )
  // Insert dynamic skills at the right position...
}
四种技能来源及其起源

技能(从 Markdown 文件加载的提示类型命令)从四个地方到达: getSkills(cwd):

  • skillDirCommands — 加载自 .claude/skills/ 在项目或用户主页中。 这些是您或您的团队编写的 SKILL.md 文件。
  • pluginSkills - 已安装插件中捆绑的技能(例如 /plugin install frontend-design@claude-plugins-official).
  • bundledSkills — 技能编译到 Claude Code 二进制文件本身中(在启动时通过同步注册 getBundledSkills()).
  • builtinPluginSkills - 来自始终启用的内置插件的技能,通过 getBuiltinPluginSkillCommands().

如果任何源加载失败,则会捕获并记录错误,但其余部分继续 - 技能加载故意是非致命的。

INTERNAL_ONLY_COMMANDS — 内部构建门

命令子集仅存在于 Anthropic 内部版本中。 它们被声明在 INTERNAL_ONLY_COMMANDS 并且仅附加到 COMMANDS() when process.env.USER_TYPE === 'ant':

export const INTERNAL_ONLY_COMMANDS = [
  backfillSessions,
  breakCache,
  bughunter,
  commit,
  commitPushPr,
  mockLimits,
  bridgeKick,
  // ...many more
].filter(Boolean)

// Inside COMMANDS():
...(!process.env.IS_DEMO && process.env.USER_TYPE === 'ant'
  ? INTERNAL_ONLY_COMMANDS : [])

这意味着像这样的命令 /commit and /bughunter 实际上,公共二进制文件中不存在它们 - 它们被 Bun 的捆绑程序消除了死代码。

5. 输入处理

当用户提交以以下内容开头的文本时 /,REPL 在任何内容接触模型之前运行查找和分派。 关键帮手住在最底层 src/commands.ts:

查找功能

src/commands.ts — 查找/有/获取
// Returns the first Command matching by name, userFacingName, or alias
export function findCommand(commandName: string, commands: Command[]): Command | undefined

// Presence check (wraps findCommand)
export function hasCommand(commandName: string, commands: Command[]): boolean

// Throws ReferenceError listing all available commands if not found
export function getCommand(commandName: string, commands: Command[]): Command

The findCommand 匹配器按顺序检查三件事: _.name === commandName, getCommandName(_) === commandName (面向用户的覆盖),以及 _.aliases?.includes(commandName)。 这就是为什么 /reset and /new 两者都会触发清除命令。

参数传递

命令名称(已修剪)之后的所有内容都是 参数字符串。 没有框架级参数解析——每个命令负责解释自己的参数。 /compact focus on the database layer delivers "focus on the database layer" 到紧凑处理程序,该处理程序将其传递到汇总模型,如下所示 customInstructions.

提示中的 Shell 命令替换

提示命令通常内联嵌入 shell 输出。 这 executeShellCommandsInPrompt 实用程序扫描提示文本 !`shell command` 模式并在提示到达模型之前将其替换为实时输出。 /commit 使用它来自动注入 git status, git diff HEAD,以及最近的日志输出:

src/commands/commit.ts — 提示模板摘录
const PROMPT = `## Context

- Current git status: !\`git status\`
- Current git diff: !\`git diff HEAD\`
- Current branch: !\`git branch --show-current\`
- Recent commits: !\`git log --oneline -10\`

## Your task
Based on the above changes, create a single git commit...`

UI 与模型的描述格式

The formatDescriptionWithSource(cmd) 实用程序为面向用户的表面(提前输入、帮助屏幕)添加出处注释,而不会污染面向模型的描述。 来自名为“frontend-design”的插件的技能显示为 "(frontend-design) Polish and refine UI components" 在自动完成中,但模型只看到 "Polish and refine UI components".

6. REPL 集成

REPL(读取-评估-打印循环)是交互式会话的核心。 它通过渲染 launchRepl in src/replLauncher.tsx,它会延迟加载 App and REPL 墨水成分。 命令根据其类型以三个不同的调度路径流过 REPL:

sequenceDiagram participant U as User Input participant R as REPL participant LC as LocalCommand participant LJ as LocalJSX participant PC as PromptCommand participant M as Model U->>R: /compact "focus on DB" R->>R: findCommand("compact") R->>LC: load() then call(args, ctx) LC-->>R: {type:'compact', ...} R->>R: update messages state U->>R: /model R->>LJ: load() then call(onDone, ctx, args) LJ-->>R: ReactNode (renders picker UI) R->>R: onDone() → resume input U->>R: /commit R->>PC: getPromptForCommand(args, ctx) PC-->>R: ContentBlockParam[] R->>M: send as user turn M-->>R: streaming response

processSlash命令流程

在 REPL 内部,斜杠命令处理遵循以下顺序:

1. 解析输入→commandName + args 2.findCommand(命令名,命令) 3.检查立即标志 4. 按类型调度 5. 处理结果/拆卸

The immediate 命令上的标志绕过了正常的“等待任何正在进行的 AI 请求停止”行为。 /status sets immediate: true 因此,即使长时间生成正在运行,您也可以检查连接状态。

按类型处理结果

TypeDispatchPost-dispatch
local await cmd.load() then call(args, ctx) 如果结果是 {type:'compact'}, REPL 替换消息。 如果 {type:'text'},添加系统消息。 如果 {type:'skip'},什么也不做。
local-jsx await cmd.load() 然后渲染返回 ReactNode REPL 安装组件。 什么时候 onDone(result, opts) 触发:卸载,可选地附加结果,可选地调用模型,如果 opts.shouldQuery = true.
prompt await cmd.getPromptForCommand(args, ctx) Returned ContentBlockParam[] 成为第一条用户留言。 REPL 进入查询模式,就像用户键入该文本一样。 progressMessage 显示在状态行中。
onDone 回调合约 (local-jsx)

The LocalJSXCommandOnDone 回调比看起来更丰富。 完整签名:

type LocalJSXCommandOnDone = (
  result?: string,
  options?: {
    display?: 'skip' | 'system' | 'user'  // default: 'user'
    shouldQuery?: boolean               // send messages to model after done
    metaMessages?: string[]            // model-visible but hidden from UI
    nextInput?: string                 // pre-fill the input box
    submitNextInput?: boolean          // auto-submit nextInput
  }
) => void

这意味着 JSX 命令可以在关闭时自动将预先编写的消息注入到模型管道中 - 例如 模型选择器可以在模型选择后自动提交确认。

非交互模式(无头CLI)

当 Claude Code 在非交互(无头)模式下运行时(例如 claude -p "..."), 本地命令可以声明 supportsNonInteractive: true 保持可用。 /compact and /cost 两者都这样做。 由于没有终端 TUI,JSX 命令在无头模式下始终被阻止。

提示命令声明 disableNonInteractive: true 当它们依赖于交互状态(例如活动会话消息)时。 执行繁重模型工作的内置提示命令通常在两种模式下都可以工作。

7. 可用性和功能门控

命令有两个独立的门层,在命令出现在 REPL 中之前,两者都必须经过:

availability

授权提供商门

检查者 meetsAvailabilityRequirement(cmd)。 两个可能的值: 'claude-ai' (需要 OAuth 订户)或 'console' (需要直接 API 密钥用户)。 没有此字段的命令将无条件通过。 每一次都重新评估 getCommands() 调用 so auth 之后更改 /login 立即生效。

isEnabled

运行时功能门

一个功能 () => boolean。 可以通过读取 GrowthBook 标志 feature('FLAG_NAME')、环境变量、平台检查或任何其他运行时条件。 每次过滤都被称为新鲜。 命令不带 isEnabled 默认为 true.

src/commands.ts — 满足AvailabilityRequirement
export function meetsAvailabilityRequirement(cmd: Command): boolean {
  if (!cmd.availability) return true
  for (const a of cmd.availability) {
    switch (a) {
      case 'claude-ai':
        if (isClaudeAISubscriber()) return true; break
      case 'console':
        if (!isClaudeAISubscriber() && !isUsing3PServices()
            && isFirstPartyAnthropicBaseUrl()) return true; break
    }
  }
  return false
}

功能标记命令

仅当 Bun 捆绑包功能标志处于活动状态时,才存在多个命令。 在构建时,如果该功能关闭,Bun 的死代码消除会删除整个 require 链:

src/commands.ts — 条件要求模式
const ultraplan = feature('ULTRAPLAN')
  ? require('./commands/ultraplan.js').default
  : null

const voiceCommand = feature('VOICE_MODE')
  ? require('./commands/voice/index.js').default
  : null

// Then in COMMANDS():
...(ultraplan ? [ultraplan] : []),
...(voiceCommand ? [voiceCommand] : []),

8. 缓存管理

命令加载的成本很高——它涉及磁盘 I/O、YAML 解析、动态导入和 MCP 往返。 三层记忆可快速重复调用:

CacheKey它存储什么
COMMANDS() 无(单例) 静态内置命令列表。 清除者 clearCommandMemoizationCaches().
loadAllCommands cwd string 合并给定工作目录的所有来源的命令池。
getSkillToolCommands cwd string 符合 SkillTool 模型调用条件的筛选提示命令。

针对不同的失效场景,存在两种粒度明确的函数:

src/commands.ts
// Clears command memoization only — does NOT clear skill file caches.
// Use when dynamic skills are added mid-session.
export function clearCommandMemoizationCaches(): void {
  loadAllCommands.cache?.clear?.()
  getSkillToolCommands.cache?.clear?.()
  getSlashCommandToolSkills.cache?.clear?.()
  clearSkillIndexCache?.()  // outer search index must also be cleared
}

// Full reset: command + plugin + skill file caches.
// Use when plugins are installed/removed or skills dir changes.
export function clearCommandsCache(): void {
  clearCommandMemoizationCaches()
  clearPluginCommandCache()
  clearPluginSkillsCache()
  clearSkillCaches()
}
Important: meetsAvailabilityRequirement and isCommandEnabled 是故意的 not 已记忆——每次都会对它们进行重新评估 getCommands() 称呼。 这确保了 /login 或者 GrowthBook 标志翻转立即生效,无需缓存清除。

9. 桥接和远程模式

Claude Code 可以在 远程模式 (通过浏览器/移动设备访问)并且可以通过 bridge (远程控制协议)。 两种模式都限制可用的命令。

远程安全命令(--remote 标志)

当 Claude Code 开头时 --remote,仅命令 REMOTE_SAFE_COMMANDS 在 CCR 初始化消息到达之前可用。 这些命令仅影响本地 TUI 状态,不会影响文件系统、git、shell 或 IDE:

src/commands.ts — REMOTE_SAFE_COMMANDS(子集)
export const REMOTE_SAFE_COMMANDS: Set<Command> = new Set([
  session,    // Shows QR code / URL for remote session
  exit,       // Exit the TUI
  clear,      // Clear screen
  help,       // Show help
  theme,      // Change terminal theme
  cost,       // Show session cost
  plan,       // Plan mode toggle
  // ...more
])

桥接安全命令

桥接器(移动/Web 客户端)通过远程控制连接发送斜杠命令。 这 isBridgeSafeCommand 谓词决定执行哪些谓词而不是默默地删除:

src/commands.ts — isBridgeSafeCommand
export function isBridgeSafeCommand(cmd: Command): boolean {
  if (cmd.type === 'local-jsx') return false  // always blocked (renders Ink UI)
  if (cmd.type === 'prompt') return true      // always safe (expands to text)
  return BRIDGE_SAFE_COMMANDS.has(cmd)          // 'local' needs explicit opt-in
}

规则很直观: local-jsx 命令呈现桥客户端无法显示的终端 UI,因此它们始终被阻止。 prompt 命令仅生成文本,因此它们始终是安全的。 清楚的 local 命令必须明确列出在 BRIDGE_SAFE_COMMANDS - 默认情况下它们被阻止。 允许名单包括 /compact, /clear, /cost, /files,以及其他一些。

10. 要点

  • 🔵
    每个斜杠命令都是一个 Command 对象——一个 CommandBase 受歧视联盟 三种执行类型: local (纯TS函数), local-jsx (墨水成分),以及 prompt (注入模型上下文的文本)。
  • Both local and local-jsx 命令使用 延迟加载 via load: () => import('./cmd.js') — 在实际调用命令之前不会导入实现模块,从而保持快速的启动时间。
  • 🔀
    The 注册管道 通过合并捆绑技能、插件技能、技能目录命令、工作流程、插件命令和静态内置命令 loadAllCommands(cwd),然后过滤 availability and isEnabled 在每一个 getCommands() call.
  • 🛡️
    两个独立的门 控制可见性: availability (静态身份验证提供者检查,每次调用重新评估)和 isEnabled() (运行时功能标志检查)。 两者都必须通过。 两者都不会被记住,因此身份验证更改会立即生效。
  • 🌐
    桥接和远程模式 应用第三个过滤器。 local-jsx 命令始终通过桥被阻止(它们呈现终端 UI)。 prompt 命令始终是允许的。 local 命令需要明确选择加入 BRIDGE_SAFE_COMMANDS.
  • 📝
    提示命令使用 外壳替换 via !`cmd` 在到达模型之前将实时 shell 输出嵌入到提示中的模式 - 这就是如何 /commit auto-injects git status, git diff HEAD和最近的日志,无需粘贴它们。
  • 🔒
    仅供内部使用的命令(/commit, /bughunter等)被包裹在 INTERNAL_ONLY_COMMANDS and dead-code-eliminated 在公共二进制文件中构建时由 Bun 生成 - 它们在用户安装的版本中根本不存在。

11. 测验

Q1. 您想要添加一个新的斜线命令,该命令打开交互式菜单以选择 GitHub PR 进行审核。 您应该使用哪种类型?

A
local - 它不会向模型发送任何内容
B
local-jsx — 它需要渲染一个交互式 UI 组件
C
提示——需要使用模型来总结PR差异
D
任何类型均可; type 只影响启动性能
正确的。 当命令需要为交互式终端 UI 渲染 React/Ink 组件时,local-jsx 是正确的选择。
不完全是。 local-jsx 是正确的选择——它是为渲染交互式终端 UI 组件的命令而设计的。

Q2。 用户安装新插件并立即输入 /plugin-command。 未找到该命令。 最可能的原因是什么?

A
该命令位于 INTERNAL_ONLY_COMMANDS 中
B
命令的 isEnabled() 返回 false
C
loadAllCommands 按 cwd 进行记忆 — 旧缓存没有对应的条目
D
插件命令使用与内置命令不同的查找路径
正确的。 loadAllCommands 会根据 cwd 进行记忆,因此在调用clearCommandsCache() 之前(例如通过 /reload-plugins),新安装的插件不会出现。
不完全是。 记忆的 loadAllCommands 是罪魁祸首 - 在清除缓存并重新加载命令之前,新安装的插件不会出现。

Q3。 关于哪一个说法 REMOTE_SAFE_COMMANDS vs BRIDGE_SAFE_COMMANDS 是正确的吗?

A
REMOTE_SAFE_COMMANDS 在 CCR init 之前过滤初始命令列表; BRIDGE_SAFE_COMMANDS 控制初始化后通过桥连接到达的命令
B
它们是同一组的别名 - 都控制相同的过滤器通道
C
REMOTE_SAFE_COMMANDS 包括所有提示类型命令; BRIDGE_SAFE_COMMANDS 包括所有本地类型命令
D
BRIDGE_SAFE_COMMANDS 仅在移动客户端上强制执行,而不是在桌面远程模式上强制执行
正确的。 这两组服务于远程会话生命周期中的不同时刻:REMOTE_SAFE_COMMANDS 是 CCR 初始化之前可用的内容,BRIDGE_SAFE_COMMANDS 控制可以随时通过桥触发的内容。
不完全是。 它们是具有不同角色的不同集合 - REMOTE_SAFE_COMMANDS 用于预 CCR-init 模式,BRIDGE_SAFE_COMMANDS 用于正在进行的桥接触发命令。

Q4。 一个 prompt 命令集 allowedTools: ['Bash(git add:*)', 'Bash(git commit:*)']。 What does this do?

A
这些是命令的 getPromptForCommand 可以用来构建提示的唯一工具
B
这些工具会自动预先批准全球用户的权限上下文
C
在此命令期间,模型仅在其系统提示符中显示这些工具
D
在执行此命令期间,模型只能调用与这些模式匹配的工具 - 范围权限列表
正确的。 allowedTools 范围允许模型在命令执行轮次期间调用哪些工具 - 它是一个安全边界,可防止模型超出声明的列表。
不完全是。 allowedTools 是一个范围权限列表,专门限制模型在此命令执行期间可以调用哪些工具。

Q5. 目的是什么 !`shell command` 提示命令的模板字符串中的模式?

A
它指示模型运行该 shell 命令并包含其输出
B
在文本到达模型之前,它由executeShellCommandsInPrompt 处理,用实际的 shell 输出替换模式
C
它是一个语法糖,用于将命令添加到 allowedTools
D
它将这些行标记为注释,在发送到模型之前将其删除
正确的。 executeShellCommandsInPrompt 在调用时扫描提示,运行 shell 命令,并在模型看到提示字符串之前将其输出替换为提示字符串。
不完全是。 !`cmd` 模式通过executeShellCommandsInPrompt 在客户端解析——模型接收替换的输出,而不是模式本身。