Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Add --allow-hidden-dirs flag to gh skill install#13213

Merged
SamMorrowDrums merged 1 commit into
trunkfrom
sammorrowdrums/sm-allow-hidden-dirs-flag
Apr 20, 2026
Merged

Add --allow-hidden-dirs flag to gh skill install#13213
SamMorrowDrums merged 1 commit into
trunkfrom
sammorrowdrums/sm-allow-hidden-dirs-flag

Conversation

@SamMorrowDrums
Copy link
Copy Markdown
Contributor

@SamMorrowDrums SamMorrowDrums commented Apr 17, 2026

Description

Adds --allow-hidden-dirs flag to gh skill install to support discovering skills in hidden (dot-prefixed) directories such as .claude/skills/, .agents/skills/, and .github/skills/.

Motivation

Some repositories publish skills exclusively under hidden directories (e.g. .claude/skills/). The current discovery logic only looks in standard conventions (skills/, plugins/, root-level */), so these repos appear empty to gh skill install.

We want to be less strict about where skills can live, but we do not want to fall back to pure recursive parsing of arbitrary directories. Hidden-dir discovery uses the same structured conventions as standard discovery, just rooted under a dot-prefixed host directory:

  • .{host}/skills/*/SKILL.md (hidden-dir)
  • .{host}/skills/{scope}/*/SKILL.md (hidden-dir-namespaced)

This keeps discovery predictable and convention-based while supporting real-world repos.

Why this is opt-in

Hidden directories are typically installation targets (where consumers store skills) rather than publication roots (where publishers share skills). Skills found in these directories may be committed copies from another publisher, making attribution unclear. Keeping this behind a flag:

  • Preserves the distinction between publishing and consuming
  • Warns users that skills found in hidden dirs may be redistributed copies
  • Unblocks users who need to install from repos that only publish in hidden dirs

Architecture

Discovery layer returns all skills; callers decide filtering. Following review feedback, the discovery package no longer references CLI flags:

  • DiscoverSkillsWithOptions / DiscoverLocalSkillsWithOptions always return all skills (standard + hidden-dir)
  • DiscoverSkills / DiscoverLocalSkills (convenience wrappers) auto-filter hidden-dir skills for backward compatibility with preview, update, and publish commands
  • The install command applies --allow-hidden-dirs flag logic via filterHiddenDirSkills(), showing a clear error when hidden skills exist but the flag is not set

UX

Error when hidden skills exist but flag is not set:

no standard skills found, but 3 skill(s) exist in hidden directories
  Use --allow-hidden-dirs to include them

Warning when --allow-hidden-dirs is set:

! Skills in hidden directories (e.g. .claude/, .agents/) may be installed
  copies from another publisher. Verify the skill's origin and check for a
  canonical source.

Example

# Without flag - clear guidance
$ gh skill install mrgoonie/claudekit-skills
no standard skills found, but 45 skill(s) exist in hidden directories
  Use --allow-hidden-dirs to include them

# With flag - discovers and warns
$ gh skill install mrgoonie/claudekit-skills --allow-hidden-dirs
! Skills in hidden directories (e.g. .claude/, .agents/) may be installed
  copies from another publisher. ...
? Select skill(s) to install:
> [ ]  [hidden-dir] aesthetic
  [ ]  [hidden-dir] ai-multimodal
  [ ]  [hidden-dir] backend-development

Works with both remote repos and --from-local.

Fixes #13197

Related: https://github.com/orgs/community/discussions/192851

@SamMorrowDrums SamMorrowDrums requested a review from a team April 17, 2026 18:50
@SamMorrowDrums SamMorrowDrums requested a review from a team as a code owner April 17, 2026 18:50
@SamMorrowDrums SamMorrowDrums requested review from Copilot and williammartin and removed request for Copilot April 17, 2026 18:50
@SamMorrowDrums SamMorrowDrums force-pushed the sammorrowdrums/sm-allow-hidden-dirs-flag branch from 3352e80 to f5505ac Compare April 17, 2026 18:55
Copilot AI review requested due to automatic review settings April 17, 2026 18:55
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds an opt-in --allow-hidden-dirs flag to gh skill install to discover skills stored under dot-prefixed directories (e.g. .claude/skills/, .agents/skills/), including improved messaging and warnings about potential attribution concerns.

Changes:

  • Introduces hidden-directory discovery conventions and options-based discovery APIs (remote + local).
  • Updates install flow to wire --allow-hidden-dirs into discovery and warn when hidden-dir skills are included.
  • Adds tests for hidden-dir matching and discovery option behavior.
Show a summary per file
File Description
pkg/cmd/skills/install/install.go Adds the --allow-hidden-dirs flag, uses options-based discovery, and prints a hidden-dir warning when applicable.
internal/skills/discovery/discovery.go Implements hidden-dir conventions, discovery options, and hidden-skill counting for improved “no skills found” messaging.
internal/skills/discovery/discovery_test.go Adds unit tests for hidden-dir matching, discovery options behavior, and display name/warning helpers.

Copilot's findings

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 3/3 changed files
  • Comments generated: 3

Comment thread pkg/cmd/skills/install/install.go
Comment thread internal/skills/discovery/discovery.go Outdated
Comment on lines +522 to +530
msg := fmt.Sprintf("no skills found in %s/%s\n"+
" Expected skills in skills/*/SKILL.md, skills/{scope}/*/SKILL.md,\n"+
" */SKILL.md, or plugins/*/skills/*/SKILL.md\n"+
" This repository may be a curated list rather than a skills publisher",
owner, repo)
if hiddenCount > 0 {
msg += fmt.Sprintf("\n Found %d skill(s) in hidden directories - use --allow-hidden-dirs to include them", hiddenCount)
}
return nil, errors.New(msg)
Copy link

Copilot AI Apr 17, 2026

Choose a reason for hiding this comment

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

The discovery package’s “no skills found” error message hard-codes an install-command flag ("use --allow-hidden-dirs"). DiscoverSkills is also used by other commands (e.g. pkg/cmd/skills/preview/preview.go:154, pkg/cmd/skills/update/update.go:283), so they can end up emitting guidance for a flag they don’t support. Consider returning a typed error that includes HiddenCount, and let each command decide how to format user-facing guidance (or make the hint configurable via DiscoverOptions).

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I agree with this - let's emit a typed error and consume it higher up the stack in the gh skill install command logic.

Comment thread internal/skills/discovery/discovery.go Outdated
Comment on lines +885 to +892
msg := fmt.Sprintf("no skills found in %s\n"+
" Expected SKILL.md in the directory, or skills in skills/*/SKILL.md,\n"+
" skills/{scope}/*/SKILL.md, */SKILL.md, or plugins/*/skills/*/SKILL.md",
dir)
if hiddenCount > 0 {
msg += fmt.Sprintf("\n Found %d skill(s) in hidden directories - use --allow-hidden-dirs to include them", hiddenCount)
}
return nil, errors.New(msg)
Copy link

Copilot AI Apr 17, 2026

Choose a reason for hiding this comment

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

Same issue for local discovery: the returned error message includes "use --allow-hidden-dirs", but DiscoverLocalSkills is consumed by other commands like gh skill publish (pkg/cmd/skills/publish/publish.go:188). This couples a shared library error to a specific CLI flag. Prefer a typed error (including hidden-skill count) and have the CLI layer append flag-specific guidance only where supported.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Yeah, Copilot's right. Mixing display/business logic ties our hands like this.

How about returning both normal and hidden skills from this function, and then at the caller side we decide on the error message (based on one being empty and the other non-empty)?

@BagToad BagToad self-requested a review April 17, 2026 19:14
Copy link
Copy Markdown
Member

@babakks babakks left a comment

Choose a reason for hiding this comment

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

LGTM, except for missing tests. I approve in case you're planning to do a follow up for tests.

Comment thread internal/skills/discovery/discovery.go
Comment thread internal/skills/discovery/discovery.go
Comment thread internal/skills/discovery/discovery.go Outdated
Comment on lines +885 to +892
msg := fmt.Sprintf("no skills found in %s\n"+
" Expected SKILL.md in the directory, or skills in skills/*/SKILL.md,\n"+
" skills/{scope}/*/SKILL.md, */SKILL.md, or plugins/*/skills/*/SKILL.md",
dir)
if hiddenCount > 0 {
msg += fmt.Sprintf("\n Found %d skill(s) in hidden directories - use --allow-hidden-dirs to include them", hiddenCount)
}
return nil, errors.New(msg)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Yeah, Copilot's right. Mixing display/business logic ties our hands like this.

How about returning both normal and hidden skills from this function, and then at the caller side we decide on the error message (based on one being empty and the other non-empty)?

Comment thread internal/skills/discovery/discovery_test.go
Comment on lines +916 to +921
{
name: "hidden dirs excluded by default",
opts: DiscoverOptions{},
tree: hiddenDirTree,
wantErr: "Found 2 skill(s) in hidden directories",
},
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Let's also have an edge-case test for when there' no skill at all.

Comment thread pkg/cmd/skills/install/install.go
Comment thread pkg/cmd/skills/install/install.go Outdated
Comment on lines +1078 to +1083
// printHiddenDirWarning warns that skills found in hidden directories may be
// installed copies from another publisher rather than original publications.
func printHiddenDirWarning(w io.Writer, cs *iostreams.ColorScheme) {
fmt.Fprintf(w, "%s Skills in hidden directories (e.g. .claude/, .agents/) may be installed copies\n"+
" from another publisher. Verify the skill's origin and check for a canonical source.\n", cs.WarningIcon())
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

💭 Could consider inlining this
💅 Should be a heredoc.Docf string for readability

@oWretch
Copy link
Copy Markdown

oWretch commented Apr 20, 2026

One comment on the provenance issue for skills in hidden directories (which I mentioned in community/community#192851) would be to inspect the metadata of the found skill and preserve the upstream location metadata if it already existed. This would retain the link to the original skill publisher (for attribution) but probably needs a warning or notice to the user that they aren't actually installing from the specified location.

Move --allow-hidden-dirs filtering logic from the discovery package to
the install command, addressing review feedback. Discovery functions now
always return all skills (including hidden-dir), and callers decide how
to handle them.

Changes:
- DiscoverSkillsWithOptions/DiscoverLocalSkillsWithOptions always return
  hidden-dir skills; callers filter using IsHiddenDirConvention()
- DiscoverSkills/DiscoverLocalSkills (convenience wrappers) auto-filter
  hidden-dir skills for backward compatibility with preview/update/publish
- Remove --allow-hidden-dirs reference from discovery error messages
- Add filterHiddenDirSkills in install.go with caller-side flag logic
- Inline warning using heredoc.Docf, remove printHiddenDirWarning
- Add inline comments in matchHiddenDirConventions (babakks nitpicks)
- Add non-hidden-namespaced dir and no-skills-at-all test cases
- Add --allow-hidden-dirs tests in TestNewCmdInstall, TestInstallRun,
  and TestRunLocalInstall

Co-authored-by: Copilot <[email protected]>
@SamMorrowDrums SamMorrowDrums force-pushed the sammorrowdrums/sm-allow-hidden-dirs-flag branch from f5505ac to eaa0185 Compare April 20, 2026 09:23
@SamMorrowDrums SamMorrowDrums merged commit 61a7865 into trunk Apr 20, 2026
11 checks passed
@SamMorrowDrums SamMorrowDrums deleted the sammorrowdrums/sm-allow-hidden-dirs-flag branch April 20, 2026 09:33
@SamMorrowDrums
Copy link
Copy Markdown
Contributor Author

@oWretch handling that here: #13236

tmeijn pushed a commit to tmeijn/dotfiles that referenced this pull request May 8, 2026
This MR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [cli/cli](https://github.com/cli/cli) | minor | `v2.90.0` → `v2.92.0` |

MR created with the help of [el-capitano/tools/renovate-bot](https://gitlab.com/el-capitano/tools/renovate-bot).

**Proposed changes to behavior should be submitted there as MRs.**

---

### Release Notes

<details>
<summary>cli/cli (cli/cli)</summary>

### [`v2.92.0`](https://github.com/cli/cli/releases/tag/v2.92.0): GitHub CLI 2.92.0

[Compare Source](cli/cli@v2.91.0...v2.92.0)

#### Support GitHub Enterprise Cloud (GHEC) in `skill` commandset

Now `gh skill` subcommands (`install`, `preview`, `publish`, `search`, `update`) are able to work with [GHEC](https://docs.github.com/en/enterprise-cloud@latest/admin/overview/about-github-enterprise-cloud) hosts with data residency.

#### Add `--allow-hidden-dirs` flag to `skill preview`

Following the addition of `--allow-hidden-dirs` to `skill install` in the previous release, now the flag is also supported in `skill preview`, allowing users to preview skills located in hidden (dot-prefixed) directories such as `.claude/skills/`, `.agents/skills/`, and `.github/skills/`.

#### What's Changed

##### ✨ Features

- feat(skills): add --allow-hidden-dirs flag to preview command by [@&#8203;SamMorrowDrums](https://github.com/SamMorrowDrums) in [#&#8203;13265](cli/cli#13265)
- feat(skills): support GHEC with data residency hosts by [@&#8203;SamMorrowDrums](https://github.com/SamMorrowDrums) in [#&#8203;13264](cli/cli#13264)

##### 🐛 Fixes

- Fix SetSampleRate not updating sample\_rate dimension by [@&#8203;williammartin](https://github.com/williammartin) in [#&#8203;13259](cli/cli#13259)
- Fix log terminal injection by [@&#8203;williammartin](https://github.com/williammartin) in [#&#8203;13272](cli/cli#13272)
- Add "Resource not accessible" to ProjectsV2IgnorableError by [@&#8203;maxbeizer](https://github.com/maxbeizer) in [#&#8203;13281](cli/cli#13281)

##### 📚 Docs & Chores

- fix: using variable interpolation \`${{ in deployment.yml... by [@&#8203;orbisai0security](https://github.com/orbisai0security) in [#&#8203;13258](cli/cli#13258)
- docs: correct typo in Linux Homebrew copy by [@&#8203;cassidyjames](https://github.com/cassidyjames) in [#&#8203;13273](cli/cli#13273)
- Install skills flat by Name, not namespaced InstallName by [@&#8203;SamMorrowDrums](https://github.com/SamMorrowDrums) in [#&#8203;13266](cli/cli#13266)
- chore: fix zsh completion on debian by [@&#8203;babakks](https://github.com/babakks) in [#&#8203;13274](cli/cli#13274)
- Add trust disclaimer to extension help text by [@&#8203;travellertales](https://github.com/travellertales) in [#&#8203;13296](cli/cli#13296)
- Bump Go to 1.26.2 by [@&#8203;github-actions](https://github.com/github-actions)\[bot] in [#&#8203;13301](cli/cli#13301)

##### :dependabot: Dependencies

- chore(deps): bump github.com/mattn/go-isatty from 0.0.20 to 0.0.21 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;13161](cli/cli#13161)
- chore(deps): bump github.com/google/go-containerregistry from 0.21.4 to 0.21.5 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;13162](cli/cli#13162)
- chore(deps): bump charm.land/lipgloss/v2 from 2.0.2 to 2.0.3 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;13163](cli/cli#13163)
- chore(deps): bump charm.land/bubbletea/v2 from 2.0.2 to 2.0.6 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;13206](cli/cli#13206)
- chore(deps): bump github.com/gdamore/tcell/v2 from 2.13.8 to 2.13.9 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;13241](cli/cli#13241)
- chore(deps): bump github.com/mattn/go-isatty from 0.0.21 to 0.0.22 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;13298](cli/cli#13298)

#### New Contributors

- [@&#8203;orbisai0security](https://github.com/orbisai0security) made their first contribution in [#&#8203;13258](cli/cli#13258)
- [@&#8203;cassidyjames](https://github.com/cassidyjames) made their first contribution in [#&#8203;13273](cli/cli#13273)
- [@&#8203;travellertales](https://github.com/travellertales) made their first contribution in [#&#8203;13296](cli/cli#13296)

**Full Changelog**: <cli/cli@v2.91.0...v2.92.0>

### [`v2.91.0`](https://github.com/cli/cli/releases/tag/v2.91.0): GitHub CLI 2.91.0

[Compare Source](cli/cli@v2.90.0...v2.91.0)

#### GitHub CLI now collects pseudonymous telemetry

To better understand how features are used in practice, especially as agentic adoption grows, GitHub CLI now sends pseudonymous telemetry.

See [Telemetry](https://cli.github.com/telemetry) for more details on what's collected, why, and how to opt out.

#### Support more agents in `gh skill`

Thanks to community feedback, `gh` now supports a large number of agent hosts. Run `gh skill install --help` for the list of available agents.

#### Improve skill discovery

`gh skill install` now adds the `--allow-hidden-dirs` flag to support discovering skills in hidden (dot-prefixed) directories such as `.claude/skills/`, `.agents/skills/`, and `.github/skills/`.

#### Detect skills re-published from other sources

GitHut CLI now detects if the skill to be installed is re-published from an upstream source and offers the option to install it from there. The `--upstream` flag is also added for non-interactive use cases.

#### What's Changed

##### ✨ Features

- Add support for installation in multiple agent hosts in `gh skills install` by [@&#8203;tommaso-moro](https://github.com/tommaso-moro) in [#&#8203;13209](cli/cli#13209)
- Add --allow-hidden-dirs flag to gh skill install by [@&#8203;SamMorrowDrums](https://github.com/SamMorrowDrums) in [#&#8203;13213](cli/cli#13213)
- Make skill discovery less strict: support nested `skills/` directories by [@&#8203;SamMorrowDrums](https://github.com/SamMorrowDrums) in [#&#8203;13235](cli/cli#13235)
- feat(skills): detect re-published skills and offer upstream install by [@&#8203;SamMorrowDrums](https://github.com/SamMorrowDrums) in [#&#8203;13236](cli/cli#13236)

##### 🐛 Fixes

- Fix `skills publish --fix` to not publish by [@&#8203;SamMorrowDrums](https://github.com/SamMorrowDrums) in [#&#8203;13237](cli/cli#13237)
- fix(skills): match skills by install name in preview command by [@&#8203;SamMorrowDrums](https://github.com/SamMorrowDrums) in [#&#8203;13249](cli/cli#13249)

##### 📚 Docs & Chores

- Remove misleading text by [@&#8203;tommaso-moro](https://github.com/tommaso-moro) in [#&#8203;13203](cli/cli#13203)
- Add sampled command telemetry by [@&#8203;williammartin](https://github.com/williammartin) in [#&#8203;13191](cli/cli#13191)
- Do not send telemetry for aliases by [@&#8203;williammartin](https://github.com/williammartin) in [#&#8203;13192](cli/cli#13192)
- Add skills specific telemetry by [@&#8203;williammartin](https://github.com/williammartin) in [#&#8203;13204](cli/cli#13204)
- Record CI context in telemetry by [@&#8203;williammartin](https://github.com/williammartin) in [#&#8203;13210](cli/cli#13210)
- Record official extension telemetry by [@&#8203;williammartin](https://github.com/williammartin) in [#&#8203;13205](cli/cli#13205)
- Add telemetry command by [@&#8203;williammartin](https://github.com/williammartin) in [#&#8203;13253](cli/cli#13253)
- Log when there is no telemetry by [@&#8203;williammartin](https://github.com/williammartin) in [#&#8203;13255](cli/cli#13255)
- docs(skills): add gh and gh-skill agent skills by [@&#8203;BagToad](https://github.com/BagToad) in [#&#8203;13244](cli/cli#13244)
- Enable telemetry without env var by [@&#8203;williammartin](https://github.com/williammartin) in [#&#8203;13254](cli/cli#13254)

**Full Changelog**: <cli/cli@v2.90.0...v2.91.0>

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever MR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this MR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this MR, check this box

---

This MR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xNjkuNCIsInVwZGF0ZWRJblZlciI6IjQzLjE2OS40IiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJSZW5vdmF0ZSBCb3QiLCJhdXRvbWF0aW9uOmJvdC1hdXRob3JlZCIsImRlcGVuZGVuY3ktdHlwZTo6bWlub3IiXX0=-->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

gh skill: support .claude/skills/ as a discovery path

5 participants