Spor C / C2.2 (#3, akseptanse K3): fanger et fritt prosa-felt i onboarding og overflater det (kappet) ambient i hver sesjon. - lib/user-data.mjs: FREE_CONTEXT_FILE (utenfor ORG_FILES — valgfri, teller ikke mot fullføring), collapseProse() surfacer fri kontekst som ÉTT felt uansett markdown-struktur (ingen stille drop), capValue() ekstrahert (DRY). - session-start-context.mjs: leser free-context.md valgfritt (ingen count++). - onboarding-agent.md: ny Phase 6 (valgfri); onboard.md: prosess/Task/status. - 11 agenter: uniform 6. bullet (grep 11/11). - Tester FØR kode: user-data 25/25 (+9), test-hooks 11/11 (+1 K3-ambient). Gates: validate 239/0/0 · kb-update 200 · kb-eval 100 · kb-integrity 192/192 (220 baseline-warns) · discovery 13/13 · gitleaks 3 pre-eksisterende. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
166 lines
4.6 KiB
Bash
166 lines
4.6 KiB
Bash
#!/bin/bash
|
|
# test-hooks.sh — Unit tests for ms-ai-architect hook scripts
|
|
# Usage: bash tests/test-hooks.sh
|
|
|
|
set -euo pipefail
|
|
|
|
PLUGIN_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
|
SCRIPTS_DIR="$PLUGIN_ROOT/hooks/scripts"
|
|
PASS=0
|
|
FAIL=0
|
|
|
|
pass() { echo -e "\033[0;32m ✓ $1\033[0m"; PASS=$((PASS + 1)); }
|
|
fail() { echo -e "\033[0;31m ✗ $1\033[0m"; FAIL=$((FAIL + 1)); }
|
|
|
|
echo "=== Hook Script Tests ==="
|
|
echo ""
|
|
|
|
# NB: the pre-edit-secrets.mjs hook was removed in v1.7.0 (secrets scanning
|
|
# consolidated to the llm-security plugin — see CHANGELOG). Its tests were
|
|
# removed with it; secrets-scanning coverage now lives in llm-security.
|
|
|
|
# -------------------------------------------------------
|
|
# session-start-context.mjs
|
|
# -------------------------------------------------------
|
|
echo "--- session-start-context.mjs ---"
|
|
|
|
OUTPUT=$(CLAUDE_PLUGIN_ROOT="$PLUGIN_ROOT" node "$SCRIPTS_DIR/session-start-context.mjs" 2>/dev/null)
|
|
EXIT_CODE=$?
|
|
|
|
if [ $EXIT_CODE -eq 0 ]; then
|
|
pass "Runs without error (exit 0)"
|
|
else
|
|
fail "Expected exit 0, got $EXIT_CODE"
|
|
fi
|
|
|
|
if echo "$OUTPUT" | grep -q "Architect:"; then
|
|
pass "Output contains 'Architect:' prefix"
|
|
else
|
|
fail "Output missing 'Architect:' prefix"
|
|
fi
|
|
|
|
# C2.1: ambient org-context injection from the USER-owned org dir (HOME override).
|
|
# Proves K1 — the hook injects org CONTENT, not just a status nudge.
|
|
TMPHOME=$(mktemp -d)
|
|
mkdir -p "$TMPHOME/.claude/ms-ai-architect/org"
|
|
cat > "$TMPHOME/.claude/ms-ai-architect/org/organization-profile.md" <<'ORGEOF'
|
|
---
|
|
category: organization-profile
|
|
completed: true
|
|
---
|
|
|
|
# Virksomhetsprofil
|
|
|
|
## Sektor
|
|
Statlig
|
|
|
|
## Virksomhet
|
|
Testetaten
|
|
ORGEOF
|
|
|
|
# C2.2: optional free-prose file — read for the ambient summary, NOT counted
|
|
# toward onboarding completeness. Proves K3 (free-text visible in interaction).
|
|
cat > "$TMPHOME/.claude/ms-ai-architect/org/free-context.md" <<'FREEEOF'
|
|
---
|
|
category: free-context
|
|
completed: true
|
|
---
|
|
|
|
# Fri kontekst
|
|
|
|
## Fri kontekst
|
|
Vi migrerer fra on-prem til Azure i 2026.
|
|
FREEEOF
|
|
|
|
OUTPUT=$(CLAUDE_PLUGIN_ROOT="$PLUGIN_ROOT" HOME="$TMPHOME" node "$SCRIPTS_DIR/session-start-context.mjs" 2>/dev/null)
|
|
|
|
if echo "$OUTPUT" | grep -q "Virksomhetskontekst (auto-injisert"; then
|
|
pass "Injects ambient org-context block when user org/ has content (K1)"
|
|
else
|
|
fail "Missing ambient org-context block when user org/ has content"
|
|
fi
|
|
|
|
if echo "$OUTPUT" | grep -q "Sektor: Statlig"; then
|
|
pass "Ambient block reflects an org fact (Sektor: Statlig)"
|
|
else
|
|
fail "Ambient block missing org fact"
|
|
fi
|
|
|
|
if echo "$OUTPUT" | grep -q "Fri kontekst: Vi migrerer fra on-prem til Azure"; then
|
|
pass "Ambient block surfaces optional free-context (K3)"
|
|
else
|
|
fail "Ambient block missing free-context content (K3)"
|
|
fi
|
|
|
|
# Empty home (no user org, no plugin org) => onboarding nudge, NO ambient block.
|
|
TMPHOME2=$(mktemp -d)
|
|
OUTPUT=$(CLAUDE_PLUGIN_ROOT="$PLUGIN_ROOT" HOME="$TMPHOME2" node "$SCRIPTS_DIR/session-start-context.mjs" 2>/dev/null)
|
|
|
|
if echo "$OUTPUT" | grep -q "Ingen virksomhetstilpasning"; then
|
|
pass "No org content => onboarding nudge"
|
|
else
|
|
fail "Expected onboarding nudge when no org content"
|
|
fi
|
|
|
|
if echo "$OUTPUT" | grep -q "Virksomhetskontekst (auto-injisert"; then
|
|
fail "Should NOT inject ambient block when org is empty"
|
|
else
|
|
pass "No ambient block when org is empty"
|
|
fi
|
|
|
|
rm -rf "$TMPHOME" "$TMPHOME2"
|
|
|
|
echo ""
|
|
|
|
# -------------------------------------------------------
|
|
# stop-assessment-reminder.mjs
|
|
# -------------------------------------------------------
|
|
echo "--- stop-assessment-reminder.mjs ---"
|
|
|
|
# Test from a temp dir without .work/
|
|
TMPDIR_TEST=$(mktemp -d)
|
|
OUTPUT=$(cd "$TMPDIR_TEST" && node "$SCRIPTS_DIR/stop-assessment-reminder.mjs" 2>/dev/null)
|
|
EXIT_CODE=$?
|
|
|
|
if [ $EXIT_CODE -eq 0 ]; then
|
|
pass "No .work/: exit 0"
|
|
else
|
|
fail "No .work/: expected exit 0, got $EXIT_CODE"
|
|
fi
|
|
|
|
if [ "$OUTPUT" = "{}" ]; then
|
|
pass "No .work/: returns {}"
|
|
else
|
|
fail "No .work/: expected {}, got: $OUTPUT"
|
|
fi
|
|
|
|
# Test with a fresh .work/ session
|
|
mkdir -p "$TMPDIR_TEST/.work/test-session"
|
|
touch "$TMPDIR_TEST/.work/test-session/state.json"
|
|
OUTPUT=$(cd "$TMPDIR_TEST" && node "$SCRIPTS_DIR/stop-assessment-reminder.mjs" 2>/dev/null)
|
|
|
|
if echo "$OUTPUT" | grep -q "systemMessage"; then
|
|
pass "Fresh .work/: returns systemMessage"
|
|
else
|
|
fail "Fresh .work/: expected systemMessage in output"
|
|
fi
|
|
|
|
if echo "$OUTPUT" | grep -q "architect:adr"; then
|
|
pass "Fresh .work/: suggests /architect:adr"
|
|
else
|
|
fail "Fresh .work/: missing /architect:adr suggestion"
|
|
fi
|
|
|
|
rm -rf "$TMPDIR_TEST"
|
|
|
|
echo ""
|
|
|
|
# -------------------------------------------------------
|
|
# Summary
|
|
# -------------------------------------------------------
|
|
TOTAL=$((PASS + FAIL))
|
|
echo "=== Results: $PASS/$TOTAL passed, $FAIL failed ==="
|
|
|
|
if [ "$FAIL" -gt 0 ]; then
|
|
exit 1
|
|
fi
|