Skip to content

refactor(skills): publish skills with copy mode only#168

Merged
BlackHole1 merged 1 commit into
mainfrom
use-copy
May 8, 2026
Merged

refactor(skills): publish skills with copy mode only#168
BlackHole1 merged 1 commit into
mainfrom
use-copy

Conversation

@BlackHole1
Copy link
Copy Markdown
Member

@BlackHole1 BlackHole1 commented May 8, 2026

Remove symlink publication for bundled, registry, and local skills because supported agents handle linked skill directories inconsistently.

Startup synchronization now treats existing managed symlink targets as stale and replaces them with copied directories. Local canonical skills are also synchronized to newly detected hosts without overwriting registry-managed targets.


View in Codesmith
Need help on this PR? Tag @codesmith with what you need.

  • Let Codesmith autofix CI failures and bot reviews

Remove symlink publication for bundled, registry, and local skills
because supported agents handle linked skill directories inconsistently.

Startup synchronization now treats existing managed symlink targets as
stale and replaces them with copied directories. Local canonical skills
are also synchronized to newly detected hosts without overwriting
registry-managed targets.

Signed-off-by: Kevin Cui <bh@bugs.cc>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 8, 2026

Review Change Stack

Summary by CodeRabbit

  • Documentation

    • Updated skill command reference documentation to reflect current behavior for skill initialization, installation, and synchronization workflows.
  • Improvements

    • Skills now install consistently by copying to all target directories, replacing previous mixed copy/symlink behavior.
    • Startup synchronization extended to manage local skills alongside bundled and registry skills.

Walkthrough

This PR eliminates the symlink-or-copy publication strategy for bundled and published skills, converting to copy-only behavior. The isManagedSkillPublicationCurrent function is simplified to detect symlinks (non-current) versus copied directories (current). Core publication now always copies bundled skills into installation paths. A new local-skill synchronization pass is added during CLI startup that discovers local skills, validates paths, compares content, and publishes local canonical skills to installed locations while respecting registry-managed skill priority. Tests are updated throughout to verify copy behavior instead of symlink creation. Documentation reflects the new uniform copy-only publication mode.

Possibly related PRs

  • oomol-lab/oo-cli#111: Introduced the base startup managed-skill synchronization that this PR refines by adding local-skill sync and converting to copy-only publication semantics.
  • oomol-lab/oo-cli#123: Added per-agent publication mode resolution and symlink-or-copy behavior that this PR removes in favor of uniform copy-only publication.
  • oomol-lab/oo-cli#92: Modified publishBundledSkillInstallation and publication mode handling that this PR simplifies by removing mode-dependent logic entirely.
🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The pull request title follows the required format '(): ' with 'refactor' as type and 'skills' as scope, and clearly describes the main change of removing symlink publication.
Description check ✅ Passed The description is directly related to the changeset, explaining the removal of symlink publication and changes to synchronization behavior for bundled, registry, and local skills.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch use-copy

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

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/application/commands/skills/index.test.ts (1)

2953-2961: ⚡ Quick win

Move this copied-directory assertion into a shared test helper.

This helper is now duplicating the same realpath(...) !== ... plus lstat(...).isSymbolicLink() === false checks that also appear in other changed test files. Centralizing it in __tests__/helpers.ts will keep future publication-mode changes from drifting across suites.

As per coding guidelines, "When identical logic appears in 2+ files, extract it to a shared module with parameterized varying parts" and "If a helper function might be called by other test files, place it in the tests/helpers.ts file."

🤖 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 `@src/application/commands/skills/index.test.ts` around lines 2953 - 2961,
Extract the duplicated assertion helper expectCopiedSkillDirectory into the
shared test helpers file by creating/exporting the function from
__tests__/helpers.ts (keep the same async signature:
expectCopiedSkillDirectory(skillDirectoryPath: string,
canonicalSkillDirectoryPath: string): Promise<void>) and then replace the local
definition in src/application/commands/skills/index.test.ts with an import of
that helper; update any other test files that contain the same realpath + lstat
checks to import and use the shared expectCopiedSkillDirectory, and remove the
duplicate local implementations so all suites use the single exported helper.
🤖 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 `@src/application/commands/skills/managed-skill-publication.test.ts`:
- Around line 12-23: The test "treats a copied target as current" currently
creates an empty directory and asserts isManagedSkillPublicationCurrent(...)
returns true; instead, seed the fixture directory with the concrete managed
publication files that isManagedSkillPublicationCurrent expects (e.g., the skill
manifest and any marker files or metadata created for managed installs) before
calling isManagedSkillPublicationCurrent, or alternatively tighten
isManagedSkillPublicationCurrent to validate those files' presence/content
rather than treating any non-symlink directory as current; update the test to
create those files (using mkdir + writeFile) so the assertion reflects a real
managed publication.

---

Nitpick comments:
In `@src/application/commands/skills/index.test.ts`:
- Around line 2953-2961: Extract the duplicated assertion helper
expectCopiedSkillDirectory into the shared test helpers file by
creating/exporting the function from __tests__/helpers.ts (keep the same async
signature: expectCopiedSkillDirectory(skillDirectoryPath: string,
canonicalSkillDirectoryPath: string): Promise<void>) and then replace the local
definition in src/application/commands/skills/index.test.ts with an import of
that helper; update any other test files that contain the same realpath + lstat
checks to import and use the shared expectCopiedSkillDirectory, and remove the
duplicate local implementations so all suites use the single exported helper.
🪄 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

Run ID: d968661d-898a-4b63-8ede-7c1881f31f9f

📥 Commits

Reviewing files that changed from the base of the PR and between 632548c and 15da4ad.

📒 Files selected for processing (19)
  • docs/commands.md
  • docs/commands.zh-CN.md
  • src/application/commands/skills/auto-sync.ts
  • src/application/commands/skills/bundled-skill-filesystem.ts
  • src/application/commands/skills/index.cli.test.ts
  • src/application/commands/skills/index.test.ts
  • src/application/commands/skills/init.test.ts
  • src/application/commands/skills/init.ts
  • src/application/commands/skills/managed-skill-publication.test.ts
  • src/application/commands/skills/managed-skill-publication.ts
  • src/application/commands/skills/publish.test.ts
  • src/application/commands/skills/publish.ts
  • src/application/commands/skills/registry-skill-install.ts
  • src/application/commands/skills/registry-skill-publication.ts
  • src/application/commands/skills/shared.test.ts
  • src/application/commands/skills/shared.ts
  • src/application/commands/skills/update.test.ts
  • src/application/commands/skills/update.ts
  • src/i18n/catalog.ts
💤 Files with no reviewable changes (3)
  • src/i18n/catalog.ts
  • src/application/commands/skills/update.ts
  • src/application/commands/skills/registry-skill-install.ts

Comment on lines +12 to +23
test("treats a copied target as current", async () => {
const skillDirectoryPath = join(
tmpdir(),
`oo-managed-skill-publication-target-${Bun.randomUUIDv7()}`,
);

try {
await mkdir(skillDirectoryPath, { recursive: true });

await expect(
isManagedSkillPublicationCurrent(skillDirectoryPath),
).resolves.toBeTrue();
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Don't bless an empty directory as a current managed publication.

This fixture only creates an empty folder, so the test now codifies that any non-symlink directory is "current". That would let partially deleted or otherwise corrupted copied installs bypass repair/startup synchronization. Seed the fixture with the required managed files, or keep isManagedSkillPublicationCurrent(...) validating them before returning true.

🤖 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 `@src/application/commands/skills/managed-skill-publication.test.ts` around
lines 12 - 23, The test "treats a copied target as current" currently creates an
empty directory and asserts isManagedSkillPublicationCurrent(...) returns true;
instead, seed the fixture directory with the concrete managed publication files
that isManagedSkillPublicationCurrent expects (e.g., the skill manifest and any
marker files or metadata created for managed installs) before calling
isManagedSkillPublicationCurrent, or alternatively tighten
isManagedSkillPublicationCurrent to validate those files' presence/content
rather than treating any non-symlink directory as current; update the test to
create those files (using mkdir + writeFile) so the assertion reflects a real
managed publication.

@BlackHole1 BlackHole1 merged commit f769150 into main May 8, 2026
6 checks passed
@BlackHole1 BlackHole1 deleted the use-copy branch May 8, 2026 15:33
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.

1 participant