CommandCodeAI / CommandCodeAI/command-code
Mod-registered tools cannot be scoped to a specific agent — addTool is global and no blocking hook receives agent identity
还没有人认领这个 Issue。
- 主要语言
- 没有语言数据
- 星标
- 4k
- 派生
- 350
- PR 合并指标
- 30 天内没有已合并 PR
描述
Authorship note: This issue was written by an AI assistant (Command Code) on behalf of a human user who hit the problem and explicitly asked that it be filed. The user directed the investigation and the framing; the AI wrote this text. No paths, account names, repository names, project names, or other identifying details are included, at the reporter's explicit request — so any template field below is left blank rather than partially filled.
Summary
A mod can add a tool to Command Code, but it cannot say who may use it. cmd.addTool registers into a single global tool registry with no scoping parameter, and the beforeToolCall hook — the only place a mod can block a call — receives no agent identity in its context. So a mod that intends a narrow, single-purpose tool for one sub-agent has no way to express that intent, and the tool silently ends up on the broadest surface available: the main loop.
The per-agent tools: frontmatter allowlist is the only lever, and it only ever narrows. Callers that declare no allowlist receive every registered tool by default.
What was observed
Setup: a mod registering one custom read-only tool, intended for a single sub-agent, declared in exactly one agent definition's tools: allowlist. Each caller was then spawned and asked to report its own available tools, and — where the tool was present — called it, which returned a real result:
| Caller | Tool available? |
|---|---|
| Main loop | yes — called it successfully |
Bundled general agent |
yes — called it successfully |
Bundled explore agent |
no |
A custom agent whose tools: omit it |
no |
The narrowing works where an allowlist exists. It does nothing where one does not. general is a bundled agent defined with the full tool set and holds a reserved name, so it cannot be shadowed with a locally-defined equivalent, and the main loop has no agent file at all. The mod author's assumption — that agents which do not list the tool simply do not get it — holds for exactly the agents that bothered to declare an allowlist, and fails for the two that matter most.
Why a mod cannot fix this itself
cmd.addToolaccepts a schema, arunfunction, and flags such asreadOnly. There is no agent or scope parameter, so registration is global.beforeToolCall({toolCallId, toolName, input, state}, ctx)—ctxis{emit, signal, cwd, session}. There is no agent identity in it, so a mod cannot gate its own tool on "am I being called by agent X".- Agent identity does surface as
subagentType, but only on thesubagent_start/subagent_progressevents, which are observe-only (cmd.on). The blocking hook has no equivalent field. - A
permissions.denyrule is global, so removing the tool from the main loop also removes it from the one agent that legitimately uses it. There is no per-agent exemption, and deny outranks every narrower allow.
The practical result is that minimal-privilege tool design is unreachable for mods. The author's intent degrades silently: the tool works, appears correctly in the one intended agent, and is additionally present everywhere else — including the context with the largest tool surface and the least scrutiny.
Expected behavior
Any one of these would close it:
- A scope on registration — an optional agents/scope field on
addTool(by agent name, wildcard, or "main loop only"). - Agent identity in the
beforeToolCallcontext —subagentType, or an explicit "main loop" marker when there is none — so a mod can enforce its own scoping. - Agent-targeted
deny/allowrules, so a tool can be withheld from the main loop while remaining available to a named agent. - If none of the above is intended: document plainly that mod-registered tools are global and cannot be scoped, so authors stop designing around a capability that does not exist.
Related
- #852 — sub-agent tool calls bypass
PreToolUsehooks and modbeforeToolCall. Cited as related; not independently re-verified for this report. It compounds this one: ifbeforeToolCalldoes not run for sub-agent calls, then even option (2) above would leave no working seam. Both reports turn on the same underlying question — which execution contexts a mod's hooks and a mod's tools are actually scoped to. - #861 — project-root resolution, which governs where mod files are discovered at all.
Command Code Version
1.54.0
Operating System
Linux
Confidence / what was not verified
- The caller/tool-availability table was reproduced by spawning each caller, having it report its own available tools, and invoking the tool where present. Rows marked yes executed the call and returned a real result.
- The absence of a scoping parameter on
addTool, and of agent identity in the mod hook context, is read from the shipped mods and hooks reference documentation, not from the implementation. - Not verified: whether
beforeToolCallexecutes for sub-agent tool calls (see #852). The compounding interaction described under "Related" is conditional on that being true.
贡献指南
这个仓库没有索引到贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
调研方向
从随附的 mods 和 hooks 参考文档开始,尤其关注 cmd.addTool、beforeToolCall、permissions.deny 和 subagent 事件。追踪主循环、general、explore 和 custom agents 之间的工具可用性差异。完成的标准是:已实现或记录了经同意的 scoping 行为,并且通过验证覆盖了观察到的 caller 矩阵。
由索引模型根据 Issue 内容生成。
评估
- 领域
- cli, devtools, security
- Issue 类型
- 功能
- 难度
- 5/5
- 预计耗时
- 一周以上
- 活跃度
- 活跃
- 描述清晰度
- 基本清楚
- 新手友好度
- 35/100