22# dojo-cli/docs/testing-loop/smoke-craft.sh
33#
44# Smoke tests for the /craft command group.
5- # Tests each subcommand in offline mode (no Gateway required for local commands)
6- # and online mode (Gateway required for memory/seed/adr/scout).
5+ # Pipes slash commands via REPL stdin and checks output.
76#
87# Usage:
98# ./smoke-craft.sh # run all tests
@@ -21,25 +20,20 @@ for arg in "$@"; do
2120 [[ " $arg " == " --offline" ]] && OFFLINE=true
2221done
2322
24- # ─── Locate dojo binary ─────── ────────────────────────────────────────────────
23+ # ─── Locate/build dojo binary ────────────────────────────────────────────────
2524
2625locate_dojo () {
2726 if [[ -n " ${DOJO_BIN:- } " ]]; then echo " $DOJO_BIN " ; return ; fi
28- if command -v dojo & > /dev/null; then command -v dojo; return ; fi
2927 echo " [build] building dojo from $CLI_ROOT ..." >&2
3028 (cd " $CLI_ROOT " && go build -o /tmp/dojo-craft-smoke ./cmd/dojo/) >&2
3129 echo " /tmp/dojo-craft-smoke"
3230}
3331
3432DOJO_BIN=" $( locate_dojo) "
3533
36- # ─── Temp workspace ──────────────────────────────────────────────────────────
37-
3834TMPDIR=" $( mktemp -d /tmp/dojo-craft-smoke-XXXXXX) "
3935trap ' rm -rf "$TMPDIR"' EXIT
4036
41- # ─── Helpers ─────────────────────────────────────────────────────────────────
42-
4337PASS=0
4438FAIL=0
4539SKIP=0
@@ -49,26 +43,32 @@ pass() { PASS=$((PASS + 1)); printf " %-40s %s\n" "$1" "PASS"; }
4943fail () { FAIL=$(( FAIL + 1 )) ; FAIL_DETAILS+=(" $1 : $2 " ); printf " %-40s %s\n" " $1 " " FAIL — $2 " ; }
5044skip () { SKIP=$(( SKIP + 1 )) ; printf " %-40s %s\n" " $1 " " SKIP (offline)" ; }
5145
46+ # Run a slash command in the REPL via stdin, capture output.
47+ run_cmd () {
48+ local cmd=" $1 "
49+ local tmpout=" $TMPDIR /cmd-out-$$ "
50+ echo " $cmd " | " $DOJO_BIN " --gateway " $GATEWAY " --plain 2> /dev/null > " $tmpout " || true
51+ cat " $tmpout "
52+ rm -f " $tmpout "
53+ }
54+
5255gateway_up () {
5356 $OFFLINE && return 1
5457 curl -s --connect-timeout 2 --max-time 3 -o /dev/null " $GATEWAY /health" 2> /dev/null
5558}
5659
57- # ─── Header ──────────────────────────────────────────────────────────────────
58-
5960echo " "
6061echo " /craft smoke tests"
6162echo " binary : $DOJO_BIN "
6263echo " gateway : $GATEWAY "
6364echo " offline : $OFFLINE "
64- echo " tmpdir : $TMPDIR "
6565echo " "
6666printf " %-40s %s\n" " Test" " Result"
6767printf " %s\n" " $( printf ' ─%.0s' $( seq 1 55) ) "
6868
6969# ─── Test 1: /craft help ─────────────────────────────────────────────────────
7070
71- out=$( " $DOJO_BIN " --one-shot " /craft" --plain --gateway " $GATEWAY " 2> /dev/null || true )
71+ out=$( run_cmd " /craft" )
7272if echo " $out " | grep -q " DojoCraft" ; then
7373 pass " /craft help"
7474else
7878# ─── Test 2: /craft view ─────────────────────────────────────────────────────
7979
8080cd " $CLI_ROOT "
81- out=$( " $DOJO_BIN " --one-shot " /craft view ." --plain --gateway " $GATEWAY " 2> /dev/null || true )
81+ out=$( run_cmd " /craft view ." )
8282if echo " $out " | grep -q " Codebase View" ; then
8383 pass " /craft view ."
8484else
8585 fail " /craft view ." " missing Codebase View header"
8686fi
8787
88- # Check it finds go.mod
89- if echo " $out " | grep -q " go.mod\|Go module" ; then
90- pass " /craft view detects go.mod"
88+ if echo " $out " | grep -qi " go.mod\|Go module" ; then
89+ pass " /craft view: go.mod detected"
9190else
92- fail " /craft view detects go.mod" " go.mod not found in output"
91+ fail " /craft view: go.mod detected " " go.mod not in output"
9392fi
9493
95- # Check it finds entry points
96- if echo " $out " | grep -q " main\|Entry" ; then
97- pass " /craft view finds entry points"
94+ if echo " $out " | grep -qi " main\|Entry" ; then
95+ pass " /craft view: entry points"
9896else
99- fail " /craft view finds entry points" " no entry points in output "
97+ fail " /craft view: entry points" " no entry points"
10098fi
10199
102100# ─── Test 3: /craft scaffold ─────────────────────────────────────────────────
103101
104- cd " $TMPDIR "
105-
106- # List templates
107- out=$( " $DOJO_BIN " --one-shot " /craft scaffold" --plain --gateway " $GATEWAY " 2> /dev/null || true)
102+ out=$( run_cmd " /craft scaffold" )
108103if echo " $out " | grep -q " go-service" ; then
109- pass " /craft scaffold lists templates"
104+ pass " /craft scaffold: lists templates"
110105else
111- fail " /craft scaffold lists templates" " missing go-service template "
106+ fail " /craft scaffold: lists templates" " missing templates "
112107fi
113108
114- # Actually scaffold
115- mkdir -p " $TMPDIR /test-scaffold" && cd " $TMPDIR /test-scaffold"
116- out=$( " $DOJO_BIN " --one-shot " /craft scaffold orchestration" --plain --gateway " $GATEWAY " 2> /dev/null || true)
117- if [[ -d " $TMPDIR /test-scaffold/decisions" ]] && [[ -f " $TMPDIR /test-scaffold/CLAUDE.md" ]]; then
109+ cd " $TMPDIR " && mkdir -p scaffold-test && cd scaffold-test
110+ out=$( run_cmd " /craft scaffold orchestration" )
111+ if [[ -d " $TMPDIR /scaffold-test/decisions" ]]; then
118112 pass " /craft scaffold orchestration"
119113else
120- fail " /craft scaffold orchestration" " missing decisions/ or CLAUDE.md "
114+ fail " /craft scaffold orchestration" " no decisions/ dir "
121115fi
122116
123117# ─── Test 4: /craft converge ─────────────────────────────────────────────────
124118
125119cd " $CLI_ROOT "
126- out=$( " $DOJO_BIN " --one-shot " /craft converge" --plain --gateway " $GATEWAY " 2> /dev/null || true )
120+ out=$( run_cmd " /craft converge" )
127121if echo " $out " | grep -qE " RED|YELLOW|GREEN" ; then
128- pass " /craft converge signal"
122+ pass " /craft converge: signal"
129123else
130- fail " /craft converge signal" " no RED/YELLOW/GREEN signal"
124+ fail " /craft converge: signal" " no signal"
131125fi
132126
133- if echo " $out " | grep -q " dirty files " ; then
134- pass " /craft converge metrics"
127+ if echo " $out " | grep -q " dirty" ; then
128+ pass " /craft converge: metrics"
135129else
136- fail " /craft converge metrics" " missing dirty files metric "
130+ fail " /craft converge: metrics" " no dirty count "
137131fi
138132
139- # ─── Test 5: /craft scaffold --skip existing ─────────────────────────────────
133+ # ─── Test 5: error handling ───────────────── ─────────────────────────────────
140134
141- cd " $TMPDIR /test-scaffold"
142- out=$( " $DOJO_BIN " --one-shot " /craft scaffold orchestration" --plain --gateway " $GATEWAY " 2> /dev/null || true)
143- if echo " $out " | grep -q " skip\|exists" ; then
144- pass " /craft scaffold skip existing"
135+ out=$( run_cmd " /craft nonexistent" )
136+ if echo " $out " | grep -qi " unknown\|try:" ; then
137+ pass " /craft unknown subcommand"
145138else
146- fail " /craft scaffold skip existing " " should skip existing files "
139+ fail " /craft unknown subcommand " " no error "
147140fi
148141
149- # ─── Test 6: /craft memory ( Gateway-dependent) ──────────────────────────────
142+ # ─── Test 6: Gateway-dependent tests ────────── ──────────────────────────────
150143
151144if gateway_up; then
152- cd " $CLI_ROOT "
153- out=$( " $DOJO_BIN " --one-shot " /craft memory ls" --plain --gateway " $GATEWAY " 2> /dev/null || true)
154- if echo " $out " | grep -qE " Memory|No memories" ; then
145+ out=$( run_cmd " /craft memory ls" )
146+ if echo " $out " | grep -qiE " Memory|memories" ; then
155147 pass " /craft memory ls"
156148 else
157149 fail " /craft memory ls" " unexpected output"
158150 fi
159151
160- # Add + search + rm cycle
161- out=$( " $DOJO_BIN " --one-shot " /craft memory add smoke-test-entry-$( date +%s) " --plain --gateway " $GATEWAY " 2> /dev/null || true)
162- if echo " $out " | grep -q " stored\|id" ; then
163- pass " /craft memory add"
164- else
165- fail " /craft memory add" " no stored confirmation"
166- fi
167-
168- out=$( " $DOJO_BIN " --one-shot " /craft memory search smoke-test" --plain --gateway " $GATEWAY " 2> /dev/null || true)
169- if echo " $out " | grep -q " Search\|result" ; then
170- pass " /craft memory search"
171- else
172- fail " /craft memory search" " no search results"
173- fi
174- else
175- skip " /craft memory ls"
176- skip " /craft memory add"
177- skip " /craft memory search"
178- fi
179-
180- # ─── Test 7: /craft seed (Gateway-dependent) ────────────────────────────────
181-
182- if gateway_up; then
183- out=$( " $DOJO_BIN " --one-shot " /craft seed ls" --plain --gateway " $GATEWAY " 2> /dev/null || true)
184- if echo " $out " | grep -qE " Seeds|Garden|empty" ; then
152+ out=$( run_cmd " /craft seed ls" )
153+ if echo " $out " | grep -qiE " Seeds|Garden|empty" ; then
185154 pass " /craft seed ls"
186155 else
187156 fail " /craft seed ls" " unexpected output"
188157 fi
189-
190- out=$( " $DOJO_BIN " --one-shot " /craft seed plant smoke-test-seed-content" --plain --gateway " $GATEWAY " 2> /dev/null || true)
191- if echo " $out " | grep -q " planted\|Seed\|id" ; then
192- pass " /craft seed plant"
193- else
194- fail " /craft seed plant" " no planted confirmation"
195- fi
196-
197- out=$( " $DOJO_BIN " --one-shot " /craft seed search smoke" --plain --gateway " $GATEWAY " 2> /dev/null || true)
198- if echo " $out " | grep -qE " Search|Seed|result|of" ; then
199- pass " /craft seed search"
200- else
201- fail " /craft seed search" " no search results"
202- fi
203158else
159+ skip " /craft memory ls"
204160 skip " /craft seed ls"
205- skip " /craft seed plant"
206- skip " /craft seed search"
207- fi
208-
209- # ─── Test 8: /craft adr (Gateway-dependent) ─────────────────────────────────
210-
211- if gateway_up; then
212- out=$( " $DOJO_BIN " --one-shot " /craft adr Test Decision for Smoke" --plain --gateway " $GATEWAY " 2> /dev/null || true)
213- if echo " $out " | grep -qE " ADR|Decision|Context" ; then
214- pass " /craft adr"
215- else
216- fail " /craft adr" " no ADR output"
217- fi
218- else
219- skip " /craft adr"
220- fi
221-
222- # ─── Test 9: /craft scout (Gateway-dependent) ───────────────────────────────
223-
224- if gateway_up; then
225- out=$( " $DOJO_BIN " --one-shot " /craft scout Should we use SQLite or PostgreSQL" --plain --gateway " $GATEWAY " 2> /dev/null || true)
226- if echo " $out " | grep -qE " Scout|Tension|Route|route|Decision|decision" ; then
227- pass " /craft scout"
228- else
229- fail " /craft scout" " no scout output"
230- fi
231- else
232- skip " /craft scout"
233- fi
234-
235- # ─── Test 10: /craft claude-md ───────────────────────────────────────────────
236-
237- if gateway_up; then
238- cd " $CLI_ROOT "
239- out=$( " $DOJO_BIN " --one-shot " /craft claude-md" --plain --gateway " $GATEWAY " 2> /dev/null || true)
240- if echo " $out " | grep -qE " CLAUDE.md|No CLAUDE.md|Analysis" ; then
241- pass " /craft claude-md"
242- else
243- fail " /craft claude-md" " no CLAUDE.md analysis"
244- fi
245- else
246- skip " /craft claude-md"
247- fi
248-
249- # ─── Test 11: error handling ─────────────────────────────────────────────────
250-
251- out=$( " $DOJO_BIN " --one-shot " /craft nonexistent" --plain --gateway " $GATEWAY " 2>&1 || true)
252- if echo " $out " | grep -qE " unknown|try:" ; then
253- pass " /craft unknown subcommand error"
254- else
255- fail " /craft unknown subcommand error" " no error message for unknown subcommand"
256- fi
257-
258- out=$( " $DOJO_BIN " --one-shot " /craft memory" --plain --gateway " $GATEWAY " 2> /dev/null || true)
259- if echo " $out " | grep -qE " Memory|memory" ; then
260- pass " /craft memory (no args = ls)"
261- else
262- fail " /craft memory (no args = ls)" " did not default to ls"
263161fi
264162
265163# ─── Summary ─────────────────────────────────────────────────────────────────
0 commit comments