@sundial-ai/cli 0.0.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 (108) hide show
  1. package/DEV.md +58 -0
  2. package/README.md +30 -0
  3. package/dist/commands/add.d.ts +13 -0
  4. package/dist/commands/add.d.ts.map +1 -0
  5. package/dist/commands/add.js +111 -0
  6. package/dist/commands/add.js.map +1 -0
  7. package/dist/commands/config.d.ts +5 -0
  8. package/dist/commands/config.d.ts.map +1 -0
  9. package/dist/commands/config.js +40 -0
  10. package/dist/commands/config.js.map +1 -0
  11. package/dist/commands/list.d.ts +5 -0
  12. package/dist/commands/list.d.ts.map +1 -0
  13. package/dist/commands/list.js +53 -0
  14. package/dist/commands/list.js.map +1 -0
  15. package/dist/commands/remove.d.ts +13 -0
  16. package/dist/commands/remove.d.ts.map +1 -0
  17. package/dist/commands/remove.js +129 -0
  18. package/dist/commands/remove.js.map +1 -0
  19. package/dist/commands/show-dev.d.ts +20 -0
  20. package/dist/commands/show-dev.d.ts.map +1 -0
  21. package/dist/commands/show-dev.js +195 -0
  22. package/dist/commands/show-dev.js.map +1 -0
  23. package/dist/commands/show.d.ts +11 -0
  24. package/dist/commands/show.d.ts.map +1 -0
  25. package/dist/commands/show.js +175 -0
  26. package/dist/commands/show.js.map +1 -0
  27. package/dist/core/agent-detect.d.ts +22 -0
  28. package/dist/core/agent-detect.d.ts.map +1 -0
  29. package/dist/core/agent-detect.js +107 -0
  30. package/dist/core/agent-detect.js.map +1 -0
  31. package/dist/core/agents.d.ts +8 -0
  32. package/dist/core/agents.d.ts.map +1 -0
  33. package/dist/core/agents.js +34 -0
  34. package/dist/core/agents.js.map +1 -0
  35. package/dist/core/config-manager.d.ts +9 -0
  36. package/dist/core/config-manager.d.ts.map +1 -0
  37. package/dist/core/config-manager.js +47 -0
  38. package/dist/core/config-manager.js.map +1 -0
  39. package/dist/core/skill-hash.d.ts +12 -0
  40. package/dist/core/skill-hash.d.ts.map +1 -0
  41. package/dist/core/skill-hash.js +53 -0
  42. package/dist/core/skill-hash.js.map +1 -0
  43. package/dist/core/skill-info.d.ts +34 -0
  44. package/dist/core/skill-info.d.ts.map +1 -0
  45. package/dist/core/skill-info.js +213 -0
  46. package/dist/core/skill-info.js.map +1 -0
  47. package/dist/core/skill-install.d.ts +24 -0
  48. package/dist/core/skill-install.d.ts.map +1 -0
  49. package/dist/core/skill-install.js +123 -0
  50. package/dist/core/skill-install.js.map +1 -0
  51. package/dist/core/skill-source.d.ts +29 -0
  52. package/dist/core/skill-source.d.ts.map +1 -0
  53. package/dist/core/skill-source.js +111 -0
  54. package/dist/core/skill-source.js.map +1 -0
  55. package/dist/index.d.ts +3 -0
  56. package/dist/index.d.ts.map +1 -0
  57. package/dist/index.js +104 -0
  58. package/dist/index.js.map +1 -0
  59. package/dist/types/index.d.ts +57 -0
  60. package/dist/types/index.d.ts.map +1 -0
  61. package/dist/types/index.js +2 -0
  62. package/dist/types/index.js.map +1 -0
  63. package/dist/utils/fuzzy-match.d.ts +16 -0
  64. package/dist/utils/fuzzy-match.d.ts.map +1 -0
  65. package/dist/utils/fuzzy-match.js +37 -0
  66. package/dist/utils/fuzzy-match.js.map +1 -0
  67. package/dist/utils/prompts.d.ts +16 -0
  68. package/dist/utils/prompts.d.ts.map +1 -0
  69. package/dist/utils/prompts.js +46 -0
  70. package/dist/utils/prompts.js.map +1 -0
  71. package/dist/utils/registry.d.ts +6 -0
  72. package/dist/utils/registry.d.ts.map +1 -0
  73. package/dist/utils/registry.js +14 -0
  74. package/dist/utils/registry.js.map +1 -0
  75. package/package.json +42 -0
  76. package/src/commands/add.ts +136 -0
  77. package/src/commands/config.ts +47 -0
  78. package/src/commands/list.ts +68 -0
  79. package/src/commands/remove.ts +154 -0
  80. package/src/commands/show-dev.ts +223 -0
  81. package/src/commands/show.ts +203 -0
  82. package/src/core/agent-detect.ts +125 -0
  83. package/src/core/agents.ts +40 -0
  84. package/src/core/config-manager.ts +55 -0
  85. package/src/core/skill-hash.ts +61 -0
  86. package/src/core/skill-info.ts +248 -0
  87. package/src/core/skill-install.ts +165 -0
  88. package/src/core/skill-source.ts +125 -0
  89. package/src/index.ts +116 -0
  90. package/src/types/index.ts +64 -0
  91. package/src/utils/fuzzy-match.ts +48 -0
  92. package/src/utils/prompts.ts +54 -0
  93. package/src/utils/registry.ts +16 -0
  94. package/test/README.md +123 -0
  95. package/test/fixtures/multi-skills/skill-one/SKILL.md +8 -0
  96. package/test/fixtures/multi-skills/skill-two/SKILL.md +8 -0
  97. package/test/fixtures/sample-skill/SKILL.md +8 -0
  98. package/test/logs/add-remove.log +108 -0
  99. package/test/logs/config.log +72 -0
  100. package/test/logs/fuzzy-match.log +64 -0
  101. package/test/logs/show.log +110 -0
  102. package/test/run-all.sh +83 -0
  103. package/test/test-add-remove.sh +245 -0
  104. package/test/test-config.sh +208 -0
  105. package/test/test-fuzzy-match.sh +166 -0
  106. package/test/test-show.sh +179 -0
  107. package/tsconfig.json +20 -0
  108. package/vitest.config.ts +15 -0
@@ -0,0 +1,72 @@
1
+ === Test run: Wed Jan 14 14:16:56 PST 2026 ===
2
+ TEMP_DIR: /var/folders/64/t_nm43xn2mx3jnxm5pfyxrd80000gn/T/tmp.2bN6LcogXW
3
+ TEMP_HOME: /var/folders/64/t_nm43xn2mx3jnxm5pfyxrd80000gn/T/tmp.VjYCdVOIZu
4
+
5
+ TEST: Config directory creation
6
+ --------------------------------
7
+ Agent Folders & Installed Skills
8
+ ────────────────────────────────────────
9
+
10
+ ○ Claude Code (local)
11
+ /private/var/folders/64/t_nm43xn2mx3jnxm5pfyxrd80000gn/T/tmp.2bN6LcogXW/.claude
12
+ No skills installed
13
+
14
+ ✓ = affected by sun add/remove in this directory
15
+ Run "sun config" to change selected agents.
16
+ PASS: Directory exists: /var/folders/64/t_nm43xn2mx3jnxm5pfyxrd80000gn/T/tmp.VjYCdVOIZu/.sun
17
+
18
+ TEST: Config file is read correctly
19
+ ------------------------------------
20
+ PASS: File exists: /var/folders/64/t_nm43xn2mx3jnxm5pfyxrd80000gn/T/tmp.VjYCdVOIZu/.sun/config.json
21
+ PASS: File /var/folders/64/t_nm43xn2mx3jnxm5pfyxrd80000gn/T/tmp.VjYCdVOIZu/.sun/config.json contains 'claude'
22
+
23
+ TEST: Config with multiple default agents
24
+ ------------------------------------------
25
+ PASS: File /var/folders/64/t_nm43xn2mx3jnxm5pfyxrd80000gn/T/tmp.VjYCdVOIZu/.sun/config.json contains 'claude'
26
+ PASS: File /var/folders/64/t_nm43xn2mx3jnxm5pfyxrd80000gn/T/tmp.VjYCdVOIZu/.sun/config.json contains 'codex'
27
+
28
+ TEST: Add command uses default agents from config
29
+ --------------------------------------------------
30
+ - Adding /Users/bmo/skills/cli/test/fixtures/sample-skill...
31
+ ✔ Added sample-skill
32
+
33
+ Added sample-skill to Claude Code and Codex (local)
34
+ (use --global to install globally)
35
+ PASS: Directory exists: .claude/skills/sample-skill
36
+ PASS: Directory exists: .codex/skills/sample-skill
37
+
38
+ TEST: Explicit flags override config defaults
39
+ ----------------------------------------------
40
+ - Adding /Users/bmo/skills/cli/test/fixtures/sample-skill...
41
+ ✔ Added sample-skill
42
+
43
+ Added sample-skill to Gemini (local)
44
+ (use --global to install globally)
45
+ PASS: Directory exists: .gemini/skills/sample-skill
46
+ PASS: Skill correctly not in .claude
47
+
48
+ TEST: First run detection
49
+ --------------------------
50
+ Agent Folders & Installed Skills
51
+ ────────────────────────────────────────
52
+
53
+ ○ Claude Code (local)
54
+ /private/var/folders/64/t_nm43xn2mx3jnxm5pfyxrd80000gn/T/tmp.2bN6LcogXW/.claude
55
+ No skills installed
56
+
57
+ ○ Codex (local)
58
+ /private/var/folders/64/t_nm43xn2mx3jnxm5pfyxrd80000gn/T/tmp.2bN6LcogXW/.codex
59
+ No skills installed
60
+
61
+ ○ Gemini (local)
62
+ /private/var/folders/64/t_nm43xn2mx3jnxm5pfyxrd80000gn/T/tmp.2bN6LcogXW/.gemini
63
+ Skills (1):
64
+ - sample-skill - A sample skill for testing the CLI
65
+
66
+ ✓ = affected by sun add/remove in this directory
67
+ Run "sun config" to change selected agents.
68
+ PASS: CLI runs without config file
69
+
70
+ ============================================
71
+ All config tests passed!
72
+ ============================================
@@ -0,0 +1,64 @@
1
+ === Test run: Wed Jan 14 14:16:57 PST 2026 ===
2
+ TEMP_DIR: /var/folders/64/t_nm43xn2mx3jnxm5pfyxrd80000gn/T/tmp.B5cbTZKdHB
3
+ TEMP_HOME: /var/folders/64/t_nm43xn2mx3jnxm5pfyxrd80000gn/T/tmp.2Sby58UZ3Q
4
+
5
+ TEST: Typo 'ad' suggests 'add'
6
+ -------------------------------
7
+ Error: Unknown command 'ad'
8
+ Did you mean 'add'?
9
+
10
+ Valid commands: add, remove, list, show, config
11
+ PASS: Output contains 'Unknown command'
12
+ PASS: Output contains 'add'
13
+
14
+ TEST: Typo 'remov' suggests 'remove'
15
+ -------------------------------------
16
+ Error: Unknown command 'remov'
17
+ Did you mean 'remove'?
18
+
19
+ Valid commands: add, remove, list, show, config
20
+ PASS: Output contains 'Unknown command'
21
+ PASS: Output contains 'remove'
22
+
23
+ TEST: Typo 'lst' suggests 'list'
24
+ ---------------------------------
25
+ Error: Unknown command 'lst'
26
+ Did you mean 'list'?
27
+
28
+ Valid commands: add, remove, list, show, config
29
+ PASS: Output contains 'Unknown command'
30
+ PASS: Output contains 'list'
31
+
32
+ TEST: Typo 'shw' suggests 'show'
33
+ ---------------------------------
34
+ Error: Unknown command 'shw'
35
+ Did you mean 'show'?
36
+
37
+ Valid commands: add, remove, list, show, config
38
+ PASS: Output contains 'Unknown command'
39
+ PASS: Output contains 'show'
40
+
41
+ TEST: Typo 'confg' suggests 'config'
42
+ -------------------------------------
43
+ Error: Unknown command 'confg'
44
+ Did you mean 'config'?
45
+
46
+ Valid commands: add, remove, list, show, config
47
+ PASS: Output contains 'Unknown command'
48
+ PASS: Output contains 'config'
49
+
50
+ TEST: Wrong command shows valid commands list
51
+ ----------------------------------------------
52
+ Error: Unknown command 'foobar'
53
+
54
+ Valid commands: add, remove, list, show, config
55
+ PASS: Output contains 'Unknown command'
56
+ PASS: Output contains 'Valid commands'
57
+
58
+ TEST: Exit code is non-zero for unknown commands
59
+ --------------------------------------------------
60
+ PASS: Command correctly returned non-zero exit code
61
+
62
+ ============================================
63
+ All fuzzy-match tests passed!
64
+ ============================================
@@ -0,0 +1,110 @@
1
+ === Test run: Wed Jan 14 14:16:56 PST 2026 ===
2
+ TEMP_DIR: /var/folders/64/t_nm43xn2mx3jnxm5pfyxrd80000gn/T/tmp.JUFs4ZCqJO
3
+ TEMP_HOME: /var/folders/64/t_nm43xn2mx3jnxm5pfyxrd80000gn/T/tmp.VUf0DF6mwK
4
+
5
+ TEST: Show with no agent folders
6
+ ---------------------------------
7
+ No agent folders found.
8
+ Agent folders are directories like .claude/, .codex/, .gemini/
9
+ PASS: Output contains 'No agent folders found'
10
+
11
+ TEST: Show with empty agent folder
12
+ -----------------------------------
13
+ Agent Folders & Installed Skills
14
+ ────────────────────────────────────────
15
+
16
+ ✓ Claude Code (local)
17
+ /private/var/folders/64/t_nm43xn2mx3jnxm5pfyxrd80000gn/T/tmp.JUFs4ZCqJO/.claude
18
+ No skills installed
19
+
20
+ ✓ = affected by sun add/remove in this directory
21
+ Run "sun config" to change selected agents.
22
+ PASS: Output contains 'Claude'
23
+ PASS: Output contains 'No skills installed'
24
+
25
+ TEST: Show with installed skill
26
+ --------------------------------
27
+ - Adding /Users/bmo/skills/cli/test/fixtures/sample-skill...
28
+ ✔ Added sample-skill
29
+
30
+ Added sample-skill to Claude Code (local)
31
+ (use --global to install globally)
32
+ Agent Folders & Installed Skills
33
+ ────────────────────────────────────────
34
+
35
+ ✓ Claude Code (local)
36
+ /private/var/folders/64/t_nm43xn2mx3jnxm5pfyxrd80000gn/T/tmp.JUFs4ZCqJO/.claude
37
+ Skills (1):
38
+ - sample-skill - A sample skill for testing the CLI
39
+
40
+ ✓ = affected by sun add/remove in this directory
41
+ Run "sun config" to change selected agents.
42
+ PASS: Output contains 'sample-skill'
43
+ PASS: Output contains 'A sample skill for testing'
44
+
45
+ TEST: Show specific skill details
46
+ ----------------------------------
47
+ Skill: sample-skill
48
+ Description: A sample skill for testing the CLI
49
+
50
+ Installed in:
51
+ - .claude/ (local)
52
+ PASS: Output contains 'sample-skill'
53
+ PASS: Output contains 'Description'
54
+ PASS: Output contains 'Installed in'
55
+
56
+ TEST: Show skill in multiple locations
57
+ ---------------------------------------
58
+ - Adding /Users/bmo/skills/cli/test/fixtures/sample-skill...
59
+ ✔ Added sample-skill
60
+
61
+ Added sample-skill to Claude Code (global)
62
+ Skill: sample-skill
63
+ Description: A sample skill for testing the CLI
64
+
65
+ Installed in:
66
+ - .claude/ (local)
67
+ - .claude/ (global)
68
+ PASS: Output contains 'local'
69
+ PASS: Output contains 'global'
70
+
71
+ TEST: Show multiple agents with skills
72
+ ---------------------------------------
73
+ - Adding /Users/bmo/skills/cli/test/fixtures/multi-skills/skill-one...
74
+ ✔ Added skill-one
75
+
76
+ Added skill-one to Codex (local)
77
+ (use --global to install globally)
78
+ Agent Folders & Installed Skills
79
+ ────────────────────────────────────────
80
+
81
+ ✓ Claude Code (local)
82
+ /private/var/folders/64/t_nm43xn2mx3jnxm5pfyxrd80000gn/T/tmp.JUFs4ZCqJO/.claude
83
+ Skills (1):
84
+ - sample-skill - A sample skill for testing the CLI
85
+
86
+ ○ Codex (local)
87
+ /private/var/folders/64/t_nm43xn2mx3jnxm5pfyxrd80000gn/T/tmp.JUFs4ZCqJO/.codex
88
+ Skills (1):
89
+ - skill-one - First skill in multi-skills directory
90
+
91
+ ○ Claude Code (global)
92
+ /var/folders/64/t_nm43xn2mx3jnxm5pfyxrd80000gn/T/tmp.VUf0DF6mwK/.claude
93
+ Skills (1):
94
+ - sample-skill - A sample skill for testing the CLI
95
+
96
+ ✓ = affected by sun add/remove in this directory
97
+ Run "sun config" to change selected agents.
98
+ PASS: Output contains 'Claude'
99
+ PASS: Output contains 'Codex'
100
+ PASS: Output contains 'sample-skill'
101
+ PASS: Output contains 'skill-one'
102
+
103
+ TEST: Show non-existent skill
104
+ ------------------------------
105
+ Skill "non-existent-skill" is not installed.
106
+ PASS: Output contains 'not installed'
107
+
108
+ ============================================
109
+ All show tests passed!
110
+ ============================================
@@ -0,0 +1,83 @@
1
+ #!/bin/bash
2
+ # ============================================================================
3
+ # run-all.sh
4
+ # ============================================================================
5
+ # Master test runner for the Sundial CLI integration tests.
6
+ #
7
+ # This script runs all test scripts in sequence and reports results.
8
+ # Each test script logs output to the logs/ directory.
9
+ #
10
+ # Usage:
11
+ # ./run-all.sh
12
+ #
13
+ # Prerequisites:
14
+ # - CLI must be built first: npm run build
15
+ #
16
+ # Exit codes:
17
+ # 0 - All tests passed
18
+ # 1 - One or more tests failed
19
+ # ============================================================================
20
+
21
+ set -e
22
+
23
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
24
+ CLI_DIR="$SCRIPT_DIR/.."
25
+
26
+ # Colors for output
27
+ RED='\033[0;31m'
28
+ GREEN='\033[0;32m'
29
+ YELLOW='\033[1;33m'
30
+ NC='\033[0m' # No Color
31
+
32
+ echo "============================================"
33
+ echo "Sundial CLI Integration Tests"
34
+ echo "============================================"
35
+ echo ""
36
+
37
+ # Ensure logs directory exists
38
+ mkdir -p "$SCRIPT_DIR/logs"
39
+
40
+ # Check if CLI is built
41
+ if [ ! -f "$CLI_DIR/dist/index.js" ]; then
42
+ echo -e "${YELLOW}CLI not built. Running npm run build...${NC}"
43
+ cd "$CLI_DIR"
44
+ npm run build
45
+ cd "$SCRIPT_DIR"
46
+ echo ""
47
+ fi
48
+
49
+ # Track failures
50
+ FAILED=0
51
+ PASSED=0
52
+ TESTS=("test-add-remove.sh" "test-config.sh" "test-show.sh" "test-fuzzy-match.sh")
53
+
54
+ for TEST in "${TESTS[@]}"; do
55
+ echo "Running $TEST..."
56
+
57
+ if "$SCRIPT_DIR/$TEST"; then
58
+ echo -e "${GREEN}✓ $TEST passed${NC}"
59
+ ((PASSED++))
60
+ else
61
+ echo -e "${RED}✗ $TEST failed${NC}"
62
+ ((FAILED++))
63
+ fi
64
+ echo ""
65
+ done
66
+
67
+ # Summary
68
+ echo "============================================"
69
+ echo "Test Summary"
70
+ echo "============================================"
71
+ echo -e "Passed: ${GREEN}$PASSED${NC}"
72
+ echo -e "Failed: ${RED}$FAILED${NC}"
73
+ echo ""
74
+ echo "Logs are in: $SCRIPT_DIR/logs/"
75
+ echo ""
76
+
77
+ if [ $FAILED -gt 0 ]; then
78
+ echo -e "${RED}Some tests failed!${NC}"
79
+ exit 1
80
+ else
81
+ echo -e "${GREEN}All tests passed!${NC}"
82
+ exit 0
83
+ fi
@@ -0,0 +1,245 @@
1
+ #!/bin/bash
2
+ # ============================================================================
3
+ # test-add-remove.sh
4
+ # ============================================================================
5
+ # Tests the `sun add` and `sun remove` commands.
6
+ #
7
+ # This script tests:
8
+ # - Adding skills from local folders (single skill)
9
+ # - Adding skills from parent directories (finds all SKILL.md files)
10
+ # - Adding skills from git repositories
11
+ # - Adding skills via registry shortcuts
12
+ # - Local vs global installation (--global flag)
13
+ # - Multi-agent installation (--claude --codex --gemini flags)
14
+ # - Removing skills from single and multiple agents
15
+ #
16
+ # Output is logged to: logs/add-remove.log
17
+ #
18
+ # Usage:
19
+ # ./test-add-remove.sh
20
+ #
21
+ # Prerequisites:
22
+ # - CLI must be built first: npm run build
23
+ # ============================================================================
24
+
25
+ set -e
26
+
27
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
28
+ LOG_FILE="$SCRIPT_DIR/logs/add-remove.log"
29
+ CLI="$SCRIPT_DIR/../dist/index.js"
30
+
31
+ # Setup temp environment
32
+ TEMP_DIR=$(mktemp -d)
33
+ TEMP_HOME=$(mktemp -d)
34
+ ORIGINAL_HOME="$HOME"
35
+ export HOME="$TEMP_HOME"
36
+ cd "$TEMP_DIR"
37
+
38
+ # Cleanup function
39
+ cleanup() {
40
+ cd /
41
+ rm -rf "$TEMP_DIR" "$TEMP_HOME"
42
+ export HOME="$ORIGINAL_HOME"
43
+ }
44
+ trap cleanup EXIT
45
+
46
+ # Logging function
47
+ log() {
48
+ echo "$@" | tee -a "$LOG_FILE"
49
+ }
50
+
51
+ # Assertion helpers
52
+ assert_dir_exists() {
53
+ if [ -d "$1" ]; then
54
+ log " PASS: Directory exists: $1"
55
+ else
56
+ log " FAIL: Directory not found: $1"
57
+ exit 1
58
+ fi
59
+ }
60
+
61
+ assert_dir_not_exists() {
62
+ if [ ! -d "$1" ]; then
63
+ log " PASS: Directory does not exist: $1"
64
+ else
65
+ log " FAIL: Directory should not exist: $1"
66
+ exit 1
67
+ fi
68
+ }
69
+
70
+ assert_file_exists() {
71
+ if [ -f "$1" ]; then
72
+ log " PASS: File exists: $1"
73
+ else
74
+ log " FAIL: File not found: $1"
75
+ exit 1
76
+ fi
77
+ }
78
+
79
+ # Start fresh log
80
+ mkdir -p "$SCRIPT_DIR/logs"
81
+ echo "=== Test run: $(date) ===" > "$LOG_FILE"
82
+ log "TEMP_DIR: $TEMP_DIR"
83
+ log "TEMP_HOME: $TEMP_HOME"
84
+ log ""
85
+
86
+ # ============================================================================
87
+ # TEST: Add single skill from local folder
88
+ # ============================================================================
89
+ log "TEST: Add single skill from local folder"
90
+ log "----------------------------------------"
91
+ mkdir -p .claude
92
+ node "$CLI" add "$SCRIPT_DIR/fixtures/sample-skill" --claude 2>&1 | tee -a "$LOG_FILE" || true
93
+ assert_dir_exists ".claude/skills/sample-skill"
94
+ assert_file_exists ".claude/skills/sample-skill/SKILL.md"
95
+ log ""
96
+
97
+ # Clean up for next test
98
+ rm -rf .claude/skills/*
99
+
100
+ # ============================================================================
101
+ # TEST: Add multiple skills from parent directory
102
+ # ============================================================================
103
+ log "TEST: Add multiple skills from parent directory"
104
+ log "------------------------------------------------"
105
+ node "$CLI" add "$SCRIPT_DIR/fixtures/multi-skills" --claude 2>&1 | tee -a "$LOG_FILE" || true
106
+ assert_dir_exists ".claude/skills/skill-one"
107
+ assert_dir_exists ".claude/skills/skill-two"
108
+ assert_file_exists ".claude/skills/skill-one/SKILL.md"
109
+ assert_file_exists ".claude/skills/skill-two/SKILL.md"
110
+ log ""
111
+
112
+ # Clean up for next test
113
+ rm -rf .claude/skills/*
114
+
115
+ # ============================================================================
116
+ # TEST: Add skill from git repository
117
+ # ============================================================================
118
+ log "TEST: Add skill from git repository"
119
+ log "------------------------------------"
120
+ # Use a known public repo with skills (sundial-org/skills)
121
+ node "$CLI" add "github:sundial-org/skills" --claude 2>&1 | tee -a "$LOG_FILE" || {
122
+ log " (Git test may fail if network unavailable - continuing)"
123
+ }
124
+ # Check if any skills were installed
125
+ if ls .claude/skills/*/ > /dev/null 2>&1; then
126
+ log " PASS: Skills installed from git repo"
127
+ else
128
+ log " SKIP: No skills installed (may need network)"
129
+ fi
130
+ log ""
131
+
132
+ # Clean up for next test
133
+ rm -rf .claude/skills/*
134
+
135
+ # ============================================================================
136
+ # TEST: Add skill via shortcut (registry)
137
+ # ============================================================================
138
+ log "TEST: Add skill via shortcut (registry)"
139
+ log "----------------------------------------"
140
+ # Try to add a skill by shortcut name
141
+ node "$CLI" add "tinker-from-docs" --claude 2>&1 | tee -a "$LOG_FILE" || {
142
+ log " (Shortcut test may fail if registry not configured - continuing)"
143
+ }
144
+ if [ -d ".claude/skills/tinker-from-docs" ]; then
145
+ log " PASS: Skill installed via shortcut"
146
+ else
147
+ log " SKIP: Shortcut not available in registry"
148
+ fi
149
+ log ""
150
+
151
+ # Clean up for next test
152
+ rm -rf .claude/skills/*
153
+
154
+ # ============================================================================
155
+ # TEST: Local vs Global installation
156
+ # ============================================================================
157
+ log "TEST: Local vs Global installation"
158
+ log "-----------------------------------"
159
+
160
+ # Add skill locally (to .claude in current directory)
161
+ node "$CLI" add "$SCRIPT_DIR/fixtures/sample-skill" --claude 2>&1 | tee -a "$LOG_FILE" || true
162
+ assert_dir_exists ".claude/skills/sample-skill"
163
+ log " Local installation verified"
164
+
165
+ # Add skill globally (to ~/.claude)
166
+ mkdir -p "$TEMP_HOME/.claude"
167
+ node "$CLI" add "$SCRIPT_DIR/fixtures/multi-skills/skill-one" --claude --global 2>&1 | tee -a "$LOG_FILE" || true
168
+ assert_dir_exists "$TEMP_HOME/.claude/skills/skill-one"
169
+ log " Global installation verified"
170
+
171
+ # Verify local and global are separate
172
+ assert_dir_exists ".claude/skills/sample-skill"
173
+ assert_dir_not_exists ".claude/skills/skill-one"
174
+ assert_dir_exists "$TEMP_HOME/.claude/skills/skill-one"
175
+ assert_dir_not_exists "$TEMP_HOME/.claude/skills/sample-skill"
176
+ log ""
177
+
178
+ # Clean up for next test
179
+ rm -rf .claude/skills/* "$TEMP_HOME/.claude/skills"/*
180
+
181
+ # ============================================================================
182
+ # TEST: Multi-agent installation (--claude --codex)
183
+ # ============================================================================
184
+ log "TEST: Multi-agent installation (--claude --codex)"
185
+ log "--------------------------------------------------"
186
+ mkdir -p .codex
187
+ node "$CLI" add "$SCRIPT_DIR/fixtures/sample-skill" --claude --codex 2>&1 | tee -a "$LOG_FILE" || true
188
+ assert_dir_exists ".claude/skills/sample-skill"
189
+ assert_dir_exists ".codex/skills/sample-skill"
190
+ log ""
191
+
192
+ # Clean up for next test
193
+ rm -rf .claude/skills/* .codex/skills/*
194
+
195
+ # ============================================================================
196
+ # TEST: Single agent flag (--gemini only)
197
+ # ============================================================================
198
+ log "TEST: Single agent flag (--gemini only)"
199
+ log "----------------------------------------"
200
+ mkdir -p .gemini
201
+ node "$CLI" add "$SCRIPT_DIR/fixtures/sample-skill" --gemini 2>&1 | tee -a "$LOG_FILE" || true
202
+ assert_dir_exists ".gemini/skills/sample-skill"
203
+ assert_dir_not_exists ".claude/skills/sample-skill"
204
+ assert_dir_not_exists ".codex/skills/sample-skill"
205
+ log ""
206
+
207
+ # Clean up for next test
208
+ rm -rf .gemini/skills/*
209
+
210
+ # ============================================================================
211
+ # TEST: Remove skill from single agent
212
+ # ============================================================================
213
+ log "TEST: Remove skill from single agent"
214
+ log "-------------------------------------"
215
+ # First add it
216
+ node "$CLI" add "$SCRIPT_DIR/fixtures/sample-skill" --claude 2>&1 | tee -a "$LOG_FILE" || true
217
+ assert_dir_exists ".claude/skills/sample-skill"
218
+
219
+ # Now remove it
220
+ node "$CLI" remove sample-skill --claude 2>&1 | tee -a "$LOG_FILE" || true
221
+ assert_dir_not_exists ".claude/skills/sample-skill"
222
+ log ""
223
+
224
+ # ============================================================================
225
+ # TEST: Remove skill from multiple agents
226
+ # ============================================================================
227
+ log "TEST: Remove skill from multiple agents"
228
+ log "----------------------------------------"
229
+ # Add to multiple agents
230
+ node "$CLI" add "$SCRIPT_DIR/fixtures/sample-skill" --claude --codex 2>&1 | tee -a "$LOG_FILE" || true
231
+ assert_dir_exists ".claude/skills/sample-skill"
232
+ assert_dir_exists ".codex/skills/sample-skill"
233
+
234
+ # Remove from both
235
+ node "$CLI" remove sample-skill --claude --codex 2>&1 | tee -a "$LOG_FILE" || true
236
+ assert_dir_not_exists ".claude/skills/sample-skill"
237
+ assert_dir_not_exists ".codex/skills/sample-skill"
238
+ log ""
239
+
240
+ # ============================================================================
241
+ # SUMMARY
242
+ # ============================================================================
243
+ log "============================================"
244
+ log "All add-remove tests passed!"
245
+ log "============================================"