feat(portable): record Swival, Junie, and Cascade as skill readers - #727
Conversation
🦋 Changeset detectedLatest commit: 2f45c84 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4c00270e50
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| "actions": [ | ||
| { | ||
| "role": "install", | ||
| "command": "cp -R skills/<skill> .agents/skills/<skill>" |
There was a problem hiding this comment.
Make the Cascade copy command create its destination
When .agents/skills/ does not already exist, as on a clean project, this generated install command fails because cp cannot create missing parent directories. It also mishandles repeat installs: if .agents/skills/<skill> already exists, GNU cp --help documents the applicable SOURCE... DIRECTORY form, so the result is <skill>/<skill>/SKILL.md, which Cascade will not discover. Create the parent and copy into .agents/skills/, or explicitly replace the target, so the command works for both first-time and repeat installs.
AGENTS.md reference: AGENTS.md:L139-L146
Useful? React with 👍 / 👎.
…ient records Nine client records were written twice in the pinned portable table, and JSON parsing keeps only the last copy: Pi shipped as a client that reads nothing while its live-probed skills-tier record sat unread. Delete the dead run, keep the record each client's evidence supports, and hold the table to one record per client in the suite, since a repeated key is not a duplicate a reader can see. Swival's own rows now say what its pages say. Its skill tree loads only once registered with --skills-dir and loses by name to .swival/skills/ and .agents/skills/, so the row is degraded like Junie's. Its mcp row is unavailable: the emitted document is a shape Swival reads, but only an invocation passing --mcp-config reads this one, and the recorded registration does not, so mcp.json is no longer claimed as a path this client reads.
Records the three instruction-and-skill hosts in the same pinned
clientsblockand validator as #721 and #723, and fixes nine records the wave before this one
wrote twice. No adapter, projection, or compiler output changes.
skillsregister—swival --skills-dir <dir>/skills "<task>"skillsregister—junie --skill-location <dir>/skillsskillsinstall— copy into.agents/skills/<skill>.swival/skills/,.agents/skills/,--skills-dirpaths, then the global roots) and reads anextra parent directory in place, so the emitted
skills/tree needs no copy.The row is
degradedfor the same reason Junie's is: the emitted root is nota default location, and "If the same skill name exists in multiple locations,
the first one in the precedence order wins" puts
.swival/skills/and.agents/skills/ahead of it. Itsmcprow isunavailable— the emitteddocument is a shape Swival reads, but
--mcp-config"replaces the default.swival/mcp.jsonlookup" and only an invocation that passes it reads thisfile, which the recorded registration does not — so
mcp.jsonis not listedas a path this client reads.
.junie/skills/,~/.junie/skills/, and.agents/skills/bydefault and any folder given with
--skill-locationorskill-locations. ItsMCP row is
unavailable: the documented locations are.junie/mcp/mcp.jsonand
~/.junie/mcp/mcp.json, and no page states which file name--mcp-locationlooks for inside an added folder..windsurf/skills/,~/.codeium/windsurf/skills/, and the cross-agent.agents/skills/, so askill directory is copied in. Its MCP configuration lives in
~/.codeium/windsurf/mcp_config.jsonwith${env:…}/${file:…}interpolation, and its own page says the Devin Local agent uses the Devin CLI
config instead — the profile already recorded as
devin-cli(Host support: Devin CLI — native plugin manifest, portable compatibility, and versioned MCP/hook profiles #701).Every manifest, placeholder, and hook row these hosts do not read carries a
dated reason naming what would be needed instead.
Duplicate records on
mainportable-1.0.0.jsononmaincarriedqoder-cli,codewhale,copilot-cli,gemini-cli,cline,hermes-agent,opencode,kiro-powers, andpitwice.JSON.parsekeeps only the last copy, so eightof them were byte-identical dead text and the ninth was a live defect:
pipublished the stale "no installable release exists" record at tier
nonewhile the live-probed record (
@mariozechner/pi-coding-agent 0.73.1, skillstier,
pi --skill <dir>/skills) was the copy the parser dropped. This PRdeletes the dead run, keeps the evidenced record for each client, and adds
portable-adapter.test.ts :: records every client once, since JSON keeps only the last of a repeated key, which reads the authored keys out of the file andholds them to the validated set — a repeated key is not a duplicate a reader
can see.
Gate
Run on
portable-client-records-instruction, which contains currentorigin/main(4dc11a4a06):pnpm build— passpnpm typecheck— passpnpm lint— passpnpm test:unit— 0 failed, 4434 passed, 6 skippedpnpm docs:site:build— pass (locale parity and link checks clean)packages/agent-bundle/tests/{install-surface,portable-adapter}.test.ts— 0failed
Deslop
Deslop: claude-opus-5-thinking-high, 3 edits (dropped a per-inventory
conditional the renderer did not need, removed a duplicated expectation string,
trimmed a comment that restated the assertion below it).
Self-review
Reviewer:
claude-fable-5-1-thinking-high, against the diff vsorigin/main.mcpreason contradicted its own page — the reason claimed nopage documents the spec's
typediscriminator or a streamable-http server,but swival.dev/pages/mcp.html documents
http,sse, andstdio. Fixed:the row is
unavailablefor the reason that actually holds — the file isread only by an invocation that passes
--mcp-config, which replaces thedefault lookup, and TOML servers win by name.
registercommand did not namemcp.jsonwhile the record requiredreading it, so
INSTALL.mdclaimed a path the command never hands over.Fixed:
mcp.jsonis out ofdiscovery.requiredand themcprow isunavailable, matching how Junie's unreachable MCP location is recorded.skillswassupportedwhile Junie's identical arrangement wasdegraded. Fixed: Swival isdegraded, with its published precedenceorder and the external read-only rule as the reason.
Register:branch or the inventory cases for the newrecords. Fixed: the four-inventory matrix now asserts Swival's rendered
line for every inventory (nothing-to-install,
Register:with theNot loaded:tail) and that thePartial \skills`bullet appears only when the build wroteskills`.main. Fixed above, with atest that fails if one returns.