@rubytech/create-maxy-code 0.1.224 → 0.1.225

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 (31) hide show
  1. package/package.json +1 -1
  2. package/payload/platform/plugins/admin/mcp/dist/index.js +1 -1
  3. package/payload/platform/plugins/admin/mcp/dist/index.js.map +1 -1
  4. package/payload/platform/plugins/admin/skills/file-presentation/SKILL.md +9 -7
  5. package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +13 -3
  6. package/payload/platform/plugins/admin/skills/professional-document/SKILL.md +1 -1
  7. package/payload/platform/plugins/docs/references/admin-ui.md +11 -1
  8. package/payload/platform/plugins/docs/references/deployment.md +1 -1
  9. package/payload/platform/plugins/graph-viewer/mcp/dist/index.js +1 -1
  10. package/payload/platform/plugins/graph-viewer/mcp/dist/index.js.map +1 -1
  11. package/payload/platform/plugins/graph-viewer/mcp/dist/tools/graph-render.d.ts.map +1 -1
  12. package/payload/platform/plugins/graph-viewer/mcp/dist/tools/graph-render.js +7 -5
  13. package/payload/platform/plugins/graph-viewer/mcp/dist/tools/graph-render.js.map +1 -1
  14. package/payload/platform/plugins/graph-viewer/skills/render-graph/SKILL.md +6 -6
  15. package/payload/platform/plugins/scheduling/PLUGIN.md +1 -1
  16. package/payload/platform/plugins/scheduling/mcp/dist/index.js +2 -2
  17. package/payload/platform/plugins/scheduling/mcp/dist/index.js.map +1 -1
  18. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-export-ics.d.ts.map +1 -1
  19. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-export-ics.js +3 -2
  20. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-export-ics.js.map +1 -1
  21. package/payload/platform/scripts/logs-read-jsonl.test.sh +307 -0
  22. package/payload/platform/scripts/logs-read.sh +435 -32
  23. package/payload/platform/services/claude-session-manager/dist/system-prompt.d.ts +0 -1
  24. package/payload/platform/services/claude-session-manager/dist/system-prompt.d.ts.map +1 -1
  25. package/payload/platform/services/claude-session-manager/dist/system-prompt.js +11 -10
  26. package/payload/platform/services/claude-session-manager/dist/system-prompt.js.map +1 -1
  27. package/payload/platform/templates/specialists/agents/content-producer.md +1 -1
  28. package/payload/server/public/assets/data-BzRzOKWv.js +1 -0
  29. package/payload/server/public/data.html +1 -1
  30. package/payload/server/server.js +13 -6
  31. package/payload/server/public/assets/data-CHdaTjgn.js +0 -1
@@ -0,0 +1,307 @@
1
+ #!/usr/bin/env bash
2
+ # bash harness for logs-read.sh rc-spawn JSONL retrieval (Task 585).
3
+ #
4
+ # Covers the three in-scope deliverables:
5
+ # 1. `logs-read.sh <key>` (bare, no type) resolves the configDir Claude tree
6
+ # and emits a merged session+subagent timeline. Key forms tested:
7
+ # session_<bridge>, bare <bridge>, full <uuid>, <uuid> prefix.
8
+ # 2. A subagent `is_error:true` tool_result is flagged inline in the timeline
9
+ # (agentType + failing tool + error text), and absent when the session is
10
+ # clean.
11
+ # 3. `logs-read.sh --scan-subagent-errors` lists every subagents/agent-*.jsonl
12
+ # carrying an is_error result, and only those.
13
+ #
14
+ # The fake configDir is pointed at via CLAUDE_CONFIG_DIR (the same override the
15
+ # session manager honours), so no real ~/.<brand> tree is touched. Each case
16
+ # builds an rc-spawn-shaped install (data/accounts/<id>/ with NO logs/ subdir)
17
+ # to prove the JSONL path does not depend on the dead per-account logs tree.
18
+ set -euo pipefail
19
+
20
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
21
+ LOGS_READ="$SCRIPT_DIR/logs-read.sh"
22
+ if [[ ! -x "$LOGS_READ" ]]; then
23
+ echo "FATAL: $LOGS_READ not executable" >&2
24
+ exit 1
25
+ fi
26
+
27
+ UUID_A="6031941e-0000-4000-8000-000000000001"
28
+ UUID_C="c0c0c0c0-0000-4000-8000-0000000000c0"
29
+ UUID_CLEAN="c1ea0000-0000-4000-8000-00000000c1ea"
30
+ BRIDGE="TESTBRIDGE01"
31
+
32
+ PASS=0
33
+ FAIL=0
34
+
35
+ # Build an rc-spawn-shaped install root + a fake CLAUDE tree. Echos two paths
36
+ # on stdout: "<logs_read_script> <claude_config_dir>".
37
+ setup_tree() {
38
+ local root="$1"
39
+ mkdir -p "$root/platform/scripts"
40
+ mkdir -p "$root/data/accounts/acct-585" # account dir exists, but NO logs/ — rc-spawn shape
41
+ ln -sf "$LOGS_READ" "$root/platform/scripts/logs-read.sh"
42
+ mkdir -p "$HOME/.$(basename "$root")/logs" # server.log home for best-effort missing-on-resolve
43
+ local cfg="$root/cfg/.claude"
44
+ mkdir -p "$cfg/sessions" "$cfg/projects/-fake-cwd"
45
+ echo "$root/platform/scripts/logs-read.sh $cfg"
46
+ }
47
+
48
+ cleanup_tree() {
49
+ local root="$1"
50
+ rm -rf "$root"
51
+ rm -rf "$HOME/.$(basename "$root")"
52
+ }
53
+
54
+ # Write a parent JSONL with a couple of turns.
55
+ write_parent() {
56
+ local cfg="$1" uuid="$2"
57
+ local f="$cfg/projects/-fake-cwd/${uuid}.jsonl"
58
+ {
59
+ printf '%s\n' '{"type":"user","timestamp":"2026-05-31T19:40:00.000Z","uuid":"p1","message":{"role":"user","content":"make me a pdf"}}'
60
+ printf '%s\n' '{"type":"assistant","timestamp":"2026-05-31T19:40:02.000Z","uuid":"p2","message":{"role":"assistant","model":"claude-opus-4-8","content":[{"type":"text","text":"dispatching content-producer"}]}}'
61
+ } > "$f"
62
+ }
63
+
64
+ # Write a FAILING subagent transcript (is_error tool_result) + its meta.
65
+ write_subagent_failed() {
66
+ local cfg="$1" parent_uuid="$2" agent="$3" atype="$4"
67
+ local d="$cfg/projects/-fake-cwd/${parent_uuid}/subagents"
68
+ mkdir -p "$d"
69
+ {
70
+ printf '%s\n' '{"type":"user","timestamp":"2026-05-31T19:40:10.000Z","uuid":"s1","message":{"role":"user","content":"produce the pdf and deliver it"}}'
71
+ printf '%s\n' '{"type":"assistant","timestamp":"2026-05-31T19:40:20.000Z","uuid":"s2","message":{"role":"assistant","content":[{"type":"tool_use","id":"toolu_DEAD","name":"Bash","input":{"command":"SendUserFile /tmp/out.pdf"}}]}}'
72
+ printf '%s\n' '{"type":"user","timestamp":"2026-05-31T19:40:21.000Z","uuid":"s3","message":{"role":"user","content":[{"type":"tool_result","tool_use_id":"toolu_DEAD","is_error":true,"content":"/bin/bash: line 1: SendUserFile: command not found"}]},"toolUseResult":"Error: Exit code 127"}'
73
+ } > "$d/${agent}.jsonl"
74
+ printf '{"agentType":"%s","description":"render pdf"}\n' "$atype" > "$d/${agent}.meta.json"
75
+ }
76
+
77
+ # Write a parent JSONL that contains its OWN failing tool_result (NOT a
78
+ # subagent error — a parent Bash that exited non-zero). Used to prove the
79
+ # parent's own errors are not mislabelled as subagent errors.
80
+ write_parent_with_error() {
81
+ local cfg="$1" uuid="$2"
82
+ local f="$cfg/projects/-fake-cwd/${uuid}.jsonl"
83
+ {
84
+ printf '%s\n' '{"type":"user","timestamp":"2026-05-31T19:39:00.000Z","uuid":"e1","message":{"role":"user","content":"check the repo"}}'
85
+ printf '%s\n' '{"type":"assistant","timestamp":"2026-05-31T19:39:02.000Z","uuid":"e2","message":{"role":"assistant","content":[{"type":"tool_use","id":"toolu_PARENT","name":"Bash","input":{"command":"grep nonesuch ."}}]}}'
86
+ printf '%s\n' '{"type":"user","timestamp":"2026-05-31T19:39:03.000Z","uuid":"e3","message":{"role":"user","content":[{"type":"tool_result","tool_use_id":"toolu_PARENT","is_error":true,"content":"Exit code 1 PARENT_OWN_GREP_MISS"}]},"toolUseResult":"Error: Exit code 1"}'
87
+ } > "$f"
88
+ }
89
+
90
+ # Write a CLEAN subagent transcript (no errors) + its meta.
91
+ write_subagent_clean() {
92
+ local cfg="$1" parent_uuid="$2" agent="$3" atype="$4"
93
+ local d="$cfg/projects/-fake-cwd/${parent_uuid}/subagents"
94
+ mkdir -p "$d"
95
+ {
96
+ printf '%s\n' '{"type":"user","timestamp":"2026-05-31T19:41:10.000Z","uuid":"q1","message":{"role":"user","content":"review the diff"}}'
97
+ printf '%s\n' '{"type":"assistant","timestamp":"2026-05-31T19:41:12.000Z","uuid":"q2","message":{"role":"assistant","content":[{"type":"tool_use","id":"toolu_OK","name":"Read","input":{"file_path":"/x"}}]}}'
98
+ printf '%s\n' '{"type":"user","timestamp":"2026-05-31T19:41:13.000Z","uuid":"q3","message":{"role":"user","content":[{"type":"tool_result","tool_use_id":"toolu_OK","content":"ok"}]}}'
99
+ } > "$d/${agent}.jsonl"
100
+ printf '{"agentType":"%s","description":"review"}\n' "$atype" > "$d/${agent}.meta.json"
101
+ }
102
+
103
+ write_pidfile() {
104
+ local cfg="$1" pid="$2" uuid="$3" bridge="$4"
105
+ printf '{"pid":%s,"sessionId":"%s","bridgeSessionId":"session_%s","cwd":"/fake/cwd","startedAt":1780000000000}\n' \
106
+ "$pid" "$uuid" "$bridge" > "$cfg/sessions/${pid}.json"
107
+ }
108
+
109
+ # meta sidecar carrying bridgeIds (persistent bridge->uuid map, survives PID-file deletion).
110
+ write_meta_bridgeids() {
111
+ local cfg="$1" uuid="$2" bridge="$3"
112
+ printf '{"senderId":"s1","role":"admin","channel":"browser","url":null,"startedAt":"2026-05-31T19:40:00.000Z","permissionMode":null,"effectivePermissionMode":null,"model":null,"hidden":false,"specialist":null,"scopeUnitToken":null,"bridgeIds":["%s"]}\n' \
113
+ "$bridge" > "$cfg/projects/-fake-cwd/${uuid}.meta.json"
114
+ }
115
+
116
+ # Parent transcript whose BODY embeds a bridge key string (no pidfile, no
117
+ # bridgeIds) — exercises the content-grep last-resort resolver tier.
118
+ write_parent_with_key_in_body() {
119
+ local cfg="$1" uuid="$2" keystr="$3"
120
+ printf '%s\n' "{\"type\":\"user\",\"timestamp\":\"2026-05-31T19:38:00.000Z\",\"uuid\":\"b1\",\"message\":{\"role\":\"user\",\"content\":\"resumed from ${keystr} earlier\"}}" \
121
+ > "$cfg/projects/-fake-cwd/${uuid}.jsonl"
122
+ }
123
+
124
+ run_case() {
125
+ local name="$1"; shift
126
+ echo ""
127
+ echo "=== CASE: $name ==="
128
+ if "$@"; then
129
+ PASS=$((PASS + 1)); echo "PASS: $name"
130
+ else
131
+ FAIL=$((FAIL + 1)); echo "FAIL: $name"
132
+ fi
133
+ }
134
+
135
+ # Capture stdout, stderr, rc of a logs-read.sh invocation under a fake config dir.
136
+ # Sets globals: OUT ERR RC.
137
+ invoke() {
138
+ local script="$1" cfg="$2"; shift 2
139
+ local errf; errf=$(mktemp)
140
+ RC=0
141
+ OUT=$(CLAUDE_CONFIG_DIR="$cfg" "$script" "$@" 2>"$errf") || RC=$?
142
+ ERR=$(cat "$errf"); rm -f "$errf"
143
+ }
144
+
145
+ # --- Case A: bare key via PID-file bridge → timeline + flagged subagent error ---
146
+ case_bridge_timeline_flagged() {
147
+ local root="/tmp/maxy-585-A-$$"; local out
148
+ out=$(setup_tree "$root"); local script="${out% *}"; local cfg="${out#* }"
149
+ write_parent "$cfg" "$UUID_A"
150
+ write_subagent_failed "$cfg" "$UUID_A" "agent-aDEAD0000" "content-producer"
151
+ write_pidfile "$cfg" 4242 "$UUID_A" "$BRIDGE"
152
+
153
+ invoke "$script" "$cfg" "session_${BRIDGE}"
154
+ cleanup_tree "$root"
155
+
156
+ [[ $RC -eq 0 ]] || { echo " expected exit 0, got $RC; err=$ERR"; return 1; }
157
+ [[ "$OUT" == *"content-producer"* ]] || { echo " missing agentType content-producer"; return 1; }
158
+ [[ "$OUT" == *"SendUserFile"* ]] || { echo " missing failing command SendUserFile"; return 1; }
159
+ [[ "$OUT" == *"command not found"* ]] || { echo " missing error text"; return 1; }
160
+ [[ "$OUT" == *"SUBAGENT ERROR"* ]] || { echo " missing SUBAGENT ERROR flag"; return 1; }
161
+ [[ "$OUT" == *"6031941e"* ]] || { echo " missing resolved session uuid"; return 1; }
162
+ return 0
163
+ }
164
+
165
+ # --- Case B: clean session → timeline, NO error flag ---
166
+ case_clean_no_flag() {
167
+ local root="/tmp/maxy-585-B-$$"; local out
168
+ out=$(setup_tree "$root"); local script="${out% *}"; local cfg="${out#* }"
169
+ write_parent "$cfg" "$UUID_A"
170
+ write_subagent_clean "$cfg" "$UUID_A" "agent-aCLEAN000" "code-reviewer"
171
+ write_pidfile "$cfg" 4243 "$UUID_A" "$BRIDGE"
172
+
173
+ invoke "$script" "$cfg" "session_${BRIDGE}"
174
+ cleanup_tree "$root"
175
+
176
+ [[ $RC -eq 0 ]] || { echo " expected exit 0, got $RC; err=$ERR"; return 1; }
177
+ [[ "$OUT" == *"code-reviewer"* ]] || { echo " missing clean subagent in timeline"; return 1; }
178
+ [[ "$OUT" != *"SUBAGENT ERROR"* ]] || { echo " unexpected SUBAGENT ERROR flag on clean session"; return 1; }
179
+ return 0
180
+ }
181
+
182
+ # --- Case C: resolve via bridgeIds sidecar when PID file is absent ---
183
+ case_resolve_via_bridgeids() {
184
+ local root="/tmp/maxy-585-C-$$"; local out
185
+ out=$(setup_tree "$root"); local script="${out% *}"; local cfg="${out#* }"
186
+ write_parent "$cfg" "$UUID_C"
187
+ write_subagent_failed "$cfg" "$UUID_C" "agent-aBEEF0000" "content-producer"
188
+ write_meta_bridgeids "$cfg" "$UUID_C" "ENDEDBRIDGE9" # no pidfile — session ended
189
+
190
+ invoke "$script" "$cfg" "session_ENDEDBRIDGE9"
191
+ cleanup_tree "$root"
192
+
193
+ [[ $RC -eq 0 ]] || { echo " expected exit 0, got $RC; err=$ERR"; return 1; }
194
+ [[ "$OUT" == *"c0c0c0c0"* ]] || { echo " did not resolve UUID_C via bridgeIds"; return 1; }
195
+ return 0
196
+ }
197
+
198
+ # --- Case D: resolve via UUID directly (full) ---
199
+ case_resolve_uuid_direct() {
200
+ local root="/tmp/maxy-585-D-$$"; local out
201
+ out=$(setup_tree "$root"); local script="${out% *}"; local cfg="${out#* }"
202
+ write_parent "$cfg" "$UUID_A"
203
+ write_subagent_clean "$cfg" "$UUID_A" "agent-aOK000000" "code-reviewer"
204
+
205
+ invoke "$script" "$cfg" "$UUID_A"
206
+ cleanup_tree "$root"
207
+
208
+ [[ $RC -eq 0 ]] || { echo " expected exit 0, got $RC; err=$ERR"; return 1; }
209
+ [[ "$OUT" == *"6031941e"* ]] || { echo " did not return timeline for UUID_A"; return 1; }
210
+ return 0
211
+ }
212
+
213
+ # --- Case E: --scan-subagent-errors lists failed subagent only ---
214
+ case_scan_lists_failed_only() {
215
+ local root="/tmp/maxy-585-E-$$"; local out
216
+ out=$(setup_tree "$root"); local script="${out% *}"; local cfg="${out#* }"
217
+ write_parent "$cfg" "$UUID_A"
218
+ write_subagent_failed "$cfg" "$UUID_A" "agent-aDEAD0000" "content-producer"
219
+ write_parent "$cfg" "$UUID_CLEAN"
220
+ write_subagent_clean "$cfg" "$UUID_CLEAN" "agent-aSAFE0000" "code-reviewer"
221
+
222
+ invoke "$script" "$cfg" "--scan-subagent-errors"
223
+ cleanup_tree "$root"
224
+
225
+ [[ $RC -eq 0 ]] || { echo " expected exit 0, got $RC; err=$ERR"; return 1; }
226
+ [[ "$OUT" == *"agent-aDEAD0000"* ]] || { echo " failed subagent not listed"; return 1; }
227
+ [[ "$OUT" == *"content-producer"* ]] || { echo " failed subagent agentType missing"; return 1; }
228
+ [[ "$OUT" == *"command not found"* ]] || { echo " error text missing in scan"; return 1; }
229
+ [[ "$OUT" != *"agent-aSAFE0000"* ]] || { echo " clean subagent wrongly listed"; return 1; }
230
+ return 0
231
+ }
232
+
233
+ # --- Case G: parent's OWN tool error is not mislabelled as a subagent error ---
234
+ case_parent_error_not_subagent() {
235
+ local root="/tmp/maxy-585-G-$$"; local out
236
+ out=$(setup_tree "$root"); local script="${out% *}"; local cfg="${out#* }"
237
+ write_parent_with_error "$cfg" "$UUID_A"
238
+ write_subagent_clean "$cfg" "$UUID_A" "agent-aCLEAN111" "code-reviewer"
239
+ write_pidfile "$cfg" 4244 "$UUID_A" "$BRIDGE"
240
+
241
+ invoke "$script" "$cfg" "session_${BRIDGE}"
242
+ cleanup_tree "$root"
243
+
244
+ [[ $RC -eq 0 ]] || { echo " expected exit 0, got $RC; err=$ERR"; return 1; }
245
+ [[ "$OUT" == *"PARENT_OWN_GREP_MISS"* ]] || { echo " parent tool error not shown in timeline"; return 1; }
246
+ [[ "$OUT" != *"SUBAGENT ERROR"* ]] || { echo " parent error wrongly tagged SUBAGENT ERROR"; return 1; }
247
+ [[ "$OUT" == *"subagent-errors: 0"* ]] || { echo " header miscounts parent error as subagent error"; return 1; }
248
+ return 0
249
+ }
250
+
251
+ # --- Case I: content-grep resolves a unique body match (last-resort tier) ---
252
+ case_content_grep_single() {
253
+ local root="/tmp/maxy-585-I-$$"; local out
254
+ out=$(setup_tree "$root"); local script="${out% *}"; local cfg="${out#* }"
255
+ write_parent_with_key_in_body "$cfg" "$UUID_A" "session_SOLOKEYxyz1" # no pidfile, no bridgeIds
256
+
257
+ invoke "$script" "$cfg" "session_SOLOKEYxyz1"
258
+ cleanup_tree "$root"
259
+
260
+ [[ $RC -eq 0 ]] || { echo " expected exit 0 (single content match), got $RC; err=$ERR"; return 1; }
261
+ [[ "$OUT" == *"6031941e"* ]] || { echo " content-grep did not resolve the unique match"; return 1; }
262
+ return 0
263
+ }
264
+
265
+ # --- Case H: content-grep refuses when the key matches multiple transcripts ---
266
+ case_content_grep_ambiguous_refuses() {
267
+ local root="/tmp/maxy-585-H-$$"; local out
268
+ out=$(setup_tree "$root"); local script="${out% *}"; local cfg="${out#* }"
269
+ write_parent_with_key_in_body "$cfg" "$UUID_A" "session_AMBIGKEYxyz"
270
+ write_parent_with_key_in_body "$cfg" "$UUID_C" "session_AMBIGKEYxyz" # same key in two bodies
271
+
272
+ invoke "$script" "$cfg" "session_AMBIGKEYxyz"
273
+ cleanup_tree "$root"
274
+
275
+ # Must NOT silently pick one of the two — refuse (exit 1), like uuid-prefix ambiguity.
276
+ [[ $RC -eq 1 ]] || { echo " expected exit 1 (ambiguous content match), got $RC; out=$OUT"; return 1; }
277
+ return 0
278
+ }
279
+
280
+ # --- Case F: unresolvable key → exit 1 (clean miss, not a crash) ---
281
+ case_unresolvable_miss() {
282
+ local root="/tmp/maxy-585-F-$$"; local out
283
+ out=$(setup_tree "$root"); local script="${out% *}"; local cfg="${out#* }"
284
+ write_parent "$cfg" "$UUID_A"
285
+
286
+ invoke "$script" "$cfg" "session_NOSUCHBRIDGE"
287
+ cleanup_tree "$root"
288
+
289
+ [[ $RC -eq 1 ]] || { echo " expected exit 1 on unresolvable key, got $RC"; return 1; }
290
+ return 0
291
+ }
292
+
293
+ run_case "bare key via PID bridge → timeline + flagged subagent error" case_bridge_timeline_flagged
294
+ run_case "clean session → timeline, no error flag" case_clean_no_flag
295
+ run_case "resolve via bridgeIds sidecar (PID file absent)" case_resolve_via_bridgeids
296
+ run_case "resolve via full UUID directly" case_resolve_uuid_direct
297
+ run_case "--scan-subagent-errors lists failed subagent only" case_scan_lists_failed_only
298
+ run_case "parent's own tool error not mislabelled SUBAGENT ERROR" case_parent_error_not_subagent
299
+ run_case "content-grep resolves a unique body match" case_content_grep_single
300
+ run_case "content-grep refuses an ambiguous (multi) body match" case_content_grep_ambiguous_refuses
301
+ run_case "unresolvable key → exit 1" case_unresolvable_miss
302
+
303
+ echo ""
304
+ echo "================================================"
305
+ echo " Passed: $PASS / Failed: $FAIL"
306
+ echo "================================================"
307
+ [[ $FAIL -eq 0 ]]