mirror of
https://github.com/nexu-io/open-design.git
synced 2026-10-27 09:51:12 +01:00
* fix(daemon): expose skill resources via cwd-relative aliases (#430) Skill bodies referenced repository-absolute paths in their preamble and relied on every agent CLI honouring `--add-dir` (or its equivalent) to open them. Most agents (codex, gemini, opencode, cursor-agent, qwen, pi, hermes, kimi) have no such flag, and Claude Code's directory-access policy can still block these reads under specific permission/trust configurations even when `--add-dir` is set, so SKILL side files fail to load mid-turn. Stage `.od-skills` and `.od-design-systems` directory links inside the project cwd before spawning the agent, and rewrite the skill preamble to address resources via the cwd-relative alias path. The alias resolves through a directory junction (Windows) or symbolic link (POSIX), so resources are reachable from inside every agent's working directory without needing an extra-allowed-directories flag. `extraAllowedDirs` is kept as a belt-and-suspenders fallback for Claude/Copilot — if the alias cannot be created (e.g. the user has a pre-existing real entry under one of the reserved names), `--add-dir` still covers the absolute paths. `ensureCwdAliases` is idempotent, repoints when the target moves, and refuses to overwrite a non-symlink entry under the reserved name to avoid clobbering user data. Closes #430. * fix(daemon): address review feedback — copy active skill, dual preamble paths Round 2 of PR #435 addressing the unresolved P1/P2/P3 review threads from @chatgpt-codex-connector, @lefarcen and @mrcfps. - P1 writable-symlink. Replace the directory link with a per-project `fs.cp` of the active skill into `<cwd>/.od-skills/<folder>/`. Writes through the staged copy no longer mutate the shipped repo resource. A regression test pins this down so a future "optimisation" that re-introduces a symlink would fail loud. - P1 absolute fallback. Rewrite the skill preamble to advertise both the cwd-relative alias path (primary) and the absolute path (fallback). When `stageActiveSkill` is skipped (no project cwd) or errors, Claude/Copilot still reach the resource via the absolute path covered by `--add-dir`; other agents that fall back to `PROJECT_ROOT` as cwd reach it natively because the absolute path is in-cwd there. - P2 symlinked source root. Use `stat()` instead of `lstat()` on the source so a symlinked `SKILLS_DIR` or skill folder is followed rather than skipped. - P2 stale ordering. `ensureCwdAliases` is gone; staging now happens independently of prompt composition and never silently diverges from what the preamble advertises. - P3 unsafe spec name. Validate `folderName` against an explicit segment policy (no path separators, no dot segments, no absolute, no null bytes) so a malformed caller cannot escape the alias root. - P3 strong types. Drop the `@ts-nocheck` pragma on `cwd-aliases.ts` and type the public API (`SkillStagingResult`, `SkillStagingLogger`). Also drops the `.od-design-systems` alias entirely. Design-system bodies are read by the daemon and folded into the system prompt directly, so an agent never has to open them through the filesystem; exposing that tree as cwd-visible was unnecessary surface area. Test additions: 17 cases in `cwd-aliases.test.ts` covering the copy semantics, the write-barrier regression, symlinked-source handling, legacy-symlink upgrade, alias-root collision refusal, cwd=null guard, and a parameterised set of unsafe folder names. * fix(daemon): unify effectiveCwd and use junctions on Windows test fixtures Round 3 of PR #435 addressing two non-blocking follow-ups from @mrcfps: - server.ts: collapse the chat-handler `cwd` resolution into a single `effectiveCwd = cwd ?? PROJECT_ROOT` and feed it consistently to `buildArgs`, `spawn`, and the ACP/Pi RPC session adapters. Previously `spawn(... { cwd: cwd || undefined })` let no-project runs inherit whatever working directory the daemon process was started from (packaged daemons / service launches do not start in the workspace root), which made the "absolute path is in-cwd" guarantee in the new skill preamble untrue for that exact case the comment claimed to cover. With `effectiveCwd`, agents in no-project mode land in `PROJECT_ROOT` and the absolute fallback path emitted by the preamble is genuinely a relative-to-cwd path. - cwd-aliases.test.ts: replace `symlinkSync(..., 'dir')` fixtures with a platform-aware `dirLinkType` (`'junction'` on Windows, `'dir'` elsewhere). Directory symlinks on Windows require SeCreateSymbolicLinkPrivilege / Developer Mode, which is not enabled on most CI images, so the previous form would fail the daemon test suite on Windows runners even though the production code (which uses `fs.cp`) does not need symlinks at all.