Skip to content

Deploying Artifacts to a Project

Deploy your imported artifacts to any project—locally or via a Git pull request. This guide covers both workflows: simple local deployment and the advanced Git-PR feature for collaborative artifact sharing.

Overview

Deployment places artifacts from your SkillMeat collection into a project's .claude/ directory, making them available to Claude Code and the CLI. SkillMeat supports two deployment modes:

Mode Use Case Requirements
Local Deploy Deploy to a project on your machine Project directory exists
Git-PR Deploy Deploy via pull request (collaborative) Git connection configured; repo has PR permissions

The Git-PR mode is the standout feature: it creates a pull request in your GitHub repository with the artifact files, allowing team code review and approval before merging.

Prerequisites

Before deploying, you need:

  1. An artifact in your collection — See Adding Artifacts to Your Collection to learn how to add skills, commands, agents, and other artifact types
  2. A target project — The project directory must exist (can be local or on GitHub)
  3. For Git-PR mode only:
  4. A Git connection configured to your GitHub repository (covered below)
  5. Write access to the repository

Deploy Locally to a Project

Local deployment writes artifacts directly to your project's .claude/ directory. This is the fastest way to test artifacts.

CLI

# Deploy a single artifact
skillmeat deploy canvas --to /path/to/project

# Deploy multiple artifacts at once
skillmeat deploy canvas python review --to /path/to/project

# Deploy from current project directory
cd /path/to/project
skillmeat deploy canvas

Output:

Deploying 1 artifact(s)...
✓ canvas -> .claude/skills/canvas/
✓ Deployed 1 artifact(s)

Scope selection: By default, artifacts deploy to the local scope (./.claude/). To deploy to the global user scope (~/.skillmeat/), add --scope user:

skillmeat deploy canvas --scope user

Web UI

  1. Navigate to the Projects page
  2. Open your target project and go to the Artifacts tab
  3. Click Add Artifacts or the Plus button
  4. Search for and select the artifacts you want to deploy
  5. Click Deploy to write them to the project

Artifacts are immediately available in your .claude/ directory after deployment.

When you deploy an artifact that already exists at the target project path, SkillMeat can automatically link it instead of overwriting. This preserves any local modifications you've made while keeping a deployment record.

SkillMeat compares the SHA (checksum) of the local artifact with the version in your collection:

  • SHA matches — The local copy is identical to the collection version. SkillMeat automatically links it, records a deployment, and skips the file copy. This is silent and fast.
  • SHA differs — The local copy has been modified. SkillMeat shows you a summary and prompts for your choice (see below).
  • --overwrite flag — Bypasses the prompt and always overwrites with the collection version (backward compatible with existing workflows).

Interactive Mode (Default)

In interactive mode, when SHAs differ, you'll see a summary of the differences and three options:

[D]iff: Show detailed changes
[L]ink as-is: Record deployment, keep local modifications
[O]verwrite with collection: Copy from collection (discard local changes)
[C]ancel: Skip this artifact and continue

Select your choice by pressing the key or typing the full word:

# Deploy with default interactive behavior
skillmeat deploy my-skill

# When prompted:
# Artifact 'my-skill' already exists locally (SHA mismatch)
# [D]iff [L]ink [O]verwrite [C]ancel: L
# ✓ Linked 'my-skill' (skill) -- deployment recorded, local copy preserved

Options: - [D]iff — Display side-by-side changes between local and collection versions - [L]ink as-is — Record deployment preserving your local modifications - [O]verwrite with collection — Replace local copy with collection version (destructive) - [C]ancel — Skip this artifact and continue with the next one (if deploying multiple)

When deploying via the web interface:

  1. Select artifacts to deploy
  2. If an artifact exists locally with a different version, a warning banner appears
  3. Click the artifact to see a side-by-side diff
  4. Choose Link As-Is or Overwrite before confirming deployment

Non-Overwrite Behavior

When SHAs match (local copy is identical to collection), no prompt is shown:

skillmeat deploy my-skill
# Output: ✓ Linked 'my-skill' (skill) -- local copy matches collection.

This is the same in both interactive and non-interactive modes.

Force Overwrite

Use the --overwrite flag to bypass the prompt and always copy from the collection:

skillmeat deploy my-skill --overwrite

This is useful when you know you want to replace local modifications, or for backward compatibility with existing scripts.

Non-Interactive Mode

Non-interactive mode is designed for CI/CD pipelines where you need predictable behavior and fast failure on conflicts:

skillmeat deploy my-skill --non-interactive

Behavior: - SHA match — Auto-links silently (same as interactive) - SHA mismatch — Exits with non-zero status (fails fast, no prompt) - Combined with --overwrite — Always overwrites regardless of SHA, no prompt

Use this in automated deployments:

#!/bin/bash
# CI/CD deploy script
skillmeat deploy my-skill --non-interactive || {
  echo "Deploy failed: artifact SHA mismatch"
  exit 1
}

Examples

# Deploy an artifact already at the project path (same SHA)
skillmeat deploy my-skill

# Output
Linked 'my-skill' (skill) -- local copy matches collection.
Deployment recorded.

Interactive Prompt with Differences

# Deploy when local copy has been modified
skillmeat deploy my-skill

# Artifact 'my-skill' already exists locally (SHA mismatch)
# Differences detected: 2 lines added, 1 line modified
# [D]iff [L]ink [O]verwrite [C]ancel: L

# Output
 Linked 'my-skill' (skill) -- deployment recorded, local copy preserved

Force Overwrite (Discard Local Changes)

# Replace local modifications with collection version
skillmeat deploy my-skill --overwrite

# Output
 Deployed 'my-skill' (skill) with collection version
  Overwrote 1 local modification(s)

CI/CD Deployment

# In a CI/CD pipeline: auto-link or fail fast
skillmeat deploy my-skill --non-interactive

# If SHA matches: deployment recorded silently
# If SHA differs: exits with error code 1 (stops the pipeline)
# Deploy multiple artifacts (prompts for each with differences)
skillmeat deploy skill-a skill-b command-c --to /path/to/project

# skill-a: [L]ink as-is
# skill-b: [O]verwrite
# command-c: linked (no prompt, SHA matched)

Deploy Via Git Pull Request

The Git-PR deploy feature creates a pull request on GitHub with the artifact files, enabling collaborative review and approval.

Step 1: Set Up a Git Connection

A Git connection links a GitHub repository to SkillMeat for scanning and deployment.

Create a New Connection

skillmeat connection create \
  --repo https://github.com/username/my-project \
  --token ghp_your_personal_access_token \
  --branch main

Output:

✓ Connection created: https://github.com/username/my-project
  Branch: main
  Auth: Personal Access Token (hidden)

  1. Go to Settings or Git Connections (usually in the top navigation)
  2. Click Add Connection or the Plus button
  3. Enter:
  4. Repository URL: Full GitHub URL (https://github.com/username/repo)
  5. Branch: The branch to target (usually main)
  6. Token (optional): GitHub PAT for private repositories
  7. Click Create

GitHub Personal Access Token (PAT)

To authenticate with GitHub, create a Personal Access Token:

  1. Go to GitHub Settings → Developer Settings → Personal Access Tokens
  2. Click Generate new token (classic)
  3. Give it a name (e.g., "SkillMeat Deploy")
  4. Select scopes: repo (full control of private repositories)
  5. Click Generate token and copy it
  6. Store it securely—you won't see it again

Token Security

Treat your GitHub PAT like a password. SkillMeat encrypts stored tokens but never shares them. Always use narrow scopes (don't grant unnecessary permissions).

Optional for Public Repos

Public repositories don't require a token for deployment (GitHub allows unauthenticated PRs), but providing one increases rate limits.

Link the Git connection you just created to your project so it knows where to deploy.

skillmeat project link-connection \
  --project /path/to/project \
  --connection https://github.com/username/my-project

Output:

✓ Connection linked to project
  Repository: https://github.com/username/my-project
  Branch: main

  1. Open your project on the Projects page
  2. Go to the Git Sources tab
  3. Click Link Connection or the Plus button
  4. Select a Git connection from the dropdown
  5. Click Link

A project can have multiple Git connections linked—useful for projects that pull artifacts from different sources.

Step 3: Initiate a Git-PR Deploy

Now deploy artifacts via a pull request on GitHub.

# Deploy to create a pull request
skillmeat deploy canvas python \
  --to /path/to/project \
  --via-pr \
  --branch "chore/add-artifacts" \
  --title "Add canvas and python skills" \
  --description "Adding new Claude artifacts to the project"

Options: - --via-pr — Create a pull request instead of writing directly - --branch — Branch name for the PR (default: skillmeat/deploy-TIMESTAMP) - --title — PR title (default: auto-generated) - --description — PR description/body (supports markdown) - --reviewers — Comma-separated GitHub usernames (optional) - --labels — Comma-separated PR labels (optional)

Output:

✓ PR created: https://github.com/username/my-project/pull/123
  Branch: chore/add-artifacts
  Files: 2 changed

  1. Open your project and go to the Artifacts tab
  2. Click Add Artifacts or Deploy
  3. Select the artifacts to deploy
  4. In the Deployment Options section:
  5. Select Deploy via Pull Request
  6. Enter a branch name (or use auto-generated)
  7. Optionally add PR title, description, reviewers, and labels
  8. Click Create Pull Request

A link to the new PR appears immediately. You can review the files in the PR on GitHub before merging.

Monitor PR Status

After creating a PR, you can track it:

# Check PR status
skillmeat pr status --project /path/to/project --number 123
  1. Open the project's Deployments tab
  2. Find the PR in the list—status shows as Open, Merged, or Closed
  3. Click the PR link to review on GitHub

Verify Deployment

Confirm that artifacts were deployed successfully.

# List deployed artifacts in a project
skillmeat list --project /path/to/project

# Check specific deployment
ls -la /path/to/project/.claude/skills/canvas/

Expected output for canvas skill:

SKILL.md           # Artifact metadata
README.md          # Optional documentation
[other files]      # Skill content

  1. Open your project and go to the Artifacts tab
  2. Use the Filter controls to search for deployed artifacts
  3. Click an artifact to view its status and files
  4. The Deployed badge appears next to the artifact name

Deployment is complete when artifact files appear in the .claude/ directory.

Custom Deployment Profiles

A deployment profile describes where and how artifacts deploy: its root directory, which artifact types it supports, and optional path mappings for different artifact types. SkillMeat ships with six built-in profiles (claude_code, codex, gemini, cursor, bob, other), but you can also declare custom profiles to target internal tools, forked conventions, or team-specific directories.

Declaring a Custom Profile

Custom profiles live in TOML configuration under [deployment.profiles.<name>], either at the project level (./.skillmeat/config.toml) or user level (~/.skillmeat/config.toml).

Minimal profile:

[deployment.profiles.my-tool]
root_dir = ".my-tool"
supported_artifact_types = ["skill", "command"]

Profile with inheritance (single-level extends):

[deployment.profiles.my-codex-fork]
extends = "codex"
root_dir = ".my-fork"
# Other fields (artifact_path_map, supported_artifact_types, etc.) 
# are inherited from 'codex' and can be selectively overridden

Profile with all fields:

[deployment.profiles.my-custom]
root_dir = ".artifacts"
supported_artifact_types = ["skill", "command", "agent"]
extends = "codex"  # Optional: inherit from built-in, then override

[deployment.profiles.my-custom.artifact_path_map]
skill = "skills"
command = "commands"
agent = "agents"

[deployment.profiles.my-custom.overlay_substitution]
".claude" = ".my-custom"

[deployment.profiles.my-custom.context_prefixes]
# Array of strings
# (optional, inherits from 'extends' if not set)

TOML Schema

Each custom profile accepts these fields:

Field Type Required Notes
root_dir string Yes Subdirectory where artifacts deploy (e.g. .my-tool, .agents). Must be relative to project root.
supported_artifact_types array of strings Yes Which artifact types this profile accepts (e.g. ["skill", "command", "agent"]). Fail-closed: missing or invalid list rejects all artifact types.
extends string No Name of a built-in platform to inherit from (single-level only). Must be one of: claude_code, codex, gemini, cursor, bob, other.
artifact_path_map dict No Maps artifact type → subdirectory under root_dir (e.g. { skill = "skills", command = "commands" }).
overlay_substitution dict No Path substitutions for overlay operations (e.g. { ".claude" = ".my-tool" }).
context_prefixes array of strings No Context-sync path prefixes for filtering.

Using Custom Profiles

Once declared, custom profiles are immediately available for deployment and initialization:

# Deploy to a custom profile
skillmeat deploy my-skill --profile my-tool

# Initialize a project with a custom profile
skillmeat init --profile my-tool

# View all registered custom profiles
skillmeat profile list

# Show the fully resolved profile (after extends merge + overrides)
skillmeat profile show my-tool

Managing Profiles via CLI

The skillmeat profile command group mirrors skillmeat instance for managing profiles:

# Register a new custom profile (at user-global scope by default)
skillmeat profile add my-tool --root-dir .my-tool --supported-types skill,command

# Register at project scope instead
skillmeat profile add my-tool --root-dir .my-tool --supported-types skill,command --project

# Register with inheritance from a built-in
skillmeat profile add my-fork --extends codex --root-dir .my-fork

# Edit an existing profile (partial update)
skillmeat profile edit my-tool --root-dir .my-tool-v2

# List profiles in both layers (shows which layer each is in)
skillmeat profile list

# Show resolved profile (including inheritance)
skillmeat profile show my-tool --json

Precedence and Inheritance

Profile name precedence (highest wins):

  1. Project-scoped custom profile (./.skillmeat/config.toml)
  2. User-scoped custom profile (~/.skillmeat/config.toml)
  3. Built-in platform (hardcoded)

If both project and user have a profile named my-tool, the project one wins. Use skillmeat profile show my-tool to see which layer is active and all values after inheritance resolution.

Field-level inheritance (when using extends):

When a custom profile declares extends = "codex", it inherits every unspecified field from the built-in codex profile. Fields you explicitly set in your custom profile override the inherited values. Multi-level inheritance (custom extends custom) is not supported — only single-level (custom extends built-in).

Validation and Error Handling

Custom profiles are validated both at declaration time (when profile add/edit is run) and at deployment time:

  • Missing supported_artifact_types — Rejected immediately; a profile without an eligibility matrix is invalid.
  • Invalid extends target — Must name a built-in platform; referencing another custom profile or a typo raises a clear error.
  • Invalid root_dir — Paths that escape the project root (e.g. ../../etc) are rejected for security.

If validation fails, skillmeat profile add exits with a descriptive error before writing the TOML. This prevents silent misdeployments at deploy time.

Example Workflows

Scenario 1: Internal Tool with Custom Artifact Paths

# Set up a profile for an internal tool
skillmeat profile add internal-tool \
  --root-dir .internal-tool \
  --supported-types skill,command \
  --path-map skill=skills \
  --path-map command=commands

# Initialize a project with this profile
skillmeat init --profile internal-tool

# Now deploy skills and commands to this custom location
skillmeat deploy my-skill --profile internal-tool

Scenario 2: Forking an Existing Convention

# Extend codex profile with a custom root directory
skillmeat profile add my-codex-fork \
  --extends codex \
  --root-dir .my-codex \
  --project  # Store at project scope only

# Deploy to the forked convention
skillmeat deploy my-skill --profile my-codex-fork

When Deployment Fails: Eligibility Errors

If you try to deploy an artifact to a profile that doesn't support its type, you'll see a structured error:

Error: Artifact type 'composite' is not supported by profile 'my-tool'.
Supported types: skill, command

This is fail-closed by design — a profile with a missing or invalid supported_artifact_types will never silently accept all artifact types.


Rollback a Deployment

If you need to remove or revert a deployed artifact, see the Sync & Version Rollback Guide for detailed rollback procedures.

Quick reference:

# Remove deployed artifact
skillmeat undeploy canvas --from /path/to/project

# Restore from snapshot
skillmeat restore --project /path/to/project --snapshot <snapshot-id>
  1. Open the project's Sync tab
  2. Select the version or snapshot to restore
  3. Click Restore and confirm

See Sync & Version Rollback Guide for complete details.

Enterprise Deployment Scoping

If you are using SkillMeat Enterprise, additional scoping options are available to control which projects and deployment profiles are affected by your deployment operations.

Undeploy with Project Scoping

In Enterprise edition, undeploying an artifact requires specifying the project_id (as a UUID). This ensures artifacts are only removed from the intended project.

# Undeploy from a specific project (required in Enterprise)
skillmeat undeploy canvas \
  --project-id 550e8400-e29b-41d4-a716-446655440000

Output:

✓ Undeployed canvas from project
  Profiles affected: 2

Optional: Undeploy from a specific deployment profile only

# Remove artifact from a single deployment profile
skillmeat undeploy canvas \
  --project-id 550e8400-e29b-41d4-a716-446655440000 \
  --deployment-profile-id 660f9510-f30c-52e5-b827-557766551111

Output:

✓ Undeployed canvas from profile
  Profile: 660f9510-f30c-52e5-b827-557766551111

  1. Open your project and go to the Deployments tab
  2. Find the artifact you want to remove
  3. Click the Undeploy or Remove button
  4. (Optional) If your artifact is deployed to multiple profiles, select the specific profile to undeploy from, or leave empty to remove all
  5. Click Confirm

Filter Deployments by Profile

When viewing deployments, you can filter by deployment profile to see only the profiles relevant to your task.

# List all deployments for a specific project
skillmeat deployment list \
  --project-id 550e8400-e29b-41d4-a716-446655440000

# Filter deployments to a specific profile
skillmeat deployment list \
  --project-id 550e8400-e29b-41d4-a716-446655440000 \
  --deployment-profile-id 660f9510-f30c-52e5-b827-557766551111

Output:

Deployments for project:

Profile: 660f9510-f30c-52e5-b827-557766551111 (production)
  ✓ canvas         v2.1.0  (deployed)
  ✓ python-review  v1.3.2  (deployed)

  1. Open your project and go to the Deployments tab
  2. Use the Profile Filter dropdown to select a specific deployment profile
  3. The list updates to show only deployments for that profile

When to Use Project and Profile Scoping

Scenario Use This
Remove artifact from one project only --project-id (required)
Remove artifact from staging but keep in production --project-id + --deployment-profile-id
View all deployments in a multi-tenant setup GET /deploy?project_id=<uuid>
Audit what's deployed to a specific environment Filter by project_id + deployment_profile_id

Project ID vs Project Path

In Enterprise edition, projects are identified by UUID (project_id), not file paths. The legacy project_path parameter is deprecated — always use project_id (UUID) when available.

Common Workflows

Deploy and Review via PR

Collaborative artifact sharing:

# 1. Create Git connection (one time)
skillmeat connection create \
  --repo https://github.com/team/shared-project \
  --token ghp_xxxxx

# 2. Link connection to project (one time)
skillmeat project link-connection \
  --project ./ \
  --connection https://github.com/team/shared-project

# 3. Deploy via PR for team review
skillmeat deploy my-custom-skill \
  --via-pr \
  --title "feat: Add custom analysis skill" \
  --description "Adds skill for automated code analysis" \
  --reviewers alice,bob

Deploy Multiple Artifacts at Once

skillmeat deploy \
  python python-advanced canvas review \
  --to /path/to/project

Deploy to Both Local and Git

Local deploy for immediate testing, then PR for team approval:

# Test locally first
skillmeat deploy canvas --to /path/to/project

# Once tested, create PR for team
skillmeat deploy canvas --to /path/to/project --via-pr

Troubleshooting

"Connection not found"

The project doesn't have a Git connection linked. Link one first:

skillmeat project link-connection \
  --project /path/to/project \
  --connection https://github.com/username/repo

"GitHub token expired or invalid"

Update the connection with a new token:

skillmeat connection update \
  --connection https://github.com/username/repo \
  --token ghp_new_token

"Permission denied on branch"

You don't have write access to the repository or branch. Check that: - Your GitHub token has repo scope - You're pushing to a branch you can write to - The repository isn't archived or locked

"PR files don't look right"

Verify the artifacts in your collection:

skillmeat list
skillmeat show canvas  # View artifact details

Next Steps