Summary
On Windows, init prints
! .agents/skills symlink could not be created (filesystem without symlink support) — skipped.
The filesystem supports symlinks; what fails is symlinkSync(..., "dir") with EPERM, because Windows only grants SeCreateSymbolicLinkPrivilege to administrators or with Developer Mode on. A directory junction needs no privilege and works for this purpose:
> node -e "fs.symlinkSync('../.claude/skills','.agents/skills','dir')"
code: EPERM | EPERM: operation not permitted, symlink '..\.claude\skills' -> '...\.agents\skills'
> node -e "fs.symlinkSync('../.claude/skills','.agents/skills','junction')"
junction OK
Where
src/init.mjs:513-519 catches every error from symlinkSync and reports the same message.
Why it matters
.agents/skills is how non-Claude tooling discovers the vendored skills (init.mjs:507, concepts/method.md:153, validate-delivery-loop.md:186), so on a Windows workstation the Codex lane runs without them and the warning points the user at the wrong cause.
Fix
On EPERM, retry with type: "junction" (Node resolves the target to an absolute path for junctions, which is fine here); if that fails too, print the actual error code instead of guessing. One-line change plus a test that asserts either a symlink or a junction exists after init on win32. Happy to open the PR.
Summary
On Windows,
initprintsThe filesystem supports symlinks; what fails is
symlinkSync(..., "dir")withEPERM, because Windows only grantsSeCreateSymbolicLinkPrivilegeto administrators or with Developer Mode on. A directory junction needs no privilege and works for this purpose:Where
src/init.mjs:513-519catches every error fromsymlinkSyncand reports the same message.Why it matters
.agents/skillsis how non-Claude tooling discovers the vendored skills (init.mjs:507,concepts/method.md:153,validate-delivery-loop.md:186), so on a Windows workstation the Codex lane runs without them and the warning points the user at the wrong cause.Fix
On
EPERM, retry withtype: "junction"(Node resolves the target to an absolute path for junctions, which is fine here); if that fails too, print the actual error code instead of guessing. One-line change plus a test that asserts either a symlink or a junction exists afterinitonwin32. Happy to open the PR.