github / github/copilot-cli

Support git symlinks in plugin install on Windows

Abierto
#2,286 3 comentarios 0 reacciones 0 asignados Ver en GitHub
area:installation area:platform-windows area:plugins
Lenguaje dominante
Shell
Estrellas
11.2k
Forks
1.9k
Merge medio
14 h 16 min
PR fusionados (30 d)
6

Descripción

### Describe the feature or problem you'd like to solve

Plugin install should resolve git symlink text stubs on Windows (`core.symlinks=false`)

### Proposed solution

When `copilot plugin install` clones a marketplace repository on Windows, Git for Windows (which defaults to `core.symlinks=false`) materializes symlinks as plain-text files containing the target path instead of creating actual symlinks. The CLI reads these text stubs as literal file content, causing agents, skills, commands, and instructions to fail with "missing or malformed YAML frontmatter" errors. On Linux and macOS this works correctly because git creates real symlinks.

We'd love to see the CLI handle this transparently so plugin authors don't need to restructure their repositories. A few ideas, roughly in order of impact:

**1. Post-clone symlink resolution (most robust)**

After `git clone`, detect and resolve text stubs:

- Use `git ls-files -s` to identify mode `120000` entries (symlinks)
- Check if the working-tree file is a small text file containing a relative path (text stub) rather than actual content
- Resolve each stub's path against the full cloned repository tree and copy the real file content in place
- Warn the user if resolution fails

This works regardless of the user's OS configuration and requires no changes from plugin authors.

**2. Clone with `-c core.symlinks=true` (low effort, partial fix)**

Passing `-c core.symlinks=true` to `git clone` helps Windows machines where Developer Mode is enabled. Note: without Developer Mode, `CreateSymbolicLinkW` silently fails and git writes text stubs anyway with exit code 0 — so this alone is not sufficient but is a nice baseline improvement.

**3. Detect and warn on broken installations**

If the CLI detects text stubs (small files starting with `../` in agent/skill/command directories), emit a clear diagnostic explaining the symlink issue and suggesting remediation.

**4. Future consideration: additional source types**

Looking ahead, we wonder whether the `source` field in `marketplace.json` could eventually support distribution mechanisms beyond git clones — for example, npm packages or archive URLs. Package managers like npm resolve symlinks during `npm pack`, producing tarballs with real file content. This would eliminate the problem entirely for plugin authors who can publish to a package registry. We understand this may be a longer-term consideration and wanted to note it as a potential direction.

### Example prompts or workflows

**Broken workflow on Windows (current behavior):**

```bash
# 1. Register the marketplace
copilot plugin marketplace add microsoft/hve-core

# 2. Install a plugin
copilot plugin install hve-core@hve-core

# 3. Start interactive session
copilot

# 4. Try to use an agent
> /agent
# Result: agents are listed but produce "missing or malformed YAML frontmatter" errors
# Every agent file contains a path string like "../../../../.github/agents/hve-core/task-planner.agent.md"
# instead of the actual agent definition with YAML frontmatter
```

**Working workflow on Linux/macOS/WSL (same steps, no errors):**

The exact same commands produce a fully functional installation because git creates real symlinks that resolve correctly within the cloned repository tree.

**Expected behavior after fix:**

```bash
copilot plugin marketplace add microsoft/hve-core
copilot plugin install hve-core@hve-core
copilot
> /agent
# All agents load correctly with proper YAML frontmatter — identical to Linux/macOS behavior
```

### Additional context

### Why plugin authors use symlinks

Symlinks are a natural fit for plugin marketplaces that offer multiple collections assembled from shared source artifacts. Rather than duplicating hundreds of files across collections, the repository maintains one copy of each artifact and uses symlinks in plugin directories. This is a standard git workflow that works on Linux/macOS and in CI environments.

### Affected repositories

**microsoft/hve-core** ([issue #785](https://github.com/microsoft/hve-core/issues/785)) — 14 plugin collections, 546 git symlinks (mode `120000`). Every one becomes a broken text stub on Windows. All 18 agent files produce frontmatter errors.

**github/awesome-copilot** — The official awesome-copilot marketplace hit the identical problem:
- [Issue #736](https://github.com/github/awesome-copilot/issues/736): "broken file references after Copilot CLI installation" (Windows 11, CLI v0.0.410)
- [Issue #751](https://github.com/github/awesome-copilot/issues/751): Maintainer confirmed *"the Copilot CLI clones the repo behind the scenes and does not handle symlinks properly"* and *"Clearly, the use of symlinks was going to be a problem going forward."*
- [PR #750](https://github.com/github/awesome-copilot/pull/750): Eliminated all 185 symlinks and introduced a publish pipeline that materializes files — a workaround for this CLI limitation

### Current workarounds available to plugin authors

1. **Inline copies** — Replace symlinks with real file copies. Awesome-copilot adopted this. Works but introduces duplication and requires sync pipelines.
2. **Separate distribution repo** — Use the object form of `source` in marketplace.json pointing to a repo with real files. Adds cross-repo maintenance overhead.
3. **Manual user fix** — Ask Windows users to enable Developer Mode + `git config --global core.symlinks true` + clear cache + reinstall. Fragile, enterprise-hostile, doesn't scale.

None address the root cause. We'd love to avoid requiring every plugin marketplace author to restructure their repositories for a platform-specific git behavior.

### Environment details

- **Copilot CLI:** Tested with v0.0.410+ through current
- **Git for Windows:** Default `core.symlinks=false` (all install methods: winget, Chocolatey, official installer — checkbox unchecked by default)
- **Windows:** 10/11, Developer Mode disabled (enterprise default — frequently locked by Group Policy)
- **Working environments:** Linux, macOS, WSL (all default to `core.symlinks=true`)
- **Industry precedent:** Every major package ecosystem (npm, Cargo, Go modules, pip) resolves symlinks at publish/install time rather than relying on consumer OS support

Thank you for considering this request. We're happy to provide additional details, test proposed changes, or help validate a fix.

Guía de contribución

Abrir la guía de contribución

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.