Skip to content

feat: Skills use the project-matched CLI by default - #1404

Merged
hatayama merged 7 commits into
mainfrom
feature/issue-1385-v2-cli-version-isolation
Jun 25, 2026
Merged

feat: Skills use the project-matched CLI by default#1404
hatayama merged 7 commits into
mainfrom
feature/issue-1385-v2-cli-version-isolation

Conversation

@hatayama

@hatayama hatayama commented Jun 25, 2026

Copy link
Copy Markdown
Owner

Summary

  • Skills installed from Unity now use the project-matched CLI version by default via version-pinned npx.
  • Users can still switch back to the global uloop command from the setup/settings UI.
  • Setup and Settings now expose the project CLI mode consistently for skill installation and updates.

User Impact

  • Multi-project users are less likely to hit CLI/package version mismatches after installing skills.
  • Existing users who prefer a globally installed CLI can opt out by disabling project CLI mode.

Changes

  • Add skill CLI invocation settings for global and npx modes.
  • Rewrite installed skill markdown commands to npx --yes uloop-cli@<packageVersion> in project CLI mode.
  • Add UI controls and setup flow handling for project CLI mode.
  • Make project CLI mode the default for new or invalid tool settings.

Verification

  • uloop compile
  • uloop run-tests --test-mode EditMode --filter-type regex --filter-value ".*ToolSettingsTests.*|.*ToolSkillSynchronizerTests.*SkillCliInvocation.*"
  • npm run test:unit -- --runTestsByPath src/__tests__/tool-settings-loader.test.ts src/__tests__/skills-manager.test.ts src/__tests__/skills-command.test.ts --runInBand
  • npm run lint
  • npm run build

Closes #1385

Review in cubic

This PR adds project-scoped CLI invocation support for skills, defaulting to npx-based execution so generated/installed skill markdown invokes the Unity project’s pinned uloop-cli version rather than the globally installed binary.

Key changes:

  • Introduced global vs npx skill CLI invocation mode persisted in .uloop/settings.tools.json via new skillCliInvocation setting, with normalization and safe defaults (defaulting to npx when settings are missing/invalid/unreadable).
  • Updated skill installation/content packaging to rewrite installed skill markdown (and related referenced files when applicable) so uloop invocations become npx --yes uloop-cli@<packageVersion>, using the project’s installed Unity CLI Loop package package.json version (and bypassing rewriting when global is selected).
  • Exposed a “Use project CLI version” toggle across Setup Wizard and Editor UI, including state wiring/events and eligibility gating (IsCliInstalled || UseProjectCliVersion) for managing skills.
  • Updated skill install/refresh flows so switching from npx back to global marks previously npx-installed skills as outdated.
  • Extended the CLI install command to accept --cli-invocation npx|global, validating inputs and rejecting conflicting --cli-invocation usage with --global.

Tests were added/updated to cover:

  • Setup Wizard decision logic for when to show target-selection UI and installable-skill target handling.
  • Tool settings loading/saving and defaulting/normalization behavior for skillCliInvocation.
  • Skill installation rewriting correctness for npx mode and outdated detection when toggling back to global.
  • CLI command behavior for forwarding/rejecting --cli-invocation, plus project CLI version resolution and install failure/error cases when the Unity CLI Loop package root/version can’t be resolved.

hatayama added 6 commits June 23, 2026 21:43
Allow project skill installs to opt into npx-based uloop-cli invocation while keeping global invocation as the default. Store the choice in tool settings, apply it consistently in CLI and Unity-driven installs/status checks, and expose the toggle in setup/settings UI.
Move the project CLI version toggle out of the skills controls so it reads as a CLI execution mode. Hide global CLI install/status UI while project CLI mode is enabled, while keeping global CLI as the default path.
Handle clicks on the checkbox area even when Unity's Toggle control does not emit a value change, while avoiding double toggles when the built-in control already handled the click.
Project CLI version installs must keep every markdown workflow on the pinned package CLI. Apply the npx rewrite to referenced markdown files as well as SKILL.md in both CLI and Editor installers.
Setup Wizard should let users choose where to install skills when no target tool folders are present, instead of blocking installation behind a create-folder message.
Make project skill installation use the package-matched npx command by default so new installs avoid global CLI version drift, while preserving explicit global mode as an opt-out.
@coderabbitai

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: df37d980-be5d-493c-97f8-460220fd475c

📥 Commits

Reviewing files that changed from the base of the PR and between 684ec9f and 64d9986.

📒 Files selected for processing (6)
  • Packages/src/Cli~/src/__tests__/skills-manager.test.ts
  • Packages/src/Cli~/src/__tests__/tool-settings-loader.test.ts
  • Packages/src/Cli~/src/skills/skills-manager.ts
  • Packages/src/Cli~/src/tool-settings-loader.ts
  • Packages/src/Editor/UI/Setup/SetupWizardWindow.cs
  • Packages/src/Editor/UI/UIToolkit/Components/CliSetupSection.cs
🚧 Files skipped from review as they are similar to previous changes (3)
  • Packages/src/Cli~/src/tests/tool-settings-loader.test.ts
  • Packages/src/Cli~/src/tool-settings-loader.ts
  • Packages/src/Cli~/src/skills/skills-manager.ts

📝 Walkthrough

Walkthrough

Adds per-project skill CLI invocation state, --cli-invocation CLI support, npx-based skill rewriting during install, and editor/setup UI controls that read and update the invocation mode.

Changes

Project CLI invocation

Layer / File(s) Summary
Invocation settings storage
Packages/src/Editor/CLI/CliConstants.cs, Packages/src/Cli~/src/tool-settings-loader.ts, Packages/src/Editor/Config/ToolSettingsData.cs, Packages/src/Editor/Config/ToolSettings.cs, Packages/src/Cli~/src/__tests__/tool-settings-loader.test.ts, Assets/Tests/Editor/ToolSettingsTests.cs
Adds the global/npx invocation type, persists it in project settings, and normalizes load/save behavior for the new setting.
CLI install option
Packages/src/Cli~/src/skills/skills-command.ts, Packages/src/Cli~/src/__tests__/skills-command.test.ts
Adds --cli-invocation, validates global and npx, blocks invalid combinations, and forwards the selected mode into skill installation.
Skill collection and rewrite
Packages/src/Cli~/src/skills/skills-manager.ts, Packages/src/Editor/Config/SkillInstallLayout.cs
Resolves the effective invocation mode, rewrites skill markdown and additional files for npx using the project package version, and collects skills in the appropriate invocation context.
Skill rewrite validation
Packages/src/Cli~/src/__tests__/skills-manager.test.ts, Assets/Tests/Editor/ToolSkillSynchronizerTests.cs
Covers npx install output, package-version resolution, and the outdated state when project skills switch back to global mode.
Editor UI toggle wiring
Packages/src/Editor/UI/McpEditorWindowViewData.cs, Packages/src/Editor/UI/McpEditorWindow.cs, Packages/src/Editor/UI/UIToolkit/Components/CliSetupSection.cs, Packages/src/Editor/UI/UIToolkit/McpEditorWindowUI.cs, Packages/src/Editor/UI/UIToolkit/McpEditorWindow.uxml, Assets/Tests/Editor/SkillsTargetSelectionResolverTests.cs
Carries the project CLI flag through the editor UI model, adds the toggle and event wiring, and updates visibility and enablement rules for skill controls.
Setup wizard flow
Packages/src/Editor/UI/Setup/SetupWizardWindow.cs, Packages/src/Editor/UI/Setup/SetupWizardWindow.uxml, Assets/Tests/Editor/SetupWizardWindowTests.cs
Adds the project CLI toggle, target-selection rules, installable-target computation, and matching setup wizard tests.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: making skills use the project-matched CLI by default.
Linked Issues check ✅ Passed The changes implement per-project npx-pinned skill invocation, version sourcing, generation-time rewriting, and UI/settings support requested by #1385.
Out of Scope Changes check ✅ Passed The touched files stay focused on CLI invocation, skill generation, settings, UI, and tests with no clear unrelated additions.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/issue-1385-v2-cli-version-isolation

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 issues found across 21 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread Packages/src/Cli~/src/skills/skills-manager.ts Outdated
Comment thread Packages/src/Editor/UI/Setup/SetupWizardWindow.cs Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (2)
Packages/src/Editor/UI/UIToolkit/Components/CliSetupSection.cs (2)

320-337: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Row-click dedup strategy differs from HandleGroupSkillsRowClicked.

The group-skills row guards against double-invocation by checking whether the click target is inside the toggle, while this handler relies on the _projectCliVersionChangedByToggle flag plus a scheduled reset. Both are functionally correct, but aligning the two row handlers on one approach would reduce cognitive load. Optional.

🤖 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 `@Packages/src/Editor/UI/UIToolkit/Components/CliSetupSection.cs` around lines
320 - 337, Align HandleProjectCliVersionRowClicked with the row-click dedup
pattern used in HandleGroupSkillsRowClicked by using the same
click-target-inside-toggle guard instead of relying on
_projectCliVersionChangedByToggle and a scheduled reset. Update the
CliSetupSection row handler to follow one consistent approach for both row-click
methods, keeping the toggle update and OnUseProjectCliVersionChanged invocation
behavior unchanged.

233-243: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Misleading isCliInstalled parameter name.

UpdateInstallSkillsButton now passes CanManageSkills(data) (true when either the global CLI is installed or project CLI/npx mode is enabled) into the isCliInstalled parameter of GetInstallSkillsButtonText and IsInstallSkillsButtonEnabled. The behavior is correct, but the parameter name no longer reflects what is passed. Consider renaming to canManageSkills for clarity.

Also applies to: 259-300

🤖 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 `@Packages/src/Editor/UI/UIToolkit/Components/CliSetupSection.cs` around lines
233 - 243, The `UpdateInstallSkillsButton` path is passing
`CanManageSkills(data)` into parameters named `isCliInstalled`, which is
misleading because the value now means “can manage skills” rather than strict
CLI installation. Rename the relevant parameter(s) in
`GetInstallSkillsButtonText` and `IsInstallSkillsButtonEnabled` to
`canManageSkills` (and update their call sites/usages in the related methods
around `UpdateInstallSkillsButton`) so the naming matches the behavior.
🤖 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 `@Packages/src/Cli`~/src/skills/skills-manager.ts:
- Around line 886-899: The crash comes from collectAllSkills passing a null
packageVersion into formatSkillsForCliInvocation for local invocations. Update
collectAllSkills so that when cliInvocation is not global and
resolvePackageRoot(projectRoot) returns null, it handles that case before
calling formatSkillsForCliInvocation, either by returning a safe empty result or
by throwing a clear specific error. Keep the logic centered around
collectAllSkills, resolvePackageRoot, and formatSkillsForCliInvocation so local
npx runs do not hit the non-null assertion in formatSkillsForCliInvocation.

In `@Packages/src/Cli`~/src/tool-settings-loader.ts:
- Around line 137-141: Reject arrays in the tool settings parser so they cannot
be returned as ToolSettingsData and later serialize to an empty array. Update
the validation in tool-settings-loader.ts around the parsed object check to
explicitly exclude array values in addition to null/non-objects, so only plain
object settings are accepted before the parsed value is cast and persisted.

In `@Packages/src/Editor/UI/Setup/SetupWizardWindow.cs`:
- Around line 345-356: The click guard in InitializeProjectCliVersionToggle is
relying on _projectCliVersionChangedByToggle being set too late, so update the
row click handling to match HandleGroupSkillsRowClicked by inspecting the
ClickEvent source directly instead of using the async flag. In
SetupWizardWindow, change the _projectCliVersionRow.RegisterCallback<ClickEvent>
path so HandleProjectCliVersionRowClicked is skipped when the event originated
from _projectCliVersionToggle (or its toggle/label subtree), and keep the
toggle’s value-change callback only for handling actual value updates.

---

Nitpick comments:
In `@Packages/src/Editor/UI/UIToolkit/Components/CliSetupSection.cs`:
- Around line 320-337: Align HandleProjectCliVersionRowClicked with the
row-click dedup pattern used in HandleGroupSkillsRowClicked by using the same
click-target-inside-toggle guard instead of relying on
_projectCliVersionChangedByToggle and a scheduled reset. Update the
CliSetupSection row handler to follow one consistent approach for both row-click
methods, keeping the toggle update and OnUseProjectCliVersionChanged invocation
behavior unchanged.
- Around line 233-243: The `UpdateInstallSkillsButton` path is passing
`CanManageSkills(data)` into parameters named `isCliInstalled`, which is
misleading because the value now means “can manage skills” rather than strict
CLI installation. Rename the relevant parameter(s) in
`GetInstallSkillsButtonText` and `IsInstallSkillsButtonEnabled` to
`canManageSkills` (and update their call sites/usages in the related methods
around `UpdateInstallSkillsButton`) so the naming matches the behavior.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 26ce8fb7-7c93-463c-b2cf-eacc686740f9

📥 Commits

Reviewing files that changed from the base of the PR and between 554f6f1 and 684ec9f.

📒 Files selected for processing (21)
  • Assets/Tests/Editor/SetupWizardWindowTests.cs
  • Assets/Tests/Editor/SkillsTargetSelectionResolverTests.cs
  • Assets/Tests/Editor/ToolSettingsTests.cs
  • Assets/Tests/Editor/ToolSkillSynchronizerTests.cs
  • Packages/src/Cli~/src/__tests__/skills-command.test.ts
  • Packages/src/Cli~/src/__tests__/skills-manager.test.ts
  • Packages/src/Cli~/src/__tests__/tool-settings-loader.test.ts
  • Packages/src/Cli~/src/skills/skills-command.ts
  • Packages/src/Cli~/src/skills/skills-manager.ts
  • Packages/src/Cli~/src/tool-settings-loader.ts
  • Packages/src/Editor/CLI/CliConstants.cs
  • Packages/src/Editor/Config/SkillInstallLayout.cs
  • Packages/src/Editor/Config/ToolSettings.cs
  • Packages/src/Editor/Config/ToolSettingsData.cs
  • Packages/src/Editor/UI/McpEditorWindow.cs
  • Packages/src/Editor/UI/McpEditorWindowViewData.cs
  • Packages/src/Editor/UI/Setup/SetupWizardWindow.cs
  • Packages/src/Editor/UI/Setup/SetupWizardWindow.uxml
  • Packages/src/Editor/UI/UIToolkit/Components/CliSetupSection.cs
  • Packages/src/Editor/UI/UIToolkit/McpEditorWindow.uxml
  • Packages/src/Editor/UI/UIToolkit/McpEditorWindowUI.cs

Comment thread Packages/src/Cli~/src/skills/skills-manager.ts
Comment thread Packages/src/Cli~/src/tool-settings-loader.ts Outdated
Comment thread Packages/src/Editor/UI/Setup/SetupWizardWindow.cs
Avoid internal assertions when package metadata is unavailable for project CLI mode, reject array-shaped tool settings before saving invocation preferences, and make project CLI row clicks ignore events that originate from the toggle itself.
@hatayama
hatayama merged commit 5bb9d49 into main Jun 25, 2026
9 checks passed
@hatayama
hatayama deleted the feature/issue-1385-v2-cli-version-isolation branch June 25, 2026 14:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Pin the CLI version per project by invoking skills via npx uloop-cli@<unity-package-version> instead of a global uloop

1 participant