fix: improve skill discovery and list output #17

Open
KirioXX wants to merge 8 commits from KirioXX/fix/improve-skill-discovery into master
KirioXX commented 2026-06-04 15:13:44 +00:00 (Migrated from github.com)

Description

Fix skill discovery so skills list can find skills installed via skills install across canonical storage (~/.skills, ./.skills) and agent-specific directories. Also adds
source paths to skills list output for easier inspection, and updates docs/tests accordingly.

Type of Change

  • Bug fix
  • New feature
  • Documentation update
  • Refactoring

Testing

  • npm run build passes
  • Tested with skills --help
  • Tested relevant commands

Checklist

  • Code follows existing style
  • Self-reviewed my code
  • Added comments for complex code
  • Updated docs if needed

Fixes #15

Summary by CodeRabbit

  • New Features

    • Expanded skill discovery to check canonical locations (~/.skills, ./.skills) and agent-specific directories
    • Skills list now shows each skill’s source path (JSON/table includes a “Source” column); descriptions shown only in verbose mode
    • Duplicate skills across locations are deduplicated, preferring the canonical path
  • Tests

    • Added tests covering discovery paths and deduplication
  • Documentation

    • README and planning docs updated with skill discovery path details
## Description Fix skill discovery so `skills list` can find skills installed via `skills install` across canonical storage (`~/.skills`, `./.skills`) and agent-specific directories. Also adds source paths to `skills list` output for easier inspection, and updates docs/tests accordingly. ## Type of Change - [x] Bug fix - [ ] New feature - [x] Documentation update - [x] Refactoring ## Testing - [x] `npm run build` passes - [x] Tested with `skills --help` - [x] Tested relevant commands ## Checklist - [x] Code follows existing style - [x] Self-reviewed my code - [x] Added comments for complex code - [x] Updated docs if needed Fixes #15 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Expanded skill discovery to check canonical locations (~/.skills, ./.skills) and agent-specific directories * Skills list now shows each skill’s source path (JSON/table includes a “Source” column); descriptions shown only in verbose mode * Duplicate skills across locations are deduplicated, preferring the canonical path * **Tests** * Added tests covering discovery paths and deduplication * **Documentation** * README and planning docs updated with skill discovery path details <!-- end of auto-generated comment: release notes by coderabbit.ai -->
coderabbitai[bot] commented 2026-06-04 15:14:06 +00:00 (Migrated from github.com)

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 8f1a0a42-7b44-4061-be73-18d4ce20840c

📥 Commits

Reviewing files that changed from the base of the PR and between df37628523 and eb8a3f12d4.

📒 Files selected for processing (5)
  • README.md
  • docs/superpowers/plans/2026-06-01-skill-discovery-paths.md
  • src/cli/commands/list.ts
  • src/core/loader.test.ts
  • src/core/loader.ts
Files skipped from review due to trivial changes (1)
  • docs/superpowers/plans/2026-06-01-skill-discovery-paths.md
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/core/loader.test.ts
  • src/cli/commands/list.ts

📝 Walkthrough

Walkthrough

Expands discovery to include canonical (~/.skills, ./​.skills) and agent-specific directories, deduplicates discovered skills by metadata.name, exposes agent discovery helpers, integrates merged search paths into skills list output (including source paths), and adds tests and documentation.

Changes

Skill Discovery Path Expansion and Deduplication

Layer / File(s) Summary
Core loader discovery paths and deduplication
src/core/loader.ts
getDefaultSkillPaths(cwd, home) centralizes discovery roots; DEFAULT_SKILL_PATHS is derived from it. discoverSkills() globs **/SKILL.md per-root (cwd roots, dot files, maxDepth), loads metadata, and deduplicates results by metadata.name, returning one SkillRef per name.
Loader regression tests
src/core/loader.test.ts
Tests assert default search paths include ~/.skills and ./.skills, and that two identical skills under different roots are deduplicated to a single canonical path.
Agent-specific discovery configuration
src/cli/agents.ts
AgentConfig gains optional discoveryDirs?: string[]. getAgentDiscoveryPaths(agent) aggregates globalDir, projectDir, and discoveryDirs with legacy fallbacks for unknown agents; getAllAgentDiscoveryPaths() unions deduped roots across agents.
List command integration and output formatting
src/cli/commands/list.ts, src/cli/commands/list.test.ts
Add ListedSkill type and helpers: getListSearchPaths() (merges DEFAULT_SKILL_PATHS + getAllAgentDiscoveryPaths()), formatSkillSourcePath(), getListJsonEntry(), getListDisplayLines(). registerListCommand() uses merged search paths for discoverSkills, includes sourcePath in JSON, adds a “Source” table column, always prints Source in default output, and prints description only with --verbose. Tests verify search path contents and sourcePath presence.
Documentation and implementation plan
README.md, docs/superpowers/plans/2026-06-01-skill-discovery-paths.md
README adds a discovery note describing canonical and agent-specific search paths. The plan document details tasks: tests, production changes (getDefaultSkillPaths, DEFAULT_SKILL_PATHS, updated discoverSkills with dedupe), and verification steps.

Sequence Diagram

sequenceDiagram
  participant User
  participant ListCmd as registerListCommand
  participant SearchPaths as getListSearchPaths
  participant Discovery as discoverSkills
  participant Output as formatters
  User->>ListCmd: skills list [--verbose]
  ListCmd->>SearchPaths: getListSearchPaths()
  SearchPaths->>Discovery: DEFAULT_SKILL_PATHS + getAllAgentDiscoveryPaths()
  Discovery->>Discovery: glob **/SKILL.md (per-root), load metadata, dedupe by metadata.name
  Discovery-->>ListCmd: SkillRef[] (deduped)
  ListCmd->>Output: getListJsonEntry() / getListDisplayLines()
  Output-->>ListCmd: formatted entries (include sourcePath)
  ListCmd-->>User: JSON/table/default output

🎯 3 (Moderate) | ⏱️ ~25 minutes

🐰 A discovery quest begins, no more hiding spots!
Paths now merge, dedupes abound, skill names unite,
List command shines with source paths and verbose delight!
Home to agents, canonical to custom, all searching as one,
Agent skills CLI just got its discovery done! 🎯

🚥 Pre-merge checks | 5
Passed checks (5 passed)
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title 'fix: improve skill discovery and list output' is concise, clear, and accurately summarizes the primary changes: fixing skill discovery and improving the list command output.
Linked Issues check Passed All key requirements from issue #15 are addressed: discovery paths now include canonical storage (~/.skills, ./.skills), agent-specific directories are supported, and installed skills are now discoverable via skills list.
Out of Scope Changes check Passed All changes are directly related to resolving issue #15: skill discovery path alignment, list command improvements, supporting tests, documentation, and README updates are all in scope.
Docstring Coverage Passed Docstring coverage is 94.12% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

<!-- This is an auto-generated comment: summarize by coderabbit.ai --> <!-- review_stack_entry_start --> [![Review Change Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/Karanjot786/agent-skills-cli/pull/17?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack) <!-- review_stack_entry_end --> No actionable comments were generated in the recent review. 🎉 <details> <summary>ℹ️ Recent review info</summary> <details> <summary>⚙️ Run configuration</summary> **Configuration used**: defaults **Review profile**: CHILL **Plan**: Pro Plus **Run ID**: `8f1a0a42-7b44-4061-be73-18d4ce20840c` </details> <details> <summary>📥 Commits</summary> Reviewing files that changed from the base of the PR and between df37628523bca7615c2ed9c3736cc869e840b7ea and eb8a3f12d4081a0abca6f4e13f61292b730f3ca4. </details> <details> <summary>📒 Files selected for processing (5)</summary> * `README.md` * `docs/superpowers/plans/2026-06-01-skill-discovery-paths.md` * `src/cli/commands/list.ts` * `src/core/loader.test.ts` * `src/core/loader.ts` </details> <details> <summary>✅ Files skipped from review due to trivial changes (1)</summary> * docs/superpowers/plans/2026-06-01-skill-discovery-paths.md </details> <details> <summary>🚧 Files skipped from review as they are similar to previous changes (2)</summary> * src/core/loader.test.ts * src/cli/commands/list.ts </details> </details> --- <!-- walkthrough_start --> <details> <summary>📝 Walkthrough</summary> ## Walkthrough Expands discovery to include canonical (~/.skills, ./​.skills) and agent-specific directories, deduplicates discovered skills by metadata.name, exposes agent discovery helpers, integrates merged search paths into `skills list` output (including source paths), and adds tests and documentation. ## Changes **Skill Discovery Path Expansion and Deduplication** |Layer / File(s)|Summary| |---|---| |**Core loader discovery paths and deduplication** <br> `src/core/loader.ts`|`getDefaultSkillPaths(cwd, home)` centralizes discovery roots; `DEFAULT_SKILL_PATHS` is derived from it. `discoverSkills()` globs `**/SKILL.md` per-root (cwd roots, dot files, maxDepth), loads metadata, and deduplicates results by `metadata.name`, returning one `SkillRef` per name.| |**Loader regression tests** <br> `src/core/loader.test.ts`|Tests assert default search paths include `~/.skills` and `./.skills`, and that two identical skills under different roots are deduplicated to a single canonical path.| |**Agent-specific discovery configuration** <br> `src/cli/agents.ts`|`AgentConfig` gains optional `discoveryDirs?: string[]`. `getAgentDiscoveryPaths(agent)` aggregates `globalDir`, `projectDir`, and `discoveryDirs` with legacy fallbacks for unknown agents; `getAllAgentDiscoveryPaths()` unions deduped roots across agents.| |**List command integration and output formatting** <br> `src/cli/commands/list.ts`, `src/cli/commands/list.test.ts`|Add `ListedSkill` type and helpers: `getListSearchPaths()` (merges `DEFAULT_SKILL_PATHS` + `getAllAgentDiscoveryPaths()`), `formatSkillSourcePath()`, `getListJsonEntry()`, `getListDisplayLines()`. `registerListCommand()` uses merged search paths for `discoverSkills`, includes `sourcePath` in JSON, adds a “Source” table column, always prints Source in default output, and prints description only with `--verbose`. Tests verify search path contents and `sourcePath` presence.| |**Documentation and implementation plan** <br> `README.md`, `docs/superpowers/plans/2026-06-01-skill-discovery-paths.md`|README adds a discovery note describing canonical and agent-specific search paths. The plan document details tasks: tests, production changes (`getDefaultSkillPaths`, `DEFAULT_SKILL_PATHS`, updated `discoverSkills` with dedupe), and verification steps.| ## Sequence Diagram ```mermaid sequenceDiagram participant User participant ListCmd as registerListCommand participant SearchPaths as getListSearchPaths participant Discovery as discoverSkills participant Output as formatters User->>ListCmd: skills list [--verbose] ListCmd->>SearchPaths: getListSearchPaths() SearchPaths->>Discovery: DEFAULT_SKILL_PATHS + getAllAgentDiscoveryPaths() Discovery->>Discovery: glob **/SKILL.md (per-root), load metadata, dedupe by metadata.name Discovery-->>ListCmd: SkillRef[] (deduped) ListCmd->>Output: getListJsonEntry() / getListDisplayLines() Output-->>ListCmd: formatted entries (include sourcePath) ListCmd-->>User: JSON/table/default output ``` 🎯 3 (Moderate) | ⏱️ ~25 minutes > 🐰 A discovery quest begins, no more hiding spots! > Paths now merge, dedupes abound, skill names unite, > List command shines with source paths and verbose delight! > Home to agents, canonical to custom, all searching as one, > Agent skills CLI just got its discovery done! 🎯 </details> <!-- walkthrough_end --> <!-- pre_merge_checks_walkthrough_start --> <details> <summary>🚥 Pre-merge checks | ✅ 5</summary> <details> <summary>✅ Passed checks (5 passed)</summary> | Check name | Status | Explanation | | :------------------------: | :------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Description Check | ✅ Passed | Check skipped - CodeRabbit’s high-level summary is enabled. | | Title check | ✅ Passed | The title 'fix: improve skill discovery and list output' is concise, clear, and accurately summarizes the primary changes: fixing skill discovery and improving the list command output. | | Linked Issues check | ✅ Passed | All key requirements from issue `#15` are addressed: discovery paths now include canonical storage (~/.skills, ./.skills), agent-specific directories are supported, and installed skills are now discoverable via skills list. | | Out of Scope Changes check | ✅ Passed | All changes are directly related to resolving issue `#15`: skill discovery path alignment, list command improvements, supporting tests, documentation, and README updates are all in scope. | | Docstring Coverage | ✅ Passed | Docstring coverage is 94.12% which is sufficient. The required threshold is 80.00%. | </details> <sub>✏️ Tip: You can configure your own custom pre-merge checks in the settings.</sub> </details> <!-- pre_merge_checks_walkthrough_end --> <!-- finishing_touch_checkbox_start --> <details> <summary>✨ Finishing Touches</summary> <details> <summary>🧪 Generate unit tests (beta)</summary> - [ ] <!-- {"checkboxId": "f47ac10b-58cc-4372-a567-0e02b2c3d479", "radioGroupId": "utg-output-choice-group-unknown_comment_id"} --> Create PR with unit tests </details> </details> <!-- finishing_touch_checkbox_end --> <!-- tips_start --> --- <sub>Comment `@coderabbitai help` to get the list of available commands and usage tips.</sub> <!-- tips_end --> <!-- internal state start --> <!-- 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 --> <!-- internal state end -->
coderabbitai[bot] (Migrated from github.com) reviewed 2026-06-04 15:19:17 +00:00
coderabbitai[bot] (Migrated from github.com) left a comment

Actionable comments posted: 6

🧹 Nitpick comments (1)
docs/superpowers/plans/2026-06-01-skill-discovery-paths.md (1)

44-61: 💤 Low value

Plan test code differs from actual implementation.

The test structure in the plan uses paths like join(root, 'home', '.skills', 'demo-skill') and join(root, 'repo', '.agent', 'skills', 'demo-skill') (lines 46-47, 55), but the actual implementation shown in context snippets uses simpler paths like join(root, 'canonical', 'demo-skill') and join(root, 'agent', 'demo-skill').

While the test logic is equivalent, the discrepancy between plan and implementation could confuse readers referencing this document.

📝 Optional update to match actual implementation
-    const canonical = join(root, 'home', '.skills', 'demo-skill');
-    const agentDir = join(root, 'repo', '.agent', 'skills', 'demo-skill');
+    const canonical = join(root, 'canonical', 'demo-skill');
+    const agentDir = join(root, 'agent', 'demo-skill');
 
     await mkdir(canonical, { recursive: true });
     await mkdir(agentDir, { recursive: true });
@@ -52,7 +52,7 @@
     await writeFile(join(agentDir, 'SKILL.md'), skillMd);
 
     const skills = await discoverSkills({
-      searchPaths: [join(root, 'home', '.skills'), join(root, 'repo', '.agent', 'skills')],
+      searchPaths: [join(root, 'canonical'), join(root, 'agent')],
       maxDepth: 3,
     });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/superpowers/plans/2026-06-01-skill-discovery-paths.md` around lines 44 -
61, Test path literals in the plan differ from the actual implementation which
uses simpler directories; update the plan's example test to match the
implementation by replacing occurrences of join(root, 'home', '.skills',
'demo-skill') and join(root, 'repo', '.agent', 'skills', 'demo-skill') with the
actual canonical/agent layout used by discoverSkills (e.g., join(root,
'canonical', 'demo-skill') and join(root, 'agent', 'demo-skill')), and likewise
adjust the created directory variables (canonical, agentDir) and the searchPaths
passed to discoverSkills so the example matches the real code paths.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/superpowers/plans/2026-06-01-skill-discovery-paths.md`:
- Around line 99-107: The plan's getDefaultSkillPaths implementation is missing
two entries present in the real loader: add join(home, ".gemini", "antigravity",
"skills") and the ".agent/skills" path to the returned array in
getDefaultSkillPaths so the plan matches the actual implementation; locate the
getDefaultSkillPaths function and update its returned list to include these two
paths in the appropriate order to mirror the loader.
- Around line 1-12: Add an H2 heading "## Implementation Tasks" immediately
after the existing H1 "Skill Discovery Paths Implementation Plan" and before the
current Task 1 section (the first H3), so the document follows proper Markdown
heading hierarchy; update any references or anchors that assume the previous
structure if needed.

In `@README.md`:
- Around line 251-252: The discovery note block (the quoted line starting with
"**Discovery note:** `skills list`...") was inserted between table rows and
breaks the Markdown table; move that entire quote out of the table body and
place it either immediately above or below the table (for example after the
table closure) so the table rows (including the OpenCode row and subsequent
agent information) render correctly; update the README.md by removing the quote
from inside the table and inserting it as a standalone paragraph outside the
table boundaries.

In `@src/cli/commands/list.ts`:
- Around line 63-69: The printed skill-paths are hardcoded; update the block in
src/cli/commands/list.ts to print the actual computed search paths instead.
Locate where the skill discovery array is built (e.g., variable or function name
like searchPaths, skillSearchPaths, or getSkillSearchPaths) and replace the
fixed console.log lines with code that logs the header ("Skills are searched
in:") then iterates over that array and logs each path with chalk.gray. Ensure
you reference the existing computed array name
(searchPaths/skillSearchPaths/getSkillSearchPaths) so the output always reflects
the real discovery locations.

In `@src/core/loader.test.ts`:
- Around line 17-21: The test is using process.env.HOME which can differ from
the OS homedir used in production; update the assertion to use homedir() instead
of process.env.HOME so DEFAULT_SKILL_PATHS is compared against join(homedir(),
".skills"); ensure you import homedir from 'os' at the top of the test file if
it's not already imported and keep the rest of the assertions (e.g.,
join(process.cwd(), ".skills")) unchanged.

In `@src/core/loader.ts`:
- Line 63: The discovery config currently sets maxDepth using the
falsy-coalescing pattern (config.maxDepth || 3) which ignores an explicit 0;
change this to use an undefined-only fallback so 0 is respected (e.g., use the
nullish coalescing operator or an explicit undefined check). Update the location
where maxDepth is assigned (the object property maxDepth in loader/discovery
setup that references config.maxDepth) to use config.maxDepth ?? 3 or
(config.maxDepth !== undefined ? config.maxDepth : 3) so an explicit maxDepth: 0
is honored.

---

Nitpick comments:
In `@docs/superpowers/plans/2026-06-01-skill-discovery-paths.md`:
- Around line 44-61: Test path literals in the plan differ from the actual
implementation which uses simpler directories; update the plan's example test to
match the implementation by replacing occurrences of join(root, 'home',
'.skills', 'demo-skill') and join(root, 'repo', '.agent', 'skills',
'demo-skill') with the actual canonical/agent layout used by discoverSkills
(e.g., join(root, 'canonical', 'demo-skill') and join(root, 'agent',
'demo-skill')), and likewise adjust the created directory variables (canonical,
agentDir) and the searchPaths passed to discoverSkills so the example matches
the real code paths.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: dcd1f777-149d-4405-bbbb-0fd75524954a

📥 Commits

Reviewing files that changed from the base of the PR and between 956140bfce and 909c1ce150.

📒 Files selected for processing (7)
  • README.md
  • docs/superpowers/plans/2026-06-01-skill-discovery-paths.md
  • src/cli/agents.ts
  • src/cli/commands/list.test.ts
  • src/cli/commands/list.ts
  • src/core/loader.test.ts
  • src/core/loader.ts
**Actionable comments posted: 6** <details> <summary>🧹 Nitpick comments (1)</summary><blockquote> <details> <summary>docs/superpowers/plans/2026-06-01-skill-discovery-paths.md (1)</summary><blockquote> `44-61`: _💤 Low value_ **Plan test code differs from actual implementation.** The test structure in the plan uses paths like `join(root, 'home', '.skills', 'demo-skill')` and `join(root, 'repo', '.agent', 'skills', 'demo-skill')` (lines 46-47, 55), but the actual implementation shown in context snippets uses simpler paths like `join(root, 'canonical', 'demo-skill')` and `join(root, 'agent', 'demo-skill')`. While the test logic is equivalent, the discrepancy between plan and implementation could confuse readers referencing this document. <details> <summary>📝 Optional update to match actual implementation</summary> ```diff - const canonical = join(root, 'home', '.skills', 'demo-skill'); - const agentDir = join(root, 'repo', '.agent', 'skills', 'demo-skill'); + const canonical = join(root, 'canonical', 'demo-skill'); + const agentDir = join(root, 'agent', 'demo-skill'); await mkdir(canonical, { recursive: true }); await mkdir(agentDir, { recursive: true }); @@ -52,7 +52,7 @@ await writeFile(join(agentDir, 'SKILL.md'), skillMd); const skills = await discoverSkills({ - searchPaths: [join(root, 'home', '.skills'), join(root, 'repo', '.agent', 'skills')], + searchPaths: [join(root, 'canonical'), join(root, 'agent')], maxDepth: 3, }); ``` </details> <details> <summary>🤖 Prompt for AI Agents</summary> ``` Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/superpowers/plans/2026-06-01-skill-discovery-paths.md` around lines 44 - 61, Test path literals in the plan differ from the actual implementation which uses simpler directories; update the plan's example test to match the implementation by replacing occurrences of join(root, 'home', '.skills', 'demo-skill') and join(root, 'repo', '.agent', 'skills', 'demo-skill') with the actual canonical/agent layout used by discoverSkills (e.g., join(root, 'canonical', 'demo-skill') and join(root, 'agent', 'demo-skill')), and likewise adjust the created directory variables (canonical, agentDir) and the searchPaths passed to discoverSkills so the example matches the real code paths. ``` </details> </blockquote></details> </blockquote></details> <details> <summary>🤖 Prompt for all review comments with AI agents</summary> ``` Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. Inline comments: In `@docs/superpowers/plans/2026-06-01-skill-discovery-paths.md`: - Around line 99-107: The plan's getDefaultSkillPaths implementation is missing two entries present in the real loader: add join(home, ".gemini", "antigravity", "skills") and the ".agent/skills" path to the returned array in getDefaultSkillPaths so the plan matches the actual implementation; locate the getDefaultSkillPaths function and update its returned list to include these two paths in the appropriate order to mirror the loader. - Around line 1-12: Add an H2 heading "## Implementation Tasks" immediately after the existing H1 "Skill Discovery Paths Implementation Plan" and before the current Task 1 section (the first H3), so the document follows proper Markdown heading hierarchy; update any references or anchors that assume the previous structure if needed. In `@README.md`: - Around line 251-252: The discovery note block (the quoted line starting with "**Discovery note:** `skills list`...") was inserted between table rows and breaks the Markdown table; move that entire quote out of the table body and place it either immediately above or below the table (for example after the table closure) so the table rows (including the OpenCode row and subsequent agent information) render correctly; update the README.md by removing the quote from inside the table and inserting it as a standalone paragraph outside the table boundaries. In `@src/cli/commands/list.ts`: - Around line 63-69: The printed skill-paths are hardcoded; update the block in src/cli/commands/list.ts to print the actual computed search paths instead. Locate where the skill discovery array is built (e.g., variable or function name like searchPaths, skillSearchPaths, or getSkillSearchPaths) and replace the fixed console.log lines with code that logs the header ("Skills are searched in:") then iterates over that array and logs each path with chalk.gray. Ensure you reference the existing computed array name (searchPaths/skillSearchPaths/getSkillSearchPaths) so the output always reflects the real discovery locations. In `@src/core/loader.test.ts`: - Around line 17-21: The test is using process.env.HOME which can differ from the OS homedir used in production; update the assertion to use homedir() instead of process.env.HOME so DEFAULT_SKILL_PATHS is compared against join(homedir(), ".skills"); ensure you import homedir from 'os' at the top of the test file if it's not already imported and keep the rest of the assertions (e.g., join(process.cwd(), ".skills")) unchanged. In `@src/core/loader.ts`: - Line 63: The discovery config currently sets maxDepth using the falsy-coalescing pattern (config.maxDepth || 3) which ignores an explicit 0; change this to use an undefined-only fallback so 0 is respected (e.g., use the nullish coalescing operator or an explicit undefined check). Update the location where maxDepth is assigned (the object property maxDepth in loader/discovery setup that references config.maxDepth) to use config.maxDepth ?? 3 or (config.maxDepth !== undefined ? config.maxDepth : 3) so an explicit maxDepth: 0 is honored. --- Nitpick comments: In `@docs/superpowers/plans/2026-06-01-skill-discovery-paths.md`: - Around line 44-61: Test path literals in the plan differ from the actual implementation which uses simpler directories; update the plan's example test to match the implementation by replacing occurrences of join(root, 'home', '.skills', 'demo-skill') and join(root, 'repo', '.agent', 'skills', 'demo-skill') with the actual canonical/agent layout used by discoverSkills (e.g., join(root, 'canonical', 'demo-skill') and join(root, 'agent', 'demo-skill')), and likewise adjust the created directory variables (canonical, agentDir) and the searchPaths passed to discoverSkills so the example matches the real code paths. ``` </details> <details> <summary>🪄 Autofix (Beta)</summary> Fix all unresolved CodeRabbit comments on this PR: - [ ] <!-- {"checkboxId": "4b0d0e0a-96d7-4f10-b296-3a18ea78f0b9"} --> Push a commit to this branch (recommended) - [ ] <!-- {"checkboxId": "ff5b1114-7d8c-49e6-8ac1-43f82af23a33"} --> Create a new PR with the fixes </details> --- <details> <summary>ℹ️ Review info</summary> <details> <summary>⚙️ Run configuration</summary> **Configuration used**: defaults **Review profile**: CHILL **Plan**: Pro Plus **Run ID**: `dcd1f777-149d-4405-bbbb-0fd75524954a` </details> <details> <summary>📥 Commits</summary> Reviewing files that changed from the base of the PR and between 956140bfce17aab9ef7ba9afbb12ee0bd8a8ef1c and 909c1ce150b2c61ed633e887c2972d5c77233e09. </details> <details> <summary>📒 Files selected for processing (7)</summary> * `README.md` * `docs/superpowers/plans/2026-06-01-skill-discovery-paths.md` * `src/cli/agents.ts` * `src/cli/commands/list.test.ts` * `src/cli/commands/list.ts` * `src/core/loader.test.ts` * `src/core/loader.ts` </details> </details> <!-- This is an auto-generated comment by CodeRabbit for review status -->
@ -350,0 +245,4 @@
| **OpenAI Codex** | `.codex/skills/` | `~/.codex/skills/` |
| **Windsurf** | `.windsurf/skills/` | `~/.codeium/windsurf/skills/` |
| **Cline** | `.cline/skills/` | `~/.cline/skills/` |
| **Gemini CLI** | `.gemini/skills/` | `~/.gemini/skills/` |
coderabbitai[bot] (Migrated from github.com) commented 2026-06-04 15:19:14 +00:00

⚠️ Potential issue | 🟠 Major | Quick win

Move the discovery note outside the table to fix broken rendering.

The discovery note is inserted between table rows, which breaks the Markdown table structure. Most parsers will terminate the table before this note, causing the OpenCode row and subsequent agent information to render incorrectly.

📝 Proposed fix to relocate the note
 | **Antigravity** | `.agent/skills/` | `~/.gemini/antigravity/skills/` |
-
-> **Discovery note:** `skills list` searches both canonical install storage (`~/.skills/`, `./.skills/`) and agent-specific skill directories, so skills installed by `skills install` remain discoverable even before syncing.
 | **OpenCode** | `.opencode/skill/` | `~/.config/opencode/skill/` |
 
 **+32 more agents:** Amp, Kilo, Roo, Goose, CodeBuddy, Continue, Crush, Clawdbot, Droid, Kiro, MCPJam, Mux, OpenHands, Pi, Qoder, Qwen Code, Trae, Zencoder, Neovate, Command Code, Ara, Aide, Alex, BB, CodeStory, Helix AI, Meekia, Pear AI, Adal, Pochi, Sourcegraph Cody, Void AI
+
+> **Discovery note:** `skills list` searches both canonical install storage (`~/.skills/`, `./.skills/`) and agent-specific skill directories, so skills installed by `skills install` remain discoverable even before syncing.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@README.md` around lines 251 - 252, The discovery note block (the quoted line
starting with "**Discovery note:** `skills list`...") was inserted between table
rows and breaks the Markdown table; move that entire quote out of the table body
and place it either immediately above or below the table (for example after the
table closure) so the table rows (including the OpenCode row and subsequent
agent information) render correctly; update the README.md by removing the quote
from inside the table and inserting it as a standalone paragraph outside the
table boundaries.

Addressed in commits bea1b49 to eb8a3f1

_⚠️ Potential issue_ | _🟠 Major_ | _⚡ Quick win_ **Move the discovery note outside the table to fix broken rendering.** The discovery note is inserted between table rows, which breaks the Markdown table structure. Most parsers will terminate the table before this note, causing the OpenCode row and subsequent agent information to render incorrectly. <details> <summary>📝 Proposed fix to relocate the note</summary> ```diff | **Antigravity** | `.agent/skills/` | `~/.gemini/antigravity/skills/` | - -> **Discovery note:** `skills list` searches both canonical install storage (`~/.skills/`, `./.skills/`) and agent-specific skill directories, so skills installed by `skills install` remain discoverable even before syncing. | **OpenCode** | `.opencode/skill/` | `~/.config/opencode/skill/` | **+32 more agents:** Amp, Kilo, Roo, Goose, CodeBuddy, Continue, Crush, Clawdbot, Droid, Kiro, MCPJam, Mux, OpenHands, Pi, Qoder, Qwen Code, Trae, Zencoder, Neovate, Command Code, Ara, Aide, Alex, BB, CodeStory, Helix AI, Meekia, Pear AI, Adal, Pochi, Sourcegraph Cody, Void AI + +> **Discovery note:** `skills list` searches both canonical install storage (`~/.skills/`, `./.skills/`) and agent-specific skill directories, so skills installed by `skills install` remain discoverable even before syncing. ``` </details> <details> <summary>🤖 Prompt for AI Agents</summary> ``` Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@README.md` around lines 251 - 252, The discovery note block (the quoted line starting with "**Discovery note:** `skills list`...") was inserted between table rows and breaks the Markdown table; move that entire quote out of the table body and place it either immediately above or below the table (for example after the table closure) so the table rows (including the OpenCode row and subsequent agent information) render correctly; update the README.md by removing the quote from inside the table and inserting it as a standalone paragraph outside the table boundaries. ``` </details> <!-- fingerprinting:phantom:triton:puma --> <!-- This is an auto-generated comment by CodeRabbit --> ✅ Addressed in commits bea1b49 to eb8a3f1
@ -0,0 +1,195 @@
# Skill Discovery Paths Implementation Plan
coderabbitai[bot] (Migrated from github.com) commented 2026-06-04 15:19:14 +00:00

⚠️ Potential issue | 🟡 Minor | Quick win

Consider adding an h2 section heading before Task 1.

The document jumps from h1 (line 1) to h3 (line 13), which violates Markdown heading hierarchy. Adding an h2 heading like ## Implementation Tasks before Task 1 would improve document structure and fix the markdownlint warning.

📋 Proposed fix for heading hierarchy
 **Tech Stack:** TypeScript, Vitest, Node.js filesystem APIs, existing glob/gray-matter loader.
 
 ---
+
+## Implementation Tasks
 
 ### Task 1: Add regression tests for default discovery roots and deduplication
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/superpowers/plans/2026-06-01-skill-discovery-paths.md` around lines 1 -
12, Add an H2 heading "## Implementation Tasks" immediately after the existing
H1 "Skill Discovery Paths Implementation Plan" and before the current Task 1
section (the first H3), so the document follows proper Markdown heading
hierarchy; update any references or anchors that assume the previous structure
if needed.

Addressed in commits bea1b49 to eb8a3f1

_⚠️ Potential issue_ | _🟡 Minor_ | _⚡ Quick win_ **Consider adding an h2 section heading before Task 1.** The document jumps from h1 (line 1) to h3 (line 13), which violates Markdown heading hierarchy. Adding an h2 heading like `## Implementation Tasks` before Task 1 would improve document structure and fix the markdownlint warning. <details> <summary>📋 Proposed fix for heading hierarchy</summary> ```diff **Tech Stack:** TypeScript, Vitest, Node.js filesystem APIs, existing glob/gray-matter loader. --- + +## Implementation Tasks ### Task 1: Add regression tests for default discovery roots and deduplication ``` </details> <details> <summary>🤖 Prompt for AI Agents</summary> ``` Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/superpowers/plans/2026-06-01-skill-discovery-paths.md` around lines 1 - 12, Add an H2 heading "## Implementation Tasks" immediately after the existing H1 "Skill Discovery Paths Implementation Plan" and before the current Task 1 section (the first H3), so the document follows proper Markdown heading hierarchy; update any references or anchors that assume the previous structure if needed. ``` </details> <!-- fingerprinting:phantom:triton:puma --> <!-- This is an auto-generated comment by CodeRabbit --> ✅ Addressed in commits bea1b49 to eb8a3f1
coderabbitai[bot] (Migrated from github.com) commented 2026-06-04 15:19:14 +00:00

⚠️ Potential issue | 🟡 Minor | Quick win

Plan implementation differs from actual loader code.

The getDefaultSkillPaths implementation in the plan (lines 99-107) doesn't match the actual implementation shown in context snippets:

Plan is missing:

  • join(home, ".gemini", "antigravity", "skills") (the plan shows shorter join(home, '.antigravity', 'skills'))
  • ".agent/skills" directory

Actual implementation has 6 paths, plan shows 5.

This discrepancy could mislead readers referencing this plan document. The actual implementation correctly includes the full Antigravity path and the agent-specific .agent/skills directory as mentioned in the PR objectives.

📝 Proposed fix to match actual implementation
 export function getDefaultSkillPaths(cwd: string = process.cwd(), home: string = homedir()): string[] {
     return [
+        // Canonical storage used by `skills install`
         join(home, '.skills'),
         join(cwd, '.skills'),
-        join(home, '.antigravity', 'skills'),
+        // Antigravity compatibility / legacy locations
+        join(home, '.gemini', 'antigravity', 'skills'),
+        '.agent/skills',
         '.antigravity/skills',
+        // Local development skills
         './skills',
     ];
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

export function getDefaultSkillPaths(cwd: string = process.cwd(), home: string = homedir()): string[] {
    return [
        // Canonical storage used by `skills install`
        join(home, '.skills'),
        join(cwd, '.skills'),
        // Antigravity compatibility / legacy locations
        join(home, '.gemini', 'antigravity', 'skills'),
        '.agent/skills',
        '.antigravity/skills',
        // Local development skills
        './skills',
    ];
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/superpowers/plans/2026-06-01-skill-discovery-paths.md` around lines 99 -
107, The plan's getDefaultSkillPaths implementation is missing two entries
present in the real loader: add join(home, ".gemini", "antigravity", "skills")
and the ".agent/skills" path to the returned array in getDefaultSkillPaths so
the plan matches the actual implementation; locate the getDefaultSkillPaths
function and update its returned list to include these two paths in the
appropriate order to mirror the loader.

Addressed in commits bea1b49 to eb8a3f1

_⚠️ Potential issue_ | _🟡 Minor_ | _⚡ Quick win_ **Plan implementation differs from actual loader code.** The `getDefaultSkillPaths` implementation in the plan (lines 99-107) doesn't match the actual implementation shown in context snippets: **Plan is missing:** - `join(home, ".gemini", "antigravity", "skills")` (the plan shows shorter `join(home, '.antigravity', 'skills')`) - `".agent/skills"` directory **Actual implementation has 6 paths, plan shows 5.** This discrepancy could mislead readers referencing this plan document. The actual implementation correctly includes the full Antigravity path and the agent-specific `.agent/skills` directory as mentioned in the PR objectives. <details> <summary>📝 Proposed fix to match actual implementation</summary> ```diff export function getDefaultSkillPaths(cwd: string = process.cwd(), home: string = homedir()): string[] { return [ + // Canonical storage used by `skills install` join(home, '.skills'), join(cwd, '.skills'), - join(home, '.antigravity', 'skills'), + // Antigravity compatibility / legacy locations + join(home, '.gemini', 'antigravity', 'skills'), + '.agent/skills', '.antigravity/skills', + // Local development skills './skills', ]; } ``` </details> <!-- suggestion_start --> <details> <summary>📝 Committable suggestion</summary> > ‼️ **IMPORTANT** > Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements. ```suggestion export function getDefaultSkillPaths(cwd: string = process.cwd(), home: string = homedir()): string[] { return [ // Canonical storage used by `skills install` join(home, '.skills'), join(cwd, '.skills'), // Antigravity compatibility / legacy locations join(home, '.gemini', 'antigravity', 'skills'), '.agent/skills', '.antigravity/skills', // Local development skills './skills', ]; } ``` </details> <!-- suggestion_end --> <details> <summary>🤖 Prompt for AI Agents</summary> ``` Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/superpowers/plans/2026-06-01-skill-discovery-paths.md` around lines 99 - 107, The plan's getDefaultSkillPaths implementation is missing two entries present in the real loader: add join(home, ".gemini", "antigravity", "skills") and the ".agent/skills" path to the returned array in getDefaultSkillPaths so the plan matches the actual implementation; locate the getDefaultSkillPaths function and update its returned list to include these two paths in the appropriate order to mirror the loader. ``` </details> <!-- fingerprinting:phantom:triton:puma --> <!-- This is an auto-generated comment by CodeRabbit --> ✅ Addressed in commits bea1b49 to eb8a3f1
@ -1,87 +1,171 @@
/**
coderabbitai[bot] (Migrated from github.com) commented 2026-06-04 15:19:14 +00:00

⚠️ Potential issue | 🟡 Minor | Quick win

Print the actual computed search paths instead of a hardcoded list.

Lines 63–69 can become stale and misleading because discovery now includes additional agent-specific directories.

Proposed fix
 						console.log(chalk.yellow("No skills found."));
 						console.log(chalk.gray("Skills are searched in:"));
-						console.log(chalk.gray("  - ~/.skills/"));
-						console.log(chalk.gray("  - ./.skills/"));
-						console.log(chalk.gray("  - ~/.gemini/antigravity/skills/"));
-						console.log(chalk.gray("  - .agent/skills/"));
-						console.log(chalk.gray("  - .antigravity/skills/"));
-						console.log(chalk.gray("  - ./skills/"));
+						for (const p of config.searchPaths) {
+							console.log(chalk.gray(`  - ${p}`));
+						}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

					console.log(chalk.yellow("No skills found."));
					console.log(chalk.gray("Skills are searched in:"));
					for (const p of config.searchPaths) {
						console.log(chalk.gray(`  - ${p}`));
					}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/cli/commands/list.ts` around lines 63 - 69, The printed skill-paths are
hardcoded; update the block in src/cli/commands/list.ts to print the actual
computed search paths instead. Locate where the skill discovery array is built
(e.g., variable or function name like searchPaths, skillSearchPaths, or
getSkillSearchPaths) and replace the fixed console.log lines with code that logs
the header ("Skills are searched in:") then iterates over that array and logs
each path with chalk.gray. Ensure you reference the existing computed array name
(searchPaths/skillSearchPaths/getSkillSearchPaths) so the output always reflects
the real discovery locations.

Addressed in commits bea1b49 to eb8a3f1

_⚠️ Potential issue_ | _🟡 Minor_ | _⚡ Quick win_ **Print the actual computed search paths instead of a hardcoded list.** Lines 63–69 can become stale and misleading because discovery now includes additional agent-specific directories. <details> <summary>Proposed fix</summary> ```diff console.log(chalk.yellow("No skills found.")); console.log(chalk.gray("Skills are searched in:")); - console.log(chalk.gray(" - ~/.skills/")); - console.log(chalk.gray(" - ./.skills/")); - console.log(chalk.gray(" - ~/.gemini/antigravity/skills/")); - console.log(chalk.gray(" - .agent/skills/")); - console.log(chalk.gray(" - .antigravity/skills/")); - console.log(chalk.gray(" - ./skills/")); + for (const p of config.searchPaths) { + console.log(chalk.gray(` - ${p}`)); + } ``` </details> <!-- suggestion_start --> <details> <summary>📝 Committable suggestion</summary> > ‼️ **IMPORTANT** > Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements. ```suggestion console.log(chalk.yellow("No skills found.")); console.log(chalk.gray("Skills are searched in:")); for (const p of config.searchPaths) { console.log(chalk.gray(` - ${p}`)); } ``` </details> <!-- suggestion_end --> <details> <summary>🤖 Prompt for AI Agents</summary> ``` Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/cli/commands/list.ts` around lines 63 - 69, The printed skill-paths are hardcoded; update the block in src/cli/commands/list.ts to print the actual computed search paths instead. Locate where the skill discovery array is built (e.g., variable or function name like searchPaths, skillSearchPaths, or getSkillSearchPaths) and replace the fixed console.log lines with code that logs the header ("Skills are searched in:") then iterates over that array and logs each path with chalk.gray. Ensure you reference the existing computed array name (searchPaths/skillSearchPaths/getSkillSearchPaths) so the output always reflects the real discovery locations. ``` </details> <!-- fingerprinting:phantom:poseidon:hawk --> <!-- This is an auto-generated comment by CodeRabbit --> ✅ Addressed in commits bea1b49 to eb8a3f1
@ -0,0 +1,45 @@
import { describe, expect, it } from "vitest";
coderabbitai[bot] (Migrated from github.com) commented 2026-06-04 15:19:14 +00:00

⚠️ Potential issue | 🟡 Minor | Quick win

Use homedir() in the test instead of process.env.HOME.

Line 17 can diverge from runtime path resolution used by production code, causing environment-dependent failures.

Proposed fix
-import { tmpdir } from "os";
+import { homedir, tmpdir } from "os";
@@
-		const home = process.env.HOME || "";
+		const home = homedir();
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/core/loader.test.ts` around lines 17 - 21, The test is using
process.env.HOME which can differ from the OS homedir used in production; update
the assertion to use homedir() instead of process.env.HOME so
DEFAULT_SKILL_PATHS is compared against join(homedir(), ".skills"); ensure you
import homedir from 'os' at the top of the test file if it's not already
imported and keep the rest of the assertions (e.g., join(process.cwd(),
".skills")) unchanged.

Addressed in commits bea1b49 to eb8a3f1

_⚠️ Potential issue_ | _🟡 Minor_ | _⚡ Quick win_ **Use `homedir()` in the test instead of `process.env.HOME`.** Line 17 can diverge from runtime path resolution used by production code, causing environment-dependent failures. <details> <summary>Proposed fix</summary> ```diff -import { tmpdir } from "os"; +import { homedir, tmpdir } from "os"; @@ - const home = process.env.HOME || ""; + const home = homedir(); ``` </details> <details> <summary>🤖 Prompt for AI Agents</summary> ``` Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/core/loader.test.ts` around lines 17 - 21, The test is using process.env.HOME which can differ from the OS homedir used in production; update the assertion to use homedir() instead of process.env.HOME so DEFAULT_SKILL_PATHS is compared against join(homedir(), ".skills"); ensure you import homedir from 'os' at the top of the test file if it's not already imported and keep the rest of the assertions (e.g., join(process.cwd(), ".skills")) unchanged. ``` </details> <!-- fingerprinting:phantom:poseidon:hawk --> <!-- This is an auto-generated comment by CodeRabbit --> ✅ Addressed in commits bea1b49 to eb8a3f1
@ -204,1 +1,3 @@
}
/**
* Skill Loader Module
* Handles discovery and loading of skills from the filesystem
coderabbitai[bot] (Migrated from github.com) commented 2026-06-04 15:19:14 +00:00

⚠️ Potential issue | 🟡 Minor | Quick win

Respect explicit maxDepth: 0 in discovery config.

Line 63 uses config.maxDepth || 3, so an explicit 0 is ignored and replaced with 3.

Proposed fix
-				maxDepth: config.maxDepth || 3,
+				maxDepth: config.maxDepth ?? 3,
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

				maxDepth: config.maxDepth ?? 3,
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/core/loader.ts` at line 63, The discovery config currently sets maxDepth
using the falsy-coalescing pattern (config.maxDepth || 3) which ignores an
explicit 0; change this to use an undefined-only fallback so 0 is respected
(e.g., use the nullish coalescing operator or an explicit undefined check).
Update the location where maxDepth is assigned (the object property maxDepth in
loader/discovery setup that references config.maxDepth) to use config.maxDepth
?? 3 or (config.maxDepth !== undefined ? config.maxDepth : 3) so an explicit
maxDepth: 0 is honored.

Addressed in commits bea1b49 to eb8a3f1

_⚠️ Potential issue_ | _🟡 Minor_ | _⚡ Quick win_ **Respect explicit `maxDepth: 0` in discovery config.** Line 63 uses `config.maxDepth || 3`, so an explicit `0` is ignored and replaced with `3`. <details> <summary>Proposed fix</summary> ```diff - maxDepth: config.maxDepth || 3, + maxDepth: config.maxDepth ?? 3, ``` </details> <!-- suggestion_start --> <details> <summary>📝 Committable suggestion</summary> > ‼️ **IMPORTANT** > Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements. ```suggestion maxDepth: config.maxDepth ?? 3, ``` </details> <!-- suggestion_end --> <details> <summary>🤖 Prompt for AI Agents</summary> ``` Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/core/loader.ts` at line 63, The discovery config currently sets maxDepth using the falsy-coalescing pattern (config.maxDepth || 3) which ignores an explicit 0; change this to use an undefined-only fallback so 0 is respected (e.g., use the nullish coalescing operator or an explicit undefined check). Update the location where maxDepth is assigned (the object property maxDepth in loader/discovery setup that references config.maxDepth) to use config.maxDepth ?? 3 or (config.maxDepth !== undefined ? config.maxDepth : 3) so an explicit maxDepth: 0 is honored. ``` </details> <!-- fingerprinting:phantom:poseidon:hawk --> <!-- This is an auto-generated comment by CodeRabbit --> ✅ Addressed in commits bea1b49 to eb8a3f1
This pull request has changes conflicting with the target branch.
  • README.md
  • docs/superpowers/plans/2026-06-01-skill-discovery-paths.md
  • src/cli/agents.ts
  • src/cli/commands/list.test.ts
  • src/cli/commands/list.ts
  • src/core/loader.test.ts
  • src/core/loader.ts
View command line instructions

Manual merge helper

Use this merge commit message when completing the merge manually.

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin KirioXX/fix/improve-skill-discovery:KirioXX/fix/improve-skill-discovery
git switch KirioXX/fix/improve-skill-discovery

Merge

Merge the changes and update on Forgejo.

Warning: The "Autodetect manual merge" setting is not enabled for this repository, you will have to mark this pull request as manually merged afterwards.

git switch master
git merge --no-ff KirioXX/fix/improve-skill-discovery
git switch KirioXX/fix/improve-skill-discovery
git rebase master
git switch master
git merge --ff-only KirioXX/fix/improve-skill-discovery
git switch KirioXX/fix/improve-skill-discovery
git rebase master
git switch master
git merge --no-ff KirioXX/fix/improve-skill-discovery
git switch master
git merge --squash KirioXX/fix/improve-skill-discovery
git switch master
git merge --ff-only KirioXX/fix/improve-skill-discovery
git switch master
git merge KirioXX/fix/improve-skill-discovery
git push origin master
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
rtlabs-llm-agents/agent-skills-cli!17
No description provided.