Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
6c88230
feat(windsurf): add Windsurf as APM compilation and integration target
jaloncad Apr 28, 2026
2aadb92
feat(windsurf): add Windsurf as APM compilation and integration target
jaloncad Apr 30, 2026
06edc27
Merge branch 'main' into feature/windsurf-target
yoelabril Apr 30, 2026
919be11
Merge branch 'main' into feature/windsurf-target
yoelabril May 1, 2026
e84f68d
Merge branch 'main' into feature/windsurf-target
yoelabril May 1, 2026
aea013f
Merge branch 'main' into feature/windsurf-target
yoelabril May 1, 2026
ac37f54
Merge branch 'main' into feature/windsurf-target
yoelabril May 2, 2026
f7cba3f
Merge branch 'main' into feature/windsurf-target
yoelabril May 2, 2026
63a23d5
merge: resolve upstream/main conflicts (agent-skills target)
jaloncad May 2, 2026
81d6917
Merge branch 'main' into feature/windsurf-target
yoelabril May 2, 2026
0fe7ac1
Merge branch 'main' into feature/windsurf-target
danielmeppiel May 2, 2026
76a1315
feat(windsurf): warn on dropped agent frontmatter (tools, model)
May 2, 2026
0beed8b
fix(security): guard hook script copy with ensure_path_within
May 2, 2026
521c0b4
docs(windsurf): add Windsurf Integration section
May 2, 2026
751c11a
test(windsurf): add coverage for adapter, hook routing, and warnings
May 2, 2026
0332c7d
refactor(targets): centralize per-target metadata to remove N+1 regis…
May 2, 2026
a3783de
fix(conflict-detector): dispatch on adapter.mcp_servers_key, repair 4…
May 2, 2026
fd63b1f
fix(pack): derive target prefixes from KNOWN_TARGETS, repair windsurf…
May 2, 2026
2babc9d
fix(compile): derive multi-target family routing from TargetProfile.c…
May 2, 2026
42f76e8
fix(install): use TargetProfile.hooks_config_display for hook log path
May 2, 2026
f8aa150
fix(targets): close residual N+1 sites surfaced by review panel
May 2, 2026
1b40e4f
fix(lint): exempt agent_integrator yaml.safe_dump from yaml-io guard
May 2, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Regression tests for `apm compile` placement of narrow `applyTo` patterns: instructions whose matches all live deep inside one subtree are now pinned to the deepest covering directory instead of being hoisted to the project root, across both selective and single-point placement strategies. Also covers the file-walk cache that skips repeated filesystem scans for the same glob. (#871)
- **`apm pack` marketplace builder hardening.** Local source paths are now emitted relative to `metadata.pluginRoot` (fixes double-prefix bug). New pass-through fields: `author`, `license`, `repository`, `keywords` (alias for `tags`). Curator-wins override semantics for `description`/`version` on remote entries. Security guards reject path traversal and absolute paths post-subtraction. (#1061)
- **Plugin manifest schema-conformance tests.** `tests/unit/test_plugin_exporter_schema.py` validates every shape of `plugin.json` produced by `apm pack` (synthesized, authored, and authored-with-stale-keys) against the vendored official schema. Companion marketplace conformance lives in `tests/unit/marketplace/test_schema_conformance.py`. (#1061)
- **APM now compiles and integrates to Windsurf/Cascade.** New first-class `--target windsurf` support: instructions deploy as `.windsurf/rules/` with trigger frontmatter, agents deploy as `.windsurf/skills/<name>/SKILL.md`, commands as `.windsurf/workflows/`, hooks merge into `.windsurf/hooks.json`, and MCP servers configure via `~/.codeium/windsurf/mcp_config.json`. Auto-detection, user-scope deployment, and `apm pack` all support the new target. (#1066)
- Slash commands installed from APM packages now surface argument hints in Claude Code -- `apm install` automatically maps prompt `input:` to Claude's `arguments:` front-matter, rewrites `${input:name}` references to `$name`, and auto-generates `argument-hint`. Argument names are validated against an allowlist to prevent YAML injection from third-party packages, and the mapping is reported at install time. (#1039)

### Changed
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

Think `package.json`, `requirements.txt`, or `Cargo.toml` — but for AI agent configuration.

GitHub Copilot · Claude Code · Cursor · OpenCode · Codex · Gemini
GitHub Copilot · Claude Code · Cursor · OpenCode · Codex · Gemini · Windsurf
Comment thread
yoelabril marked this conversation as resolved.

**[Documentation](https://microsoft.github.io/apm/)** · **[Quick Start](https://microsoft.github.io/apm/getting-started/quick-start/)** · **[CLI Reference](https://microsoft.github.io/apm/reference/cli-commands/)** · **[Roadmap](https://github.com/orgs/microsoft/projects/2304)**
Comment thread
yoelabril marked this conversation as resolved.
Comment thread
yoelabril marked this conversation as resolved.

Expand Down Expand Up @@ -67,7 +67,7 @@ One command, no configuration -- VS Code and GitHub Copilot read the file automa

One `apm.yml` describes every primitive your agents need — instructions, skills, prompts, agents, hooks, plugins, MCP servers — and `apm install` reproduces the exact same setup across every client on every machine. `apm.lock.yaml` pins the resolved tree the way `package-lock.json` does for npm.

- **[One manifest for everything](https://microsoft.github.io/apm/reference/primitive-types/)** — declared once, deployed across Copilot, Claude, Cursor, OpenCode, Codex, Gemini
- **[One manifest for everything](https://microsoft.github.io/apm/reference/primitive-types/)** — declared once, deployed across Copilot, Claude, Cursor, OpenCode, Codex, Gemini, Windsurf
- **[Install from anywhere](https://microsoft.github.io/apm/guides/dependencies/)** — GitHub, GitLab, Bitbucket, Azure DevOps, GitHub Enterprise, any git host
- **[Transitive dependencies](https://microsoft.github.io/apm/guides/dependencies/)** — packages can depend on packages; APM resolves the full tree
- **[Author plugins](https://microsoft.github.io/apm/guides/plugins/)** — build Copilot, Claude, and Cursor plugins with dependency management, then export standard `plugin.json`
Expand Down Expand Up @@ -145,7 +145,7 @@ apm marketplace add github/awesome-copilot
apm install azure-cloud-development@awesome-copilot
```

Or add an MCP server (wired into Copilot, Claude, Cursor, Codex, OpenCode, and Gemini):
Or add an MCP server (wired into Copilot, Claude, Cursor, Codex, OpenCode, Gemini, and Windsurf):

```bash
apm install --mcp io.github.github/github-mcp-server --transport http # connects over HTTPS
Expand Down
1 change: 1 addition & 0 deletions build/apm.spec
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ hiddenimports = [
'apm_cli.adapters.client',
'apm_cli.adapters.client.base',
'apm_cli.adapters.client.vscode',
'apm_cli.adapters.client.windsurf',
'apm_cli.adapters.package_manager',
'apm_cli.compilation', # Add compilation module
'apm_cli.compilation.agents_compiler',
Expand Down
8 changes: 6 additions & 2 deletions docs/src/content/docs/guides/compilation.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ sidebar:
order: 1
---

Compilation is **optional for some users**. If your team uses GitHub Copilot, Claude, or Cursor, `apm install` deploys all primitives in their native format -- you can skip this guide entirely. For Gemini, `apm install` deploys commands, skills, and hooks, but instructions require `apm compile` to generate `GEMINI.md`. For OpenCode and Codex, `apm install` deploys agents, commands, skills, and hooks, but instructions require `apm compile` to generate `AGENTS.md`.
Compilation is **optional for some users**. If your team uses GitHub Copilot, Claude, or Cursor, `apm install` deploys all primitives in their native format -- you can skip this guide entirely. For Gemini, `apm install` deploys commands, skills, and hooks, but instructions require `apm compile` to generate `GEMINI.md`. For OpenCode and Codex, `apm install` deploys agents, commands, skills, and hooks, but instructions require `apm compile` to generate `AGENTS.md`. For Windsurf, `apm install` deploys all primitives natively (instructions to `.windsurf/rules/`, agents to `.windsurf/skills/`); `apm compile` is optional if you also want a compiled `AGENTS.md` roll-up.

**Solving the AI agent scalability problem through constraint satisfaction optimization**

Expand All @@ -24,6 +24,7 @@ When you run `apm compile` without specifying a target, APM automatically detect
| `.claude/` folder only | `claude` | CLAUDE.md (instructions only) |
| `.codex/` folder exists | `codex` | AGENTS.md (instructions only) |
| `.gemini/` folder exists | `gemini` | GEMINI.md (instructions only) |
| `.windsurf/` folder exists | `windsurf` | AGENTS.md (instructions only) |
| Multiple folders exist | `all` | AGENTS.md + CLAUDE.md + GEMINI.md |
| Neither folder exists | `minimal` | AGENTS.md only (universal format) |

Expand All @@ -33,6 +34,7 @@ apm compile --target copilot # Force GitHub Copilot, Cursor
apm compile --target claude # Force Claude Code, Claude Desktop
apm compile --target gemini # Force Gemini CLI
apm compile --target codex # Force Codex CLI
apm compile --target windsurf # Force Windsurf/Cascade
apm compile -t claude,copilot # Multiple targets (comma-separated)
```

Expand All @@ -57,6 +59,7 @@ target: [claude, copilot] # multiple targets -- only these are compiled
| `claude` | `CLAUDE.md` | Claude Code, Claude Desktop |
| `gemini` | `GEMINI.md` | Gemini CLI |
| `codex` | `AGENTS.md` | Codex CLI |
| `windsurf` | `AGENTS.md` | Windsurf/Cascade |
| `all` | `AGENTS.md` + `CLAUDE.md` + `GEMINI.md` | Universal compatibility |
| `minimal` | `AGENTS.md` only | Works everywhere, no folder integration |

Expand Down Expand Up @@ -451,8 +454,9 @@ Different AI tools get different levels of support from `apm install` vs `apm co
| OpenCode | `.opencode/agents/`, `.opencode/commands/`, `.opencode/skills/`, `opencode.json` (MCP) | Via `AGENTS.md` | **Full** |
| Codex CLI | `.agents/skills/`, `.codex/agents/`, `.codex/hooks.json` | `AGENTS.md` (instructions) | **Full** |
| Gemini | `.gemini/commands/`, `.gemini/skills/`, `.gemini/settings.json` (MCP, hooks) | `GEMINI.md` (instructions) | **Full** |
| Windsurf | `.windsurf/rules/`, `.windsurf/skills/`, `.windsurf/workflows/`, `.windsurf/hooks.json` | `AGENTS.md` (instructions) | **Full** |

For Copilot, Claude, and Cursor users, `apm install` handles everything natively. Gemini, OpenCode, and Codex users should also run `apm compile` to generate their instruction roll-up (`GEMINI.md` or `AGENTS.md`).
For Copilot, Claude, and Cursor users, `apm install` handles everything natively. Gemini, OpenCode, Codex, and Windsurf users should also run `apm compile` to generate their instruction roll-up (`GEMINI.md` or `AGENTS.md`).

## Theoretical Foundations

Expand Down
42 changes: 41 additions & 1 deletion docs/src/content/docs/integrations/ide-tool-integration.md
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,47 @@ APM maintains synchronization between packages and Claude primitives:
- **Update**: Refreshes rules, agents, commands, and skills when package version changes
- **Virtual Packages**: Individual files and skills (e.g., `github/awesome-copilot/skills/review-and-refactor`) are tracked via `apm.lock.yaml` and removed correctly on uninstall

## Windsurf Integration

APM integrates with Windsurf/Cascade by deploying primitives into the workspace `.windsurf/` directory.

> **Auto-Detection**: Windsurf integration is enabled only when a `.windsurf/` folder ALREADY exists in your project. Unlike VS Code or Claude, `apm install` will NOT create the folder for you. To opt in, either run `mkdir .windsurf` first, pass an explicit target (`apm install --target windsurf`), or set `target: windsurf` in `apm.yml`.

### Native Windsurf Primitives

When you run `apm install` (with `.windsurf/` present or `--target windsurf`), APM deploys package primitives to Windsurf's native locations:

| APM Primitive | Windsurf Destination | Format |
|---|---|---|
| Instructions (`.instructions.md`) | `.windsurf/rules/*.md` | Windsurf rules markdown with `trigger`/`globs` frontmatter |
| Agents (`.agent.md`) | `.windsurf/skills/<name>/SKILL.md` | Converted to a Windsurf Skill (lossy, see below) |
| Skills (`SKILL.md`) | `.windsurf/skills/<name>/SKILL.md` | Standard `SKILL.md` format |
| Commands (`.prompt.md`) | `.windsurf/workflows/*.md` | Windsurf workflow markdown |
| Hooks | `.windsurf/hooks.json` | Hook definitions merged into a single file |

Reference: [Windsurf memories and rules](https://docs.windsurf.com/windsurf/cascade/memories).

### Lossy Agent to Skill Conversion

Windsurf has no native equivalent of an `.agent.md` persona, so APM converts each agent into a Windsurf Skill (`SKILL.md`). The conversion is deliberately lossy:

- **Preserved**: `name`, `description`, and the full markdown body (verbatim).
- **Dropped**: `tools` and `model` frontmatter keys -- Windsurf Skills do not support them.

APM prints a warning when a dropped field is detected, so the loss is never silent. If your agent depends on a specific tool list or model pin, prefer a target that supports those keys natively (Copilot, Claude).

### MCP Configuration

Windsurf reads MCP server definitions from a USER-SCOPE file at `~/.codeium/windsurf/mcp_config.json`. The schema is the standard `mcpServers` JSON used by GitHub Copilot CLI. The workspace `.windsurf/` directory does NOT contain MCP config -- there is nothing to commit per project.

Reference: [Windsurf MCP integration](https://docs.windsurf.com/windsurf/cascade/mcp).

### User-Scope Installation Limitations

Windsurf has partial user-scope support. `apm install -g --target windsurf` deploys agents, skills, commands, and hooks under `~/.codeium/windsurf/`, but **instructions (rules) are skipped** at user scope -- Windsurf does not expose a user-level rules directory in the same shape as the workspace one. Keep instruction packages workspace-local.

See [Global Installation](../../guides/dependencies/#global-user-scope-installation) for cross-target user-scope coverage.

## Other IDE Support

### IDEs with GitHub Copilot
Expand Down Expand Up @@ -649,7 +690,6 @@ dependencies:
The following IDE integrations are planned for future releases:

- **JetBrains IDE support**: Native integration with IntelliJ, PyCharm, WebStorm, and other JetBrains IDEs
- **Windsurf support**: Integration with the Windsurf AI coding environment
- **Cursor deeper integration**: Enhanced Cursor support including rule versioning and conflict resolution

## Related Resources
Expand Down
2 changes: 1 addition & 1 deletion docs/src/content/docs/introduction/how-it-works.md
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ These tools support the full set of APM primitives. Running `apm install` deploy
- **GitHub Copilot** (AGENTS.md + .github/) - instructions, prompts, chat modes, context, hooks, MCP
- **Claude Code** (CLAUDE.md + .claude/) - commands, skills, MCP configuration

APM auto-detects targets based on project structure -- deploying to every recognized directory (`.github/`, `.claude/`, `.cursor/`, `.opencode/`) that exists, falling back to `.github/` when none do. Set `target` in `apm.yml` to restrict to specific targets (single string or list).
APM auto-detects targets based on project structure -- deploying to every recognized directory (`.github/`, `.claude/`, `.cursor/`, `.opencode/`, `.windsurf/`) that exists, falling back to `.github/` when none do. Set `target` in `apm.yml` to restrict to specific targets (single string or list).

### Compiled instructions

Expand Down
13 changes: 8 additions & 5 deletions docs/src/content/docs/reference/cli-commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,11 @@ apm install [PACKAGES...] [OPTIONS]
- `PACKAGES` - Optional APM packages to add and install. Accepts shorthand (`owner/repo`), HTTPS URLs, SSH URLs, FQDN shorthand (`host/owner/repo`), local filesystem paths (`./path`, `../path`, `/absolute/path`, `~/path`), or marketplace references (`NAME@MARKETPLACE[#ref]`). All forms are normalized to canonical format in `apm.yml`.

**Options:**
- `--runtime TEXT` - Target specific runtime only (copilot, codex, vscode, cursor, opencode, gemini, claude)
- `--runtime TEXT` - Target specific runtime only (copilot, codex, vscode, cursor, opencode, gemini, claude,windsurf)
- `--exclude TEXT` - Exclude specific runtime from installation
- `--only [apm|mcp]` - Install only specific dependency type
- `--target [copilot|claude|cursor|codex|opencode|gemini|agent-skills|copilot-cowork|all]` - Force deployment to specific target(s). Accepts comma-separated values for multiple targets (e.g., `-t claude,copilot`). Overrides auto-detection. `agent-skills` deploys to `.agents/skills/` (cross-client). `all` = copilot+claude+cursor+opencode+codex+gemini (excludes agent-skills); combine with `agent-skills` for both.
- `--target [copilot|claude|cursor|codex|opencode|gemini|windsurf|agent-skills|copilot-cowork|all]` - Force deployment to specific target(s). Accepts comma-separated values for multiple targets (e.g., `-t claude,copilot`). Overrides auto-detection. `agent-skills` deploys to `.agents/skills/` (cross-client). `all` = copilot+claude+cursor+opencode+codex+gemini+windsurf (excludes agent-skills); combine with `agent-skills` for both.
- `windsurf` - Windsurf/Cascade (`.windsurf/rules/`, `.windsurf/skills/`, `.windsurf/workflows/`, `.windsurf/hooks.json`)
- `copilot-cowork` - Microsoft 365 Copilot Cowork skills (user scope only, requires `copilot-cowork` experimental flag)
- `vscode`, `agents` - Deprecated aliases for `copilot` (`.github/`). Still accepted by the parser; prefer `copilot` for GitHub Copilot deployment, or `agent-skills` for cross-client `.agents/skills/` deployment. Removal in v1.0.
- `--update` - Update dependencies to latest Git references
Expand Down Expand Up @@ -594,7 +595,7 @@ apm pack [OPTIONS]

**Options:**
- `-o, --output PATH` - Bundle output directory (default: `./build`). Does not affect `marketplace.json` path.
- `-t, --target [copilot|vscode|claude|cursor|codex|opencode|gemini|all]` - Filter bundle files by target. Accepts comma-separated values (e.g., `-t claude,copilot`). Auto-detects from `apm.yml` if omitted. `vscode` is an alias for `copilot`. No-op for marketplace output.
- `-t, --target [copilot|vscode|claude|cursor|codex|opencode|gemini|windsurf|all]` - Filter bundle files by target. Accepts comma-separated values (e.g., `-t claude,copilot`). Auto-detects from `apm.yml` if omitted. `vscode` is an alias for `copilot`. No-op for marketplace output.
- `--archive` - Produce a `.tar.gz` archive instead of a directory. Bundle only.
- `--format [plugin|apm]` - Bundle format (default: `plugin`). `plugin` emits a Claude Code plugin directory with a schema-conformant `plugin.json` ([official schema](https://json.schemastore.org/claude-code-plugin.json)). `apm` produces the legacy APM bundle layout (consumed by `microsoft/apm-action@v1` restore mode and other bundle-aware tooling). No-op for marketplace output.
- `--force` - On collision (plugin format), last writer wins instead of first. Bundle only.
Expand Down Expand Up @@ -1017,7 +1018,7 @@ apm deps update [PACKAGES...] [OPTIONS]
- `--verbose, -v` - Show detailed update information
- `--force` - Overwrite locally-authored files on collision
- `-g, --global` - Update user-scope dependencies (`~/.apm/`)
- `--target, -t` - Force deployment to specific target(s). Accepts comma-separated values (e.g., `-t claude,copilot`). Valid values: copilot, claude, cursor, opencode, codex, gemini, agent-skills, vscode, agents (deprecated), all. `agent-skills` deploys to `.agents/skills/` (cross-client). `all` excludes agent-skills.
- `--target, -t` - Force deployment to specific target(s). Accepts comma-separated values (e.g., `-t claude,copilot`). Valid values: copilot, claude, cursor, opencode, codex, gemini, windsurf, agent-skills, vscode, agents (deprecated), all. `agent-skills` deploys to `.agents/skills/` (cross-client). `all` excludes agent-skills.
- `--parallel-downloads` - Max concurrent downloads (default: 4)

**Policy enforcement:** `apm deps update` runs the install pipeline and is therefore gated by org `apm-policy.yml`. There is no `--no-policy` flag on this command -- the only escape hatch is `APM_POLICY_DISABLE=1` for the shell session. See [Policy reference](../../enterprise/policy-reference/#install-time-enforcement).
Expand Down Expand Up @@ -1691,7 +1692,7 @@ apm compile [OPTIONS]

**Options:**
- `-o, --output TEXT` - Output file path (for single-file mode)
- `-t, --target [copilot|claude|cursor|codex|opencode|gemini|agent-skills|all]` - Target agent format. Accepts comma-separated values for multiple targets (e.g., `-t claude,copilot`). `vscode` and `agents` are accepted as deprecated aliases for `copilot` (removal in v1.0). `agent-skills` is a no-op for compile (skills-only target). Auto-detects if not specified.
- `-t, --target [copilot|claude|cursor|codex|opencode|gemini|windsurf|agent-skills|all]` - Target agent format. Accepts comma-separated values for multiple targets (e.g., `-t claude,copilot`). `vscode` and `agents` are accepted as deprecated aliases for `copilot` (removal in v1.0). `agent-skills` is a no-op for compile (skills-only target). Auto-detects if not specified.
- `--chatmode TEXT` - Chatmode to prepend to the AGENTS.md file
- `--dry-run` - Preview compilation without writing files (shows placement decisions)
- `--no-links` - Skip markdown link resolution
Expand All @@ -1713,6 +1714,7 @@ When `--target` is not specified, APM auto-detects based on existing project str
| `.claude/` exists only | `claude` | CLAUDE.md + .claude/ |
| `.codex/` exists | `codex` | AGENTS.md + .codex/ + .agents/ |
| `.gemini/` exists | `gemini` | GEMINI.md + .gemini/ |
| `.windsurf/` exists | `windsurf` | AGENTS.md + .windsurf/ |
| Both folders exist | `all` | All outputs |
| Neither folder exists | `minimal` | AGENTS.md only |

Expand All @@ -1738,6 +1740,7 @@ target: [claude, copilot] # multiple targets -- only these are compiled/install
| `codex` | AGENTS.md, .agents/skills/, .codex/agents/, .codex/hooks.json | Codex CLI |
| `opencode` | AGENTS.md, .opencode/agents/, .opencode/commands/, .opencode/skills/ | OpenCode |
| `gemini` | GEMINI.md, .gemini/commands/, .gemini/skills/ | Gemini CLI |
| `windsurf` | AGENTS.md, .windsurf/rules/, .windsurf/skills/, .windsurf/workflows/ | Windsurf/Cascade |
| `agent-skills` | .agents/skills/ only | Cross-client shared skills |
| `agents` | *(deprecated)* alias for `vscode` | Use `copilot` or `agent-skills` instead |
| `all` | All of the above (excludes `agent-skills`) | Universal compatibility |
Expand Down
Loading
Loading