feat(workspace): `skill publish <name>` and a "Publish to workspace" action
Issue for this PR
Part of #1271 β the surface. #1280 added the publish path; this PR is what invokes it.
Was stacked on #1280; retargeted to main after it merged (rebuilt as one commit carrying only the command and the dialog action). The skill publish command here is what ran the end-to-end pass recorded on #1280.
Type of change
- New feature
What does this PR do?
Two ways to publish a locally authored skill to the linked workspace, saying the same things.
altimate-code skill publish <name> β resolves the skill the way skill test does, refuses a built-in (there is no directory to bundle; the workspace-owned snapshot is refused by publishSkill itself), and prints one line on success. Every deliberate refusal is printed as-is, because each already says what to do next:
$ altimate-code skill publish hello
This project is not linked to a workspace. Run `altimate-code link` first.
"Publish to workspace" in the Skills dialog's per-skill action picker, next to Show / Edit / Test / Remove. This is the discoverability half: the UAT report was that a participant could not tell whether publishing from the CLI was possible at all. A row that anyone who opens a skill will see answers that; a row under /workspace would only be found by someone already thinking about workspaces β and the verb needs a skill name, which that menu does not have. Disabled for built-ins and for skills the workspace sent us, the same way Remove is disabled for built-ins.
Deliberately not done: auto-publishing from skill create. A freshly scaffolded skill is a stub, publish should be an explicit "this is ready for the team" act, and create works on unlinked projects where publish cannot.
describePublish / explainPublishError in skill-publish.ts give both surfaces one vocabulary; a skill_published telemetry event records the outcome alongside the existing skill_created / skill_installed / skill_removed.
How did you verify your code works?
- 538 pass across
test/altimate/workspace,test/altimate/plugin, the install classifier and the fork-feature guards; typecheck clean. - New tests pin the shared wording and that a deliberate error passes through while an unexpected one does not.
skill publishsmoke-run from source on an unlinked project (prints the not-linked line) and on a missing skill (prints the not-found line);skill --helplists the subcommand.
Screenshots / recordings
Not a visual change beyond one new row in an existing picker.
Checklist
- I have tested my changes locally
- I have not included unrelated changes in this PR
π€ Generated with Claude Code
https://claude.ai/code/session_012Q51zFUmPg1WwtS5CrGJE6
Summary by cubic
Adds a skill publish <name> CLI command and a "Publish to workspace" action in the Skills dialog's per-skill picker, so locally authored skills can be uploaded to the linked workspace (part of #1271). The publish path from #1280 existed but nothing invoked it; the dialog's built-in check only caught embedded and relative skills, so filesystem-installed built-ins under ~/.altimate/builtin were publishable and publishing one would have synced a managed override to the whole team.
- Both surfaces now refuse built-ins, personal skills, workspace-sent skills, symlinked skill roots, and skills whose real path lies outside the project, using shared
describePublish/explainPublishErrorwording. - Skills are judged against the worktree root (or the session directory when the project has no git), so publishing from a subdirectory still reaches skills under the repo root; the boundary is resolved before checking, so a root symlinked to
/can't bypass the fallback. - Path classification uses
path.relativesegments rather than string prefixes, so siblings like~/.claude/skills-archivearen't mistaken for personal skills. The picker publishes one skill at a time instead of double-firing on Enter, and askill_publishedtelemetry event records the outcome from both CLI and TUI. The CLI's not-found message no longer assumes.opencode/skillsis the only location.
Summary by CodeRabbit
- New Features
- Added CLI support for publishing project skills to a linked workspace.
- Added a βPublish to workspaceβ action in the skill picker.
- Added publishing summaries, error messages, and telemetry for created or updated skills.
- Bug Fixes
- Prevented publishing built-in, personal, symlinked, root-level, or out-of-project skills.
- Improved skill classification for similarly named directories and consistent CLI/TUI behavior.
- Prevented duplicate publish actions while a publish is in progress.
- Tests
- Added coverage for publishing workflows, validation, error handling, and skill classification.