Skip to content

fix(skills): resolve skills info name mismatches#38701

Closed
NewdlDewdl wants to merge 1 commit into
openclaw:mainfrom
NewdlDewdl:fix/issue-38546-skills-info-lookup
Closed

fix(skills): resolve skills info name mismatches#38701
NewdlDewdl wants to merge 1 commit into
openclaw:mainfrom
NewdlDewdl:fix/issue-38546-skills-info-lookup

Conversation

@NewdlDewdl

Copy link
Copy Markdown
Contributor

Summary

  • make openclaw skills info <name> resolve skills using exact, case-insensitive, and separator-normalized matching
  • normalize lookup tokens across whitespace, underscores, slashes, and dashes so list-visible names and skill keys resolve consistently
  • trim the requested name in not-found JSON/text responses for cleaner UX

Why

Fixes #38546 where skills can show as ready in skills list but fail lookup in skills info (and by extension agent-facing selection paths) due strict identifier matching.

Testing

  • pnpm -C /Users/newdldewdl/.openclaw/workspace/memory/openclaw-contrib/worktrees/issue-38686 test src/cli/skills-cli.test.ts
  • bash /Users/newdldewdl/.openclaw/workspace/skills/openclaw-autonomous-contributor/scripts/quality_gate.sh /Users/newdldewdl/.openclaw/workspace/memory/openclaw-contrib/worktrees/issue-38686

@openclaw-barnacle openclaw-barnacle Bot added cli CLI command changes size: S r: too-many-prs Auto-close: author has more than twenty active PRs. labels Mar 7, 2026
@openclaw-barnacle

Copy link
Copy Markdown

Closing this PR because the author has more than 10 active PRs in this repo. Please reduce the active PR queue and reopen or resubmit once it is back under the limit. You can close your own PRs to get back under the limit.

@openclaw-barnacle openclaw-barnacle Bot closed this Mar 7, 2026
@greptile-apps

greptile-apps Bot commented Mar 7, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes the skills info name-mismatch bug (issue #38546) by replacing the previous strict equality lookup with a three-level resolution strategy: exact match, case-insensitive match, and separator-normalized match. The implementation is clean and the UX improvement of trimming the name in not-found error messages is a welcome addition.

Key points:

  • normalizeSkillLookupToken correctly handles whitespace, underscores, slashes, and dashes via a sensible regex pipeline.
  • resolveSkillByName is well-structured and the fallback chain is easy to follow.
  • The new test "resolves skill info case-insensitively" has a fixture whose skillKey exactly matches the query, so it succeeds on the first direct-equality check — the case-insensitive code branch (toLowerCase comparison) is never executed and therefore has no test coverage. See inline comment for details.
  • The separator-variant test is correct and does exercise the normalized lookup path.
  • The .trim() call added to formatSkillInfo before forwarding to resolveSkillByName is redundant (the helper already trims internally), but it is harmless.

Confidence Score: 4/5

  • PR is safe to merge; the logic change is correct and the only issue is incomplete test coverage for one new code path.
  • The implementation correctly resolves the reported bug with a sensible and well-ordered fallback strategy. The sole concern is that the test named "resolves skill info case-insensitively" does not actually reach the case-insensitive branch, leaving that code path unverified. This is a test quality issue rather than a production logic bug, so it warrants a score of 4 rather than 5.
  • src/cli/skills-cli.test.ts — the case-insensitive test fixture should be fixed to ensure the toLowerCase branch is genuinely exercised.

Last reviewed commit: 1355cae

Comment on lines +152 to +163
it("resolves skill info case-insensitively", () => {
const report = createMockReport([
createMockSkill({
name: "Excel-XLSX",
skillKey: "excel-xlsx",
description: "Spreadsheet helpers",
}),
]);

const output = formatSkillInfo(report, "excel-xlsx", {});
expect(output).toContain("Spreadsheet helpers");
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Test bypasses the case-insensitive code path

This test is labeled "resolves skill info case-insensitively" but the skill fixture's skillKey is already an exact lowercase match for the requested name. resolveSkillByName therefore finds the skill on the very first direct equality check and returns before the case-insensitive branch is ever evaluated.

To actually cover the toLowerCase comparison branch, both name and skillKey in the fixture should use a casing that does not exactly match the query, so the lookup is forced past the direct-match step. As currently written, a regression in the case-insensitive logic would leave this test green.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/cli/skills-cli.test.ts
Line: 152-163

Comment:
**Test bypasses the case-insensitive code path**

This test is labeled "resolves skill info case-insensitively" but the skill fixture's `skillKey` is already an exact lowercase match for the requested name. `resolveSkillByName` therefore finds the skill on the very first direct equality check and returns before the case-insensitive branch is ever evaluated.

To actually cover the `toLowerCase` comparison branch, both `name` and `skillKey` in the fixture should use a casing that does not exactly match the query, so the lookup is forced past the direct-match step. As currently written, a regression in the case-insensitive logic would leave this test green.

How can I resolve this? If you propose a fix, please make it concise.

@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: 1355caefff

ℹ️ 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 +101 to +104
report.skills.find(
(s) =>
normalizeSkillLookupToken(s.name) === normalized ||
normalizeSkillLookupToken(s.skillKey) === normalized,

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 Disambiguate normalized skill-name collisions

resolveSkillByName picks the first entry whose normalized token matches, so skills info can return the wrong skill when multiple entries normalize to the same value (for example foo-bar and foo bar, or a name colliding with another skill’s skillKey). This is reachable because skill loading keeps distinct names as separate entries (src/agents/skills/workspace.ts:369-388), and the result then depends on source/load order rather than the user’s intended skill. Please detect multiple normalized candidates and surface an explicit ambiguous-name error instead of silently choosing the first match.

Useful? React with 👍 / 👎.

@NewdlDewdl

Copy link
Copy Markdown
Contributor Author

Queue is now under limit and I opened replacement PR #38713 with the same fix plus updated case-insensitive test coverage from bot feedback.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cli CLI command changes r: too-many-prs Auto-close: author has more than twenty active PRs. size: S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Title: Skills show as "ready" in list but "not found" in info, and can't be used by agent Steps to reproduce:

1 participant