Skip to content

fix(cli): clarify plugin tool command mistakes#79693

Merged
steipete merged 3 commits into
mainfrom
maint/77221-cli-tool-diagnostic
May 9, 2026
Merged

fix(cli): clarify plugin tool command mistakes#79693
steipete merged 3 commits into
mainfrom
maint/77221-cli-tool-diagnostic

Conversation

@steipete

@steipete steipete commented May 9, 2026

Copy link
Copy Markdown
Contributor

Summary

Real behavior proof

  • Behavior addressed: openclaw <toolName> used to report generic CLI/proxy guidance or the misleading plugins.allow suggestion when <toolName> was an agent tool, not a CLI command.
  • Real environment tested: local OpenClaw checkout with a temp OPENCLAW_HOME, temp config, and temp external lossless-claw plugin manifest declaring contracts.tools=["lcm_recent"].
  • Exact steps or command run after this patch: pnpm openclaw lcm_recent.
  • Evidence after fix: terminal output from the patched CLI run:
$ pnpm openclaw lcm_recent
"lcm_recent" is an agent tool available from the "lossless-claw" plugin, not a CLI subcommand.
Agent tools run inside conversations; start OpenClaw with a supported channel/agent, then ask the agent to use this tool.
  • Observed result after fix: command exited 1 with the agent-tool diagnostic and no plugins.allow suggestion.
  • What was not tested: no additional gaps.

Verification

  • pnpm test src/cli/run-main.test.ts src/cli/run-main.exit.test.ts src/plugins/manifest-command-aliases.test.ts
  • pnpm exec oxfmt --check --threads=1 CHANGELOG.md src/cli/run-main-policy.ts src/cli/run-main.ts src/cli/run-main.test.ts src/cli/run-main.exit.test.ts src/plugins/manifest-command-aliases.ts src/plugins/manifest-command-aliases.runtime.ts src/plugins/manifest-command-aliases.test.ts
  • pnpm build

Closes #77214. Supersedes #77221.

@openclaw-barnacle openclaw-barnacle Bot added cli CLI command changes size: M maintainer Maintainer-authored PR labels May 9, 2026
@clawsweeper

clawsweeper Bot commented May 9, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge.

Summary
The branch adds manifest-declared agent tool ownership lookup to unknown CLI command diagnostics, updates the early proxy unknown-command path, adds tests, adjusts bundled sidecar test fixtures, and adds a changelog entry.

Reproducibility: yes. source-level. Current main can emit the misleading plugins.allow fallback for a root token that is not a CLI command or command alias, and the PR's remaining denylist mismatch is visible by comparing the new resolver with current runtime tool discovery.

Real behavior proof
Needs stronger real behavior proof before merge: The PR body states a temp-installed manifest smoke was run, but it does not include copied CLI output, a terminal screenshot, recording, artifact, or redacted log showing the after-fix diagnostic. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, ask a maintainer to comment @clawsweeper re-review.

Next step before merge
This needs maintainer or author follow-up for the denylist correctness bug and stronger live proof; no repair lane should start without explicit maintainer opt-in.

Security
Cleared: The diff is limited to CLI diagnostic logic, manifest metadata lookup helpers, tests, and changelog text; I found no concrete security or supply-chain regression.

Review findings

  • [P2] Honor the plugin denylist when resolving tool owners — src/plugins/manifest-command-aliases.runtime.ts:92-96
Review details

Best possible solution:

Keep the manifest-backed agent-tool diagnostic, but make tool-owner resolution share the runtime plugin policy, including plugins.deny, before merging.

Do we have a high-confidence way to reproduce the issue?

Yes, source-level. Current main can emit the misleading plugins.allow fallback for a root token that is not a CLI command or command alias, and the PR's remaining denylist mismatch is visible by comparing the new resolver with current runtime tool discovery.

Is this the best way to solve the issue?

No. The diagnostic direction is the narrow maintainable fix, but this patch must honor plugins.deny for the owning plugin and include focused regression coverage before it is the best solution.

Full review comments:

  • [P2] Honor the plugin denylist when resolving tool owners — src/plugins/manifest-command-aliases.runtime.ts:92-96
    The new resolver treats isManifestPluginAvailableForControlPlane as a complete availability check, but that helper returns true for bundled plugins before consulting config. Runtime tool discovery still skips normalizedPlugins.deny, so a denylisted bundled plugin can be reported as providing a tool. Apply the same deny/entry policy before returning ownership.
    Confidence: 0.9

Overall correctness: patch is incorrect
Overall confidence: 0.89

Acceptance criteria:

  • pnpm test src/cli/run-main.test.ts src/cli/run-main.exit.test.ts src/plugins/manifest-command-aliases.test.ts
  • pnpm exec oxfmt --check --threads=1 CHANGELOG.md src/cli/run-main-policy.ts src/cli/run-main.ts src/cli/run-main.test.ts src/cli/run-main.exit.test.ts src/plugins/manifest-command-aliases.ts src/plugins/manifest-command-aliases.runtime.ts src/plugins/manifest-command-aliases.test.ts
  • pnpm build

What I checked:

Likely related people:

  • steipete: Local blame/log for the central CLI policy and manifest eligibility files points to Peter Steinberger's recent current-main commit, and this PR is on the same CLI/plugin diagnostic surface. (role: recent maintainer and adjacent behavior owner; confidence: high; commits: 195db88d711a; files: src/cli/run-main-policy.ts, src/cli/run-main.ts, src/plugins/manifest-contract-eligibility.ts)
  • vincentkoc: The prior ClawSweeper review for the superseded PR identifies recent src/plugins/tools.ts work by Vincent Koc around manifest optional tools and denylist behavior, which is the policy this PR must match. (role: adjacent tool-availability maintainer; confidence: medium; commits: 571d75aab351, 443f7035a2e5, 09e7eb6687a1; files: src/plugins/tools.ts)

Remaining risk / open question:

  • The PR can still tell users a denylisted bundled plugin provides an agent tool even though runtime tool discovery will not materialize that plugin's tools.
  • I did not run tests because this review was constrained to read-only inspection; validation here is source and diff review plus the PR-stated commands.

Codex review notes: model gpt-5.5, reasoning high; reviewed against 2e29090c3713.

Re-review progress:

100yenadmin and others added 2 commits May 9, 2026 07:57
…tool name

When `openclaw <name>` does not match a CLI subcommand or a plugin id,
the unknown-subcommand handler now first looks up <name> against the
manifest plugin tool registry. If <name> is an agent tool declared by a
plugin (e.g. `lcm_recent` from `lossless-claw`), emit a clear 'this is
an agent tool, not a CLI subcommand' error pointing at model tool-use
instead of the misleading `plugins.allow` suggestion.

The previous error told the user to add the tool name to
`plugins.allow`, but `plugins.allow` accepts plugin ids (not tool
names), and config patches against it are rejected by the
protected-config-paths guard. In the wild this sent an agent down 3
restart cycles trying to 'fix' config that was never the problem.

Filtering: the runtime resolver consults the full manifest snapshot and
filters through `isManifestPluginAvailableForControlPlane` (covering
`plugins.allow`/`plugins.deny`/`plugins.entries[id].enabled`/installed
index) plus per-tool `hasManifestToolAvailability` (covering
`toolMetadata.configSignals` like Feishu's `appId`/`appSecret` gate).
The diagnostic also re-checks `plugins.allow` and
`plugins.entries[X].enabled` for the OWNING plugin before emitting, so
denied/disabled plugins are not falsely attributed.

Wording: when ownership is only manifest-provable (per-account
`enabled` flags and per-tool toggles in the Feishu family are
runtime-only and not declarable as configSignals, so the manifest is
necessarily an over-approximation), emit a softer 'may be provided by
the X plugin' message instead of asserting 'registered by'. The strong
wording is reserved for the case where both control-plane availability
and tool availability pass.

Fall-throughs: if <name> is not a registered tool, the existing
`plugins.allow` and `plugins.entries.<id>.enabled` suggestions are
emitted unchanged. The new branch only fires when the tool-registry
lookup matches AND the owning plugin passes availability filters.

Closes #77214.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2fd02077a2

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +197 to +199
const ownerEnabled =
config?.plugins?.entries?.[toolOwner.pluginId]?.enabled !== false &&
(allow.length === 0 || allow.includes(toolOwner.pluginId));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Respect plugins.deny before attributing agent tool ownership

This new tool-diagnostic path only gates ownership on plugins.allow and plugins.entries[...].enabled, so a tool from a plugin listed in plugins.deny can still be reported as "available from" that plugin. In that configuration, openclaw <tool_name> will produce an inaccurate hint because denylisted plugins are not loadable; please include a denylist check here (or reuse the same activation-state predicate used for plugin enablement) before emitting the positive agent-tool message.

Useful? React with 👍 / 👎.

@steipete steipete force-pushed the maint/77221-cli-tool-diagnostic branch from 2fd0207 to aee87c6 Compare May 9, 2026 06:59

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: aee87c6346

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +93 to +97
const pluginAvailable = isManifestPluginAvailableForControlPlane({
snapshot,
plugin,
config: params.config,
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Honor plugins.deny when resolving tool owners

This resolver assumes isManifestPluginAvailableForControlPlane enforces plugins.deny, but for bundled plugins that helper returns true unconditionally, so a denylisted bundled plugin can still be reported as owning a tool and drive the CLI message that the tool is "available from" that plugin. Fresh evidence in this commit is the new resolveManifestToolOwner flow using this check before returning ownership, which means openclaw <tool_name> can produce a false positive attribution whenever plugins.deny blocks the owning bundled plugin.

Useful? React with 👍 / 👎.

@steipete steipete merged commit 0c50957 into main May 9, 2026
118 of 119 checks passed
@steipete steipete deleted the maint/77221-cli-tool-diagnostic branch May 9, 2026 07:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cli CLI command changes maintainer Maintainer-authored PR size: M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

CLI suggests plugins.allow for unknown subcommands when input is actually an agent tool name

1 participant