Follow-up from "Restructure repo to have flexible distribution options"
The following discussions from !17 should be addressed:
- [ ] @pshutsin started a [discussion](https://gitlab.com/gitlab-org/ai/skills/-/merge_requests/17#note_3184360175): (+1 comment)
> `plugin.json` has higher priority so in `marketplace.json` we can only specify name in source in the marketplace file.
- [ ] @pshutsin started a [discussion](https://gitlab.com/gitlab-org/ai/skills/-/merge_requests/17#note_3184360209):
> this script is autoupdated by CC. I wonder if we should follow next approach:
>
> 1. `.claude-plugin/plugins` directory has list of committed plugins.
> 2. we have a script to add a skill to specific CC plugin
> 3. we have a script to add new empty CC plugin.
>
> That way we don't have to have each skill as a separate plugin and we can bundle skills as we want.
- [ ] @pshutsin started a [discussion](https://gitlab.com/gitlab-org/ai/skills/-/merge_requests/17#note_3184379947): (+1 comment)
> @dgruzd @erran this is a draft structure we can use:
>
> ```
> ./
> ├── src/
> │ └── skills/ # Skill source files (single source of truth)
> │ ├── glab/
> │ ├── opencode-refine/
> │ └── run-in-tmux-pane/
> │
> ├── .opencode/
> │ └── skills/ # OpenCode distribution (directory symlinks)
> │ ├── glab -> ../../src/skills/glab
> │ ├── opencode-refine -> ../../src/skills/opencode-refine
> │ └── run-in-tmux-pane -> ../../src/skills/run-in-tmux-pane
> │
> ├── .claude-plugin/ # Claude Code marketplace distribution
> │ ├── marketplace.json
> │ └── plugins/
> │ ├── glab/
> │ │ ├── plugin.json
> │ │ └── skills/glab -> ../../../../src/skills/glab
> │ ├── opencode-refine/
> │ │ ├── plugin.json
> │ │ └── skills/opencode-refine -> ../../../../src/skills/opencode-refine
> │ └── run-in-tmux-pane/
> │ ├── plugin.json
> │ └── skills/run-in-tmux-pane -> ../../../../src/skills/run-in-tmux-pane
> ```
>
> `src` is for actual source of skills\commands\agents\hooks and `.opencode`, `.claude-plugin`, `.codex`, `.cursor-plugin` for encapsulated distribution logic for specific environment.
>
> Before I work more in this direction I'd love to hear your thoughts on it.
- [ ] @pshutsin started a [discussion](https://gitlab.com/gitlab-org/ai/skills/-/merge_requests/17#note_3186727223): (+1 comment)
> @erran @dgruzd I'm a bit confused about `compatibility: opencode` line. As far as I understand now it's purely informative now? There's no dependencies which block the skills from being executed by Claude or other envs? I wonder if we need this line at all with this MR? Since this MR introduces separate distribution configs for each common environment we can simply assume that "if a skill in `.claude-plugin` directory it means it's compatible with CC", can't we?
- [ ] @dgruzd started a [discussion](https://gitlab.com/gitlab-org/ai/skills/-/merge_requests/17#note_3189220899): (+1 comment)
> > [!note]
> > An agent helped me draft this quickly
>
> ## 🔴 The `src/` move breaks existing installations, and doesn't need to happen
>
> The MR moves skill sources from `skills/<name>/` to `src/skills/<name>/`. I don't think this adds enough value to justify the cost.
>
> **What breaks:**
>
> 1. All existing users who installed via `@dgruzd/skills add https://gitlab.com/gitlab-org/ai/skills/-/tree/main/skills ...` - the `skills/` path is now gone. Their next `skills update` or `skills check` will fail silently or error.
>
> 2. The install URL in the README (and any docs referencing it) needs to change, with no automatic redirect or deprecation window.
>
> 3. Agents that have `.agents/skills/<name> -> .../gitlab-org/ai/skills/skills/<name>` symlinks in their configs (which is the documented manual install path) now have dead symlinks.
>
> **What `src/` adds:** Nothing that can't be achieved by pointing distribution directories at `./skills/` instead of `./src/skills/`. The distribution goal is separating the "source" tree from the "agent-facing" install manifests. But the _only_ consumers of `src/` are going to be symlinks in `.opencode/` and `.claude-plugin/`. There's no human or tool that benefits from the extra `src/` layer.
>
> **Concrete alternative:** Keep `skills/<name>/` as canonical. Change the symlinks:
>
> ```
> # Instead of:
> .opencode/skills/glab -> ../../src/skills/glab
>
> # Do:
> .opencode/skills/glab -> ../../skills/glab
> ```
>
> Same result. Zero breaking changes. All the other improvements in this MR (the `generate_opencode.py` script, the `verify-opencode` CI job, the `.claude-plugin/plugins/` restructure, the minimal `marketplace.json` entries) survive unchanged.
>
> ---
>
> ## 🟡 Symlink portability — worth documenting
>
> The committed symlinks (`.opencode/skills/*`, `.claude-plugin/plugins/*/skills/*`) are relative symlinks stored as git blobs. This works great on Linux and macOS. On Windows, git requires either Developer Mode or `core.symlinks=true`, which isn't the default in most Windows setups. Without it, git silently materializes these as text files containing the path — which would make the plugin/skill loading fail in ways that are hard to diagnose.
>
> I'm not saying this is a blocker, we're primarily targeting Linux/macOS environments. But it should be documented in `doc/contributing.md` or the README, and we should decide whether Windows support is in or out of scope for this repo.
>
> The new `verify-opencode` CI job (Linux/Alpine) won't catch Windows issues, which is fine, but it's worth calling out explicitly.
>
> ---
>
> ## 🟡 `marketplace.json` format change — interaction with ai/marketplace !1
>
> The `marketplace.json` change removes per-entry metadata (`description`, `version`, `author`, `license`) from marketplace entries, keeping only `name` + `source`. This is cleaner — metadata lives in `plugin.json` where `plugin.json` takes precedence anyway.
>
> But this is a format change. Claude Code users who installed the plugin before this MR (with the old `source: ./skills/<name>` entries) may see plugin loading issues after their next sync. Worth noting in the MR description as a known breakage + "reinstall required" note in the README.
>
> Also: this MR changes the interaction with `ai/marketplace !1`, which points to the skills repo URL expecting to enumerate its `marketplace.json`. The restructure of `marketplace.json` source paths is fine from the marketplace's perspective (it just follows the URL indirection), but the compatibility window for existing installs is something to think about.
>
> ---
>
> ## Summary
>
> My ask: try flipping the symlinks to point at `./skills/<name>` instead of `./src/skills/<name>`, and drop the `src/` move entirely. Everything else in this MR can land as-is in my personal opinion (we still need approval of other maintainers).
>
> WDYT?
- [ ] @erran started a [discussion](https://gitlab.com/gitlab-org/ai/skills/-/merge_requests/17#note_3194452912):
> We could just let this script fail if marketplace.json is missing right?
- [ ] @erran started a [discussion](https://gitlab.com/gitlab-org/ai/skills/-/merge_requests/17#note_3194452931):
> ````suggestion:-0+0
> /plugin install glab@gitlab-skills
> ```
>
> To use plugin skills you must open a different session:
>
> ```shell
> # Plugin skill becomes available once you start/resume a session:
> /glab:glab list open mrs
>
> # Auto-completes if no conflicting skills are found:
> /glab list open issue
> ````
issue