kenaz 0.3.7 → 0.3.9

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 (34) hide show
  1. package/core/.claude/commands/Ansuz.md +7 -1
  2. package/core/.claude/hooks/autonomy-stop.js +20 -0
  3. package/core/.claude/hooks/turn-context.js +7 -2
  4. package/core/.claude/settings.json +10 -0
  5. package/core/.collaboration/core/reconcile.js +3 -1
  6. package/core/.collaboration/core/task-2404-reconcile.test.js +8 -0
  7. package/core/.formation/bifrost/openai/codex-hook-shim.js +12 -1
  8. package/core/.formation/bifrost/openai/codex-hook-shim.test.js +1 -1
  9. package/core/.formation/tools/__tests__/dispatch-model.test.js +58 -0
  10. package/core/.formation/tools/dispatch-model.js +91 -0
  11. package/core/.formation/tools/dispatch.js +8 -6
  12. package/core/.specialist/Ansuz/RULES.md +36 -14
  13. package/core/.specialist/Ansuz/elixir.yaml +7 -5
  14. package/core/.specialist/tools/__tests__/autonomy.test.js +91 -0
  15. package/core/.specialist/tools/__tests__/rea-detect.test.js +71 -0
  16. package/core/.specialist/tools/ansuz-boot-fast.js +1 -0
  17. package/core/.specialist/tools/autonomy.js +88 -0
  18. package/core/.specialist/tools/rea-detect.js +67 -0
  19. package/core/KENAZ_CORE_VERSION +1 -1
  20. package/core/plugins/kenaz/commands/Ansuz.md +7 -1
  21. package/core/plugins/kenaz/hooks/hooks.json +2 -1
  22. package/core/plugins/kenaz/hooks/kenaz-hook.js +1 -0
  23. package/core/plugins/kenaz/scripts/kenaz.test.js +1 -1
  24. package/core/plugins/kenaz/scripts/ygg.js +10 -2
  25. package/core/plugins/kenaz-peer/hooks/register.test.ts +52 -0
  26. package/core/plugins/kenaz-peer/hooks/register.ts +31 -1
  27. package/lib/cli.js +59 -1
  28. package/lib/cli.test.js +26 -0
  29. package/package.json +6 -6
  30. package/core/k-cli/README.md +0 -330
  31. package/core/k-cli/package.json +0 -21
  32. package/core/k-cli/templates/k-cli.md +0 -91
  33. package/core/k-cli/test/TEST_SPEC.md +0 -117
  34. package/core/k-cli/test/run.sh +0 -403
@@ -1,403 +0,0 @@
1
- #!/usr/bin/env bash
2
- # k-cli Test Runner
3
- # Usage: cd k-cli && bash test/run.sh
4
-
5
- set -uo pipefail
6
-
7
- # ─── Paths ───
8
- SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
9
- KCLI_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
10
- CORE_DIR="$(cd "$KCLI_DIR/.." && pwd)"
11
- SANDBOX="$SCRIPT_DIR/sandbox"
12
- KCLI="node $KCLI_DIR/dist/index.js"
13
-
14
- # ─── Log ───
15
- LOG_FILE="$SCRIPT_DIR/test-report-$(date +%Y%m%d-%H%M%S).log"
16
-
17
- log() {
18
- echo "$@" >> "$LOG_FILE"
19
- }
20
-
21
- log_separator() {
22
- log ""
23
- log "═══════════════════════════════════════════════════════════════"
24
- }
25
-
26
- # Run a k-cli command: log the command + full output, capture in LOG_CMD_OUTPUT
27
- run_cmd() {
28
- local cmd_display="$*"
29
- log " ▶ $cmd_display"
30
- LOG_CMD_OUTPUT=$("$@" 2>&1) || true
31
- if [ -n "$LOG_CMD_OUTPUT" ]; then
32
- echo "$LOG_CMD_OUTPUT" >> "$LOG_FILE"
33
- else
34
- log " (no output)"
35
- fi
36
- }
37
-
38
- # ─── State ───
39
- PASS=0
40
- FAIL=0
41
- TOTAL=11
42
-
43
- # ─── Helpers ───
44
- cleanup() {
45
- rm -rf "$SANDBOX"
46
- mkdir -p "$SANDBOX"
47
- }
48
-
49
- assert_contains() {
50
- local label="$1" output="$2" expected="$3"
51
- if echo "$output" | grep -qi "$expected"; then
52
- log " ✓ assert_contains($label): found \"$expected\""
53
- return 0
54
- else
55
- log " ✗ assert_contains($label): NOT found \"$expected\""
56
- log " Got: $(echo "$output" | head -3)"
57
- echo " Expected output to contain \"$expected\""
58
- echo " Got: $(echo "$output" | head -3)"
59
- return 1
60
- fi
61
- }
62
-
63
- assert_file_exists() {
64
- local filepath="$1"
65
- if [ -f "$filepath" ]; then
66
- log " ✓ file exists: $filepath"
67
- return 0
68
- else
69
- log " ✗ file NOT found: $filepath"
70
- echo " File not found: $filepath"
71
- return 1
72
- fi
73
- }
74
-
75
- assert_file_not_exists() {
76
- local filepath="$1"
77
- if [ ! -f "$filepath" ]; then
78
- log " ✓ file not exists (expected): $filepath"
79
- return 0
80
- else
81
- log " ✗ file should not exist: $filepath"
82
- echo " File should not exist: $filepath"
83
- return 1
84
- fi
85
- }
86
-
87
- run_test() {
88
- local num="$1" name="$2"
89
- shift 2
90
- local label
91
- label=$(printf "[%2d/%d] %s" "$num" "$TOTAL" "$name")
92
- printf "[%2d/%d] %-24s " "$num" "$TOTAL" "$name"
93
- log_separator
94
- log "TEST $label"
95
- log " Started: $(date '+%Y-%m-%d %H:%M:%S')"
96
- log ""
97
- if "$@"; then
98
- echo "PASS"
99
- log ""
100
- log " ▸ Result: PASS"
101
- PASS=$((PASS + 1))
102
- else
103
- echo "FAIL"
104
- log ""
105
- log " ▸ Result: FAIL"
106
- FAIL=$((FAIL + 1))
107
- fi
108
- }
109
-
110
- # ─── Setup ───
111
- echo ""
112
- echo "k-cli Test Suite"
113
- echo "========================================"
114
- echo "Core: $CORE_DIR"
115
- echo "k-cli: $KCLI_DIR"
116
- echo "Sandbox: $SANDBOX"
117
- echo "Log: $LOG_FILE"
118
- echo ""
119
-
120
- log "k-cli Test Report"
121
- log "Generated: $(date '+%Y-%m-%d %H:%M:%S')"
122
- log "Core: $CORE_DIR"
123
- log "k-cli: $KCLI_DIR"
124
- log "Sandbox: $SANDBOX"
125
-
126
- # Build before testing
127
- echo "Building k-cli..."
128
- (cd "$KCLI_DIR" && npm run build 2>&1) || {
129
- echo "ERROR: Build failed."
130
- exit 1
131
- }
132
- echo "Build OK"
133
- echo ""
134
-
135
- cleanup
136
-
137
- # =========================================
138
- # Test 1: project initialize + install
139
- # =========================================
140
- test_1_init_install() {
141
- log " --- Step: project initialize ---"
142
- run_cmd $KCLI project initialize --project-path "$SANDBOX"
143
- local output="$LOG_CMD_OUTPUT"
144
-
145
- # Verify .kenaz/project.yaml
146
- assert_file_exists "$SANDBOX/.kenaz/project.yaml" || return 1
147
-
148
- # Verify task status dirs
149
- for status in backlog active done blocked cancel; do
150
- [ -d "$SANDBOX/.kenaz/tasks/$status" ] || { log " ✗ .kenaz/tasks/$status/ not found"; echo " .kenaz/tasks/$status/ not found"; return 1; }
151
- log " ✓ dir exists: .kenaz/tasks/$status/"
152
- done
153
-
154
- # Verify log formation dirs
155
- for formation in unit solo squad legion misc legacy; do
156
- [ -d "$SANDBOX/.kenaz/logs/$formation" ] || { log " ✗ .kenaz/logs/$formation/ not found"; echo " .kenaz/logs/$formation/ not found"; return 1; }
157
- log " ✓ dir exists: .kenaz/logs/$formation/"
158
- done
159
-
160
- # Verify k-cli.md was created
161
- assert_file_exists "$SANDBOX/k-cli.md" || return 1
162
-
163
- # Delete k-cli.md
164
- log " --- Step: delete k-cli.md ---"
165
- rm -f "$SANDBOX/k-cli.md"
166
- assert_file_not_exists "$SANDBOX/k-cli.md" || return 1
167
-
168
- # Reinstall via project install
169
- log " --- Step: project install k-cli ---"
170
- run_cmd $KCLI project install k-cli --project-path "$SANDBOX"
171
- output="$LOG_CMD_OUTPUT"
172
-
173
- # Verify k-cli.md restored
174
- assert_file_exists "$SANDBOX/k-cli.md" || return 1
175
-
176
- # Verify content
177
- local content
178
- content=$(cat "$SANDBOX/k-cli.md")
179
- assert_contains "k-cli.md content" "$content" "k-cli" || return 1
180
-
181
- return 0
182
- }
183
-
184
- # =========================================
185
- # Test 2: ping
186
- # =========================================
187
- test_2_ping() {
188
- run_cmd $KCLI ping --project-path "$SANDBOX"
189
- local output="$LOG_CMD_OUTPUT"
190
- assert_contains "ping" "$output" "k-cli" || return 1
191
- assert_contains "ping" "$output" "sub-project" || return 1
192
- return 0
193
- }
194
-
195
- # =========================================
196
- # Test 3: project status
197
- # =========================================
198
- test_3_project_status() {
199
- run_cmd $KCLI project status --project-path "$SANDBOX" --json
200
- local output="$LOG_CMD_OUTPUT"
201
-
202
- # Must be valid JSON
203
- echo "$output" | node -e "let d='';process.stdin.on('data',c=>d+=c);process.stdin.on('end',()=>{try{JSON.parse(d);process.exit(0)}catch(e){process.exit(1)}})" 2>/dev/null || {
204
- log " ✗ Output is not valid JSON"
205
- echo " Output is not valid JSON"
206
- echo " Got: $(echo "$output" | head -3)"
207
- return 1
208
- }
209
- log " ✓ valid JSON output"
210
-
211
- assert_contains "status" "$output" "sub-project" || return 1
212
- return 0
213
- }
214
-
215
- # =========================================
216
- # Test 4: specialist list
217
- # =========================================
218
- test_4_specialist_list() {
219
- run_cmd $KCLI specialist list --project-path "$SANDBOX"
220
- local output="$LOG_CMD_OUTPUT"
221
- assert_contains "specialist" "$output" "Ansuz" || return 1
222
- assert_contains "specialist" "$output" "Amelia" || return 1
223
- return 0
224
- }
225
-
226
- # =========================================
227
- # Test 5: task create x3 -> list -> get
228
- # =========================================
229
- test_5_task_create() {
230
- local task_id
231
-
232
- # Task A: Hello World
233
- log " --- Step: task create A (Hello World) ---"
234
- run_cmd $KCLI task create "write a Node.js script that console.log outputs Hello World" \
235
- --project-path "$SANDBOX"
236
- local output="$LOG_CMD_OUTPUT"
237
- task_id=$(echo "$output" | grep -oE "TASK_[0-9]+" | head -1)
238
- [ -n "$task_id" ] || { log " ✗ Could not extract TASK_A ID"; echo " Could not extract TASK_A ID"; return 1; }
239
- echo "$task_id" > "$SANDBOX/.test_task_a"
240
- log " ✓ TASK_A = $task_id"
241
-
242
- # Task B: 10+10
243
- log " --- Step: task create B (10+10) ---"
244
- run_cmd $KCLI task create "write a Node.js script that calculates 10+10 and prints the result" \
245
- --project-path "$SANDBOX"
246
- output="$LOG_CMD_OUTPUT"
247
- task_id=$(echo "$output" | grep -oE "TASK_[0-9]+" | head -1)
248
- [ -n "$task_id" ] || { log " ✗ Could not extract TASK_B ID"; echo " Could not extract TASK_B ID"; return 1; }
249
- echo "$task_id" > "$SANDBOX/.test_task_b"
250
- log " ✓ TASK_B = $task_id"
251
-
252
- # Task C: list files
253
- log " --- Step: task create C (list files) ---"
254
- run_cmd $KCLI task create "write a Node.js script that reads and prints the file list of current directory" \
255
- --project-path "$SANDBOX"
256
- output="$LOG_CMD_OUTPUT"
257
- task_id=$(echo "$output" | grep -oE "TASK_[0-9]+" | head -1)
258
- [ -n "$task_id" ] || { log " ✗ Could not extract TASK_C ID"; echo " Could not extract TASK_C ID"; return 1; }
259
- echo "$task_id" > "$SANDBOX/.test_task_c"
260
- log " ✓ TASK_C = $task_id"
261
-
262
- # Verify list contains all 3
263
- log " --- Step: task list ---"
264
- run_cmd $KCLI task list --project-path "$SANDBOX"
265
- local list_output="$LOG_CMD_OUTPUT"
266
- local ta tb tc
267
- ta=$(cat "$SANDBOX/.test_task_a")
268
- tb=$(cat "$SANDBOX/.test_task_b")
269
- tc=$(cat "$SANDBOX/.test_task_c")
270
- assert_contains "list" "$list_output" "$ta" || return 1
271
- assert_contains "list" "$list_output" "$tb" || return 1
272
- assert_contains "list" "$list_output" "$tc" || return 1
273
-
274
- # Verify get TASK_A
275
- log " --- Step: task get $ta ---"
276
- run_cmd $KCLI task get "$ta" --project-path "$SANDBOX"
277
- local get_output="$LOG_CMD_OUTPUT"
278
- assert_contains "get" "$get_output" "$ta" || return 1
279
-
280
- return 0
281
- }
282
-
283
- # =========================================
284
- # Test 9: task delete -> verify
285
- # =========================================
286
- test_9_task_delete() {
287
- local task_id
288
- task_id=$(cat "$SANDBOX/.test_task_a" 2>/dev/null) || { echo " No TASK_A from test 5"; return 1; }
289
- log " Target: $task_id"
290
-
291
- # Verify via get — task should exist
292
- log " --- Step: task get (before delete) ---"
293
- run_cmd $KCLI task get "$task_id" --project-path "$SANDBOX"
294
- local output="$LOG_CMD_OUTPUT"
295
- assert_contains "get before delete" "$output" "$task_id" || return 1
296
-
297
- # Delete (direct rm, no status restriction)
298
- log " --- Step: task delete ---"
299
- run_cmd $KCLI task delete "$task_id" --project-path "$SANDBOX"
300
- output="$LOG_CMD_OUTPUT"
301
- assert_contains "delete output" "$output" "$task_id\|Deleted\|delet" || return 1
302
-
303
- # Verify deleted: task should not appear in list
304
- log " --- Step: task list (after delete) ---"
305
- run_cmd $KCLI task list --project-path "$SANDBOX"
306
- local list_output="$LOG_CMD_OUTPUT"
307
- if echo "$list_output" | grep -q "$task_id"; then
308
- log " ✗ Task $task_id still in list after delete"
309
- echo " Task $task_id still in list after delete"
310
- return 1
311
- fi
312
- log " ✓ Task $task_id no longer in list"
313
- return 0
314
- }
315
-
316
- # =========================================
317
- # Test 10: specialist run Amelia
318
- # =========================================
319
- test_10_specialist_run() {
320
- run_cmd $KCLI specialist run --agent Amelia "list task status in sandbox project" \
321
- --project-path "$SANDBOX"
322
- local output="$LOG_CMD_OUTPUT"
323
-
324
- # Should produce some output (not empty)
325
- [ -n "$output" ] || { log " ✗ specialist run produced no output"; echo " specialist run produced no output"; return 1; }
326
- log " ✓ specialist run produced output (${#output} chars)"
327
- return 0
328
- }
329
-
330
- # =========================================
331
- # Test 11: --dry-run (all commands)
332
- # =========================================
333
- test_11_dry_run() {
334
- local output
335
-
336
- # 1. project initialize --dry-run (use fresh temp dir since sandbox is already initialized)
337
- log " --- dry-run: project initialize ---"
338
- local dryrun_tmp="$SANDBOX/_dryrun_tmp"
339
- mkdir -p "$dryrun_tmp"
340
- run_cmd $KCLI project initialize --project-path "$dryrun_tmp" --dry-run
341
- output="$LOG_CMD_OUTPUT"
342
- rm -rf "$dryrun_tmp"
343
- assert_contains "init dry-run" "$output" "dry-run\|dry.run\|dryRun" || return 1
344
-
345
- # 2. task create --dry-run
346
- log " --- dry-run: task create ---"
347
- run_cmd $KCLI task create "dry-run test" --project-path "$SANDBOX" --dry-run
348
- output="$LOG_CMD_OUTPUT"
349
- assert_contains "create dry-run" "$output" "dry-run\|dry.run\|dryRun" || return 1
350
-
351
- # 3. task delete --dry-run
352
- log " --- dry-run: task delete ---"
353
- local tb
354
- tb=$(cat "$SANDBOX/.test_task_b" 2>/dev/null) || tb="TASK_999"
355
- run_cmd $KCLI task delete "$tb" --project-path "$SANDBOX" --dry-run
356
- output="$LOG_CMD_OUTPUT"
357
- assert_contains "delete dry-run" "$output" "dry-run\|dry.run\|dryRun" || return 1
358
-
359
- log " --- dry-run: specialist run ---"
360
- run_cmd $KCLI specialist run --agent Amelia "test" --project-path "$SANDBOX" --dry-run
361
- output="$LOG_CMD_OUTPUT"
362
- assert_contains "specialist dry-run" "$output" "dry-run\|dry.run\|dryRun" || return 1
363
-
364
- # 4. project install --dry-run
365
- log " --- dry-run: project install ---"
366
- run_cmd $KCLI project install k-cli --project-path "$SANDBOX" --dry-run
367
- output="$LOG_CMD_OUTPUT"
368
- assert_contains "install dry-run" "$output" "dry-run\|dry.run\|dryRun" || return 1
369
-
370
- return 0
371
- }
372
-
373
- # =========================================
374
- # Run All Tests
375
- # =========================================
376
- run_test 1 "project init+install" test_1_init_install
377
- run_test 2 "ping" test_2_ping
378
- run_test 3 "project status" test_3_project_status
379
- run_test 4 "specialist list" test_4_specialist_list
380
- run_test 5 "task create x3" test_5_task_create
381
- run_test 9 "task delete" test_9_task_delete
382
- run_test 10 "specialist run Amelia" test_10_specialist_run
383
- run_test 11 "--dry-run" test_11_dry_run
384
-
385
- # =========================================
386
- # Summary
387
- # =========================================
388
- echo ""
389
- echo "========================================"
390
- echo "Result: $PASS/$TOTAL passed"
391
- echo "Log: $LOG_FILE"
392
-
393
- log_separator
394
- log "SUMMARY: $PASS/$TOTAL passed"
395
- log "Finished: $(date '+%Y-%m-%d %H:%M:%S')"
396
-
397
- if [ $FAIL -gt 0 ]; then
398
- echo "WARNING: $FAIL test(s) failed"
399
- exit 1
400
- else
401
- echo "All tests passed"
402
- exit 0
403
- fi