agent-skill-deploy
Agent Skill Collection Deploy
Purpose
Automate multi-surface deployment of agent skill collections:
- Pre-flight validation of git state, skills inventory, and surface readiness
- Conventional commit analysis with version bump recommendation
- Version bumping across all detected surface configuration files
- Surface-specific deployment with dry-run capability
- User approval gates before irreversible operations
When to Use This Skill
Use this skill when the user:
- Asks to "release", "deploy", "publish", or "ship" a skills collection
- Wants to bump versions and push to one or more marketplaces
- Needs to create a GitHub release for a skills repository
- Wants to publish skills to Claude Code, VS Code, or Copilot CLI marketplaces
- Asks to check deployment readiness or run a dry-run release
Do not use for npm packages, Docker deployments, Azure resource provisioning, or repositories without a /skills directory.
Supported Surfaces
| Surface | Config Files | Deploy Action | Tool Required |
|---|---|---|---|
| github | Git remote URL | Create tag + GitHub release | gh |
| claude-code | .claude-plugin/plugin.json (required), .claude-plugin/marketplace.json (optional) |
Bump plugin version, commit, push | git |
| vscode | package.json |
Bump version, commit, push | git |
| copilot-cli | package.json, .github/plugin/plugin.json, .github/plugin/marketplace.json (optional) |
Bump plugin version, commit, push | git |
Bundled Scripts
This skill includes three Node.js helper scripts in scripts/ for cross-platform operation (Windows and macOS):
- deploy-preflight.mjs — Validates git state, discovers surfaces, checks tool availability, verifies version consistency (including git tag version)
- deploy-analyze.mjs — Inventories skills, analyzes commits since last tag, recommends version bump
- deploy-execute.mjs — Bumps versions in all detected config files (regardless of selected surfaces), commits, tags, and deploys to selected surfaces
Run scripts from the skill directory:
node scripts/deploy-preflight.mjs
node scripts/deploy-analyze.mjs
node scripts/deploy-execute.mjs 1.2.0 --surfaces github,claude-code --dry-run
Version Handling Rules
Marketplace.json files contain two distinct version fields with different semantics:
plugins[].version(plugin version) — Tracks the version of each listed plugin. Bumped during releases for local plugins (wheresourceis".").metadata.version(marketplace version) — Tracks the version of the marketplace collection itself. Never bumped during skill/plugin releases. Managed independently.
Cross-file sync rules:
- All plugin versions must stay consistent:
plugin.json,package.json,plugins[].versionin marketplace files, and the git tag. - All
metadata.versionvalues across marketplace.json files (.claude-plugin/marketplace.jsonand.github/plugin/marketplace.json) must stay in sync with each other.
Deploy Workflow
Follow these steps in order. Stop immediately if any step fails.
Step 1: Pre-flight Checks
Run the preflight script to validate readiness:
node scripts/deploy-preflight.mjs
This checks:
- Current directory is a git repository
- Current branch is
masterormain - Working tree is clean (no uncommitted changes)
/skillsdirectory exists and contains at least one skill- Detects which surfaces are configured based on existing config files
- Verifies required tools are available for each surface
- Checks that both
.claude-plugin/plugin.jsonand.github/plugin/plugin.jsonexist; warns if either is missing (auto-created during deploy) - Reports version consistency across all surface configs, including git tag version
If checks fail, report the problem and suggest a fix. Do not proceed.
Step 2: Analyze Changes
Run the analysis script to understand what changed:
node scripts/deploy-analyze.mjs
This will:
- Inventory all skills in
/skillswith their names - Find the last release tag (or handle first release)
- List all commits since that tag
- Count commits by conventional type using anchored regex
- Detect breaking changes (
type!:suffix orBREAKING CHANGEin body) - Show file change statistics
- Print a version bump recommendation
Version bump criteria:
| Bump | When |
|---|---|
| Major | Breaking changes — type!: prefix or BREAKING CHANGE body |
| Minor | New features — any feat: commits |
| Patch | Everything else — fix:, docs:, refactor:, chore:, etc. |
Step 2b: Build Per-Skill Changelog
When the github surface is selected, build a concise, human-readable changelog grouped by skill. This replaces GitHub's auto-generated notes.
Procedure:
- Identify the previous release tag from
deploy-analyze.mjsoutput (theLast release tagline). If this is the first release, compare against the root commit. - For each skill listed in the
Skills Changedoutput, run:git diff v{{PREVIOUS}}..HEAD -- skills/{{SKILL_NAME}}/ - Analyze each diff and produce a concise bullet list summarizing user-visible changes per skill. Guidelines:
- Write each bullet as a short, action-oriented statement (e.g., "Added X", "Fixed Y", "Removed Z").
- Group by skill as a level-2 heading (
## skill-name). - Omit internal-only changes (whitespace, line-ending normalization) unless they are the only change.
- Mention version bumps within skill metadata only if no other substantive changes exist for that skill.
- Cap at roughly 5–7 bullets per skill; combine minor items if needed.
- Store the assembled Markdown changelog text for use in Step 9.
Example output format:
## agent-package-manager
- Added subdirectory path and pinned tag dependency examples to template
- Expanded manifest reference with Azure DevOps and GitLab guidance
- Added "APM not installed" troubleshooting section
## agent-skill-deploy
- Made marketplace.json optional for Claude Code surface detection
- Simplified version bump recommendation logic
## github-agentic-workflows
- Added install.md URL reference for agent-assisted setup
If only a single skill changed, omit the heading and use a flat bullet list.
Step 3: Confirm Version and Surfaces with User
Present the analysis summary and ask the user to choose a version and target surfaces.
Use the AskUserQuestion tool for version:
AskUserQuestion:
question: "Recommended: {{RECOMMENDATION}}. Which version bump for v{{CURRENT}} → v{{NEXT}}?"
header: "Version"
options:
- label: "Major (v{{MAJOR}})"
description: "Breaking changes — skill removals, renames, config restructuring"
- label: "Minor (v{{MINOR}})"
description: "New features — new skills, significant enhancements"
- label: "Patch (v{{PATCH}})"
description: "Fixes, docs, refactoring, chore, CI, tests"
- label: "Cancel"
description: "Abort the deployment"
Replace {{CURRENT}} with current version, compute {{MAJOR}}, {{MINOR}}, {{PATCH}} by incrementing the relevant segment (reset lower segments to 0).
If user selects Cancel, stop the workflow.
Use the AskUserQuestion tool for surfaces:
AskUserQuestion:
question: "Detected surfaces: {{DETECTED_SURFACES}}. Which surfaces to deploy to?"
header: "Surfaces"
options:
- label: "All detected ({{DETECTED_SURFACES}})"
description: "Deploy to every surface that has config files"
- label: "GitHub release only"
description: "Create tag and GitHub release"
- label: "Marketplaces only"
description: "Update marketplace configs without GitHub release"
- label: "Custom selection"
description: "Specify exact surfaces"
- label: "Cancel"
description: "Abort the deployment"
Step 4: Dry Run (Recommended)
Before making changes, perform a dry run to verify what will happen:
node scripts/deploy-execute.mjs {{VERSION}} --surfaces {{SURFACES}} --dry-run
Present the dry-run output to the user. The dry run shows:
- Which files will be modified and how
- Which git operations will be performed
- Which surface-specific deploy commands will run
- No files are changed, no git operations are executed
If the dry run reveals issues, address them before proceeding.
Step 5: Bump Versions
Execute the version bump across all detected surface configs:
node scripts/deploy-execute.mjs {{VERSION}} --surfaces {{SURFACES}} --bump-only
IMPORTANT — version sync invariant: The script always bumps every detected config file (plugin.json, marketplace.json, package.json) regardless of which surfaces were selected via --surfaces. This prevents version drift between surfaces. The --surfaces flag only controls which deployment actions run in --push mode.
Auto-creation of missing plugin.json: Before bumping, the script checks that both .claude-plugin/plugin.json (claude-code surface) and .github/plugin/plugin.json (copilot-cli surface) exist. If either file is missing, it is automatically created from the sibling plugin.json (preferred) or from package.json metadata (name, description, version, author, repository, license, keywords) as a fallback. The copilot-cli variant also gets "skills": "skills/".
This updates version fields in:
.claude-plugin/plugin.json→.version(claude-code surface).claude-plugin/marketplace.json→.plugins[0].version(claude-code surface, only if the file exists)package.json→.version(vscode and copilot-cli surfaces).github/plugin/plugin.json→.version(copilot-cli surface, only if the file exists).github/plugin/marketplace.json→.plugins[0].versionand.metadata.version(copilot-cli surface, only if the file exists)
If marketplace.json is absent, the plugin is assumed to be listed by a marketplace defined in another repository. Only plugin.json is bumped.
Verify all files were updated correctly by reading them back.
Step 6: Commit Version Bump
Stage and commit all modified config files:
git add -A
git commit -m "Release v{{VERSION}}"
Step 7: Create Git Tag
Tag the release commit:
git tag v{{VERSION}}
Step 8: User Approval Before Push
CRITICAL: Always pause here for user approval.
Present a summary and ask for confirmation.
Use the AskUserQuestion tool:
AskUserQuestion:
question: "Ready to push v{{VERSION}} and deploy to {{SURFACES}}?"
header: "Deploy"
options:
- label: "Yes — push and deploy"
description: "Push commits, tags, and run surface-specific deployments"
- label: "Push only — skip surface deploys"
description: "Push commits and tags but skip marketplace-specific actions"
- label: "No — keep local"
description: "Keep local commit and tag, do not push"
If user selects No, inform them:
- The commit and tag remain local
- To undo:
git reset --hard HEAD~1 && git tag -d v{{VERSION}}
Step 9: Push and Deploy
Only after user approves:
- Save the per-skill changelog from Step 2b to a temporary file:
echo '{{CHANGELOG}}' > /tmp/release-notes.md - Run the push and deploy:
node scripts/deploy-execute.mjs {{VERSION}} --surfaces {{SURFACES}} --push --notes-file /tmp/release-notes.md
This performs:
git push && git push --tagsfor all surfaces- For github surface: create the release using the per-skill changelog from Step 2b:
Ifgh release create v{{VERSION}} --title "v{{VERSION}}" --notes-file /tmp/release-notes.md--notes-fileis not provided, the script falls back to--generate-notes. Always prefer providing the per-skill changelog.
After pushing, print the remote URL and relevant marketplace links.
Error Handling
- No
/skillsdirectory: Report that the repository does not follow the expected skill collection layout and stop. - Missing tools: Report which tools are missing for which surfaces. Suggest installation commands. Allow deployment to surfaces whose tools are available.
- Version mismatch across surfaces: Report the mismatch and suggest running the bump step to synchronize all config files.
- Tag already exists: Report the conflict and suggest either choosing a different version or deleting the existing tag with user confirmation.
- Push failure: Report the error. Do not retry automatically. Suggest checking remote access and authentication.
- Surface deploy failure: If one surface fails, report it but continue with remaining surfaces. Provide per-surface status summary at the end.
- Dry-run divergence: If the actual execution differs from the dry run, pause and report the divergence to the user.
More from webmaxru/enonic-agent-skills
enonic-webhook-integrator
Sets up Enonic XP event listeners, webhook configurations, and external system integrations triggered by content lifecycle events. Covers lib-event listener registration, node event filtering, outbound webhook configuration via com.enonic.xp.webhooks.cfg, custom HTTP service controllers for inbound webhooks, task-based async processing with lib-task, and outbound HTTP calls with lib-httpClient. Use when listening for content publish/create/update/delete events, configuring outbound webhooks, building HTTP service endpoints for inbound webhooks, or triggering async processing on content changes. Do not use for content querying, frontend component development, non-Enonic event systems, or GitHub webhook configuration.
91skill-creator
Authors and structures professional-grade agent skills following the agentskills.io spec. Use when creating new skill directories, drafting procedural instructions, or optimizing metadata for discoverability. Don't use for general documentation, non-agentic library code, or README files.
89enonic-api-reference
Enonic XP server-side JavaScript/TypeScript API reference for all /lib/xp/* libraries. Provides function signatures, parameters, return types, and usage examples for lib-content, lib-node, lib-auth, lib-portal, lib-context, lib-event, lib-task, lib-repo, lib-io, lib-mail, and lib-schema. Use when looking up Enonic XP library functions, parameter shapes, return types, or usage examples. Do not use for Guillotine GraphQL queries, content type schema definitions, Enonic CLI commands, or non-Enonic JavaScript APIs.
89enonic-content-migration
Generates Enonic XP scripts for bulk content operations — creating, updating, querying, migrating, and transforming content using lib-content and lib-node APIs. Covers the query DSL (NoQL), aggregations, batch processing, task controllers for long-running operations, and export/import workflows. Use when writing bulk content creation, update, or deletion scripts, querying with NoQL syntax, migrating content between environments, running long-running task operations, or working with aggregations and paginated retrieval. Do not use for Guillotine GraphQL frontend queries, content type schema definitions, single contentLib.get() calls, or non-Enonic data migration tools.
89enonic-sandbox-manager
Guides developers through Enonic CLI commands for sandbox management, project scaffolding, local development, app deployment, and CI/CD pipeline generation. Use when creating Enonic XP sandboxes, starting or stopping local instances, scaffolding projects from starters, running dev mode with hot-reload, deploying apps, or generating CI/CD workflows for Enonic apps. Don't use for writing XP application code (controllers, content types), querying via Guillotine or lib-content APIs, configuring non-Enonic environments, or Docker/Kubernetes deployment of XP.
89enonic-guillotine-query-builder
Composes, debugs, and optimizes Guillotine GraphQL queries for Enonic XP headless content delivery. Covers query construction, variable usage, filtering, aggregation, pagination, sorting, and TypeScript type generation from the auto-generated Guillotine schema. Use when writing or troubleshooting Guillotine queries, querying custom content types through GraphQL, or generating typed interfaces from Guillotine responses. Don't use for content type XML definitions, non-Enonic GraphQL APIs (Apollo, Hasura), server-side lib-content queries, or Guillotine deployment and CORS configuration.
89