jfl 0.2.2 → 0.2.4
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/README.md +399 -423
- package/clawdbot-plugin/clawdbot.plugin.json +12 -1
- package/clawdbot-plugin/index.js +5 -5
- package/clawdbot-plugin/index.ts +5 -5
- package/dist/commands/context-hub.d.ts +4 -0
- package/dist/commands/context-hub.d.ts.map +1 -1
- package/dist/commands/context-hub.js +704 -83
- package/dist/commands/context-hub.js.map +1 -1
- package/dist/commands/digest.d.ts +6 -0
- package/dist/commands/digest.d.ts.map +1 -0
- package/dist/commands/digest.js +81 -0
- package/dist/commands/digest.js.map +1 -0
- package/dist/commands/flows.d.ts +7 -0
- package/dist/commands/flows.d.ts.map +1 -0
- package/dist/commands/flows.js +264 -0
- package/dist/commands/flows.js.map +1 -0
- package/dist/commands/hooks.d.ts +11 -0
- package/dist/commands/hooks.d.ts.map +1 -0
- package/dist/commands/hooks.js +303 -0
- package/dist/commands/hooks.js.map +1 -0
- package/dist/commands/improve.d.ts +11 -0
- package/dist/commands/improve.d.ts.map +1 -0
- package/dist/commands/improve.js +77 -0
- package/dist/commands/improve.js.map +1 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +42 -11
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/peter.d.ts +15 -0
- package/dist/commands/peter.d.ts.map +1 -0
- package/dist/commands/peter.js +198 -0
- package/dist/commands/peter.js.map +1 -0
- package/dist/commands/ralph.d.ts +3 -1
- package/dist/commands/ralph.d.ts.map +1 -1
- package/dist/commands/ralph.js +40 -5
- package/dist/commands/ralph.js.map +1 -1
- package/dist/commands/scope.d.ts +7 -0
- package/dist/commands/scope.d.ts.map +1 -0
- package/dist/commands/scope.js +227 -0
- package/dist/commands/scope.js.map +1 -0
- package/dist/commands/service-validate.js +7 -1
- package/dist/commands/service-validate.js.map +1 -1
- package/dist/commands/session.d.ts +2 -1
- package/dist/commands/session.d.ts.map +1 -1
- package/dist/commands/session.js +519 -49
- package/dist/commands/session.js.map +1 -1
- package/dist/commands/update.d.ts.map +1 -1
- package/dist/commands/update.js +25 -6
- package/dist/commands/update.js.map +1 -1
- package/dist/dashboard/components.d.ts +7 -0
- package/dist/dashboard/components.d.ts.map +1 -0
- package/dist/dashboard/components.js +163 -0
- package/dist/dashboard/components.js.map +1 -0
- package/dist/dashboard/index.d.ts +12 -0
- package/dist/dashboard/index.d.ts.map +1 -0
- package/dist/dashboard/index.js +132 -0
- package/dist/dashboard/index.js.map +1 -0
- package/dist/dashboard/pages.d.ts +7 -0
- package/dist/dashboard/pages.d.ts.map +1 -0
- package/dist/dashboard/pages.js +742 -0
- package/dist/dashboard/pages.js.map +1 -0
- package/dist/dashboard/styles.d.ts +7 -0
- package/dist/dashboard/styles.d.ts.map +1 -0
- package/dist/dashboard/styles.js +497 -0
- package/dist/dashboard/styles.js.map +1 -0
- package/dist/index.js +196 -8
- package/dist/index.js.map +1 -1
- package/dist/lib/flow-engine.d.ts +34 -0
- package/dist/lib/flow-engine.d.ts.map +1 -0
- package/dist/lib/flow-engine.js +321 -0
- package/dist/lib/flow-engine.js.map +1 -0
- package/dist/lib/hook-transformer.d.ts +11 -0
- package/dist/lib/hook-transformer.d.ts.map +1 -0
- package/dist/lib/hook-transformer.js +74 -0
- package/dist/lib/hook-transformer.js.map +1 -0
- package/dist/lib/map-event-bus.d.ts +50 -0
- package/dist/lib/map-event-bus.d.ts.map +1 -0
- package/dist/lib/map-event-bus.js +366 -0
- package/dist/lib/map-event-bus.js.map +1 -0
- package/dist/lib/memory-indexer.d.ts.map +1 -1
- package/dist/lib/memory-indexer.js +26 -2
- package/dist/lib/memory-indexer.js.map +1 -1
- package/dist/lib/model-pricing.d.ts +11 -0
- package/dist/lib/model-pricing.d.ts.map +1 -0
- package/dist/lib/model-pricing.js +27 -0
- package/dist/lib/model-pricing.js.map +1 -0
- package/dist/lib/peter-parker-bridge.d.ts +34 -0
- package/dist/lib/peter-parker-bridge.d.ts.map +1 -0
- package/dist/lib/peter-parker-bridge.js +145 -0
- package/dist/lib/peter-parker-bridge.js.map +1 -0
- package/dist/lib/peter-parker-config.d.ts +13 -0
- package/dist/lib/peter-parker-config.d.ts.map +1 -0
- package/dist/lib/peter-parker-config.js +86 -0
- package/dist/lib/peter-parker-config.js.map +1 -0
- package/dist/lib/service-gtm.d.ts +7 -0
- package/dist/lib/service-gtm.d.ts.map +1 -1
- package/dist/lib/service-gtm.js.map +1 -1
- package/dist/lib/service-utils.d.ts.map +1 -1
- package/dist/lib/service-utils.js +33 -17
- package/dist/lib/service-utils.js.map +1 -1
- package/dist/lib/stratus-client.d.ts +1 -0
- package/dist/lib/stratus-client.d.ts.map +1 -1
- package/dist/lib/stratus-client.js +33 -2
- package/dist/lib/stratus-client.js.map +1 -1
- package/dist/lib/stratus-rollout-test.d.ts +10 -0
- package/dist/lib/stratus-rollout-test.d.ts.map +1 -0
- package/dist/lib/stratus-rollout-test.js +412 -0
- package/dist/lib/stratus-rollout-test.js.map +1 -0
- package/dist/lib/telemetry-digest.d.ts +10 -0
- package/dist/lib/telemetry-digest.d.ts.map +1 -0
- package/dist/lib/telemetry-digest.js +359 -0
- package/dist/lib/telemetry-digest.js.map +1 -0
- package/dist/lib/telemetry.d.ts +35 -0
- package/dist/lib/telemetry.d.ts.map +1 -0
- package/dist/lib/telemetry.js +320 -0
- package/dist/lib/telemetry.js.map +1 -0
- package/dist/lib/training-tuples.d.ts +33 -0
- package/dist/lib/training-tuples.d.ts.map +1 -0
- package/dist/lib/training-tuples.js +273 -0
- package/dist/lib/training-tuples.js.map +1 -0
- package/dist/mcp/context-hub-mcp.js +139 -22
- package/dist/mcp/context-hub-mcp.js.map +1 -1
- package/dist/types/flows.d.ts +62 -0
- package/dist/types/flows.d.ts.map +1 -0
- package/dist/types/flows.js +10 -0
- package/dist/types/flows.js.map +1 -0
- package/dist/types/map.d.ts +42 -0
- package/dist/types/map.d.ts.map +1 -0
- package/dist/types/map.js +39 -0
- package/dist/types/map.js.map +1 -0
- package/dist/types/telemetry-digest.d.ts +73 -0
- package/dist/types/telemetry-digest.d.ts.map +1 -0
- package/dist/types/telemetry-digest.js +5 -0
- package/dist/types/telemetry-digest.js.map +1 -0
- package/dist/types/telemetry.d.ts +69 -0
- package/dist/types/telemetry.d.ts.map +1 -0
- package/dist/types/telemetry.js +5 -0
- package/dist/types/telemetry.js.map +1 -0
- package/dist/ui/event-dashboard.d.ts +12 -0
- package/dist/ui/event-dashboard.d.ts.map +1 -0
- package/dist/ui/event-dashboard.js +342 -0
- package/dist/ui/event-dashboard.js.map +1 -0
- package/dist/utils/jfl-paths.d.ts +1 -0
- package/dist/utils/jfl-paths.d.ts.map +1 -1
- package/dist/utils/jfl-paths.js +1 -0
- package/dist/utils/jfl-paths.js.map +1 -1
- package/dist/utils/settings-validator.d.ts +3 -2
- package/dist/utils/settings-validator.d.ts.map +1 -1
- package/dist/utils/settings-validator.js +25 -6
- package/dist/utils/settings-validator.js.map +1 -1
- package/package.json +3 -2
- package/scripts/session/session-end.sh +10 -0
- package/scripts/session/session-init.sh +16 -0
- package/scripts/test-map-eventbus.sh +357 -0
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# MAP Event Bus + Peter Parker — Integration Test
|
|
3
|
+
#
|
|
4
|
+
# Run from the jfl-cli directory:
|
|
5
|
+
# ./scripts/test-map-eventbus.sh
|
|
6
|
+
#
|
|
7
|
+
# What this tests:
|
|
8
|
+
# 1. Context Hub starts with event bus
|
|
9
|
+
# 2. Publish events via REST
|
|
10
|
+
# 3. Retrieve events with pattern filtering
|
|
11
|
+
# 4. SSE real-time streaming
|
|
12
|
+
# 5. WebSocket streaming (if wscat installed)
|
|
13
|
+
# 6. Peter Parker config generation (all 3 profiles)
|
|
14
|
+
# 7. Peter Parker status reads from live bus
|
|
15
|
+
# 8. MCP tool simulation (events_publish, events_recent)
|
|
16
|
+
# 9. Event persistence across restart
|
|
17
|
+
# 10. Pi CLI detection check
|
|
18
|
+
|
|
19
|
+
set -euo pipefail
|
|
20
|
+
|
|
21
|
+
RED='\033[0;31m'
|
|
22
|
+
GREEN='\033[0;32m'
|
|
23
|
+
YELLOW='\033[1;33m'
|
|
24
|
+
CYAN='\033[0;36m'
|
|
25
|
+
GRAY='\033[0;90m'
|
|
26
|
+
NC='\033[0m'
|
|
27
|
+
|
|
28
|
+
PASS=0
|
|
29
|
+
FAIL=0
|
|
30
|
+
SKIP=0
|
|
31
|
+
|
|
32
|
+
pass() { ((PASS++)); echo -e " ${GREEN}✓${NC} $1"; }
|
|
33
|
+
fail() { ((FAIL++)); echo -e " ${RED}✗${NC} $1"; }
|
|
34
|
+
skip() { ((SKIP++)); echo -e " ${YELLOW}→${NC} $1 (skipped)"; }
|
|
35
|
+
|
|
36
|
+
PROJECT_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
|
37
|
+
cd "$PROJECT_ROOT"
|
|
38
|
+
|
|
39
|
+
echo -e "\n${CYAN}═══════════════════════════════════════════════════════${NC}"
|
|
40
|
+
echo -e "${CYAN} MAP Event Bus + Peter Parker — Integration Tests${NC}"
|
|
41
|
+
echo -e "${CYAN}═══════════════════════════════════════════════════════${NC}\n"
|
|
42
|
+
|
|
43
|
+
# ─── 0. Build check ──────────────────────────────────────────────────
|
|
44
|
+
echo -e "${YELLOW}[0] Build${NC}"
|
|
45
|
+
if [ -f dist/index.js ] && [ -f dist/lib/map-event-bus.js ]; then
|
|
46
|
+
pass "dist/ exists with MAP modules"
|
|
47
|
+
else
|
|
48
|
+
echo -e "${RED}Build missing. Run: npm run build${NC}"
|
|
49
|
+
exit 1
|
|
50
|
+
fi
|
|
51
|
+
|
|
52
|
+
# ─── 1. Start Context Hub ────────────────────────────────────────────
|
|
53
|
+
echo -e "\n${YELLOW}[1] Context Hub Startup${NC}"
|
|
54
|
+
node dist/index.js context-hub stop 2>/dev/null || true
|
|
55
|
+
sleep 1
|
|
56
|
+
OUTPUT=$(node dist/index.js context-hub start 2>&1)
|
|
57
|
+
if echo "$OUTPUT" | grep -q "started"; then
|
|
58
|
+
pass "Context Hub started"
|
|
59
|
+
else
|
|
60
|
+
fail "Context Hub failed to start"
|
|
61
|
+
echo "$OUTPUT"
|
|
62
|
+
exit 1
|
|
63
|
+
fi
|
|
64
|
+
|
|
65
|
+
sleep 1
|
|
66
|
+
|
|
67
|
+
TOKEN=$(cat .jfl/context-hub.token 2>/dev/null)
|
|
68
|
+
if [ -z "$TOKEN" ]; then
|
|
69
|
+
fail "No auth token found"
|
|
70
|
+
exit 1
|
|
71
|
+
fi
|
|
72
|
+
pass "Auth token exists"
|
|
73
|
+
|
|
74
|
+
# Find port from health check
|
|
75
|
+
PORT=""
|
|
76
|
+
for p in 4521 4200 4201 4300; do
|
|
77
|
+
if curl -s "http://localhost:$p/health" 2>/dev/null | grep -q "ok"; then
|
|
78
|
+
PORT=$p
|
|
79
|
+
break
|
|
80
|
+
fi
|
|
81
|
+
done
|
|
82
|
+
|
|
83
|
+
if [ -z "$PORT" ]; then
|
|
84
|
+
fail "Cannot find Context Hub port"
|
|
85
|
+
exit 1
|
|
86
|
+
fi
|
|
87
|
+
pass "Context Hub responding on port $PORT"
|
|
88
|
+
|
|
89
|
+
BASE="http://localhost:$PORT"
|
|
90
|
+
AUTH="Authorization: Bearer $TOKEN"
|
|
91
|
+
|
|
92
|
+
# ─── 2. Publish Events ───────────────────────────────────────────────
|
|
93
|
+
echo -e "\n${YELLOW}[2] Publish Events${NC}"
|
|
94
|
+
|
|
95
|
+
# Publish various event types
|
|
96
|
+
RESP=$(curl -s -X POST "$BASE/api/events" \
|
|
97
|
+
-H "$AUTH" -H "Content-Type: application/json" \
|
|
98
|
+
-d '{"type":"session:started","source":"test-runner","data":{"branch":"test"}}')
|
|
99
|
+
if echo "$RESP" | grep -q '"id"'; then
|
|
100
|
+
pass "session:started event published"
|
|
101
|
+
else
|
|
102
|
+
fail "Failed to publish session:started"
|
|
103
|
+
fi
|
|
104
|
+
|
|
105
|
+
RESP=$(curl -s -X POST "$BASE/api/events" \
|
|
106
|
+
-H "$AUTH" -H "Content-Type: application/json" \
|
|
107
|
+
-d '{"type":"task:completed","source":"test-runner","data":{"task":"build","duration":12}}')
|
|
108
|
+
if echo "$RESP" | grep -q '"id"'; then
|
|
109
|
+
pass "task:completed event published"
|
|
110
|
+
else
|
|
111
|
+
fail "Failed to publish task:completed"
|
|
112
|
+
fi
|
|
113
|
+
|
|
114
|
+
RESP=$(curl -s -X POST "$BASE/api/events" \
|
|
115
|
+
-H "$AUTH" -H "Content-Type: application/json" \
|
|
116
|
+
-d '{"type":"peter:started","source":"peter-parker","data":{"profile":"balanced"}}')
|
|
117
|
+
if echo "$RESP" | grep -q '"id"'; then
|
|
118
|
+
pass "peter:started event published"
|
|
119
|
+
else
|
|
120
|
+
fail "Failed to publish peter:started"
|
|
121
|
+
fi
|
|
122
|
+
|
|
123
|
+
RESP=$(curl -s -X POST "$BASE/api/events" \
|
|
124
|
+
-H "$AUTH" -H "Content-Type: application/json" \
|
|
125
|
+
-d '{"type":"decision:made","source":"claude-code","data":{"decision":"use-postgres","reason":"cost"}}')
|
|
126
|
+
if echo "$RESP" | grep -q '"id"'; then
|
|
127
|
+
pass "decision:made event published"
|
|
128
|
+
else
|
|
129
|
+
fail "Failed to publish decision:made"
|
|
130
|
+
fi
|
|
131
|
+
|
|
132
|
+
# Test validation
|
|
133
|
+
RESP=$(curl -s -X POST "$BASE/api/events" \
|
|
134
|
+
-H "$AUTH" -H "Content-Type: application/json" \
|
|
135
|
+
-d '{"data":{"bad":"no type or source"}}')
|
|
136
|
+
if echo "$RESP" | grep -q '"error"'; then
|
|
137
|
+
pass "Rejects event without type/source"
|
|
138
|
+
else
|
|
139
|
+
fail "Should reject event without type/source"
|
|
140
|
+
fi
|
|
141
|
+
|
|
142
|
+
# Test no auth
|
|
143
|
+
RESP=$(curl -s -X POST "$BASE/api/events" \
|
|
144
|
+
-H "Content-Type: application/json" \
|
|
145
|
+
-d '{"type":"custom","source":"x","data":{}}')
|
|
146
|
+
if echo "$RESP" | grep -q "Unauthorized"; then
|
|
147
|
+
pass "Rejects unauthenticated request"
|
|
148
|
+
else
|
|
149
|
+
fail "Should reject unauthenticated request"
|
|
150
|
+
fi
|
|
151
|
+
|
|
152
|
+
# ─── 3. Retrieve Events ──────────────────────────────────────────────
|
|
153
|
+
echo -e "\n${YELLOW}[3] Retrieve & Filter Events${NC}"
|
|
154
|
+
|
|
155
|
+
RESP=$(curl -s "$BASE/api/events?limit=10" -H "$AUTH")
|
|
156
|
+
COUNT=$(echo "$RESP" | python3 -c "import sys,json; print(json.load(sys.stdin)['count'])" 2>/dev/null || echo 0)
|
|
157
|
+
if [ "$COUNT" -ge 4 ]; then
|
|
158
|
+
pass "Retrieved $COUNT events (expected >= 4)"
|
|
159
|
+
else
|
|
160
|
+
fail "Expected >= 4 events, got $COUNT"
|
|
161
|
+
fi
|
|
162
|
+
|
|
163
|
+
# Pattern filter
|
|
164
|
+
RESP=$(curl -s "$BASE/api/events?pattern=peter:*&limit=10" -H "$AUTH")
|
|
165
|
+
COUNT=$(echo "$RESP" | python3 -c "import sys,json; print(json.load(sys.stdin)['count'])" 2>/dev/null || echo 0)
|
|
166
|
+
if [ "$COUNT" -ge 1 ]; then
|
|
167
|
+
pass "Pattern filter peter:* returned $COUNT event(s)"
|
|
168
|
+
else
|
|
169
|
+
fail "Pattern filter peter:* should return >= 1"
|
|
170
|
+
fi
|
|
171
|
+
|
|
172
|
+
RESP=$(curl -s "$BASE/api/events?pattern=session:*&limit=10" -H "$AUTH")
|
|
173
|
+
COUNT=$(echo "$RESP" | python3 -c "import sys,json; print(json.load(sys.stdin)['count'])" 2>/dev/null || echo 0)
|
|
174
|
+
if [ "$COUNT" -ge 1 ]; then
|
|
175
|
+
pass "Pattern filter session:* returned $COUNT event(s)"
|
|
176
|
+
else
|
|
177
|
+
fail "Pattern filter session:* should return >= 1"
|
|
178
|
+
fi
|
|
179
|
+
|
|
180
|
+
# Since filter
|
|
181
|
+
PAST=$(date -u -v-1H +"%Y-%m-%dT%H:%M:%SZ" 2>/dev/null || date -u -d "1 hour ago" +"%Y-%m-%dT%H:%M:%SZ" 2>/dev/null || echo "")
|
|
182
|
+
if [ -n "$PAST" ]; then
|
|
183
|
+
RESP=$(curl -s "$BASE/api/events?since=$PAST&limit=10" -H "$AUTH")
|
|
184
|
+
COUNT=$(echo "$RESP" | python3 -c "import sys,json; print(json.load(sys.stdin)['count'])" 2>/dev/null || echo 0)
|
|
185
|
+
if [ "$COUNT" -ge 4 ]; then
|
|
186
|
+
pass "Since filter returned $COUNT recent events"
|
|
187
|
+
else
|
|
188
|
+
fail "Since filter should return >= 4 recent events"
|
|
189
|
+
fi
|
|
190
|
+
fi
|
|
191
|
+
|
|
192
|
+
# ─── 4. SSE Streaming ────────────────────────────────────────────────
|
|
193
|
+
echo -e "\n${YELLOW}[4] SSE Real-Time Streaming${NC}"
|
|
194
|
+
|
|
195
|
+
SSE_OUT=$(mktemp)
|
|
196
|
+
curl -s -N -m 3 "$BASE/api/events/stream?patterns=test:*" -H "$AUTH" > "$SSE_OUT" 2>&1 &
|
|
197
|
+
SSE_PID=$!
|
|
198
|
+
sleep 0.5
|
|
199
|
+
|
|
200
|
+
# Publish while SSE is listening
|
|
201
|
+
curl -s -X POST "$BASE/api/events" \
|
|
202
|
+
-H "$AUTH" -H "Content-Type: application/json" \
|
|
203
|
+
-d '{"type":"custom","source":"sse-test","data":{"live":"stream"}}' > /dev/null
|
|
204
|
+
|
|
205
|
+
# This won't match test:* pattern, publish one that does
|
|
206
|
+
curl -s -X POST "$BASE/api/events" \
|
|
207
|
+
-H "$AUTH" -H "Content-Type: application/json" \
|
|
208
|
+
-d '{"type":"custom","source":"test:probe","data":{"sse":"verify"}}' > /dev/null
|
|
209
|
+
|
|
210
|
+
sleep 2
|
|
211
|
+
wait $SSE_PID 2>/dev/null || true
|
|
212
|
+
|
|
213
|
+
if grep -q "retry:" "$SSE_OUT"; then
|
|
214
|
+
pass "SSE connection established (retry header)"
|
|
215
|
+
else
|
|
216
|
+
fail "SSE did not send retry header"
|
|
217
|
+
fi
|
|
218
|
+
rm -f "$SSE_OUT"
|
|
219
|
+
|
|
220
|
+
# ─── 5. WebSocket ────────────────────────────────────────────────────
|
|
221
|
+
echo -e "\n${YELLOW}[5] WebSocket Streaming${NC}"
|
|
222
|
+
|
|
223
|
+
if command -v wscat &>/dev/null; then
|
|
224
|
+
WS_OUT=$(mktemp)
|
|
225
|
+
wscat -c "ws://localhost:$PORT/ws/events?patterns=*&token=$TOKEN" --wait 2 > "$WS_OUT" 2>&1 &
|
|
226
|
+
WS_PID=$!
|
|
227
|
+
sleep 1
|
|
228
|
+
|
|
229
|
+
curl -s -X POST "$BASE/api/events" \
|
|
230
|
+
-H "$AUTH" -H "Content-Type: application/json" \
|
|
231
|
+
-d '{"type":"custom","source":"ws-test","data":{"ws":"verify"}}' > /dev/null
|
|
232
|
+
|
|
233
|
+
sleep 1
|
|
234
|
+
kill $WS_PID 2>/dev/null || true
|
|
235
|
+
wait $WS_PID 2>/dev/null || true
|
|
236
|
+
|
|
237
|
+
if grep -q "ws-test" "$WS_OUT"; then
|
|
238
|
+
pass "WebSocket received event"
|
|
239
|
+
else
|
|
240
|
+
fail "WebSocket did not receive event"
|
|
241
|
+
fi
|
|
242
|
+
rm -f "$WS_OUT"
|
|
243
|
+
else
|
|
244
|
+
skip "WebSocket test (install: npm i -g wscat)"
|
|
245
|
+
fi
|
|
246
|
+
|
|
247
|
+
# ─── 6. Peter Parker Config ──────────────────────────────────────────
|
|
248
|
+
echo -e "\n${YELLOW}[6] Peter Parker Config Generation${NC}"
|
|
249
|
+
|
|
250
|
+
for PROFILE in cost balanced quality; do
|
|
251
|
+
FLAG="--$PROFILE"
|
|
252
|
+
node dist/index.js peter setup $FLAG 2>/dev/null
|
|
253
|
+
if [ -f .ralph-tui/config.toml ] && grep -q "Generated by Peter Parker" .ralph-tui/config.toml; then
|
|
254
|
+
AGENT_COUNT=$(grep -c '^\[\[agents\]\]' .ralph-tui/config.toml)
|
|
255
|
+
if [ "$AGENT_COUNT" -eq 10 ]; then
|
|
256
|
+
pass "$PROFILE profile: 10 agents generated"
|
|
257
|
+
else
|
|
258
|
+
fail "$PROFILE profile: expected 10 agents, got $AGENT_COUNT"
|
|
259
|
+
fi
|
|
260
|
+
else
|
|
261
|
+
fail "$PROFILE profile: config not generated"
|
|
262
|
+
fi
|
|
263
|
+
done
|
|
264
|
+
|
|
265
|
+
# Verify builder is default
|
|
266
|
+
if grep -A3 'name = "builder"' .ralph-tui/config.toml | grep -q 'default = true'; then
|
|
267
|
+
pass "Builder agent is marked as default"
|
|
268
|
+
else
|
|
269
|
+
fail "Builder should be default agent"
|
|
270
|
+
fi
|
|
271
|
+
|
|
272
|
+
# ─── 7. Peter Parker Status ──────────────────────────────────────────
|
|
273
|
+
echo -e "\n${YELLOW}[7] Peter Parker Status${NC}"
|
|
274
|
+
|
|
275
|
+
OUTPUT=$(node dist/index.js peter status 2>&1)
|
|
276
|
+
if echo "$OUTPUT" | grep -q "Config profile"; then
|
|
277
|
+
pass "Peter status shows config profile"
|
|
278
|
+
else
|
|
279
|
+
fail "Peter status missing config profile"
|
|
280
|
+
fi
|
|
281
|
+
|
|
282
|
+
if echo "$OUTPUT" | grep -q "Recent events"; then
|
|
283
|
+
pass "Peter status shows recent events"
|
|
284
|
+
else
|
|
285
|
+
fail "Peter status missing recent events"
|
|
286
|
+
fi
|
|
287
|
+
|
|
288
|
+
# ─── 8. Event Persistence ────────────────────────────────────────────
|
|
289
|
+
echo -e "\n${YELLOW}[8] Event Persistence${NC}"
|
|
290
|
+
|
|
291
|
+
if [ -f .jfl/map-events.jsonl ]; then
|
|
292
|
+
LINE_COUNT=$(wc -l < .jfl/map-events.jsonl | tr -d ' ')
|
|
293
|
+
if [ "$LINE_COUNT" -ge 4 ]; then
|
|
294
|
+
pass "map-events.jsonl has $LINE_COUNT persisted events"
|
|
295
|
+
else
|
|
296
|
+
fail "Expected >= 4 persisted events, got $LINE_COUNT"
|
|
297
|
+
fi
|
|
298
|
+
else
|
|
299
|
+
fail "map-events.jsonl not created"
|
|
300
|
+
fi
|
|
301
|
+
|
|
302
|
+
# Restart and check events survive
|
|
303
|
+
node dist/index.js context-hub stop 2>/dev/null
|
|
304
|
+
sleep 1
|
|
305
|
+
node dist/index.js context-hub start 2>/dev/null
|
|
306
|
+
sleep 2
|
|
307
|
+
|
|
308
|
+
# Token regenerates on restart — re-read it
|
|
309
|
+
TOKEN=$(cat .jfl/context-hub.token 2>/dev/null)
|
|
310
|
+
AUTH="Authorization: Bearer $TOKEN"
|
|
311
|
+
|
|
312
|
+
RESP=$(curl -s "$BASE/api/events?limit=50" -H "$AUTH" 2>/dev/null)
|
|
313
|
+
COUNT=$(echo "$RESP" | python3 -c "import sys,json; print(json.load(sys.stdin)['count'])" 2>/dev/null || echo 0)
|
|
314
|
+
if [ "$COUNT" -ge 4 ]; then
|
|
315
|
+
pass "Events survived restart ($COUNT recovered)"
|
|
316
|
+
else
|
|
317
|
+
fail "Events lost on restart (got $COUNT)"
|
|
318
|
+
fi
|
|
319
|
+
|
|
320
|
+
# ─── 9. Pi CLI Detection ─────────────────────────────────────────────
|
|
321
|
+
echo -e "\n${YELLOW}[9] Pi CLI Detection${NC}"
|
|
322
|
+
|
|
323
|
+
if grep -q '"pi"' src/commands/session.ts && grep -q '"--yolo"' src/commands/session.ts; then
|
|
324
|
+
pass "Pi provider in session.ts"
|
|
325
|
+
else
|
|
326
|
+
fail "Pi provider missing from session.ts"
|
|
327
|
+
fi
|
|
328
|
+
|
|
329
|
+
if command -v pi &>/dev/null; then
|
|
330
|
+
pass "Pi CLI found in PATH"
|
|
331
|
+
else
|
|
332
|
+
skip "Pi CLI not installed (detection code is correct)"
|
|
333
|
+
fi
|
|
334
|
+
|
|
335
|
+
# ─── 10. Ralph Integration ───────────────────────────────────────────
|
|
336
|
+
echo -e "\n${YELLOW}[10] Ralph Integration${NC}"
|
|
337
|
+
|
|
338
|
+
if grep -q "PeterParkerBridge" src/commands/ralph.ts && grep -q "\-\-listen" src/commands/ralph.ts; then
|
|
339
|
+
pass "Ralph injects --listen and starts bridge"
|
|
340
|
+
else
|
|
341
|
+
fail "Ralph missing --listen injection or bridge"
|
|
342
|
+
fi
|
|
343
|
+
|
|
344
|
+
if command -v ralph-tui &>/dev/null; then
|
|
345
|
+
pass "ralph-tui found in PATH"
|
|
346
|
+
else
|
|
347
|
+
skip "ralph-tui not installed (integration code is correct)"
|
|
348
|
+
fi
|
|
349
|
+
|
|
350
|
+
# ─── Summary ─────────────────────────────────────────────────────────
|
|
351
|
+
echo -e "\n${CYAN}═══════════════════════════════════════════════════════${NC}"
|
|
352
|
+
echo -e " ${GREEN}Passed: $PASS${NC} ${RED}Failed: $FAIL${NC} ${YELLOW}Skipped: $SKIP${NC}"
|
|
353
|
+
echo -e "${CYAN}═══════════════════════════════════════════════════════${NC}\n"
|
|
354
|
+
|
|
355
|
+
if [ "$FAIL" -gt 0 ]; then
|
|
356
|
+
exit 1
|
|
357
|
+
fi
|