@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.
- package/DEV.md +58 -0
- package/README.md +30 -0
- package/dist/commands/add.d.ts +13 -0
- package/dist/commands/add.d.ts.map +1 -0
- package/dist/commands/add.js +111 -0
- package/dist/commands/add.js.map +1 -0
- package/dist/commands/config.d.ts +5 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +40 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/list.d.ts +5 -0
- package/dist/commands/list.d.ts.map +1 -0
- package/dist/commands/list.js +53 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/remove.d.ts +13 -0
- package/dist/commands/remove.d.ts.map +1 -0
- package/dist/commands/remove.js +129 -0
- package/dist/commands/remove.js.map +1 -0
- package/dist/commands/show-dev.d.ts +20 -0
- package/dist/commands/show-dev.d.ts.map +1 -0
- package/dist/commands/show-dev.js +195 -0
- package/dist/commands/show-dev.js.map +1 -0
- package/dist/commands/show.d.ts +11 -0
- package/dist/commands/show.d.ts.map +1 -0
- package/dist/commands/show.js +175 -0
- package/dist/commands/show.js.map +1 -0
- package/dist/core/agent-detect.d.ts +22 -0
- package/dist/core/agent-detect.d.ts.map +1 -0
- package/dist/core/agent-detect.js +107 -0
- package/dist/core/agent-detect.js.map +1 -0
- package/dist/core/agents.d.ts +8 -0
- package/dist/core/agents.d.ts.map +1 -0
- package/dist/core/agents.js +34 -0
- package/dist/core/agents.js.map +1 -0
- package/dist/core/config-manager.d.ts +9 -0
- package/dist/core/config-manager.d.ts.map +1 -0
- package/dist/core/config-manager.js +47 -0
- package/dist/core/config-manager.js.map +1 -0
- package/dist/core/skill-hash.d.ts +12 -0
- package/dist/core/skill-hash.d.ts.map +1 -0
- package/dist/core/skill-hash.js +53 -0
- package/dist/core/skill-hash.js.map +1 -0
- package/dist/core/skill-info.d.ts +34 -0
- package/dist/core/skill-info.d.ts.map +1 -0
- package/dist/core/skill-info.js +213 -0
- package/dist/core/skill-info.js.map +1 -0
- package/dist/core/skill-install.d.ts +24 -0
- package/dist/core/skill-install.d.ts.map +1 -0
- package/dist/core/skill-install.js +123 -0
- package/dist/core/skill-install.js.map +1 -0
- package/dist/core/skill-source.d.ts +29 -0
- package/dist/core/skill-source.d.ts.map +1 -0
- package/dist/core/skill-source.js +111 -0
- package/dist/core/skill-source.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +104 -0
- package/dist/index.js.map +1 -0
- package/dist/types/index.d.ts +57 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/fuzzy-match.d.ts +16 -0
- package/dist/utils/fuzzy-match.d.ts.map +1 -0
- package/dist/utils/fuzzy-match.js +37 -0
- package/dist/utils/fuzzy-match.js.map +1 -0
- package/dist/utils/prompts.d.ts +16 -0
- package/dist/utils/prompts.d.ts.map +1 -0
- package/dist/utils/prompts.js +46 -0
- package/dist/utils/prompts.js.map +1 -0
- package/dist/utils/registry.d.ts +6 -0
- package/dist/utils/registry.d.ts.map +1 -0
- package/dist/utils/registry.js +14 -0
- package/dist/utils/registry.js.map +1 -0
- package/package.json +42 -0
- package/src/commands/add.ts +136 -0
- package/src/commands/config.ts +47 -0
- package/src/commands/list.ts +68 -0
- package/src/commands/remove.ts +154 -0
- package/src/commands/show-dev.ts +223 -0
- package/src/commands/show.ts +203 -0
- package/src/core/agent-detect.ts +125 -0
- package/src/core/agents.ts +40 -0
- package/src/core/config-manager.ts +55 -0
- package/src/core/skill-hash.ts +61 -0
- package/src/core/skill-info.ts +248 -0
- package/src/core/skill-install.ts +165 -0
- package/src/core/skill-source.ts +125 -0
- package/src/index.ts +116 -0
- package/src/types/index.ts +64 -0
- package/src/utils/fuzzy-match.ts +48 -0
- package/src/utils/prompts.ts +54 -0
- package/src/utils/registry.ts +16 -0
- package/test/README.md +123 -0
- package/test/fixtures/multi-skills/skill-one/SKILL.md +8 -0
- package/test/fixtures/multi-skills/skill-two/SKILL.md +8 -0
- package/test/fixtures/sample-skill/SKILL.md +8 -0
- package/test/logs/add-remove.log +108 -0
- package/test/logs/config.log +72 -0
- package/test/logs/fuzzy-match.log +64 -0
- package/test/logs/show.log +110 -0
- package/test/run-all.sh +83 -0
- package/test/test-add-remove.sh +245 -0
- package/test/test-config.sh +208 -0
- package/test/test-fuzzy-match.sh +166 -0
- package/test/test-show.sh +179 -0
- package/tsconfig.json +20 -0
- 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
|
+
}
|
package/vitest.config.ts
ADDED
|
@@ -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
|
+
});
|