craftdesk
Package manager for Claude Code skills and agents and other AI related resources
CraftDesk CLI
Dependency management for AI capabilities - Install, manage, and version control your Claude Code skills, agents, commands, hooks, and plugins.
The command-line interface for managing your Coding AI capabilities. Similar to npm for JavaScript or bundler for Ruby, CraftDesk CLI provides a complete package management solution for AI-powered development tools.
What is CraftDesk?
CraftDesk is a package manager for AI capabilities used in Claude Code and other AI development environments. It allows you to:
- Install AI skills, agents, commands, hooks, plugins, and collections from git repositories or registries
- Collections - Curate and share groups of related crafts that work together
- Plugin system - Bundle multiple crafts with automatic dependency resolution
- Multi-agent sync - Share skills across multiple AI assistants (Claude, Cursor, Windsurf, etc.)
- Lock versions for reproducible environments across teams
- Manage dependencies with automatic recursive installation
- Support monorepos with subdirectory extraction
- Auto-convert GitHub URLs - paste any GitHub URL (tree/blob)
- Direct file references - install single files from repositories
- Settings integration - Automatic registration in
.claude/settings.json - MCP server support - Configure Model Context Protocol servers via plugins
Think of it as:
- npm for Node.js → CraftDesk for AI capabilities
- Bundler for Ruby → CraftDesk for Claude tools
- Cargo for Rust → CraftDesk for AI agents
Note: A self-hosted registry server is currently under development and will be available soon, enabling private registries and centralized craft distribution.
Quick Start
Install CraftDesk
npm install -g craftdesk
Verify installation:
craftdesk --version
# x.y.z
Requirements: Node.js >= 18.0.0, Git, npm or yarn
1. Initialize a New Project
mkdir my-ai-project
cd my-ai-project
craftdesk init
This creates a craftdesk.json file:
{
"name": "my-ai-project",
"version": "1.0.0",
"type": "skill",
"dependencies": {}
}
2. Add Dependencies
# Add a single skill file from GitHub (auto-converts web URLs)
craftdesk add https://github.com/aviflombaum/rspec-rails-agents/blob/main/rspec-dry-agent.md
# Add from git repository
craftdesk add git+https://github.com/aviflombaum/rspec-rails-agents.git
# Add from monorepo subdirectory
craftdesk add https://github.com/technicalpickles/pickled-claude-plugins/tree/main/plugins/working-in-monorepos/skills/working-in-monorepos
# Add with explicit type
craftdesk add https://github.com/aviflombaum/rspec-rails-agents/blob/main/rspec-dry-agent.md --type agent
3. Install Everything
craftdesk install
This installs all dependencies to .claude/ directory and creates craftdesk.lock.
4. View Installed Crafts
craftdesk list
Output:
[email protected]
Installed crafts:
• my-skill@main (skill)
• custom-agent@main (agent)
Total: 2 crafts installed
Table of Contents
- What is CraftDesk?
- Quick Start
- Core Concepts
- Plugin System
- Command Reference
- Embedded/Local Skills
- Authentication
- Dependency Sources
- Monorepo Support
- craftdesk.json Reference
- craftdesk.lock
- CI/CD Integration
- Troubleshooting
- Development
- Documentation
Core Concepts
Crafts
A craft is any AI capability:
- Skill - Knowledge domain (e.g., ruby-on-rails, postgres-expert)
- Agent - Autonomous task executor (e.g., code-reviewer, test-runner)
- Command - Slash command (e.g., /deploy, /analyze)
- Hook - Event handler (e.g., pre-commit, post-install)
- Plugin - Bundle of multiple crafts with dependencies and MCP server configuration
- Collection - Curated group of related crafts that work together (e.g., rails-enterprise-stack)
Format Conversion
Convert CraftDesk crafts to other AI editor formats for cross-platform use.
Supported Formats:
- Cursor - Modern
.mdcformat in.cursor/rules/directory - Cursor Legacy - Plain text
.cursorrulesformat - Continue.dev - Prompt and rule files in
.continue/prompts/and.continue/rules/
Why convert formats?
- Use any AI editor - Write once, deploy to Cursor, Continue, Windsurf, etc.
- Team flexibility - Developers can use their preferred editors
- Maximum reach - Distribute crafts to wider audience
- No lock-in - Not tied to single platform
Basic Usage:
# Convert a craft to Cursor format
craftdesk convert ./my-craft --to cursor
# Convert to Continue.dev format
craftdesk convert ./my-craft --to continue
# Convert to legacy .cursorrules
craftdesk convert ./my-craft --to cursor-legacy
# Convert all installed crafts
craftdesk convert --all --to cursor --output .cursor/rules
# List available formats
craftdesk convert --list-formats
Example: Rails Skill → Cursor
Your SKILL.md:
---
name: ruby-on-rails
description: Ruby on Rails development
---
## Instructions
Expert knowledge of Rails framework...
## Best Practices
- Use Strong Parameters
- Follow RESTful conventions
Converted to .cursor/rules/ruby-on-rails.mdc:
---
description: Ruby on Rails development
globs:
- "**/*.rb"
- "**/*.erb"
- "**/*.haml"
alwaysApply: true
---
# Ruby On Rails
## Overview
Expert knowledge of Rails framework...
## Best Practices
- Use Strong Parameters
- Follow RESTful conventions
Advanced Options:
# Merge modes
craftdesk convert --to cursor --merge-mode skip # Skip existing files
craftdesk convert --to cursor --merge-mode append # Append to existing
craftdesk convert --to cursor --merge-mode overwrite # Overwrite (default)
# Custom output directory
craftdesk convert --to cursor --output /custom/path
# Convert specific craft type
craftdesk convert .claude/skills/ruby-rails --to continue
What Gets Converted:
| Section | Cursor | Continue |
|---|---|---|
| Instructions | ✓ Overview | ✓ Context |
| Code Patterns | ✓ Code Patterns | ✓ Patterns to Follow |
| Examples | ✓ Examples | ✓ Examples |
| Best Practices | ✓ Best Practices | ✓ Best Practices |
| Pitfalls | ✓ Mistakes to Avoid | ✓ Mistakes to Avoid |
| Workflows | ✓ Common Workflows | ✓ Step-by-Step Workflows |
Language-Specific Features:
Cursor converter automatically infers file globs based on content:
- Ruby/Rails →
**/*.rb,**/*.erb, config files - TypeScript →
**/*.ts,**/*.tsx - Python →
**/*.py - JavaScript →
**/*.js,**/*.jsx - And more... (Go, Rust, PHP, Java, etc.)
Continue converter generates:
- Prompts (invokable with
/) - for manual use - Rules (automatic) - applied to all matching files
CI/CD Integration:
# .github/workflows/convert-crafts.yml
name: Convert Crafts to Multiple Formats
on: [push]
jobs:
convert:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install CraftDesk
run: npm install -g craftdesk
- name: Convert to Cursor
run: craftdesk convert --all --to cursor --output dist/cursor
- name: Convert to Continue
run: craftdesk convert --all --to continue --output dist/continue
- name: Upload artifacts
uses: actions/upload-artifact@v2
with:
name: converted-crafts
path: dist/
Tips:
- Test conversions - Always verify converted files work in target editor
- Preserve originals - Keep SKILL.md as source of truth
- Update together - Convert after each craft update
- Version control - Commit both source and converted formats
Multi-Agent Sync
Share skills across multiple AI coding assistants - Sync your crafts to Claude Code, Cursor, Windsurf, Continue.dev, and more with automatic copy management and drift detection.
Why use multi-agent sync?
- Single source of truth - Maintain skills in one location (
.claude/skills/) - Cross-editor compatibility - Use the same skills in Claude, Cursor, Windsurf, etc.
- Team flexibility - Developers can use their preferred AI assistant
- Automatic sync - Install once, sync everywhere
- Drift detection - SHA-256 checksums detect modifications
- Windows compatible - Copy-based (no symlinks required)
Quick Start:
# 1. Interactive setup (recommended)
craftdesk setup-multi-agent
# 2. Detect available AI assistants
craftdesk detect-agents
# 3. Sync all crafts to configured agents
craftdesk sync
# 4. Verify sync status (check for drift)
craftdesk verify
Configuration:
Add to your craftdesk.json:
{
"name": "my-project",
"version": "1.0.0",
"dependencies": {
"ruby-expert": "^1.0.0"
},
"multiAgent": {
"enabled": true,
"canonical": ".claude",
"targets": [
".claude/skills",
".cursor/skills",
".windsurf/skills"
],
"autoSync": true
}
}
How it works:
- Canonical Location - Skills are installed to
.claude/skills/(source of truth) - Target Directories - Copies are created in
.cursor/skills/,.windsurf/skills/, etc. - Checksum Tracking - Each copy has a
.craftdesk-checksumfile (SHA-256) - Drift Detection -
craftdesk verifycompares checksums to detect modifications - Re-sync -
craftdesk syncupdates all copies from canonical
Example Workflow:
# Install a new skill
craftdesk add git+https://github.com/user/ruby-expert.git
# Skills auto-sync to all agents (if autoSync: true)
# ✓ Installed to .claude/skills/ruby-expert
# ✓ Synced to .cursor/skills/ruby-expert
# ✓ Synced to .windsurf/skills/ruby-expert
# Verify everything is in sync
craftdesk verify
# ✅ All 3 craft(s) are in sync!
# Later, check for drift
craftdesk verify
# ⚠️ ruby-expert
# Out of sync: .cursor/skills/ruby-expert (modified)
# Re-sync to fix drift
craftdesk sync --craft ruby-expert
# ✅ Synced ruby-expert to 3 location(s)
Supported AI Assistants:
| Assistant | Directory | Auto-Detected |
|---|---|---|
| Claude Code | .claude/skills/ |
✅ Always enabled (canonical) |
| Cursor | .cursor/skills/ |
✅ Yes |
| Windsurf | .windsurf/skills/ |
✅ Yes |
| Continue.dev | .continue/skills/ |
✅ Yes |
| Generic .agents | .agents/skills/ |
✅ Yes |
Commands:
# Setup wizard (interactive)
craftdesk setup-multi-agent
# Detect AI assistants in project
craftdesk detect-agents
craftdesk detect-agents --verbose
craftdesk detect-agents --format json
# Sync all crafts to all targets
craftdesk sync
craftdesk sync --craft ruby-expert # Sync specific craft
craftdesk sync --dry-run # Preview changes
craftdesk sync --force # Force re-sync
# Verify sync status
craftdesk verify
craftdesk verify --craft ruby-expert # Verify specific craft
craftdesk verify --verbose # Show checksums
craftdesk verify --format json # JSON output
Best Practices:
- Use canonical as source of truth - Always edit skills in
.claude/skills/ - Enable autoSync - New installs automatically sync to all agents
- Run verify regularly - Check for drift, especially in teams
- Sync after manual edits - If you edit a skill, run
craftdesk sync - Commit canonical only - Add target directories to
.gitignore
gitignore Example:
# Only track canonical location
.cursor/skills/*
.windsurf/skills/*
.continue/skills/*
# Track canonical
!.claude/skills/
Why copy instead of symlinks?
We use copy-based sync instead of symlinks for maximum compatibility:
- ✅ Windows compatible - No admin privileges or Developer Mode required
- ✅ Git-friendly - No
core.symlinkscomplications - ✅ Reliable - Works consistently across all platforms
- ✅ Simple - Easy to understand and debug
- ✅ Verifiable - Checksums detect any modifications
Embedded/Local Skills
Commit project-specific skills to your repository alongside managed dependencies for a hybrid approach to skill management.
What are embedded skills?
Embedded skills are local, project-specific AI capabilities that are:
- ✅ Committed to git - Part of your repository, versioned with your code
- ✅ Project-specific - Custom skills unique to your project
- ✅ Team-shared - Distributed via
git clone(notcraftdesk install) - ✅ Auto-synced - Sync to other AI assistants with multi-agent support
- ⚠️ Not managed - No version updates via
craftdesk update
When to embed vs. manage:
| Use Case | Embedded | Managed (dependencies) |
|---|---|---|
| Project-specific business logic | ✅ | ❌ |
| Custom team workflows | ✅ | ❌ |
| Proprietary domain knowledge | ✅ | ❌ |
| Shared/reusable skills | ❌ | ✅ |
| Skills that need updates | ❌ | ✅ |
| Skills from registry/git repos | ❌ | ✅ |
Quick Start:
# 1. Create a local skill manually
mkdir -p .claude/skills/my-project-skill
cat > .claude/skills/my-project-skill/SKILL.md <<EOF
---
skill: my-project-skill
version: 1.0.0
---
# My Project Skill
Project-specific knowledge about our custom architecture...
EOF
# 2. Register it as embedded
craftdesk embed my-project-skill
# 3. Commit to git
git add .claude/skills/my-project-skill craftdesk.json
git commit -m "Add my-project-skill as embedded skill"
# Team members get it via git clone (not craftdesk install!)
Configuration:
Your craftdesk.json tracks embedded skills separately from dependencies:
{
"name": "my-project",
"version": "1.0.0",
"dependencies": {
"ruby-expert": "^1.0.0", // Managed, from registry
"postgres-expert": "^2.0.0" // Managed, from git
},
"embedded": [
"my-project-skill", // Embedded, committed to git
"team-coding-standards" // Embedded, team-specific
]
}
How .gitignore works:
CraftDesk automatically generates .claude/skills/.gitignore to:
- ✅ Ignore managed skills - Not committed (installed via
craftdesk install) - ✅ Allow embedded skills - Committed with your code
- ✅ Track orphans - Skills not in either list (commented warnings)
Example generated .gitignore:
# Auto-generated by CraftDesk - DO NOT EDIT
# This file is managed automatically based on craftdesk.json and craftdesk.lock
# Managed dependencies (from craftdesk.lock)
# These are installed via `craftdesk install` and should not be committed
postgres-expert/
ruby-expert/
# Embedded/local skills (committed to git)
# These are project-specific and should be committed
# NOT ignored: my-project-skill/
# NOT ignored: team-coding-standards/
# Untracked (not in craftdesk.json or craftdesk.lock)
# Add these to dependencies or embedded list, or delete them
# orphaned-old-skill/
Commands:
craftdesk embed <name> [options]
Register a skill as embedded (committed to git).
Options:
--type <type>- Craft type: skill, agent, command, hook (default: skill)--skip-sync- Skip multi-agent sync after embedding
Examples:
# Embed a skill
craftdesk embed my-local-skill
# Embed an agent
craftdesk embed my-automation-agent --type agent
# Embed without syncing to other agents
craftdesk embed team-workflow --skip-sync
What happens:
- ✅ Adds skill to
craftdesk.jsonembeddedarray - ✅ Updates
.claude/skills/.gitignoreto allow the skill - ✅ Syncs to other AI assistants (if multi-agent enabled)
Requirements:
- Skill directory must exist (
.claude/skills/my-local-skill/) - Cannot embed a managed dependency (remove from
dependenciesfirst) - Cannot embed the same skill twice
craftdesk unembed <name> [options]
Unregister an embedded skill (no longer committed).
Options:
--remove- Also delete the skill files from disk
Examples:
# Unembed a skill (files remain on disk)
craftdesk unembed my-local-skill
# Unembed and delete files
craftdesk unembed old-skill --remove
What happens:
- ✅ Removes skill from
craftdesk.jsonembeddedarray - ✅ Updates
.claude/skills/.gitignore(skill becomes orphaned) - ⚠️ Skill files remain unless
--removeis used
After unembedding:
- Skill becomes "orphaned" (commented in
.gitignore) - Manually delete files or re-embed it
- Or add it to
dependenciesto manage it
Workflow Examples:
1. Create and embed a new skill:
# Create skill directory and file
mkdir -p .claude/skills/deployment-guide
cat > .claude/skills/deployment-guide/SKILL.md <<'EOF'
---
skill: deployment-guide
version: 1.0.0
---
# Deployment Guide
Our custom deployment process...
EOF
# Embed it
craftdesk embed deployment-guide
# Commit
git add .claude/skills/deployment-guide craftdesk.json
git commit -m "Add deployment-guide skill"
2. Convert managed skill to embedded:
# You have: [email protected] (from registry)
# You want: Modify it and commit to your repo
# 1. Remove from dependencies
craftdesk remove ruby-expert
# 2. Skill files are now orphaned (but still on disk)
# 3. Embed it
craftdesk embed ruby-expert
# 4. Commit your customized version
git add .claude/skills/ruby-expert craftdesk.json
git commit -m "Embed ruby-expert with custom modifications"
3. List and identify embedded skills:
craftdesk list
# Output shows embedded badge:
# 📚 Skills:
# [email protected]
# [email protected]
# [email protected] 📌 (embedded)
# [email protected] 📌 (embedded)
4. Team collaboration:
# Developer A: Creates and embeds skill
craftdesk embed new-feature-guide
git add .claude/skills/new-feature-guide craftdesk.json .claude/skills/.gitignore
git commit -m "Add new-feature-guide"
git push
# Developer B: Pulls and gets skill automatically
git pull
# ✅ Skill is ready to use (no craftdesk install needed!)
# Multi-agent sync works too (if enabled)
craftdesk verify
# ✅ new-feature-guide synced to .cursor/skills/
# ✅ new-feature-guide synced to .windsurf/skills/
Best Practices:
- Use embedded for project-specific knowledge - Custom workflows, business logic, proprietary info
- Use managed for reusable skills - Generic skills that can be shared across projects
- Always commit .gitignore - CraftDesk auto-generates it, keep it in git
- Document embedded skills - Add README explaining their purpose
- Version embedded skills - Update version in skill frontmatter when modified
- Verify multi-agent sync - Run
craftdesk verifyafter embedding
Collections
Collections are crafts that group related capabilities together. Instead of installing 6 individual crafts, install one collection that includes all of them.
Why use collections?
- Faster onboarding - One command installs complete workflows
- Curated quality - Experts bundle best-of-breed tools
- Consistent stacks - Teams share identical setups
- Versioned together - Dependencies tested to work together
Example: Rails Enterprise Stack
Create a collection in craftdesk.json:
{
"name": "rails-enterprise-stack",
"version": "1.0.0",
"type": "collection",
"description": "Complete Rails enterprise development setup",
"dependencies": {
"ruby-on-rails": "^7.0.0",
"rspec-testing": "^3.12.0",
"rubocop-linter": "^1.50.0",
"sidekiq-background-jobs": "^7.0.0",
"postgresql-expert": "^15.0.0",
"devise-auth": "^4.9.0"
}
}
Installing a collection:
craftdesk add git+https://github.com/company/rails-enterprise-stack.git
What happens:
- CraftDesk reads the collection's
craftdesk.json - Recursively resolves all 6 dependencies
- Installs the collection + all dependencies
- Creates lockfile tracking everything
Result: 7 crafts installed (collection + 6 dependencies)
How collections work:
Collections leverage CraftDesk's recursive dependency resolution. When you install a craft with dependencies, CraftDesk:
- Clones the repository
- Reads
craftdesk.json - Adds all dependencies to the resolution queue
- Recursively resolves transitive dependencies
- Installs everything with a single lockfile
This means any craft with dependencies acts as a collection - the type: "collection" field just improves discoverability in the registry.
Nested collections:
Collections can depend on other collections:
{
"name": "full-stack-rails",
"type": "collection",
"dependencies": {
"rails-enterprise-stack": "^1.0.0", // Another collection!
"frontend-tooling": "^2.1.0", // Another collection!
"docker-deployment": "^1.5.0"
}
}
CraftDesk handles arbitrary nesting depth with circular dependency detection.
Manifest File: craftdesk.json
Declares your project's dependencies:
{
"name": "my-project",
"version": "1.0.0",
"dependencies": {
"my-skill": {
"git": "https://github.com/user/skill.git",
"branch": "main"
}
}
}
Lockfile: craftdesk.lock
Records exact versions installed (like package-lock.json or Gemfile.lock):
{
"version": "1.0.0",
"lockfileVersion": 1,
"crafts": {
"my-skill": {
"version": "main",
"resolved": "https://github.com/user/skill.git",
"integrity": "a1b2c3d4e5f6...",
"type": "skill",
"git": "https://github.com/user/skill.git",
"branch": "main",
"commit": "a1b2c3d4e5f6789012345678901234567890abcd"
}
}
}
Always commit this file to version control!
Security: Checksum Verification
CraftDesk automatically verifies the integrity of downloaded packages:
- Registry packages: SHA-256 checksums are computed when you first add a craft and stored in
craftdesk.lock - Subsequent installs: The downloaded file is verified against the stored checksum before extraction
- MITM protection: Prevents tampering during download by detecting any modifications
- Git packages: Git commit hashes serve as checksums - stored in the lockfile and verified during clone
What happens on checksum mismatch:
Error: Checksum verification failed for john/[email protected].
Expected: a1b2c3d4e5f6...
This may indicate a corrupted download or a security issue.
Try running 'craftdesk install --no-lockfile' to re-resolve dependencies.
The lockfile contains SHA-256 hashes that ensure reproducible and secure installations across all team members.
Install Directory
By default, crafts install to .claude/ in your project:
.claude/
├── settings.json # Plugin configuration (auto-generated)
├── skills/
│ ├── ruby-on-rails/
│ └── postgres-expert/
├── agents/
│ └── code-reviewer/
├── commands/
│ └── deploy/
├── hooks/
│ └── pre-commit/
└── plugins/ # Flat plugin installation
├── company-rails-plugin/
│ ├── plugin.json
│ ├── PLUGIN.md
│ └── skills/...
└── my-skill-plugin/ # Wrapped skill
Plugin System
New in v0.3.0: CraftDesk now supports a comprehensive plugin system for bundling multiple crafts with automatic dependency management.
What are Plugins?
Plugins allow you to:
- Bundle multiple crafts (skills, agents, commands, hooks) together
- Declare dependencies that are automatically installed
- Configure MCP servers (Model Context Protocol) for external tools
- Share configurations and related files as a cohesive package
- Wrap individual crafts as plugins for better organization
Installing Plugins
# Install a plugin from registry
craftdesk add company/rails-standards-plugin
# What happens automatically:
# 1. Plugin is installed to .claude/plugins/company-rails-standards-plugin/
# 2. Dependencies are resolved and auto-installed
# 3. Plugin is registered in .claude/settings.json
# 4. MCP server is configured (if provided)
# 5. Plugin tree is added to craftdesk.lock
Example Output:
Adding company/rails-standards-plugin...
Found company/[email protected]
Installing company/rails-standards-plugin...
Plugin detected - resolving dependencies...
Resolved 3 total dependencies
Installing plugin dependency: john/rspec-testing...
✓ Resolved john/[email protected]
Installing plugin dependency: jane/postgres-toolkit...
✓ Resolved jane/[email protected]
✓ Installed company/[email protected]
Craft added successfully!
Plugin Structure
A plugin contains a plugin.json manifest:
{
"name": "company-rails-plugin",
"version": "2.1.0",
"type": "plugin",
"description": "Rails development standards",
"author": "company",
"components": {
"skills": ["coding-standards", "rails-best-practices"],
"agents": ["standards-enforcer"],
"commands": ["check-standards"]
},
"dependencies": {
"john/rspec-testing": "^1.5.0",
"jane/postgres-toolkit": "^3.2.0"
},
"mcp": {
"type": "stdio",
"command": "/usr/bin/rails-standards-mcp",
"args": ["--config", ".claude/plugins/company-rails-plugin/config.json"]
}
}
Automatic Dependency Resolution
When you install a plugin, all dependencies are automatically installed:
$ craftdesk add company/rails-plugin
# Installs dependency tree:
# company/rails-plugin (direct)
# ├── john/rspec-testing (dependency)
# └── jane/postgres-toolkit (dependency)
# └── jane/sql-helpers (nested dependency)
All dependencies are:
- ✅ Downloaded from their respective sources (registry/git)
- ✅ Installed to appropriate directories
- ✅ Verified with integrity checksums
- ✅ Marked as dependencies in lockfile
- ✅ Registered in
.claude/settings.json
Wrapping Individual Crafts
Convert any skill, agent, command, or hook into a plugin:
craftdesk add my-skill --as-plugin
What happens:
- Original craft installed to
.claude/skills/my-skill/ - Plugin wrapper created at
.claude/plugins/my-skill-plugin/ plugin.jsonandPLUGIN.mdauto-generated- Craft files copied to plugin structure
- Registered in settings as wrapped plugin
Use cases:
- Add MCP server to existing skill
- Bundle configuration with craft
- Prepare for publishing to marketplace
- Enable/disable craft from Claude Code UI
Plugin Tree Visualization
View your plugin dependency tree:
$ craftdesk list
[email protected]
🔌 Plugins:
company/[email protected]
├── john/[email protected]
└── jane/[email protected]
[email protected]
📚 Skills:
[email protected]
Total: 5 crafts installed
Removing Plugins with Dependencies
CraftDesk prevents accidental removal of required dependencies:
$ craftdesk remove john/rspec-testing
Warning: john/rspec-testing is required by:
- company/[email protected]
Use --force to remove anyway
Force removal:
craftdesk remove john/rspec-testing --force
Settings Integration
Plugins are automatically registered in .claude/settings.json:
{
"version": "1.0.0",
"plugins": {
"company-rails-plugin": {
"name": "company-rails-plugin",
"version": "2.1.0",
"enabled": true,
"installPath": "plugins/company-rails-plugin",
"dependencies": ["john-rspec-testing", "jane-postgres-toolkit"],
"mcp": {
"type": "stdio",
"command": "/usr/bin/rails-standards-mcp",
"args": ["--config", ".claude/plugins/company-rails-plugin/config.json"]
}
}
}
}
For complete details, see DEPENDENCY_MANAGEMENT.md
Command Reference
craftdesk init [options]
Initialize a new craftdesk.json file.
Options:
-y, --yes- Skip prompts and use defaults-n, --name <name>- Project name (default: directory name)-v, --version <version>- Project version (default: "1.0.0")-t, --type <type>- Project type: skill, agent, command, hook, plugin, or collection (default: "skill")-d, --description <desc>- Project description-a, --author <author>- Author name-l, --license <license>- License (default: "MIT")
Examples:
# Interactive initialization
craftdesk init
# Quick init with defaults
craftdesk init -y
# Specify options
craftdesk init --name my-skill --type skill --author "Your Name"
craftdesk install [options]
Install all dependencies from craftdesk.json.
Options:
--no-lockfile- Ignore craftdesk.lock and re-resolve dependencies--production- Skip devDependencies
Examples:
# Install all dependencies
craftdesk install
# Or use the alias
craftdesk i
# Production install (skip dev dependencies)
craftdesk install --production
# Force re-resolve (ignore lockfile)
craftdesk install --no-lockfile
What it does:
- Reads craftdesk.json
- Uses craftdesk.lock if present (ensures reproducibility)
- Resolves dependencies (registry + git sources)
- Installs to .claude/ directory
- Updates/creates craftdesk.lock
craftdesk add <craft> [options]
Add a new dependency and install it immediately.
Options:
-D, --save-dev- Save as devDependency-O, --save-optional- Save as optionalDependency-E, --save-exact- Save exact version (no ^ or ~)-t, --type <type>- Specify craft type (skill, agent, command, hook, plugin, collection)
Examples:
# GitHub web URLs (auto-converted)
craftdesk add https://github.com/user/repo/blob/main/skill.md
craftdesk add https://github.com/user/repo/tree/main/skills/auth
# With explicit type
craftdesk add https://github.com/user/repo/blob/main/agent.md --type agent
# Git dependencies (manual format)
craftdesk add git+https://github.com/user/repo.git
craftdesk add git+https://github.com/user/repo.git#develop
craftdesk add git+https://github.com/user/repo.git#v2.0.0
# Direct file reference
craftdesk add git+https://github.com/user/repo.git#main#file:skill.md
# Subdirectory (monorepo)
craftdesk add git+https://github.com/company/monorepo.git#main#path:skills/auth
craftdesk remove <craft>
Remove a dependency from craftdesk.json and the filesystem.
Examples:
craftdesk remove my-skill
craftdesk remove my-agent
craftdesk list [options]
List installed crafts.
Options:
--tree- Show dependency tree--depth <n>- Limit tree depth--json- Output as JSON
Examples:
# Simple list
craftdesk list
# Show dependency tree
craftdesk list --tree
# Limit tree depth
craftdesk list --tree --depth 2
# JSON output (for scripts)
craftdesk list --json
Example output:
[email protected]
Installed crafts:
• my-skill@main (skill)
• [email protected] (agent)
• postgres-expert@main (skill)
Total: 3 crafts installed
craftdesk search <query> [options]
Search for crafts in the registry.
Options:
-t, --type <type>- Filter by type (skill, agent, command, hook, plugin, collection)
Examples:
# Search for crafts
craftdesk search kafka
# Search for skills only
craftdesk search rails --type skill
# Search for plugins
craftdesk search standards --type plugin
Example output:
Search results for "kafka":
john/[email protected] (skill)
Expert knowledge for processing Kafka messages
jane/[email protected] (agent)
Autonomous agent for Kafka stream management
Found 2 crafts
craftdesk info <craft>
Display detailed information about a craft from the registry.
Examples:
# Get info about a craft
craftdesk info john/rails-api
# Get info about a specific version
craftdesk info john/[email protected]
Example output:
john/[email protected]
Description: Rails API development best practices
Type: skill
Author: john
License: MIT
Downloads: 1,234
Versions:
2.1.0 (latest)
2.0.0
1.5.0
Dependencies:
jane/postgres-toolkit: ^1.0.0
craftdesk outdated
Check for outdated dependencies that have newer versions available.
Examples:
# Check all dependencies
craftdesk outdated
Example output:
Checking for outdated dependencies...
Outdated crafts:
john/rails-api
Current: 2.0.0
Latest: 2.1.0
Type: skill
jane/postgres-toolkit
Current: 1.2.0
Latest: 1.5.0
Type: skill
2 outdated crafts found
Run 'craftdesk update' to update all, or 'craftdesk update <craft>' to update specific crafts.
craftdesk update [craft]
Update dependencies to their latest compatible versions.
Examples:
# Update all outdated dependencies
craftdesk update
# Update a specific craft
craftdesk update john/rails-api
What it does:
- Checks for newer versions in the registry
- Downloads and installs updates
- Updates craftdesk.lock with new versions
- Verifies checksums for security
craftdesk publish [options]
Publish a craft to the registry.
Options:
--visibility <level>- Set visibility: public, private, or organization (default: public)
Examples:
# Publish the current craft
craftdesk publish
# Publish as private
craftdesk publish --visibility private
# Publish to organization only
craftdesk publish --visibility organization
Prerequisites:
- Must be logged in (
craftdesk login) - Must have a valid
craftdesk.jsonin current directory - Craft files must exist (SKILL.md, AGENT.md, etc.)
What it does:
- Reads craftdesk.json for metadata
- Collects all craft files
- Creates a new version on the registry
- Publishes with specified visibility
craftdesk setup-multi-agent [options]
Interactive wizard to configure multi-agent sync.
Options:
--auto-sync- Enable automatic sync on install/update--skip-sync- Skip initial sync after setup
Examples:
# Interactive setup (recommended)
craftdesk setup-multi-agent
# Setup with auto-sync enabled
craftdesk setup-multi-agent --auto-sync
# Setup without initial sync
craftdesk setup-multi-agent --skip-sync
What it does:
- Detects AI coding assistants in your project
- Lets you choose which agents to sync to
- Updates
craftdesk.jsonwith multiAgent configuration - Optionally performs initial sync of existing crafts
craftdesk detect-agents [options]
Detect AI coding assistants installed in the project.
Options:
-v, --verbose- Show detailed detection information-f, --format <format>- Output format: text or json (default: text)
Examples:
# Detect agents
craftdesk detect-agents
# Verbose output
craftdesk detect-agents --verbose
# JSON output for scripting
craftdesk detect-agents --format json
Example output:
🔍 AI Coding Assistant Detection
Detected Agents:
✓ Claude Code
Directory: .claude/skills
Status: ✅ Enabled
○ Cursor
Directory: .cursor/skills
Status: ⚪ Available
Summary:
Detected: 2 agent(s)
Enabled: 1 agent(s)
💡 Tip:
You have multiple agents but sync is only enabled for one.
Run `craftdesk setup-multi-agent` to sync across all agents.
craftdesk sync [options]
Sync crafts to all configured AI agents.
Options:
-c, --craft <name>- Sync specific craft by name-f, --force- Force sync even if checksums match--dry-run- Show what would be synced without making changes
Examples:
# Sync all crafts
craftdesk sync
# Sync specific craft
craftdesk sync --craft ruby-expert
# Dry run (preview changes)
craftdesk sync --dry-run
# Force sync
craftdesk sync --force
What it does:
- Reads multiAgent configuration from craftdesk.json
- Copies crafts from canonical location to all targets
- Calculates and stores SHA-256 checksums
- Reports sync status for each location
Example output:
✅ Synced 5 craft(s)
✓ ruby-expert: 3 location(s)
✓ python-expert: 3 location(s)
✓ postgres-expert: 3 location(s)
✓ docker-expert: 3 location(s)
✓ git-expert: 3 location(s)
Summary:
Total synced: 15 location(s)
craftdesk verify [options]
Verify sync status of crafts across AI agents using checksum validation.
Options:
-c, --craft <name>- Verify specific craft by name-v, --verbose- Show detailed checksum information-f, --format <format>- Output format: text or json (default: text)
Examples:
# Verify all crafts
craftdesk verify
# Verify specific craft
craftdesk verify --craft ruby-expert
# Verbose output with checksums
craftdesk verify --verbose
# JSON output
craftdesk verify --format json
What it does:
- Reads multiAgent configuration
- Calculates SHA-256 checksums for all copies
- Compares checksums to detect drift
- Reports which copies are in sync vs. out of sync
Example output (in sync):
🔍 Sync Status: All Crafts
Summary:
Total crafts: 5
In sync: 5
Out of sync: 0
✅ All 5 craft(s) are in sync!
Example output (drift detected):
🔍 Sync Status: All Crafts
Summary:
Total crafts: 5
In sync: 4
Out of sync: 1
❌ Out of Sync (1):
ruby-expert
⚠️ .cursor/skills/ruby-expert (modified)
💡 Run `craftdesk sync` to fix all issues
Authentication
CraftDesk supports authenticated access to private registries.
craftdesk login [options]
Authenticate with a registry using an API token.
Options:
-r, --registry <url>- Registry URL (uses default from craftdesk.json if not specified)
Examples:
# Login to default registry
craftdesk login
# Login to a specific registry
craftdesk login --registry https://private.company.com
How it works:
- Prompts for your API token
- Verifies the token with the registry
- Stores credentials in
~/.craftdesk/config.json - Token is used for subsequent registry operations
Getting an API token:
- Log in to your CraftDesk registry web interface
- Navigate to Settings → API Tokens
- Generate a new token
craftdesk logout [options]
Remove stored authentication credentials.
Options:
-r, --registry <url>- Registry URL (uses default from craftdesk.json if not specified)
Examples:
# Logout from default registry
craftdesk logout
# Logout from specific registry
craftdesk logout --registry https://private.company.com
craftdesk whoami [options]
Display the currently logged-in user.
Options:
-r, --registry <url>- Registry URL (uses default from craftdesk.json if not specified)
Examples:
# Check current user
craftdesk whoami
# Check user for specific registry
craftdesk whoami --registry https://private.company.com
Example output:
Logged in to https://craftdesk.ai as john ([email protected])
Organization: acme-corp
Environment Variable Authentication
For CI/CD environments, you can use environment variables instead of craftdesk login:
# For a registry named "company-private" in craftdesk.json
export CRAFTDESK_AUTH_COMPANY_PRIVATE=your_api_token_here
# For the default registry
export CRAFTDESK_AUTH_LOCALHOST_3000=your_api_token_here
# The variable name is derived from the registry URL:
# https://example.com -> CRAFTDESK_AUTH_EXAMPLE_COM
Environment variables take precedence over stored credentials.
Global Options
Available for all commands:
-v, --version- Output the version number-d, --debug- Enable debug output-h, --help- Display help
Examples:
craftdesk --version
craftdesk --help
craftdesk init --help
Dependency Sources
CraftDesk supports both registry and git dependencies.
1. Registry Dependencies (CraftDesk Web API)
Install crafts from the CraftDesk registry using author/name format:
# Search for crafts
craftdesk search kafka
# Get information about a craft
craftdesk info john/rails-api
# Add from registry
craftdesk add john/rails-api
craftdesk add john/rails-api@^2.1.0
# Add with specific version
craftdesk add jane/[email protected]
Registry format in craftdesk.json:
{
"dependencies": {
"john/rails-api": "^2.1.0",
"jane/kafka-processing": "~1.5.2",
"team/postgres-admin": "latest"
},
"registries": {
"default": {
"url": "http://localhost:3000"
}
}
}
Important: You must configure your registry URL in craftdesk.json to use registry-based crafts. Git-based dependencies (GitHub URLs) work without any registry configuration.
Private Registry Authentication:
For private registries, set authentication tokens via environment variables:
# For a registry named "company-private" in craftdesk.json
export CRAFTDESK_AUTH_COMPANY_PRIVATE=your_token_here
# For default registry
export CRAFTDESK_AUTH_DEFAULT=your_token_here
Example craftdesk.json with private registry:
{
"registries": {
"default": {
"url": "https://your-registry.com"
},
"company-private": {
"url": "https://private.company.com",
"scope": "@company"
}
}
}
2. GitHub URLs (Easiest for Git)
Simply paste any GitHub URL - it auto-converts to the correct format:
# Directory in monorepo
craftdesk add https://github.com/user/repo/tree/main/skills/auth
# Single file
craftdesk add https://github.com/user/repo/blob/main/agent.md
# Entire repository
craftdesk add https://github.com/user/repo
3. Git Dependencies
From git repositories:
{
"dependencies": {
"custom-agent": {
"git": "https://github.com/user/agent-repo.git",
"branch": "develop"
},
"stable-skill": {
"git": "https://github.com/org/skills.git",
"tag": "v2.1.0"
},
"specific-commit": {
"git": "https://github.com/user/repo.git",
"commit": "a1b2c3d4"
}
}
}
Git options:
git- Repository URL (required)branch- Branch name (default: main/master)tag- Git tagcommit- Specific commit hashpath- Subdirectory within repo (for monorepos)file- Direct file path (for single-file crafts)
Monorepo Support
CraftDesk has full support for monorepo workflows, allowing you to install crafts from subdirectories within a repository. This is perfect for teams maintaining multiple related crafts in one repository.
Quick Start: Auto-Converting GitHub URLs
The easiest way to install from monorepos is to paste GitHub web URLs directly:
# Subdirectory from monorepo - just paste the GitHub URL!
craftdesk add https://github.com/company/monorepo/tree/main/skills/auth
# Single file from monorepo
craftdesk add https://github.com/company/monorepo/blob/main/skills/auth/SKILL.md
# Works with any branch or tag
craftdesk add https://github.com/company/monorepo/tree/v2.0.0/packages/deployer
CraftDesk automatically converts these to the correct git syntax and extracts only the specified subdirectory or file.
Git URL Syntax
For more control, use explicit git URL syntax with path or file specifiers:
# Subdirectory with branch
craftdesk add git+https://github.com/company/monorepo.git#main#path:skills/auth
# Subdirectory with tag
craftdesk add git+https://github.com/company/monorepo.git#v2.0.0#path:packages/deployer
# Subdirectory with commit hash
craftdesk add git+https://github.com/company/monorepo.git#abc123def#path:skills/auth
# Single file with branch
craftdesk add git+https://github.com/company/monorepo.git#main#file:skills/auth/SKILL.md
# Just path (uses default branch)
craftdesk add git+https://github.com/company/monorepo.git#path:skills/auth
Syntax breakdown:
#main- Branch name#v2.0.0- Git tag#abc123def- Commit hash (full 40-char)#path:skills/auth- Subdirectory to extract#file:skill.md- Single file to extract
Using in craftdesk.json
Multiple crafts from the same monorepo:
{
"dependencies": {
"auth-handler": {
"git": "https://github.com/company/ai-crafts-monorepo.git",
"tag": "v3.2.0",
"path": "skills/auth"
},
"data-processor": {
"git": "https://github.com/company/ai-crafts-monorepo.git",
"tag": "v3.2.0",
"path": "agents/processor"
},
"deploy-script": {
"git": "https://github.com/company/ai-crafts-monorepo.git",
"tag": "v3.2.0",
"file": "scripts/deploy.md"
}
}
}
Each craft can:
- Use different subdirectories (
path) - Reference single files (
file) - Use the same or different tags/branches
- Be versioned independently or together
Benefits
✅ Single repository for multiple related crafts
✅ Version together using git tags (or independently with branches)
✅ Efficient cloning - repository is cloned once and reused
✅ Clear organization - keep related crafts together
✅ Atomic updates - update all crafts by changing the tag
✅ Works with private repos - standard git authentication
Monorepo Structure Example
ai-crafts-monorepo/
├── skills/
│ ├── auth/
│ │ ├── craftdesk.json
│ │ └── SKILL.md
│ ├── database/
│ │ ├── craftdesk.json
│ │ └── SKILL.md
│ └── reporting/
│ ├── craftdesk.json
│ └── SKILL.md
├── agents/
│ ├── code-reviewer/
│ │ ├── craftdesk.json
│ │ └── AGENT.md
│ └── test-runner/
│ ├── craftdesk.json
│ └── AGENT.md
├── commands/
│ └── deploy/
│ ├── craftdesk.json
│ └── COMMAND.md
└── scripts/
├── setup.md
└── deploy.md
Lockfile Tracking
CraftDesk lockfile tracks the exact subdirectory and commit:
{
"crafts": {
"auth-handler": {
"git": "https://github.com/company/monorepo.git",
"tag": "v3.2.0",
"commit": "abc123def456...",
"path": "skills/auth",
"type": "skill",
"version": "3.2.0"
}
}
}
This ensures reproducible installations - the exact subdirectory from the exact commit is always installed.
Real-World Example
# Install from technicalpickles' monorepo
craftdesk add https://github.com/technicalpickles/pickled-claude-plugins/tree/main/plugins/working-in-monorepos/skills/working-in-monorepos
This installs only the working-in-monorepos skill from the deeply nested monorepo structure.
craftdesk.json Reference
Complete specification of the craftdesk.json format:
{
// Required fields
"name": "my-project",
"version": "1.0.0",
// Optional metadata
"type": "skill",
"description": "My awesome AI project",
"author": "Your Name <[email protected]>",
"license": "MIT",
"homepage": "https://example.com",
"repository": {
"type": "git",
"url": "https://github.com/user/repo.git"
},
"keywords": ["ai", "claude", "automation"],
// Dependencies
"dependencies": {
"my-skill": {
"git": "https://github.com/user/repo.git",
"branch": "main"
},
"auth-handler": {
"git": "https://github.com/company/monorepo.git",
"tag": "v3.2.0",
"path": "skills/auth"
},
"my-agent": {
"git": "https://github.com/user/agents.git",
"branch": "main",
"file": "agent.md"
}
},
"devDependencies": {
"test-runner": {
"git": "https://github.com/org/test-tools.git",
"branch": "main"
}
}
}
Field Descriptions
| Field | Type | Required | Description |
|---|---|---|---|
name |
string | Yes | Craft name (lowercase, no spaces) |
version |
string | Yes | Semantic version (e.g., "1.0.0") |
type |
string | No | Craft type: skill, agent, command, hook, plugin, collection |
description |
string | No | Short description |
author |
string | No | Author name and email |
license |
string | No | License identifier (e.g., "MIT") |
dependencies |
object | No | Production dependencies |
devDependencies |
object | No | Development dependencies |
craftdesk.lock
The lockfile ensures reproducible installations across different machines and times.
What's in the Lockfile?
{
"version": "1.0.0",
"lockfileVersion": 1,
"generatedAt": "2025-11-18T10:30:00.000Z",
"crafts": {
"my-skill": {
"version": "main",
"resolved": "https://github.com/user/skill.git",
"integrity": "a1b2c3d4e5f6789012345678901234567890abcd",
"type": "skill",
"author": "git",
"git": "https://github.com/user/skill.git",
"branch": "main",
"commit": "a1b2c3d4e5f6789012345678901234567890abcd",
"dependencies": {}
},
"custom-agent": {
"version": "v2.0.0",
"resolved": "https://github.com/user/agent.git",
"integrity": "b2c3d4e5f6789012345678901234567890abcdef",
"type": "agent",
"git": "https://github.com/user/agent.git",
"tag": "v2.0.0",
"commit": "b2c3d4e5f6789012345678901234567890abcdef",
"dependencies": {}
}
}
}
Best Practices
✅ DO:
- Commit craftdesk.lock to version control
- Let the CLI manage it (don't edit manually)
- Use it for reproducible builds in CI/CD
❌ DON'T:
- Ignore craftdesk.lock in .gitignore
- Edit it manually
- Delete it without
--no-lockfileflag
CI/CD Integration
GitHub Actions
name: Deploy
on: [push]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
- name: Install CraftDesk CLI
run: npm install -g craftdesk
- name: Install AI capabilities
run: craftdesk install --production
- name: Deploy
run: ./deploy.sh
GitLab CI
deploy:
image: node:18
script:
- npm install -g craftdesk
- craftdesk install --production
- ./deploy.sh
only:
- main
Docker
FROM node:18
# Install CraftDesk CLI
RUN npm install -g craftdesk
# Copy project files
WORKDIR /app
COPY craftdesk.json craftdesk.lock ./
# Install AI capabilities
RUN craftdesk install --production
# Copy rest of application
COPY . .
CMD ["node", "app.js"]
Troubleshooting
Common Issues
No craftdesk.json found
Make sure you're in a directory with a craftdesk.json file, or run craftdesk init first.
Failed to resolve dependencies
- Check internet connection
- Verify git repository URLs are accessible
- For private repos, ensure SSH keys or access tokens are configured
- Try
craftdesk install --no-lockfileto re-resolve
Git clone failed
- Verify git is installed:
git --version - Check git repository URL is accessible
- For private repos, ensure SSH keys or tokens are configured
Permission denied
- For global install:
sudo npm install -g craftdesk - Or use npx:
npx craftdesk install
Dependency conflicts
Currently uses last-write-wins. Future versions will have interactive conflict resolution.
Debug Mode
Enable verbose logging:
craftdesk --debug install
Getting Help
# General help
craftdesk --help
# Command-specific help
craftdesk init --help
craftdesk add --help
craftdesk install --help
Development
Building from Source
git clone https://github.com/mensfeld/craftdesk.git
cd craftdesk
npm install
npm run build
npm link
Project Structure
craftdesk/
├── src/
│ ├── commands/ # CLI commands
│ ├── services/ # Core services
│ ├── types/ # TypeScript types
│ └── utils/ # Utilities
├── dist/ # Compiled JavaScript
├── bin/ # Executable entry point
├── examples/ # Example craftdesk.json files
└── docs/ # Documentation
Running Tests
npm test
Publishing
CraftDesk uses automated NPM publishing via GitHub Actions with provenance attestation.
Quick release:
./scripts/release.sh patch # x.y.z → x.y.(z+1)
./scripts/release.sh minor # x.y.z → x.(y+1).0
./scripts/release.sh major # x.y.z → (x+1).0.0
The script will:
- Bump version in package.json
- Prompt you to update CHANGELOG.md
- Commit and push changes
- Create GitHub release
- GitHub Actions automatically publishes to NPM with provenance
Manual process:
npm version patch
git add package.json CHANGELOG.md
git commit -m "Bump to 0.3.1"
git push
gh release create v0.3.1 --title "v0.3.1" --generate-notes
See NPM_PUBLISHING_GUIDE.md for complete setup instructions.
Documentation
Core Documentation
- README.md - This file, general overview and quick start
- DEPENDENCY_MANAGEMENT.md - Complete guide to dependency management
- PLUGIN_IMPLEMENTATION_COMPLETE.md - Plugin system implementation details
Additional Resources
- Package.json - Project metadata and scripts
- TypeScript Source - Full source code
License
MIT
Links
- Repository: https://github.com/mensfeld/craftdesk
- Issues: https://github.com/mensfeld/craftdesk/issues
- Registry: Self-hosted registry server available at CraftDesk Web
Roadmap
Completed (v0.3.0)
- ✅ Git dependency support
- ✅ GitHub URL auto-conversion
- ✅ Direct file references
- ✅ Monorepo support
- ✅ Lockfile-based version control
- ✅ Self-hosted registry server support
- ✅ ZIP archive extraction for registry crafts
- ✅ Plugin system with dependency management
- ✅ Auto-install plugin dependencies (recursive)
- ✅ Settings integration (.claude/settings.json)
- ✅ MCP server configuration via plugins
- ✅ Craft wrapping (--as-plugin flag)
- ✅ Plugin tree visualization
- ✅ Dependency removal protection
- ✅ SHA-256 checksum verification (MITM protection)
- ✅ Registry search and info commands
- ✅
craftdesk publishcommand - ✅
craftdesk outdatedcommand - ✅
craftdesk updatecommand - ✅ Authentication system (login/logout/whoami)
- ✅ Private registry authentication (token-based)
- ✅ Environment variable auth (CI/CD support)
- ✅ Semantic versioning for registry packages
Planned
- 🔲 Plugin marketplace/directory
- 🔲
craftdesk validate <plugin>command - 🔲 Multiple dependency versions support
- 🔲 Peer dependency warnings
- 🔲 Persistent download cache
- 🔲 Offline installation mode
- 🔲 Interactive dependency conflict resolution
Made for the AI development community
Yorumlar (0)
Yorum birakmak icin giris yap.
Yorum birakSonuc bulunamadi