@rubytech/create-maxy 1.0.692 → 1.0.693
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/package.json +1 -1
- package/payload/platform/plugins/admin/mcp/dist/index.js +50 -7
- package/payload/platform/plugins/admin/mcp/dist/index.js.map +1 -1
- package/payload/platform/scripts/logs-read.sh +63 -9
- package/payload/platform/scripts/logs-read.test.sh +212 -0
- package/payload/server/chunk-Q6NDXCM6.js +11448 -0
- package/payload/server/maxy-edge.js +1 -1
- package/payload/server/server.js +1 -1
|
@@ -6,6 +6,11 @@
|
|
|
6
6
|
# continuous, conversation-scoped timeline from first [spawn] to final
|
|
7
7
|
# [process-exit] without needing to filter.
|
|
8
8
|
#
|
|
9
|
+
# Task 671: first-turn sessions (pre 1→2-user-turn flush per Task 650) land
|
|
10
|
+
# at {prefix}preflush-{sessionKey:0:12}.log. The per-conversation mode
|
|
11
|
+
# resolves either shape from the same identifier — full first, preflush as
|
|
12
|
+
# fallback.
|
|
13
|
+
#
|
|
9
14
|
# Modes:
|
|
10
15
|
# logs-read.sh <conversationId> [type] Read {prefix}-{convId}.log
|
|
11
16
|
# logs-read.sh --tail [type] [lines] Tail most recent file of type
|
|
@@ -135,7 +140,25 @@ validate_type() {
|
|
|
135
140
|
esac
|
|
136
141
|
}
|
|
137
142
|
|
|
138
|
-
# --- Per-conversation mode: read {prefix}
|
|
143
|
+
# --- Per-conversation mode: read {prefix}{convId}.log, with preflush fallback ---
|
|
144
|
+
#
|
|
145
|
+
# Task 671: writer (Task 650) emits logs under two filename shapes —
|
|
146
|
+
# FULL: {prefix}{conversationId}.log (post 1→2-user-turn flush)
|
|
147
|
+
# PREFLUSH: {prefix}preflush-{id:0:12}.log (pre-flush, first turn; the
|
|
148
|
+
# slice is of the sessionKey)
|
|
149
|
+
# This mode tries FULL across every account dir first; if zero FULL hits,
|
|
150
|
+
# falls back to PREFLUSH across every dir. If BOTH exist in the same dir,
|
|
151
|
+
# FULL wins and the preflush sibling is logged to server.log as stale
|
|
152
|
+
# (promotion-race housekeeping signal).
|
|
153
|
+
#
|
|
154
|
+
# Identity note: for the abrupt-exit case this fallback exists to solve,
|
|
155
|
+
# the operator passes the sessionKey (no conversationId was ever assigned).
|
|
156
|
+
# For post-flush retrievals the operator passes the conversationId and the
|
|
157
|
+
# FULL file is expected to exist.
|
|
158
|
+
#
|
|
159
|
+
# MIRROR: keep the two-shape contract in sync with:
|
|
160
|
+
# - platform/ui/app/lib/logs-read-resolve.ts (canonical TS helper + tests)
|
|
161
|
+
# - platform/plugins/admin/mcp/src/index.ts (conversationId branch)
|
|
139
162
|
per_conversation_mode() {
|
|
140
163
|
local conv_id="$1"
|
|
141
164
|
local filter_type="${2:-system}"
|
|
@@ -163,29 +186,60 @@ per_conversation_mode() {
|
|
|
163
186
|
exit 2
|
|
164
187
|
fi
|
|
165
188
|
|
|
189
|
+
# Build the two filenames the two-shape contract expects.
|
|
190
|
+
local full_name="${prefix}${conv_id}.log"
|
|
191
|
+
local preflush_name="${prefix}preflush-${conv_id:0:12}.log"
|
|
192
|
+
|
|
166
193
|
local found=0
|
|
167
194
|
local searched=0
|
|
168
|
-
local
|
|
195
|
+
local matched_shape=""
|
|
196
|
+
|
|
197
|
+
# Pass 1: FULL across every log dir. Records stale preflush siblings.
|
|
169
198
|
for log_dir in "${ACCOUNT_LOG_DIRS[@]}"; do
|
|
170
|
-
local
|
|
199
|
+
local full_path="$log_dir/$full_name"
|
|
171
200
|
searched=$((searched + 1))
|
|
172
|
-
if [[ ! -f "$
|
|
173
|
-
rejected=$((rejected + 1))
|
|
201
|
+
if [[ ! -f "$full_path" ]]; then
|
|
174
202
|
continue
|
|
175
203
|
fi
|
|
176
204
|
[[ $found -gt 0 ]] && echo ""
|
|
177
|
-
echo "## $(basename "$
|
|
178
|
-
cat "$
|
|
205
|
+
echo "## $(basename "$full_path") ($filter_type)$(account_suffix "$log_dir")"
|
|
206
|
+
cat "$full_path"
|
|
179
207
|
found=$((found + 1))
|
|
208
|
+
matched_shape="full"
|
|
209
|
+
# Stale-preflush detection: if the post-flush rename left the preflush
|
|
210
|
+
# sibling on disk, emit a housekeeping signal to server.log. Best-effort
|
|
211
|
+
# — retrieval must not fail if server.log is unwritable.
|
|
212
|
+
local stale_path="$log_dir/$preflush_name"
|
|
213
|
+
if [[ -f "$stale_path" ]]; then
|
|
214
|
+
local stale_ts
|
|
215
|
+
stale_ts="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
|
216
|
+
echo "${stale_ts} [logs-read] stale-preflush-detected path=${stale_path}" >> "$SERVER_LOG" 2>/dev/null || true
|
|
217
|
+
fi
|
|
180
218
|
done
|
|
181
219
|
|
|
220
|
+
# Pass 2: PREFLUSH across every dir. Only runs if zero FULL hits.
|
|
221
|
+
if [[ $found -eq 0 ]]; then
|
|
222
|
+
for log_dir in "${ACCOUNT_LOG_DIRS[@]}"; do
|
|
223
|
+
local preflush_path="$log_dir/$preflush_name"
|
|
224
|
+
searched=$((searched + 1))
|
|
225
|
+
if [[ ! -f "$preflush_path" ]]; then
|
|
226
|
+
continue
|
|
227
|
+
fi
|
|
228
|
+
[[ $found -gt 0 ]] && echo ""
|
|
229
|
+
echo "## $(basename "$preflush_path") ($filter_type)$(account_suffix "$log_dir")"
|
|
230
|
+
cat "$preflush_path"
|
|
231
|
+
found=$((found + 1))
|
|
232
|
+
matched_shape="preflush"
|
|
233
|
+
done
|
|
234
|
+
fi
|
|
235
|
+
|
|
182
236
|
# Trailer: empty output never leaves the reader guessing why.
|
|
183
237
|
if [[ $found -eq 0 ]]; then
|
|
184
|
-
echo "-- trailer: conversationId=$conv_id type=$filter_type searched=$searched found=0
|
|
238
|
+
echo "-- trailer: conversationId=$conv_id type=$filter_type searched=$searched found=0 tried=[${full_name}, ${preflush_name}] reason=file-not-found-in-either-shape" >&2
|
|
185
239
|
exit 1
|
|
186
240
|
fi
|
|
187
241
|
echo "" >&2
|
|
188
|
-
echo "-- trailer: conversationId=$conv_id type=$filter_type searched=$searched matched=$found
|
|
242
|
+
echo "-- trailer: conversationId=$conv_id type=$filter_type searched=$searched matched=$found matched_shape=$matched_shape" >&2
|
|
189
243
|
exit 0
|
|
190
244
|
}
|
|
191
245
|
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Task 671 — bash harness for logs-read.sh two-shape preflush resolution.
|
|
3
|
+
#
|
|
4
|
+
# Covers the four cases from the task brief:
|
|
5
|
+
# 1. Full-UUID file present → matched_shape=full
|
|
6
|
+
# 2. Preflush file present, full absent → matched_shape=preflush
|
|
7
|
+
# 3. Neither present → trailer lists both filenames, exit 1
|
|
8
|
+
# 4. Both present (promotion race) → full wins + stale-preflush signal to server.log
|
|
9
|
+
#
|
|
10
|
+
# MIRROR: see platform/ui/app/lib/logs-read-resolve.ts for the canonical
|
|
11
|
+
# two-shape contract and its TS unit tests.
|
|
12
|
+
set -euo pipefail
|
|
13
|
+
|
|
14
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
15
|
+
LOGS_READ="$SCRIPT_DIR/logs-read.sh"
|
|
16
|
+
if [[ ! -x "$LOGS_READ" ]]; then
|
|
17
|
+
echo "FATAL: $LOGS_READ not executable" >&2
|
|
18
|
+
exit 1
|
|
19
|
+
fi
|
|
20
|
+
|
|
21
|
+
CONV_ID="8c264cfb-441f-48bf-9811-9fa3ad3b51dc"
|
|
22
|
+
PREFLUSH_SLICE="8c264cfb-441"
|
|
23
|
+
FULL_NAME="claude-agent-stream-${CONV_ID}.log"
|
|
24
|
+
PREFLUSH_NAME="claude-agent-stream-preflush-${PREFLUSH_SLICE}.log"
|
|
25
|
+
|
|
26
|
+
PASS=0
|
|
27
|
+
FAIL=0
|
|
28
|
+
|
|
29
|
+
# logs-read.sh resolves PLATFORM_ROOT from the script location, and uses
|
|
30
|
+
# INSTALL_DIR = $PLATFORM_ROOT/.. and ACCOUNTS_DIR = $INSTALL_DIR/data/accounts.
|
|
31
|
+
# The test creates a fake install tree with the real script symlinked in.
|
|
32
|
+
setup_install_tree() {
|
|
33
|
+
local root="$1"
|
|
34
|
+
mkdir -p "$root/platform/scripts"
|
|
35
|
+
mkdir -p "$root/data/accounts/acct-test/logs"
|
|
36
|
+
mkdir -p "$HOME/.$(basename "$root")/logs"
|
|
37
|
+
# Symlink the script under test into the fake tree so PLATFORM_ROOT resolves
|
|
38
|
+
# to $root/platform and the account logs are discovered.
|
|
39
|
+
ln -sf "$LOGS_READ" "$root/platform/scripts/logs-read.sh"
|
|
40
|
+
echo "$root/platform/scripts/logs-read.sh"
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
cleanup_install_tree() {
|
|
44
|
+
local root="$1"
|
|
45
|
+
rm -rf "$root"
|
|
46
|
+
rm -rf "$HOME/.$(basename "$root")"
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
# Each case uses its own ephemeral install tree. Install-tree basename is
|
|
50
|
+
# unique so configDir (~/.{installDir}) does not collide.
|
|
51
|
+
run_case() {
|
|
52
|
+
local name="$1"
|
|
53
|
+
shift
|
|
54
|
+
echo ""
|
|
55
|
+
echo "=== CASE: $name ==="
|
|
56
|
+
if "$@"; then
|
|
57
|
+
PASS=$((PASS + 1))
|
|
58
|
+
echo "PASS: $name"
|
|
59
|
+
else
|
|
60
|
+
FAIL=$((FAIL + 1))
|
|
61
|
+
echo "FAIL: $name"
|
|
62
|
+
fi
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
# --- Case 1: full only ---
|
|
66
|
+
case_full_only() {
|
|
67
|
+
local root="/tmp/maxy-logs-read-test-1-$$"
|
|
68
|
+
local script
|
|
69
|
+
script=$(setup_install_tree "$root")
|
|
70
|
+
local logdir="$root/data/accounts/acct-test/logs"
|
|
71
|
+
echo "full-content-sentinel" > "$logdir/$FULL_NAME"
|
|
72
|
+
|
|
73
|
+
local stdout stderr rc
|
|
74
|
+
stdout=$("$script" "$CONV_ID" system 2>/tmp/maxy-logs-read-stderr-1-$$) || rc=$?
|
|
75
|
+
rc=${rc:-0}
|
|
76
|
+
stderr=$(cat /tmp/maxy-logs-read-stderr-1-$$)
|
|
77
|
+
rm -f /tmp/maxy-logs-read-stderr-1-$$
|
|
78
|
+
|
|
79
|
+
cleanup_install_tree "$root"
|
|
80
|
+
|
|
81
|
+
if [[ $rc -ne 0 ]]; then
|
|
82
|
+
echo " expected exit 0, got $rc"
|
|
83
|
+
return 1
|
|
84
|
+
fi
|
|
85
|
+
if [[ "$stdout" != *"full-content-sentinel"* ]]; then
|
|
86
|
+
echo " stdout missing sentinel"
|
|
87
|
+
return 1
|
|
88
|
+
fi
|
|
89
|
+
if [[ "$stderr" != *"matched_shape=full"* ]]; then
|
|
90
|
+
echo " stderr missing matched_shape=full: $stderr"
|
|
91
|
+
return 1
|
|
92
|
+
fi
|
|
93
|
+
return 0
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
# --- Case 2: preflush only ---
|
|
97
|
+
case_preflush_only() {
|
|
98
|
+
local root="/tmp/maxy-logs-read-test-2-$$"
|
|
99
|
+
local script
|
|
100
|
+
script=$(setup_install_tree "$root")
|
|
101
|
+
local logdir="$root/data/accounts/acct-test/logs"
|
|
102
|
+
echo "preflush-content-sentinel" > "$logdir/$PREFLUSH_NAME"
|
|
103
|
+
|
|
104
|
+
local stdout stderr rc
|
|
105
|
+
stdout=$("$script" "$CONV_ID" system 2>/tmp/maxy-logs-read-stderr-2-$$) || rc=$?
|
|
106
|
+
rc=${rc:-0}
|
|
107
|
+
stderr=$(cat /tmp/maxy-logs-read-stderr-2-$$)
|
|
108
|
+
rm -f /tmp/maxy-logs-read-stderr-2-$$
|
|
109
|
+
|
|
110
|
+
cleanup_install_tree "$root"
|
|
111
|
+
|
|
112
|
+
if [[ $rc -ne 0 ]]; then
|
|
113
|
+
echo " expected exit 0, got $rc"
|
|
114
|
+
return 1
|
|
115
|
+
fi
|
|
116
|
+
if [[ "$stdout" != *"preflush-content-sentinel"* ]]; then
|
|
117
|
+
echo " stdout missing sentinel"
|
|
118
|
+
return 1
|
|
119
|
+
fi
|
|
120
|
+
if [[ "$stderr" != *"matched_shape=preflush"* ]]; then
|
|
121
|
+
echo " stderr missing matched_shape=preflush: $stderr"
|
|
122
|
+
return 1
|
|
123
|
+
fi
|
|
124
|
+
return 0
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
# --- Case 3: neither present → miss trailer ---
|
|
128
|
+
case_neither() {
|
|
129
|
+
local root="/tmp/maxy-logs-read-test-3-$$"
|
|
130
|
+
local script
|
|
131
|
+
script=$(setup_install_tree "$root")
|
|
132
|
+
|
|
133
|
+
local stdout stderr rc=0
|
|
134
|
+
stdout=$("$script" "$CONV_ID" system 2>/tmp/maxy-logs-read-stderr-3-$$) || rc=$?
|
|
135
|
+
stderr=$(cat /tmp/maxy-logs-read-stderr-3-$$)
|
|
136
|
+
rm -f /tmp/maxy-logs-read-stderr-3-$$
|
|
137
|
+
|
|
138
|
+
cleanup_install_tree "$root"
|
|
139
|
+
|
|
140
|
+
if [[ $rc -ne 1 ]]; then
|
|
141
|
+
echo " expected exit 1, got $rc"
|
|
142
|
+
return 1
|
|
143
|
+
fi
|
|
144
|
+
if [[ "$stderr" != *"tried=[${FULL_NAME}, ${PREFLUSH_NAME}]"* ]]; then
|
|
145
|
+
echo " stderr missing tried=[…,…]: $stderr"
|
|
146
|
+
return 1
|
|
147
|
+
fi
|
|
148
|
+
if [[ "$stderr" != *"reason=file-not-found-in-either-shape"* ]]; then
|
|
149
|
+
echo " stderr missing reason=file-not-found-in-either-shape: $stderr"
|
|
150
|
+
return 1
|
|
151
|
+
fi
|
|
152
|
+
return 0
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
# --- Case 4: both present (promotion race) → full wins + stale signal ---
|
|
156
|
+
case_both_present() {
|
|
157
|
+
local root="/tmp/maxy-logs-read-test-4-$$"
|
|
158
|
+
local script
|
|
159
|
+
script=$(setup_install_tree "$root")
|
|
160
|
+
local logdir="$root/data/accounts/acct-test/logs"
|
|
161
|
+
echo "full-content-sentinel-4" > "$logdir/$FULL_NAME"
|
|
162
|
+
echo "preflush-content-sentinel-4" > "$logdir/$PREFLUSH_NAME"
|
|
163
|
+
local server_log="$HOME/.$(basename "$root")/logs/server.log"
|
|
164
|
+
: > "$server_log"
|
|
165
|
+
|
|
166
|
+
local stdout stderr rc=0
|
|
167
|
+
stdout=$("$script" "$CONV_ID" system 2>/tmp/maxy-logs-read-stderr-4-$$) || rc=$?
|
|
168
|
+
stderr=$(cat /tmp/maxy-logs-read-stderr-4-$$)
|
|
169
|
+
rm -f /tmp/maxy-logs-read-stderr-4-$$
|
|
170
|
+
|
|
171
|
+
local server_log_contents
|
|
172
|
+
server_log_contents=$(cat "$server_log" 2>/dev/null || echo "")
|
|
173
|
+
|
|
174
|
+
cleanup_install_tree "$root"
|
|
175
|
+
|
|
176
|
+
if [[ $rc -ne 0 ]]; then
|
|
177
|
+
echo " expected exit 0, got $rc"
|
|
178
|
+
return 1
|
|
179
|
+
fi
|
|
180
|
+
if [[ "$stdout" != *"full-content-sentinel-4"* ]]; then
|
|
181
|
+
echo " stdout missing full sentinel (full must win): $stdout"
|
|
182
|
+
return 1
|
|
183
|
+
fi
|
|
184
|
+
if [[ "$stdout" == *"preflush-content-sentinel-4"* ]]; then
|
|
185
|
+
echo " stdout contained preflush sentinel — preflush must be ignored when full exists"
|
|
186
|
+
return 1
|
|
187
|
+
fi
|
|
188
|
+
if [[ "$stderr" != *"matched_shape=full"* ]]; then
|
|
189
|
+
echo " stderr missing matched_shape=full"
|
|
190
|
+
return 1
|
|
191
|
+
fi
|
|
192
|
+
if [[ "$server_log_contents" != *"stale-preflush-detected"* ]]; then
|
|
193
|
+
echo " server.log missing stale-preflush-detected signal: $server_log_contents"
|
|
194
|
+
return 1
|
|
195
|
+
fi
|
|
196
|
+
if [[ "$server_log_contents" != *"$PREFLUSH_NAME"* ]]; then
|
|
197
|
+
echo " server.log stale signal missing preflush path"
|
|
198
|
+
return 1
|
|
199
|
+
fi
|
|
200
|
+
return 0
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
run_case "full only → matched_shape=full" case_full_only
|
|
204
|
+
run_case "preflush only → matched_shape=preflush" case_preflush_only
|
|
205
|
+
run_case "neither → trailer enumerates both filenames" case_neither
|
|
206
|
+
run_case "both present → full wins + stale signal" case_both_present
|
|
207
|
+
|
|
208
|
+
echo ""
|
|
209
|
+
echo "================================================"
|
|
210
|
+
echo " Passed: $PASS / Failed: $FAIL"
|
|
211
|
+
echo "================================================"
|
|
212
|
+
[[ $FAIL -eq 0 ]]
|