feat(vd): add vd install cursor - #99
Conversation
Install local skills into Cursor discovery paths with the same symlink-or-copy flow as Codex, Droid, and Pi. User scope writes $HOME/.cursor/skills (or $VD_CURSOR_HOME/skills); repo scope writes .cursor/skills. Skills-only — no plugin or marketplace install. Co-authored-by: Duc Nguyen <me@vanducng.dev>
|
✅ OpenCodeReview: Review complete: 0 finding(s) across 2 selected item(s). |
Code Review SummaryWhat changed:
✅ Resolved (1)
Review referenceRun again
Priority
Review context Last reviewed commit |
| | **OpenAI Codex** | ✅ first-class | `.agents/skills/<name>` repo-scope symlinks; `vd install codex` for user scope; prompt-context hooks via `vd install hooks` | | ||
| | **Factory Droid** | ✅ skills | `.factory/skills/<name>` repo entries (relative symlinks on Unix, copies on Windows); `vd install droid` for user scope | | ||
| | **Pi** | ✅ skills | `.pi/skills/<name>` repo entries (relative symlinks on Unix, copies on Windows); `vd install pi` for user scope | | ||
| | **Cursor** | ✅ skills | `vd install cursor` writes `$HOME/.cursor/skills/<name>` (or `$VD_CURSOR_HOME/skills`); `--scope repo` writes `.cursor/skills/<name>` (relative symlinks on Unix, copies on Windows) | |
There was a problem hiding this comment.
Docs landing page misses the new Cursor agent
The new Cursor agent is documented in README.md, docs/content/commands.md, and docs/content/usage.md, but docs/content/index.mdx (the docs site landing page that mirrors this README) was not updated.
- Its Quick start block still ends at
vd install piwith novd install cursorstep. - Its Supported agents table has no Cursor row and still says only "Droid and Pi support covers skills only, not plugins, hooks, extensions, or observability."
So the published docs site will not list the agent this PR adds. Was leaving docs/content/index.mdx unchanged intentional?
Bare vd install now detects which agent homes exist and installs skills at user scope into each one. The numbered picker moves behind --pick / --interactive. --scope repo still requires an explicit agent. Claude auto-detect uses --dev so skills land in ~/.claude/skills. Co-authored-by: Duc Nguyen <me@vanducng.dev>
The site overview in docs/content/index.mdx still stopped at Pi. Add the Cursor agent, the auto-detect vd install default, and skills-only wording so the published docs match README. Co-authored-by: Duc Nguyen <me@vanducng.dev>
| func installAgentHomes(userHome string) []InstallAgent { | ||
| return []InstallAgent{ | ||
| {Name: "claude", Home: filepath.Join(userHome, ".claude")}, | ||
| {Name: "codex", Home: envOr("VD_CODEX_HOME", filepath.Join(userHome, ".agents"))}, |
There was a problem hiding this comment.
Codex detection home disagrees with install destination
Detection treats $VD_CODEX_HOME as the Codex home, but the user-scope installer it triggers writes to ~/.agents/skills unconditionally: codexDest in internal/install/codex.go never reads VD_CODEX_HOME.
Two concrete failures on the new auto path:
VD_CODEX_HOMEset to an existing dir while~/.agentsis absent:vd installreports Codex detected, then creates and populates~/.agents/skills, a location the user's override (and inventory scanning,Service.platformRoots) never reads. Skills land where nothing discovers them.VD_CURSOR_HOME-style mismatch in reverse:VD_CODEX_HOMEpointing at a missing dir while~/.agentsexists causes Codex to be silently skipped even though the actual write target is present.
The Cursor pair in this same diff does it consistently: cursorHome() honors VD_CURSOR_HOME and both installAgentHomes and cursorDest share it. Droid (~/.factory), Pi (~/.pi), and Claude (~/.claude) also match. Codex is the only detection/install mismatch, and docs/content/commands.md now documents the inconsistency ("Present when: $HOME/.agents or $VD_CODEX_HOME" but destination always $HOME/.agents/skills).
Which side should move: should codexDest honor VD_CODEX_HOME like cursorHome does, or should detection use ~/.agents only?
| {Name: "codex", Home: envOr("VD_CODEX_HOME", filepath.Join(userHome, ".agents"))}, | |
| {Name: "codex", Home: filepath.Join(userHome, ".agents")}, |
Add a first-class
vd install cursoragent, then make barevd installauto-detect local agents and install at user scope.Why Cursor exists
Inventory already treated Cursor as a platform (
PlatformCursor,~/.cursoror$VD_CURSOR_HOME), butvd installhad no Cursor target. Cursor Cloud Agents load skills from~/.cursor/skills/and project.cursor/skills. This is a dedicated Cursor destination, not a hidden alias ofvd install codex.Destinations (unchanged)
$HOME/.cursor/skills/<name>$VD_CURSOR_HOME$VD_CURSOR_HOME/skills/<name>--scope repo).cursor/skills/<name>in the current repoTransport matches Codex/Droid/Pi: relative symlinks on Unix, copies on Windows.
Bare
vd installis now auto-detectThe numbered picker is no longer the no-arg default.
vd installlooks for agent homes and installs user-level into each one that exists:~/.claude~/.claude/skillsviaclaude --dev(per-skill symlinks — the filesystem analog; not the marketplace plugin)~/.agentsor$VD_CODEX_HOME~/.agents/skills~/.cursoror$VD_CURSOR_HOME~/.cursor/skills~/.factory~/.factory/skills~/.pi~/.pi/agent/skills--scope repo/ snapshot-copy are not guessed.--scope repowithout an explicit agent errors (vd install cursor --scope repo).--pick/--interactiverestores the old numbered picker.--dry-run,--force,--copy, and named skills apply to every detected agent.vd install cursor,vd install codex,vd install claude, etc. are unchanged.Test plan
go test ./... -count=1— all packages passedvd install --dry-runwith Cursor+Codex homes shows both user dests and no pickervd install cursorstill works--scope repowithout an agent is rejected--dev(~/.claude/skills), not the marketplace plugin