@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,208 @@
1
+ #!/bin/bash
2
+ # ============================================================================
3
+ # test-config.sh
4
+ # ============================================================================
5
+ # Tests the `sun config` command and configuration management.
6
+ #
7
+ # This script tests:
8
+ # - Config directory creation (~/.sun/)
9
+ # - Config file creation and persistence
10
+ # - Default agent configuration affects add command behavior
11
+ # - First-run detection
12
+ #
13
+ # Note: The `sun config` command uses an interactive checkbox prompt
14
+ # (@inquirer/prompts) which doesn't accept piped input easily. This test
15
+ # focuses on the config file structure and how it affects other commands.
16
+ # We manually create config files to test the configuration system.
17
+ #
18
+ # Output is logged to: logs/config.log
19
+ #
20
+ # Usage:
21
+ # ./test-config.sh
22
+ #
23
+ # Prerequisites:
24
+ # - CLI must be built first: npm run build
25
+ # ============================================================================
26
+
27
+ set -e
28
+
29
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
30
+ LOG_FILE="$SCRIPT_DIR/logs/config.log"
31
+ CLI="$SCRIPT_DIR/../dist/index.js"
32
+
33
+ # Setup temp environment
34
+ TEMP_DIR=$(mktemp -d)
35
+ TEMP_HOME=$(mktemp -d)
36
+ ORIGINAL_HOME="$HOME"
37
+ export HOME="$TEMP_HOME"
38
+ cd "$TEMP_DIR"
39
+
40
+ # Cleanup function
41
+ cleanup() {
42
+ cd /
43
+ rm -rf "$TEMP_DIR" "$TEMP_HOME"
44
+ export HOME="$ORIGINAL_HOME"
45
+ }
46
+ trap cleanup EXIT
47
+
48
+ # Logging function
49
+ log() {
50
+ echo "$@" | tee -a "$LOG_FILE"
51
+ }
52
+
53
+ # Assertion helpers
54
+ assert_file_exists() {
55
+ if [ -f "$1" ]; then
56
+ log " PASS: File exists: $1"
57
+ else
58
+ log " FAIL: File not found: $1"
59
+ exit 1
60
+ fi
61
+ }
62
+
63
+ assert_dir_exists() {
64
+ if [ -d "$1" ]; then
65
+ log " PASS: Directory exists: $1"
66
+ else
67
+ log " FAIL: Directory not found: $1"
68
+ exit 1
69
+ fi
70
+ }
71
+
72
+ assert_file_contains() {
73
+ if grep -q "$2" "$1" 2>/dev/null; then
74
+ log " PASS: File $1 contains '$2'"
75
+ else
76
+ log " FAIL: File $1 does not contain '$2'"
77
+ exit 1
78
+ fi
79
+ }
80
+
81
+ # Start fresh log
82
+ mkdir -p "$SCRIPT_DIR/logs"
83
+ echo "=== Test run: $(date) ===" > "$LOG_FILE"
84
+ log "TEMP_DIR: $TEMP_DIR"
85
+ log "TEMP_HOME: $TEMP_HOME"
86
+ log ""
87
+
88
+ # ============================================================================
89
+ # TEST: Config directory is created on first command
90
+ # ============================================================================
91
+ log "TEST: Config directory creation"
92
+ log "--------------------------------"
93
+ # Create a local agent folder so show can detect something
94
+ mkdir -p .claude
95
+
96
+ # Run show command which calls loadConfig() and creates the config dir
97
+ node "$CLI" show 2>&1 | tee -a "$LOG_FILE" || true
98
+
99
+ # Config dir should exist now
100
+ assert_dir_exists "$TEMP_HOME/.sun"
101
+ log ""
102
+
103
+ # ============================================================================
104
+ # TEST: Manually created config is respected
105
+ # ============================================================================
106
+ log "TEST: Config file is read correctly"
107
+ log "------------------------------------"
108
+ # Create a config file with claude as default
109
+ cat > "$TEMP_HOME/.sun/config.json" << 'EOF'
110
+ {
111
+ "defaultAgents": ["claude"],
112
+ "firstRunComplete": true
113
+ }
114
+ EOF
115
+ assert_file_exists "$TEMP_HOME/.sun/config.json"
116
+ assert_file_contains "$TEMP_HOME/.sun/config.json" "claude"
117
+ log ""
118
+
119
+ # ============================================================================
120
+ # TEST: Config with multiple agents
121
+ # ============================================================================
122
+ log "TEST: Config with multiple default agents"
123
+ log "------------------------------------------"
124
+ cat > "$TEMP_HOME/.sun/config.json" << 'EOF'
125
+ {
126
+ "defaultAgents": ["claude", "codex"],
127
+ "firstRunComplete": true
128
+ }
129
+ EOF
130
+ assert_file_contains "$TEMP_HOME/.sun/config.json" "claude"
131
+ assert_file_contains "$TEMP_HOME/.sun/config.json" "codex"
132
+ log ""
133
+
134
+ # ============================================================================
135
+ # TEST: Add command uses default agents from config
136
+ # ============================================================================
137
+ log "TEST: Add command uses default agents from config"
138
+ log "--------------------------------------------------"
139
+ # Set claude and codex as defaults
140
+ cat > "$TEMP_HOME/.sun/config.json" << 'EOF'
141
+ {
142
+ "defaultAgents": ["claude", "codex"],
143
+ "firstRunComplete": true
144
+ }
145
+ EOF
146
+
147
+ # Create agent folders
148
+ mkdir -p .claude .codex
149
+
150
+ # Add skill without specifying agent flags - should use defaults
151
+ node "$CLI" add "$SCRIPT_DIR/fixtures/sample-skill" 2>&1 | tee -a "$LOG_FILE" || true
152
+
153
+ # Check skill was installed to both default agents
154
+ assert_dir_exists ".claude/skills/sample-skill"
155
+ assert_dir_exists ".codex/skills/sample-skill"
156
+ log ""
157
+
158
+ # Clean up for next test
159
+ rm -rf .claude/skills/* .codex/skills/*
160
+
161
+ # ============================================================================
162
+ # TEST: Explicit flags override config defaults
163
+ # ============================================================================
164
+ log "TEST: Explicit flags override config defaults"
165
+ log "----------------------------------------------"
166
+ # Config has claude and codex as defaults
167
+ cat > "$TEMP_HOME/.sun/config.json" << 'EOF'
168
+ {
169
+ "defaultAgents": ["claude", "codex"],
170
+ "firstRunComplete": true
171
+ }
172
+ EOF
173
+
174
+ mkdir -p .gemini
175
+
176
+ # Add with explicit --gemini flag only
177
+ node "$CLI" add "$SCRIPT_DIR/fixtures/sample-skill" --gemini 2>&1 | tee -a "$LOG_FILE" || true
178
+
179
+ # Should only be in gemini, not in defaults
180
+ assert_dir_exists ".gemini/skills/sample-skill"
181
+ # These should not exist (explicit flag overrides defaults)
182
+ if [ -d ".claude/skills/sample-skill" ]; then
183
+ log " FAIL: Skill should not be in .claude when --gemini flag is used"
184
+ exit 1
185
+ else
186
+ log " PASS: Skill correctly not in .claude"
187
+ fi
188
+ log ""
189
+
190
+ # ============================================================================
191
+ # TEST: First run detection
192
+ # ============================================================================
193
+ log "TEST: First run detection"
194
+ log "--------------------------"
195
+ # Remove config to simulate first run
196
+ rm -f "$TEMP_HOME/.sun/config.json"
197
+
198
+ # Show should work and indicate no config
199
+ node "$CLI" show 2>&1 | tee -a "$LOG_FILE" || true
200
+ log " PASS: CLI runs without config file"
201
+ log ""
202
+
203
+ # ============================================================================
204
+ # SUMMARY
205
+ # ============================================================================
206
+ log "============================================"
207
+ log "All config tests passed!"
208
+ log "============================================"
@@ -0,0 +1,166 @@
1
+ #!/bin/bash
2
+ # ============================================================================
3
+ # test-fuzzy-match.sh
4
+ # ============================================================================
5
+ # Tests the fuzzy command matching feature of the CLI.
6
+ #
7
+ # When users type an incorrect command name (typo), the CLI should:
8
+ # - Display an error message
9
+ # - Suggest the closest valid command
10
+ # - List all valid commands
11
+ #
12
+ # This script tests:
13
+ # - Typo suggestions for common misspellings
14
+ # - "Did you mean" messages appear in output
15
+ # - Valid commands are listed
16
+ #
17
+ # Output is logged to: logs/fuzzy-match.log
18
+ #
19
+ # Usage:
20
+ # ./test-fuzzy-match.sh
21
+ #
22
+ # Prerequisites:
23
+ # - CLI must be built first: npm run build
24
+ # ============================================================================
25
+
26
+ set -e
27
+
28
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
29
+ LOG_FILE="$SCRIPT_DIR/logs/fuzzy-match.log"
30
+ CLI="$SCRIPT_DIR/../dist/index.js"
31
+
32
+ # Setup temp environment
33
+ TEMP_DIR=$(mktemp -d)
34
+ TEMP_HOME=$(mktemp -d)
35
+ ORIGINAL_HOME="$HOME"
36
+ export HOME="$TEMP_HOME"
37
+ cd "$TEMP_DIR"
38
+
39
+ # Cleanup function
40
+ cleanup() {
41
+ cd /
42
+ rm -rf "$TEMP_DIR" "$TEMP_HOME"
43
+ export HOME="$ORIGINAL_HOME"
44
+ }
45
+ trap cleanup EXIT
46
+
47
+ # Logging function
48
+ log() {
49
+ echo "$@" | tee -a "$LOG_FILE"
50
+ }
51
+
52
+ # Assertion helper
53
+ assert_output_contains() {
54
+ local output="$1"
55
+ local expected="$2"
56
+ if echo "$output" | grep -qi "$expected"; then
57
+ log " PASS: Output contains '$expected'"
58
+ else
59
+ log " FAIL: Output does not contain '$expected'"
60
+ log " Output was:"
61
+ echo "$output" | head -10 | tee -a "$LOG_FILE"
62
+ exit 1
63
+ fi
64
+ }
65
+
66
+ # Start fresh log
67
+ mkdir -p "$SCRIPT_DIR/logs"
68
+ echo "=== Test run: $(date) ===" > "$LOG_FILE"
69
+ log "TEMP_DIR: $TEMP_DIR"
70
+ log "TEMP_HOME: $TEMP_HOME"
71
+ log ""
72
+
73
+ # Setup: Create config so we don't trigger first-run prompts
74
+ mkdir -p "$TEMP_HOME/.sun"
75
+ cat > "$TEMP_HOME/.sun/config.json" << 'EOF'
76
+ {
77
+ "defaultAgents": ["claude"],
78
+ "firstRunComplete": true
79
+ }
80
+ EOF
81
+
82
+ # ============================================================================
83
+ # TEST: Typo for "add" -> "ad"
84
+ # ============================================================================
85
+ log "TEST: Typo 'ad' suggests 'add'"
86
+ log "-------------------------------"
87
+ OUTPUT=$(node "$CLI" ad 2>&1) || true
88
+ echo "$OUTPUT" | tee -a "$LOG_FILE"
89
+ assert_output_contains "$OUTPUT" "Unknown command"
90
+ assert_output_contains "$OUTPUT" "add"
91
+ log ""
92
+
93
+ # ============================================================================
94
+ # TEST: Typo for "remove" -> "remov"
95
+ # ============================================================================
96
+ log "TEST: Typo 'remov' suggests 'remove'"
97
+ log "-------------------------------------"
98
+ OUTPUT=$(node "$CLI" remov 2>&1) || true
99
+ echo "$OUTPUT" | tee -a "$LOG_FILE"
100
+ assert_output_contains "$OUTPUT" "Unknown command"
101
+ assert_output_contains "$OUTPUT" "remove"
102
+ log ""
103
+
104
+ # ============================================================================
105
+ # TEST: Typo for "list" -> "lst"
106
+ # ============================================================================
107
+ log "TEST: Typo 'lst' suggests 'list'"
108
+ log "---------------------------------"
109
+ OUTPUT=$(node "$CLI" lst 2>&1) || true
110
+ echo "$OUTPUT" | tee -a "$LOG_FILE"
111
+ assert_output_contains "$OUTPUT" "Unknown command"
112
+ assert_output_contains "$OUTPUT" "list"
113
+ log ""
114
+
115
+ # ============================================================================
116
+ # TEST: Typo for "show" -> "shw"
117
+ # ============================================================================
118
+ log "TEST: Typo 'shw' suggests 'show'"
119
+ log "---------------------------------"
120
+ OUTPUT=$(node "$CLI" shw 2>&1) || true
121
+ echo "$OUTPUT" | tee -a "$LOG_FILE"
122
+ assert_output_contains "$OUTPUT" "Unknown command"
123
+ assert_output_contains "$OUTPUT" "show"
124
+ log ""
125
+
126
+ # ============================================================================
127
+ # TEST: Typo for "config" -> "confg"
128
+ # ============================================================================
129
+ log "TEST: Typo 'confg' suggests 'config'"
130
+ log "-------------------------------------"
131
+ OUTPUT=$(node "$CLI" confg 2>&1) || true
132
+ echo "$OUTPUT" | tee -a "$LOG_FILE"
133
+ assert_output_contains "$OUTPUT" "Unknown command"
134
+ assert_output_contains "$OUTPUT" "config"
135
+ log ""
136
+
137
+ # ============================================================================
138
+ # TEST: Completely wrong command shows valid commands list
139
+ # ============================================================================
140
+ log "TEST: Wrong command shows valid commands list"
141
+ log "----------------------------------------------"
142
+ OUTPUT=$(node "$CLI" foobar 2>&1) || true
143
+ echo "$OUTPUT" | tee -a "$LOG_FILE"
144
+ assert_output_contains "$OUTPUT" "Unknown command"
145
+ assert_output_contains "$OUTPUT" "Valid commands"
146
+ log ""
147
+
148
+ # ============================================================================
149
+ # TEST: Exit code is non-zero for unknown commands
150
+ # ============================================================================
151
+ log "TEST: Exit code is non-zero for unknown commands"
152
+ log "--------------------------------------------------"
153
+ if node "$CLI" unknowncommand 2>/dev/null; then
154
+ log " FAIL: Command should have failed but didn't"
155
+ exit 1
156
+ else
157
+ log " PASS: Command correctly returned non-zero exit code"
158
+ fi
159
+ log ""
160
+
161
+ # ============================================================================
162
+ # SUMMARY
163
+ # ============================================================================
164
+ log "============================================"
165
+ log "All fuzzy-match tests passed!"
166
+ log "============================================"
@@ -0,0 +1,179 @@
1
+ #!/bin/bash
2
+ # ============================================================================
3
+ # test-show.sh
4
+ # ============================================================================
5
+ # Tests the `sun show` command.
6
+ #
7
+ # This script tests:
8
+ # - `sun show` (no args) - shows all agent folders and installed skills
9
+ # - `sun show <skill-name>` - shows details about a specific skill
10
+ # - Output contains expected skill names and descriptions
11
+ # - Detecting skills in multiple locations (local vs global)
12
+ #
13
+ # Output is logged to: logs/show.log
14
+ #
15
+ # Usage:
16
+ # ./test-show.sh
17
+ #
18
+ # Prerequisites:
19
+ # - CLI must be built first: npm run build
20
+ # ============================================================================
21
+
22
+ set -e
23
+
24
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
25
+ LOG_FILE="$SCRIPT_DIR/logs/show.log"
26
+ CLI="$SCRIPT_DIR/../dist/index.js"
27
+
28
+ # Setup temp environment
29
+ TEMP_DIR=$(mktemp -d)
30
+ TEMP_HOME=$(mktemp -d)
31
+ ORIGINAL_HOME="$HOME"
32
+ export HOME="$TEMP_HOME"
33
+ cd "$TEMP_DIR"
34
+
35
+ # Cleanup function
36
+ cleanup() {
37
+ cd /
38
+ rm -rf "$TEMP_DIR" "$TEMP_HOME"
39
+ export HOME="$ORIGINAL_HOME"
40
+ }
41
+ trap cleanup EXIT
42
+
43
+ # Logging function
44
+ log() {
45
+ echo "$@" | tee -a "$LOG_FILE"
46
+ }
47
+
48
+ # Assertion helpers
49
+ assert_output_contains() {
50
+ local output="$1"
51
+ local expected="$2"
52
+ if echo "$output" | grep -q "$expected"; then
53
+ log " PASS: Output contains '$expected'"
54
+ else
55
+ log " FAIL: Output does not contain '$expected'"
56
+ log " Output was:"
57
+ echo "$output" | head -20 | tee -a "$LOG_FILE"
58
+ exit 1
59
+ fi
60
+ }
61
+
62
+ assert_dir_exists() {
63
+ if [ -d "$1" ]; then
64
+ log " PASS: Directory exists: $1"
65
+ else
66
+ log " FAIL: Directory not found: $1"
67
+ exit 1
68
+ fi
69
+ }
70
+
71
+ # Start fresh log
72
+ mkdir -p "$SCRIPT_DIR/logs"
73
+ echo "=== Test run: $(date) ===" > "$LOG_FILE"
74
+ log "TEMP_DIR: $TEMP_DIR"
75
+ log "TEMP_HOME: $TEMP_HOME"
76
+ log ""
77
+
78
+ # Setup: Create config so we don't trigger first-run prompts
79
+ mkdir -p "$TEMP_HOME/.sun"
80
+ cat > "$TEMP_HOME/.sun/config.json" << 'EOF'
81
+ {
82
+ "defaultAgents": ["claude"],
83
+ "firstRunComplete": true
84
+ }
85
+ EOF
86
+
87
+ # ============================================================================
88
+ # TEST: Show with no agent folders
89
+ # ============================================================================
90
+ log "TEST: Show with no agent folders"
91
+ log "---------------------------------"
92
+ OUTPUT=$(node "$CLI" show 2>&1) || true
93
+ echo "$OUTPUT" | tee -a "$LOG_FILE"
94
+ assert_output_contains "$OUTPUT" "No agent folders found"
95
+ log ""
96
+
97
+ # ============================================================================
98
+ # TEST: Show with empty agent folder
99
+ # ============================================================================
100
+ log "TEST: Show with empty agent folder"
101
+ log "-----------------------------------"
102
+ mkdir -p .claude
103
+ OUTPUT=$(node "$CLI" show 2>&1) || true
104
+ echo "$OUTPUT" | tee -a "$LOG_FILE"
105
+ assert_output_contains "$OUTPUT" "Claude"
106
+ assert_output_contains "$OUTPUT" "No skills installed"
107
+ log ""
108
+
109
+ # ============================================================================
110
+ # TEST: Show with installed skill
111
+ # ============================================================================
112
+ log "TEST: Show with installed skill"
113
+ log "--------------------------------"
114
+ node "$CLI" add "$SCRIPT_DIR/fixtures/sample-skill" --claude 2>&1 | tee -a "$LOG_FILE" || true
115
+ OUTPUT=$(node "$CLI" show 2>&1) || true
116
+ echo "$OUTPUT" | tee -a "$LOG_FILE"
117
+ assert_output_contains "$OUTPUT" "sample-skill"
118
+ assert_output_contains "$OUTPUT" "A sample skill for testing"
119
+ log ""
120
+
121
+ # ============================================================================
122
+ # TEST: Show specific skill details
123
+ # ============================================================================
124
+ log "TEST: Show specific skill details"
125
+ log "----------------------------------"
126
+ OUTPUT=$(node "$CLI" show sample-skill 2>&1) || true
127
+ echo "$OUTPUT" | tee -a "$LOG_FILE"
128
+ assert_output_contains "$OUTPUT" "sample-skill"
129
+ assert_output_contains "$OUTPUT" "Description"
130
+ assert_output_contains "$OUTPUT" "Installed in"
131
+ log ""
132
+
133
+ # ============================================================================
134
+ # TEST: Show skill in multiple locations
135
+ # ============================================================================
136
+ log "TEST: Show skill in multiple locations"
137
+ log "---------------------------------------"
138
+ # Add to global as well
139
+ mkdir -p "$TEMP_HOME/.claude"
140
+ node "$CLI" add "$SCRIPT_DIR/fixtures/sample-skill" --claude --global 2>&1 | tee -a "$LOG_FILE" || true
141
+
142
+ OUTPUT=$(node "$CLI" show sample-skill 2>&1) || true
143
+ echo "$OUTPUT" | tee -a "$LOG_FILE"
144
+ assert_output_contains "$OUTPUT" "local"
145
+ assert_output_contains "$OUTPUT" "global"
146
+ log ""
147
+
148
+ # ============================================================================
149
+ # TEST: Show multiple agents with skills
150
+ # ============================================================================
151
+ log "TEST: Show multiple agents with skills"
152
+ log "---------------------------------------"
153
+ mkdir -p .codex
154
+ node "$CLI" add "$SCRIPT_DIR/fixtures/multi-skills/skill-one" --codex 2>&1 | tee -a "$LOG_FILE" || true
155
+
156
+ OUTPUT=$(node "$CLI" show 2>&1) || true
157
+ echo "$OUTPUT" | tee -a "$LOG_FILE"
158
+ assert_output_contains "$OUTPUT" "Claude"
159
+ assert_output_contains "$OUTPUT" "Codex"
160
+ assert_output_contains "$OUTPUT" "sample-skill"
161
+ assert_output_contains "$OUTPUT" "skill-one"
162
+ log ""
163
+
164
+ # ============================================================================
165
+ # TEST: Show non-existent skill
166
+ # ============================================================================
167
+ log "TEST: Show non-existent skill"
168
+ log "------------------------------"
169
+ OUTPUT=$(node "$CLI" show non-existent-skill 2>&1) || true
170
+ echo "$OUTPUT" | tee -a "$LOG_FILE"
171
+ assert_output_contains "$OUTPUT" "not installed"
172
+ log ""
173
+
174
+ # ============================================================================
175
+ # SUMMARY
176
+ # ============================================================================
177
+ log "============================================"
178
+ log "All show tests passed!"
179
+ log "============================================"
package/tsconfig.json ADDED
@@ -0,0 +1,20 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "ESNext",
5
+ "moduleResolution": "bundler",
6
+ "lib": ["ES2022"],
7
+ "outDir": "./dist",
8
+ "rootDir": "./src",
9
+ "strict": true,
10
+ "esModuleInterop": true,
11
+ "skipLibCheck": true,
12
+ "forceConsistentCasingInFileNames": true,
13
+ "declaration": true,
14
+ "declarationMap": true,
15
+ "sourceMap": true,
16
+ "resolveJsonModule": true
17
+ },
18
+ "include": ["src/**/*"],
19
+ "exclude": ["node_modules", "dist", "test"]
20
+ }
@@ -0,0 +1,15 @@
1
+ import { defineConfig } from 'vitest/config';
2
+
3
+ export default defineConfig({
4
+ test: {
5
+ globals: true,
6
+ environment: 'node',
7
+ include: ['test/**/*.test.ts'],
8
+ coverage: {
9
+ provider: 'v8',
10
+ reporter: ['text', 'html'],
11
+ include: ['src/**/*.ts'],
12
+ exclude: ['src/index.ts']
13
+ }
14
+ }
15
+ });