Preserve unrelated skills in plugin-companion mode#253
Conversation
Walkthrough
ChangesPlugin-companion delivery
Estimated code review effort: 4 (Complex) | ~45 minutes Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Review SummaryWhat this PR does: Relaxes Overall impression: This is a well-scoped, carefully test-driven change. The core logic in Code quality / correctness
SecurityNo injection or traversal issues found — external process calls use array-form Test coverageStrong — both the Ruby unit tests ( PerformanceNo concerns — all additions are bounded filesystem/JSON operations proportional to the number of installed skills/candidates. |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
bin/agent-workflows-delivery-state (1)
201-211: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value
Array(receipts)silently mangles a single-object receipt.
Array({"installPath" => "..."})yields[["installPath", "..."]], so a receipt recorded as an object instead of a list is reported as"invalid candidate install receipt"rather than being either honored or diagnosed accurately. It still fails closed, but an explicit shape check keeps the reason truthful and avoids theKernel#ArrayHash-coercion gotcha.♻️ Proposed refactor
- candidates = Array(receipts) + unless receipts.nil? || receipts.is_a?(Array) + return { "state" => "unknown", "reason" => "invalid Claude scw plugin receipt list shape" } + end + + candidates = Array(receipts)🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@bin/agent-workflows-delivery-state` around lines 201 - 211, Update the receipt normalization before the candidate validation in the delivery-state flow: explicitly distinguish an array of receipts from a single receipt object instead of applying Array(receipts), which coerces hashes into key-value pairs. Preserve valid list handling and either honor a valid single receipt or return a specific unknown result for the unsupported shape, ensuring invalid-shape diagnostics remain accurate.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@bin/agent-workflows-delivery-state`:
- Around line 26-42: Validate that the parsed manifest is a Hash immediately
after JSON.parse and return nil for any other root type before calling fetch in
the manifest-processing helper. Preserve the existing validation and rescue
behavior for valid Hash manifests so scalar plugin.json roots produce the
structured unknown result instead of an uncaught NoMethodError.
---
Nitpick comments:
In `@bin/agent-workflows-delivery-state`:
- Around line 201-211: Update the receipt normalization before the candidate
validation in the delivery-state flow: explicitly distinguish an array of
receipts from a single receipt object instead of applying Array(receipts), which
coerces hashes into key-value pairs. Preserve valid list handling and either
honor a valid single receipt or return a specific unknown result for the
unsupported shape, ensuring invalid-shape diagnostics remain accurate.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 21b1d055-d208-4039-ae20-80bcda54e9f2
📒 Files selected for processing (6)
CHANGELOG.mdbin/agent-workflows-delivery-statebin/agent-workflows-delivery-state-test.rbbin/agent-workflows-status-test.rbbin/install-agent-workflows-test.bashdocs/plans/2026-07-17-plugin-companion-unrelated-skills-design.md
ReviewOverviewThis PR fixes #191: Core logic lives entirely in Code quality
Minor observations (non-blocking)
SecurityNo concerns. The version-string regex ( PerformanceNo meaningful impact — the added work is a few Test coverageStrong. Both bash installer-level and Ruby unit-level regressions cover: unrelated skill preserved on fresh companion install, preserved on repeat install, collision blocked when native gains the skill name after the recorded revision, collision blocked when native still advertises a skill the current source removed, and mixed valid/invalid candidate native roots for both Codex and Claude. I was not able to execute the test suites myself in this sandboxed session (command execution required approval that wasn't available), so I relied on static review — the PR description reports Documentation
Overall: a well-scoped, carefully fail-closed fix with matching regression coverage. I'd merge as-is; the notes above are polish, not blockers. |
Why
Plugin-companion delivery should coexist with unrelated personal skills, but the installer treated every unmanaged flat skill as a conflict. That made companion mode unusable for people who kept their own skills in the same agent home.
At the same time, relaxing that check must not permit the same skill to be delivered by both the active native plugin and the flat skill directory. Native plugin discovery also needs to fail closed when its provenance or active root is ambiguous rather than guessing which installation is authoritative.
Closes #191.
What changed
Validation
ruby bin/agent-workflows-delivery-state-test.rb— 35 runs, 184 assertions, 0 failures/errors.bash bin/install-agent-workflows-test.bash— all cases passed, including the source-removed/native-still-active collision regression.bin/validate— passed after the final behavior change, including 93-file RuboCop with no offenses.shasum; validation used an isolated/tmpshasumsymlink to/usr/bin/sha1sumwithout modifying the repository.git diff --checkand targeted structure/content checks.Review evidence
/code-review ultra origin/main...HEADproduced no output and was stopped after approximately ten minutes./simplify origin/mainproduced no output and was stopped after approximately five minutes; no simplify edits were made.Churn notes