@rubytech/create-maxy-code 0.1.461 → 0.1.463

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 (186) hide show
  1. package/package.json +1 -1
  2. package/payload/platform/lib/graph-mcp/dist/index.d.ts +2 -1
  3. package/payload/platform/lib/graph-mcp/dist/index.d.ts.map +1 -1
  4. package/payload/platform/lib/graph-mcp/dist/index.js +14 -22
  5. package/payload/platform/lib/graph-mcp/dist/index.js.map +1 -1
  6. package/payload/platform/lib/graph-mcp/src/index.ts +15 -22
  7. package/payload/platform/lib/mcp-spawn-tee/dist/index.d.ts +8 -7
  8. package/payload/platform/lib/mcp-spawn-tee/dist/index.d.ts.map +1 -1
  9. package/payload/platform/lib/mcp-spawn-tee/dist/index.js +19 -19
  10. package/payload/platform/lib/mcp-spawn-tee/dist/index.js.map +1 -1
  11. package/payload/platform/lib/mcp-spawn-tee/src/__tests__/spawn-tee.test.ts +34 -5
  12. package/payload/platform/lib/mcp-spawn-tee/src/index.ts +22 -19
  13. package/payload/platform/lib/mcp-stderr-tee/dist/index.d.ts +35 -17
  14. package/payload/platform/lib/mcp-stderr-tee/dist/index.d.ts.map +1 -1
  15. package/payload/platform/lib/mcp-stderr-tee/dist/index.js +41 -48
  16. package/payload/platform/lib/mcp-stderr-tee/dist/index.js.map +1 -1
  17. package/payload/platform/lib/mcp-stderr-tee/src/index.ts +42 -51
  18. package/payload/platform/lib/storage-broker/dist/__tests__/audit.test.js +27 -0
  19. package/payload/platform/lib/storage-broker/dist/__tests__/audit.test.js.map +1 -1
  20. package/payload/platform/lib/storage-broker/dist/__tests__/cf-exec.test.js +49 -0
  21. package/payload/platform/lib/storage-broker/dist/__tests__/cf-exec.test.js.map +1 -1
  22. package/payload/platform/lib/storage-broker/dist/audit.d.ts +11 -0
  23. package/payload/platform/lib/storage-broker/dist/audit.d.ts.map +1 -1
  24. package/payload/platform/lib/storage-broker/dist/audit.js +16 -0
  25. package/payload/platform/lib/storage-broker/dist/audit.js.map +1 -1
  26. package/payload/platform/lib/storage-broker/dist/cf-exec.d.ts +18 -0
  27. package/payload/platform/lib/storage-broker/dist/cf-exec.d.ts.map +1 -1
  28. package/payload/platform/lib/storage-broker/dist/cf-exec.js +77 -0
  29. package/payload/platform/lib/storage-broker/dist/cf-exec.js.map +1 -1
  30. package/payload/platform/lib/storage-broker/dist/house-scoped-token.js +3 -0
  31. package/payload/platform/lib/storage-broker/dist/house-scoped-token.js.map +1 -1
  32. package/payload/platform/lib/storage-broker/dist/registry.d.ts +1 -1
  33. package/payload/platform/lib/storage-broker/dist/registry.d.ts.map +1 -1
  34. package/payload/platform/lib/storage-broker/dist/registry.js.map +1 -1
  35. package/payload/platform/lib/storage-broker/src/__tests__/audit.test.ts +32 -1
  36. package/payload/platform/lib/storage-broker/src/__tests__/cf-exec.test.ts +61 -0
  37. package/payload/platform/lib/storage-broker/src/audit.ts +45 -0
  38. package/payload/platform/lib/storage-broker/src/cf-exec.ts +91 -0
  39. package/payload/platform/lib/storage-broker/src/house-scoped-token.ts +3 -0
  40. package/payload/platform/lib/storage-broker/src/registry.ts +5 -1
  41. package/payload/platform/plugins/admin/lib/mcp-spawn-tee/index.js +19 -19
  42. package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +23 -12
  43. package/payload/platform/plugins/aeo/lib/mcp-spawn-tee/index.js +19 -19
  44. package/payload/platform/plugins/browser/lib/mcp-spawn-tee/index.js +19 -19
  45. package/payload/platform/plugins/cloudflare/PLUGIN.md +1 -1
  46. package/payload/platform/plugins/cloudflare/mcp/dist/index.js +5 -5
  47. package/payload/platform/plugins/cloudflare/mcp/dist/index.js.map +1 -1
  48. package/payload/platform/plugins/cloudflare/references/hosting-sites.md +2 -0
  49. package/payload/platform/plugins/cloudflare/skills/calendar-site/SKILL.md +1 -1
  50. package/payload/platform/plugins/cloudflare/skills/site-deploy/SKILL.md +2 -0
  51. package/payload/platform/plugins/connector/lib/mcp-spawn-tee/index.js +19 -19
  52. package/payload/platform/plugins/contacts/lib/mcp-spawn-tee/index.js +19 -19
  53. package/payload/platform/plugins/docs/references/admin-session.md +3 -3
  54. package/payload/platform/plugins/docs/references/cloudflare.md +2 -0
  55. package/payload/platform/plugins/docs/references/internals.md +1 -1
  56. package/payload/platform/plugins/docs/references/outlook-guide.md +11 -4
  57. package/payload/platform/plugins/docs/references/plugins-guide.md +8 -6
  58. package/payload/platform/plugins/email/lib/mcp-spawn-tee/index.js +19 -19
  59. package/payload/platform/plugins/filesystem/lib/mcp-spawn-tee/index.js +19 -19
  60. package/payload/platform/plugins/graph-viewer/lib/mcp-spawn-tee/index.js +19 -19
  61. package/payload/platform/plugins/memory/PLUGIN.md +1 -1
  62. package/payload/platform/plugins/memory/lib/mcp-spawn-tee/index.js +19 -19
  63. package/payload/platform/plugins/memory/mcp/dist/lib/log-ingest.js +2 -2
  64. package/payload/platform/plugins/memory/mcp/dist/lib/log-ingest.js.map +1 -1
  65. package/payload/platform/plugins/outlook/.claude-plugin/plugin.json +1 -1
  66. package/payload/platform/plugins/outlook/PLUGIN.md +2 -2
  67. package/payload/platform/plugins/outlook/lib/mcp-spawn-tee/index.js +19 -19
  68. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-threaded.test.d.ts +2 -0
  69. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-threaded.test.d.ts.map +1 -0
  70. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-threaded.test.js +238 -0
  71. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-threaded.test.js.map +1 -0
  72. package/payload/platform/plugins/outlook/mcp/dist/index.js +9 -5
  73. package/payload/platform/plugins/outlook/mcp/dist/index.js.map +1 -1
  74. package/payload/platform/plugins/outlook/mcp/dist/lib/message.d.ts +1 -6
  75. package/payload/platform/plugins/outlook/mcp/dist/lib/message.d.ts.map +1 -1
  76. package/payload/platform/plugins/outlook/mcp/dist/lib/message.js +9 -17
  77. package/payload/platform/plugins/outlook/mcp/dist/lib/message.js.map +1 -1
  78. package/payload/platform/plugins/outlook/mcp/dist/lib/recipients.d.ts +56 -0
  79. package/payload/platform/plugins/outlook/mcp/dist/lib/recipients.d.ts.map +1 -0
  80. package/payload/platform/plugins/outlook/mcp/dist/lib/recipients.js +40 -0
  81. package/payload/platform/plugins/outlook/mcp/dist/lib/recipients.js.map +1 -0
  82. package/payload/platform/plugins/outlook/mcp/dist/tools/draft-edit.d.ts.map +1 -1
  83. package/payload/platform/plugins/outlook/mcp/dist/tools/draft-edit.js +1 -3
  84. package/payload/platform/plugins/outlook/mcp/dist/tools/draft-edit.js.map +1 -1
  85. package/payload/platform/plugins/outlook/mcp/dist/tools/draft.d.ts +58 -9
  86. package/payload/platform/plugins/outlook/mcp/dist/tools/draft.d.ts.map +1 -1
  87. package/payload/platform/plugins/outlook/mcp/dist/tools/draft.js +97 -18
  88. package/payload/platform/plugins/outlook/mcp/dist/tools/draft.js.map +1 -1
  89. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-fetch-body.d.ts.map +1 -1
  90. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-fetch-body.js +1 -3
  91. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-fetch-body.js.map +1 -1
  92. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-reply.d.ts.map +1 -1
  93. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-reply.js +3 -18
  94. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-reply.js.map +1 -1
  95. package/payload/platform/plugins/outlook/skills/outlook/SKILL.md +5 -2
  96. package/payload/platform/plugins/quickbooks/lib/mcp-spawn-tee/index.js +19 -19
  97. package/payload/platform/plugins/replicate/lib/mcp-spawn-tee/index.js +19 -19
  98. package/payload/platform/plugins/scheduling/lib/mcp-spawn-tee/index.js +19 -19
  99. package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/agent-turn-dispatch.test.js +6 -32
  100. package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/agent-turn-dispatch.test.js.map +1 -1
  101. package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.d.ts.map +1 -1
  102. package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.js +10 -30
  103. package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.js.map +1 -1
  104. package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-cancel.test.js +24 -21
  105. package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-cancel.test.js.map +1 -1
  106. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-cancel.d.ts +27 -18
  107. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-cancel.d.ts.map +1 -1
  108. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-cancel.js +31 -27
  109. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-cancel.js.map +1 -1
  110. package/payload/platform/plugins/storage-broker/PLUGIN.md +9 -1
  111. package/payload/platform/plugins/storage-broker/lib/mcp-spawn-tee/index.js +19 -19
  112. package/payload/platform/plugins/storage-broker/mcp/dist/confine-path.d.ts.map +1 -1
  113. package/payload/platform/plugins/storage-broker/mcp/dist/confine-path.js +16 -5
  114. package/payload/platform/plugins/storage-broker/mcp/dist/confine-path.js.map +1 -1
  115. package/payload/platform/plugins/storage-broker/mcp/dist/index.js +49 -0
  116. package/payload/platform/plugins/storage-broker/mcp/dist/index.js.map +1 -1
  117. package/payload/platform/plugins/telegram/lib/mcp-spawn-tee/index.js +19 -19
  118. package/payload/platform/plugins/url-get/lib/mcp-spawn-tee/index.js +19 -19
  119. package/payload/platform/plugins/voice-mirror/lib/mcp-spawn-tee/index.js +19 -19
  120. package/payload/platform/plugins/web-designer/PLUGIN.md +1 -1
  121. package/payload/platform/plugins/web-designer/commands/website.md +6 -0
  122. package/payload/platform/plugins/web-designer/skills/web-design/references/deploy.md +12 -0
  123. package/payload/platform/plugins/whatsapp/lib/mcp-spawn-tee/index.js +19 -19
  124. package/payload/platform/plugins/work/lib/mcp-spawn-tee/index.js +19 -19
  125. package/payload/platform/plugins/workflows/lib/mcp-spawn-tee/index.js +19 -19
  126. package/payload/platform/scripts/__tests__/logs-rotate.test.sh +24 -20
  127. package/payload/platform/scripts/logs-read.sh +31 -0
  128. package/payload/platform/scripts/logs-rotate.sh +21 -18
  129. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.d.ts.map +1 -1
  130. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js +2 -0
  131. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js.map +1 -1
  132. package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts.map +1 -1
  133. package/payload/platform/services/claude-session-manager/dist/pty-spawner.js +37 -0
  134. package/payload/platform/services/claude-session-manager/dist/pty-spawner.js.map +1 -1
  135. package/payload/platform/services/claude-session-manager/dist/rc-daemon.d.ts +5 -3
  136. package/payload/platform/services/claude-session-manager/dist/rc-daemon.d.ts.map +1 -1
  137. package/payload/platform/services/claude-session-manager/dist/rc-daemon.js.map +1 -1
  138. package/payload/platform/services/telegram-channel/dist/server.d.ts.map +1 -1
  139. package/payload/platform/services/telegram-channel/dist/server.js +0 -4
  140. package/payload/platform/services/telegram-channel/dist/server.js.map +1 -1
  141. package/payload/platform/services/webchat-channel/dist/server.d.ts.map +1 -1
  142. package/payload/platform/services/webchat-channel/dist/server.js +0 -4
  143. package/payload/platform/services/webchat-channel/dist/server.js.map +1 -1
  144. package/payload/platform/services/whatsapp-channel/dist/server.d.ts.map +1 -1
  145. package/payload/platform/services/whatsapp-channel/dist/server.js +0 -4
  146. package/payload/platform/services/whatsapp-channel/dist/server.js.map +1 -1
  147. package/payload/server/{chunk-JXWFVE5X.js → chunk-BBSPFN45.js} +65 -0
  148. package/payload/server/public/assets/{AdminLoginScreens-BFbpkEUS.js → AdminLoginScreens-Bed8SDxY.js} +1 -1
  149. package/payload/server/public/assets/{AdminShell-CdOGObaZ.js → AdminShell-BLh9O6dn.js} +1 -1
  150. package/payload/server/public/assets/{Checkbox-RFD_F0c0.js → Checkbox-BC_KSbpS.js} +1 -1
  151. package/payload/server/public/assets/{admin-CYGdL-1O.js → admin-DfWgJVI3.js} +1 -1
  152. package/payload/server/public/assets/{browser-DVfa_plj.js → browser-C0vkv-hH.js} +1 -1
  153. package/payload/server/public/assets/{calendar-JC_Dxa4n.js → calendar-_pfHw0Hp.js} +1 -1
  154. package/payload/server/public/assets/chat-DYT5H81o.js +1 -0
  155. package/payload/server/public/assets/chevron-left-BnpVBu51.js +1 -0
  156. package/payload/server/public/assets/data-CR-fbPWr.js +1 -0
  157. package/payload/server/public/assets/{graph-hBUrRSkr.js → graph-BZiudUGr.js} +1 -1
  158. package/payload/server/public/assets/{graph-labels-CHh6zs8t.js → graph-labels-BzmmJwCR.js} +1 -1
  159. package/payload/server/public/assets/{maximize-2-DjxE4rm9.js → maximize-2-Bhdsv0U-.js} +1 -1
  160. package/payload/server/public/assets/{operator-BqU9SQuu.js → operator-gm2eP4r6.js} +1 -1
  161. package/payload/server/public/assets/{page-DiQhU6lD.js → page-8AB3jUa_.js} +1 -1
  162. package/payload/server/public/assets/page-BoPorLg-.js +32 -0
  163. package/payload/server/public/assets/{public-Cu_eALgY.js → public-DqJk6qgW.js} +1 -1
  164. package/payload/server/public/assets/{rotate-ccw-F9DsSTSJ.js → rotate-ccw-D_5cETGt.js} +1 -1
  165. package/payload/server/public/assets/{tasks-CE-D0f50.js → tasks-EyKLXINi.js} +1 -1
  166. package/payload/server/public/assets/{time-entry-format-D2rsWhov.js → time-entry-format-DAwmmR3i.js} +1 -1
  167. package/payload/server/public/assets/{useCopyFeedback-QxOmoobV.js → useCopyFeedback-rOWd_lzl.js} +1 -1
  168. package/payload/server/public/assets/{useSelectionMode-RIzNqFjV.js → useSelectionMode-DDmLmPph.js} +1 -1
  169. package/payload/server/public/assets/{useSubAccountSwitcher-BW_fK1Nt.css → useSubAccountSwitcher-pu0jjLCz.css} +1 -1
  170. package/payload/server/public/assets/{useVoiceRecorder-WrWurSYI.js → useVoiceRecorder-azG8zSUI.js} +1 -1
  171. package/payload/server/public/browser.html +5 -5
  172. package/payload/server/public/calendar.html +6 -6
  173. package/payload/server/public/chat.html +12 -12
  174. package/payload/server/public/data.html +10 -10
  175. package/payload/server/public/graph.html +11 -11
  176. package/payload/server/public/index.html +13 -13
  177. package/payload/server/public/operator.html +14 -14
  178. package/payload/server/public/public.html +12 -12
  179. package/payload/server/public/tasks.html +5 -5
  180. package/payload/server/server.js +596 -235
  181. package/payload/server/{src-4F37OHLK.js → src-YLGAZY36.js} +5 -1
  182. package/payload/server/public/assets/chat-Yf8Nkop8.js +0 -1
  183. package/payload/server/public/assets/chevron-left-CAiAUBxO.js +0 -1
  184. package/payload/server/public/assets/data-hqdYXaEn.js +0 -1
  185. package/payload/server/public/assets/page-B4c4_4HP.js +0 -32
  186. /package/payload/server/public/assets/{useSubAccountSwitcher-wo_qGW-I.js → useSubAccountSwitcher-CU-lOxTd.js} +0 -0
@@ -13,14 +13,15 @@
13
13
  *
14
14
  * Claude Code CLI → shim (this file) = node running <real-entry> in-process
15
15
  * stdin/stdout : untouched (JSON-RPC channel)
16
- * stderr : process.stderr.write teed → per-date + per-session + passthrough
16
+ * stderr : process.stderr.write teed → raw sink + passthrough
17
17
  *
18
- * Destinations (Task 706) — unchanged:
19
- * - `${LOG_DIR}/mcp-<name>-stderr-<date>.log` per-date raw (back-compat;
20
- * the in-process mcp-stderr-tee and the [mcp-init-error] probe read it).
21
- * - `${LOG_DIR}/mcp-<name>-<SESSION_ID>.log` — per-session raw + lifecycle
22
- * lines. Authoritative sink. Absent when SESSION_ID is unset (enumeration
23
- * spawn)then the per-date file is the fallback.
18
+ * Destinations:
19
+ * - `${LOG_DIR}/mcp-<name>-<SESSION_ID>.log` — raw stderr + lifecycle lines.
20
+ * The sole raw sink. Task 1721 retired the per-date twin: its date was
21
+ * pinned at spawn, no reader ever parsed it, and mcp-stderr-tee wrote the
22
+ * same file, so every line landed twice.
23
+ * - `${LOG_DIR}/mcp-<name>-nosession.log` — the same, for a spawn with
24
+ * no SESSION_ID (enumeration). One fixed file per server.
24
25
  * - `server.log` via the loopback log-ingest route — best-effort mirror of
25
26
  * the [mcp-helper] lifecycle lines.
26
27
  *
@@ -49,13 +50,13 @@ const PLATFORM_PORT = process.env.PLATFORM_PORT;
49
50
  const ENTRY = process.argv[2];
50
51
  const SESSION_ID8 = SESSION_ID ? SESSION_ID.slice(0, 8) : "—";
51
52
  const spawnStamp = Date.now();
52
- // Per-session raw + lifecycle log (Task 706). Empty SESSION_ID (enumeration
53
- // spawn) undefined, and the per-date file is the fallback.
54
- const perSessionPath = LOG_DIR && SESSION_ID
55
- ? (0, node_path_1.resolve)(LOG_DIR, `mcp-${SERVER_NAME}-${SESSION_ID}.log`)
56
- : undefined;
57
- const perDatePath = LOG_DIR
58
- ? (0, node_path_1.resolve)(LOG_DIR, `mcp-${SERVER_NAME}-stderr-${new Date(spawnStamp).toISOString().slice(0, 10)}.log`)
53
+ // The one raw sink (Task 1721). A sessionless spawn (rc-daemon stamps
54
+ // SESSION_ID='' rc-daemon.ts:513 while still stamping LOG_DIR) shares one
55
+ // fixed file per server rather than a date-named one: the date was never read
56
+ // by any reader and named a process lifetime, not a day. Interleaved spawns in
57
+ // the nosession file are separated by the [mcp-helper] op=spawn pid= lines.
58
+ const rawSinkPath = LOG_DIR
59
+ ? (0, node_path_1.resolve)(LOG_DIR, SESSION_ID ? `mcp-${SERVER_NAME}-${SESSION_ID}.log` : `mcp-${SERVER_NAME}-nosession.log`)
59
60
  : undefined;
60
61
  // Rolling tail of entry stderr for op=exit. Capped so a chatty server cannot
61
62
  // grow the buffer without bound.
@@ -66,7 +67,7 @@ let exitEmitted = false;
66
67
  let exitSignal;
67
68
  // The real stderr writer, captured before the tee replaces it. Lifecycle lines
68
69
  // and stderr passthrough both go through this so they are never re-teed into
69
- // the per-date sink nor recursed back into the patched writer.
70
+ // the raw sink nor recursed back into the patched writer.
70
71
  const rawStderrWrite = process.stderr.write.bind(process.stderr);
71
72
  // LOG_DIR is created once, lazily, on the first successful append — not per
72
73
  // chunk. teeWrite runs on the server's own stderr hot path now, so a per-call
@@ -115,7 +116,7 @@ function postToServerLog(suffix, level) {
115
116
  // log-ingest route rejects newlines).
116
117
  function emitLifecycle(suffix, level) {
117
118
  const line = `[mcp-helper] ${suffix}\n`;
118
- appendSafe(perSessionPath, line);
119
+ appendSafe(rawSinkPath, line);
119
120
  try {
120
121
  rawStderrWrite(line);
121
122
  }
@@ -127,12 +128,11 @@ if (!ENTRY) {
127
128
  process.exit(2);
128
129
  }
129
130
  // Replace process.stderr.write with a tee: mirror every server stderr byte to
130
- // the per-date and per-session sinks, keep a rolling tail for op=exit, emit
131
+ // the raw sink, keep a rolling tail for op=exit, emit
131
132
  // op=boot on the first bytes, then pass the write through to the real stderr.
132
133
  const teeWrite = ((...args) => {
133
134
  const chunk = args[0];
134
- appendSafe(perDatePath, chunk); // per-date raw (back-compat)
135
- appendSafe(perSessionPath, chunk); // per-session raw (Task 706)
135
+ appendSafe(rawSinkPath, chunk); // raw sink (Task 1721)
136
136
  const text = typeof chunk === "string" ? chunk : Buffer.from(chunk).toString("utf8");
137
137
  stderrTail = (stderrTail + text).slice(-TAIL_CAP);
138
138
  if (!bootEmitted) {
@@ -46,7 +46,7 @@ The plugin's only host coupling is `bin/resolve-cf.sh`. It resolves two things a
46
46
 
47
47
  Going live and the richer Cloudflare features reuse existing, proven surfaces rather than reimplementing them. The deploy references in `skills/web-design/references/` name each dependency:
48
48
 
49
- - **deploy + D1 forms** — inside maxy-code the canonical site tree is handed to `cloudflare:site-deploy` unchanged; standalone it follows the generic `wrangler pages deploy` sequence from the Cloudflare references. Extra form "buckets" are extra D1 tables and Pages Functions on the same pattern.
49
+ - **deploy + D1 forms** — inside maxy-code the canonical site tree is handed to `cloudflare:site-deploy` unchanged; standalone it follows the generic `wrangler pages deploy` sequence from the Cloudflare references. On a multi-tenant install a **client account** takes neither path: it is denied the `pages` scope (`reason=not-house`) and publishes with `storage-broker:storage-pages-deploy`, which deploys house-side against a project the house has recorded to it. Extra form "buckets" are extra D1 tables and Pages Functions on the same pattern.
50
50
  - **gated access** — Cloudflare Access is composed from the Cloudflare Access references and the proven gating pattern; no new gating mechanics are authored here.
51
51
  - **e-signing** — routed to the `business-assistant:e-sign` skill, which owns signature capture, D1 recording, PDF stamping, and dispatch. This is a host dependency, not shipped self-contained in the marketplace edition.
52
52
 
@@ -52,6 +52,12 @@ site-tree root come from is resolved by `bin/resolve-cf.sh`:
52
52
  account directory automatically and hands the built tree to `cloudflare:site-deploy`
53
53
  unchanged. The skill triggers ("design me a website") remain the primary surface
54
54
  there; this command is an equivalent entry point.
55
+ - **Inside maxy-code, as a client account on a multi-tenant install:** there is no
56
+ account Cloudflare token to resolve — the house holds the only master, and
57
+ `cf-token.sh` denies the `pages` scope (`reason=not-house`). The build is unchanged;
58
+ only going live differs. Publish with `storage-broker:storage-pages-deploy`, naming
59
+ the site folder and the Pages project. The project must already be recorded to the
60
+ account by the house.
55
61
 
56
62
  ## What you get back
57
63
 
@@ -8,6 +8,18 @@ tree per site; never deploy from a `.bak` clone or a stale sibling.
8
8
 
9
9
  This reference composes existing deploy mechanics. It does not fork them.
10
10
 
11
+ ## First: on a multi-tenant install, a client account publishes through the broker
12
+
13
+ If this session is a **client account** on an install where the house
14
+ holds the sole Cloudflare master (the post-1631 posture), neither path below will
15
+ work: `cf-token.sh` denies the `pages` scope with `reason=not-house`, because the
16
+ master is account-wide. Publish with `storage-pages-deploy` instead — it names the
17
+ site folder and the project, and the deploy runs house-side. The project must
18
+ already be recorded to this account by the house (`storage-pages-adopt`); if the
19
+ tool answers `unregistered`, ask the house to record it rather than trying to mint
20
+ a token. The two paths below are the **house account** and the **standalone**
21
+ editions.
22
+
11
23
  ## Inside maxy-code: hand off to `cloudflare:site-deploy`
12
24
 
13
25
  When the host carries the `cloudflare` plugin, hand the canonical tree to the
@@ -13,14 +13,15 @@
13
13
  *
14
14
  * Claude Code CLI → shim (this file) = node running <real-entry> in-process
15
15
  * stdin/stdout : untouched (JSON-RPC channel)
16
- * stderr : process.stderr.write teed → per-date + per-session + passthrough
16
+ * stderr : process.stderr.write teed → raw sink + passthrough
17
17
  *
18
- * Destinations (Task 706) — unchanged:
19
- * - `${LOG_DIR}/mcp-<name>-stderr-<date>.log` per-date raw (back-compat;
20
- * the in-process mcp-stderr-tee and the [mcp-init-error] probe read it).
21
- * - `${LOG_DIR}/mcp-<name>-<SESSION_ID>.log` — per-session raw + lifecycle
22
- * lines. Authoritative sink. Absent when SESSION_ID is unset (enumeration
23
- * spawn)then the per-date file is the fallback.
18
+ * Destinations:
19
+ * - `${LOG_DIR}/mcp-<name>-<SESSION_ID>.log` — raw stderr + lifecycle lines.
20
+ * The sole raw sink. Task 1721 retired the per-date twin: its date was
21
+ * pinned at spawn, no reader ever parsed it, and mcp-stderr-tee wrote the
22
+ * same file, so every line landed twice.
23
+ * - `${LOG_DIR}/mcp-<name>-nosession.log` — the same, for a spawn with
24
+ * no SESSION_ID (enumeration). One fixed file per server.
24
25
  * - `server.log` via the loopback log-ingest route — best-effort mirror of
25
26
  * the [mcp-helper] lifecycle lines.
26
27
  *
@@ -49,13 +50,13 @@ const PLATFORM_PORT = process.env.PLATFORM_PORT;
49
50
  const ENTRY = process.argv[2];
50
51
  const SESSION_ID8 = SESSION_ID ? SESSION_ID.slice(0, 8) : "—";
51
52
  const spawnStamp = Date.now();
52
- // Per-session raw + lifecycle log (Task 706). Empty SESSION_ID (enumeration
53
- // spawn) undefined, and the per-date file is the fallback.
54
- const perSessionPath = LOG_DIR && SESSION_ID
55
- ? (0, node_path_1.resolve)(LOG_DIR, `mcp-${SERVER_NAME}-${SESSION_ID}.log`)
56
- : undefined;
57
- const perDatePath = LOG_DIR
58
- ? (0, node_path_1.resolve)(LOG_DIR, `mcp-${SERVER_NAME}-stderr-${new Date(spawnStamp).toISOString().slice(0, 10)}.log`)
53
+ // The one raw sink (Task 1721). A sessionless spawn (rc-daemon stamps
54
+ // SESSION_ID='' rc-daemon.ts:513 while still stamping LOG_DIR) shares one
55
+ // fixed file per server rather than a date-named one: the date was never read
56
+ // by any reader and named a process lifetime, not a day. Interleaved spawns in
57
+ // the nosession file are separated by the [mcp-helper] op=spawn pid= lines.
58
+ const rawSinkPath = LOG_DIR
59
+ ? (0, node_path_1.resolve)(LOG_DIR, SESSION_ID ? `mcp-${SERVER_NAME}-${SESSION_ID}.log` : `mcp-${SERVER_NAME}-nosession.log`)
59
60
  : undefined;
60
61
  // Rolling tail of entry stderr for op=exit. Capped so a chatty server cannot
61
62
  // grow the buffer without bound.
@@ -66,7 +67,7 @@ let exitEmitted = false;
66
67
  let exitSignal;
67
68
  // The real stderr writer, captured before the tee replaces it. Lifecycle lines
68
69
  // and stderr passthrough both go through this so they are never re-teed into
69
- // the per-date sink nor recursed back into the patched writer.
70
+ // the raw sink nor recursed back into the patched writer.
70
71
  const rawStderrWrite = process.stderr.write.bind(process.stderr);
71
72
  // LOG_DIR is created once, lazily, on the first successful append — not per
72
73
  // chunk. teeWrite runs on the server's own stderr hot path now, so a per-call
@@ -115,7 +116,7 @@ function postToServerLog(suffix, level) {
115
116
  // log-ingest route rejects newlines).
116
117
  function emitLifecycle(suffix, level) {
117
118
  const line = `[mcp-helper] ${suffix}\n`;
118
- appendSafe(perSessionPath, line);
119
+ appendSafe(rawSinkPath, line);
119
120
  try {
120
121
  rawStderrWrite(line);
121
122
  }
@@ -127,12 +128,11 @@ if (!ENTRY) {
127
128
  process.exit(2);
128
129
  }
129
130
  // Replace process.stderr.write with a tee: mirror every server stderr byte to
130
- // the per-date and per-session sinks, keep a rolling tail for op=exit, emit
131
+ // the raw sink, keep a rolling tail for op=exit, emit
131
132
  // op=boot on the first bytes, then pass the write through to the real stderr.
132
133
  const teeWrite = ((...args) => {
133
134
  const chunk = args[0];
134
- appendSafe(perDatePath, chunk); // per-date raw (back-compat)
135
- appendSafe(perSessionPath, chunk); // per-session raw (Task 706)
135
+ appendSafe(rawSinkPath, chunk); // raw sink (Task 1721)
136
136
  const text = typeof chunk === "string" ? chunk : Buffer.from(chunk).toString("utf8");
137
137
  stderrTail = (stderrTail + text).slice(-TAIL_CAP);
138
138
  if (!bootEmitted) {
@@ -13,14 +13,15 @@
13
13
  *
14
14
  * Claude Code CLI → shim (this file) = node running <real-entry> in-process
15
15
  * stdin/stdout : untouched (JSON-RPC channel)
16
- * stderr : process.stderr.write teed → per-date + per-session + passthrough
16
+ * stderr : process.stderr.write teed → raw sink + passthrough
17
17
  *
18
- * Destinations (Task 706) — unchanged:
19
- * - `${LOG_DIR}/mcp-<name>-stderr-<date>.log` per-date raw (back-compat;
20
- * the in-process mcp-stderr-tee and the [mcp-init-error] probe read it).
21
- * - `${LOG_DIR}/mcp-<name>-<SESSION_ID>.log` — per-session raw + lifecycle
22
- * lines. Authoritative sink. Absent when SESSION_ID is unset (enumeration
23
- * spawn)then the per-date file is the fallback.
18
+ * Destinations:
19
+ * - `${LOG_DIR}/mcp-<name>-<SESSION_ID>.log` — raw stderr + lifecycle lines.
20
+ * The sole raw sink. Task 1721 retired the per-date twin: its date was
21
+ * pinned at spawn, no reader ever parsed it, and mcp-stderr-tee wrote the
22
+ * same file, so every line landed twice.
23
+ * - `${LOG_DIR}/mcp-<name>-nosession.log` — the same, for a spawn with
24
+ * no SESSION_ID (enumeration). One fixed file per server.
24
25
  * - `server.log` via the loopback log-ingest route — best-effort mirror of
25
26
  * the [mcp-helper] lifecycle lines.
26
27
  *
@@ -49,13 +50,13 @@ const PLATFORM_PORT = process.env.PLATFORM_PORT;
49
50
  const ENTRY = process.argv[2];
50
51
  const SESSION_ID8 = SESSION_ID ? SESSION_ID.slice(0, 8) : "—";
51
52
  const spawnStamp = Date.now();
52
- // Per-session raw + lifecycle log (Task 706). Empty SESSION_ID (enumeration
53
- // spawn) undefined, and the per-date file is the fallback.
54
- const perSessionPath = LOG_DIR && SESSION_ID
55
- ? (0, node_path_1.resolve)(LOG_DIR, `mcp-${SERVER_NAME}-${SESSION_ID}.log`)
56
- : undefined;
57
- const perDatePath = LOG_DIR
58
- ? (0, node_path_1.resolve)(LOG_DIR, `mcp-${SERVER_NAME}-stderr-${new Date(spawnStamp).toISOString().slice(0, 10)}.log`)
53
+ // The one raw sink (Task 1721). A sessionless spawn (rc-daemon stamps
54
+ // SESSION_ID='' rc-daemon.ts:513 while still stamping LOG_DIR) shares one
55
+ // fixed file per server rather than a date-named one: the date was never read
56
+ // by any reader and named a process lifetime, not a day. Interleaved spawns in
57
+ // the nosession file are separated by the [mcp-helper] op=spawn pid= lines.
58
+ const rawSinkPath = LOG_DIR
59
+ ? (0, node_path_1.resolve)(LOG_DIR, SESSION_ID ? `mcp-${SERVER_NAME}-${SESSION_ID}.log` : `mcp-${SERVER_NAME}-nosession.log`)
59
60
  : undefined;
60
61
  // Rolling tail of entry stderr for op=exit. Capped so a chatty server cannot
61
62
  // grow the buffer without bound.
@@ -66,7 +67,7 @@ let exitEmitted = false;
66
67
  let exitSignal;
67
68
  // The real stderr writer, captured before the tee replaces it. Lifecycle lines
68
69
  // and stderr passthrough both go through this so they are never re-teed into
69
- // the per-date sink nor recursed back into the patched writer.
70
+ // the raw sink nor recursed back into the patched writer.
70
71
  const rawStderrWrite = process.stderr.write.bind(process.stderr);
71
72
  // LOG_DIR is created once, lazily, on the first successful append — not per
72
73
  // chunk. teeWrite runs on the server's own stderr hot path now, so a per-call
@@ -115,7 +116,7 @@ function postToServerLog(suffix, level) {
115
116
  // log-ingest route rejects newlines).
116
117
  function emitLifecycle(suffix, level) {
117
118
  const line = `[mcp-helper] ${suffix}\n`;
118
- appendSafe(perSessionPath, line);
119
+ appendSafe(rawSinkPath, line);
119
120
  try {
120
121
  rawStderrWrite(line);
121
122
  }
@@ -127,12 +128,11 @@ if (!ENTRY) {
127
128
  process.exit(2);
128
129
  }
129
130
  // Replace process.stderr.write with a tee: mirror every server stderr byte to
130
- // the per-date and per-session sinks, keep a rolling tail for op=exit, emit
131
+ // the raw sink, keep a rolling tail for op=exit, emit
131
132
  // op=boot on the first bytes, then pass the write through to the real stderr.
132
133
  const teeWrite = ((...args) => {
133
134
  const chunk = args[0];
134
- appendSafe(perDatePath, chunk); // per-date raw (back-compat)
135
- appendSafe(perSessionPath, chunk); // per-session raw (Task 706)
135
+ appendSafe(rawSinkPath, chunk); // raw sink (Task 1721)
136
136
  const text = typeof chunk === "string" ? chunk : Buffer.from(chunk).toString("utf8");
137
137
  stderrTail = (stderrTail + text).slice(-TAIL_CAP);
138
138
  if (!bootEmitted) {
@@ -13,14 +13,15 @@
13
13
  *
14
14
  * Claude Code CLI → shim (this file) = node running <real-entry> in-process
15
15
  * stdin/stdout : untouched (JSON-RPC channel)
16
- * stderr : process.stderr.write teed → per-date + per-session + passthrough
16
+ * stderr : process.stderr.write teed → raw sink + passthrough
17
17
  *
18
- * Destinations (Task 706) — unchanged:
19
- * - `${LOG_DIR}/mcp-<name>-stderr-<date>.log` per-date raw (back-compat;
20
- * the in-process mcp-stderr-tee and the [mcp-init-error] probe read it).
21
- * - `${LOG_DIR}/mcp-<name>-<SESSION_ID>.log` — per-session raw + lifecycle
22
- * lines. Authoritative sink. Absent when SESSION_ID is unset (enumeration
23
- * spawn)then the per-date file is the fallback.
18
+ * Destinations:
19
+ * - `${LOG_DIR}/mcp-<name>-<SESSION_ID>.log` — raw stderr + lifecycle lines.
20
+ * The sole raw sink. Task 1721 retired the per-date twin: its date was
21
+ * pinned at spawn, no reader ever parsed it, and mcp-stderr-tee wrote the
22
+ * same file, so every line landed twice.
23
+ * - `${LOG_DIR}/mcp-<name>-nosession.log` — the same, for a spawn with
24
+ * no SESSION_ID (enumeration). One fixed file per server.
24
25
  * - `server.log` via the loopback log-ingest route — best-effort mirror of
25
26
  * the [mcp-helper] lifecycle lines.
26
27
  *
@@ -49,13 +50,13 @@ const PLATFORM_PORT = process.env.PLATFORM_PORT;
49
50
  const ENTRY = process.argv[2];
50
51
  const SESSION_ID8 = SESSION_ID ? SESSION_ID.slice(0, 8) : "—";
51
52
  const spawnStamp = Date.now();
52
- // Per-session raw + lifecycle log (Task 706). Empty SESSION_ID (enumeration
53
- // spawn) undefined, and the per-date file is the fallback.
54
- const perSessionPath = LOG_DIR && SESSION_ID
55
- ? (0, node_path_1.resolve)(LOG_DIR, `mcp-${SERVER_NAME}-${SESSION_ID}.log`)
56
- : undefined;
57
- const perDatePath = LOG_DIR
58
- ? (0, node_path_1.resolve)(LOG_DIR, `mcp-${SERVER_NAME}-stderr-${new Date(spawnStamp).toISOString().slice(0, 10)}.log`)
53
+ // The one raw sink (Task 1721). A sessionless spawn (rc-daemon stamps
54
+ // SESSION_ID='' rc-daemon.ts:513 while still stamping LOG_DIR) shares one
55
+ // fixed file per server rather than a date-named one: the date was never read
56
+ // by any reader and named a process lifetime, not a day. Interleaved spawns in
57
+ // the nosession file are separated by the [mcp-helper] op=spawn pid= lines.
58
+ const rawSinkPath = LOG_DIR
59
+ ? (0, node_path_1.resolve)(LOG_DIR, SESSION_ID ? `mcp-${SERVER_NAME}-${SESSION_ID}.log` : `mcp-${SERVER_NAME}-nosession.log`)
59
60
  : undefined;
60
61
  // Rolling tail of entry stderr for op=exit. Capped so a chatty server cannot
61
62
  // grow the buffer without bound.
@@ -66,7 +67,7 @@ let exitEmitted = false;
66
67
  let exitSignal;
67
68
  // The real stderr writer, captured before the tee replaces it. Lifecycle lines
68
69
  // and stderr passthrough both go through this so they are never re-teed into
69
- // the per-date sink nor recursed back into the patched writer.
70
+ // the raw sink nor recursed back into the patched writer.
70
71
  const rawStderrWrite = process.stderr.write.bind(process.stderr);
71
72
  // LOG_DIR is created once, lazily, on the first successful append — not per
72
73
  // chunk. teeWrite runs on the server's own stderr hot path now, so a per-call
@@ -115,7 +116,7 @@ function postToServerLog(suffix, level) {
115
116
  // log-ingest route rejects newlines).
116
117
  function emitLifecycle(suffix, level) {
117
118
  const line = `[mcp-helper] ${suffix}\n`;
118
- appendSafe(perSessionPath, line);
119
+ appendSafe(rawSinkPath, line);
119
120
  try {
120
121
  rawStderrWrite(line);
121
122
  }
@@ -127,12 +128,11 @@ if (!ENTRY) {
127
128
  process.exit(2);
128
129
  }
129
130
  // Replace process.stderr.write with a tee: mirror every server stderr byte to
130
- // the per-date and per-session sinks, keep a rolling tail for op=exit, emit
131
+ // the raw sink, keep a rolling tail for op=exit, emit
131
132
  // op=boot on the first bytes, then pass the write through to the real stderr.
132
133
  const teeWrite = ((...args) => {
133
134
  const chunk = args[0];
134
- appendSafe(perDatePath, chunk); // per-date raw (back-compat)
135
- appendSafe(perSessionPath, chunk); // per-session raw (Task 706)
135
+ appendSafe(rawSinkPath, chunk); // raw sink (Task 1721)
136
136
  const text = typeof chunk === "string" ? chunk : Buffer.from(chunk).toString("utf8");
137
137
  stderrTail = (stderrTail + text).slice(-TAIL_CAP);
138
138
  if (!bootEmitted) {
@@ -159,12 +159,12 @@ case_purge_does_not_touch_server_log() {
159
159
  rm -rf "$d"; return 0
160
160
  }
161
161
 
162
- case_mcp_stderr_live_file_size_rotates() {
162
+ case_mcp_sink_live_file_size_rotates() {
163
163
  local d; d="$(mk_logs_dir)"
164
- mk_file_of_size "$d/mcp-memory-stderr-2026-07-17.log" $((65 * 1024 * 1024))
164
+ mk_file_of_size "$d/mcp-memory-sess-abc.log" $((65 * 1024 * 1024))
165
165
  "$ROTATE" "$d" >/dev/null 2>&1
166
- [ -f "$d/mcp-memory-stderr-2026-07-17.log.1.gz" ] \
167
- || { echo " live mcp stderr log was not size-rotated"; rm -rf "$d"; return 1; }
166
+ [ -f "$d/mcp-memory-sess-abc.log.1.gz" ] \
167
+ || { echo " live mcp sink was not size-rotated"; rm -rf "$d"; return 1; }
168
168
  rm -rf "$d"; return 0
169
169
  }
170
170
 
@@ -200,22 +200,26 @@ case_gzip_failure_preserves_generations() {
200
200
  rm -rf "$d" "$bin"; return $fail
201
201
  }
202
202
 
203
- # The mcp stderr tee opens its file at process start and holds the stream for the
204
- # process's whole life, writing ONLY when the server emits stderr which a
205
- # healthy server does not do for days. So a live file's mtime DOES go stale, and
206
- # deleting it sends every later stderr write to an unlinked inode: invisible
207
- # exactly when the fault you are chasing finally appears. Never purge these.
208
- case_never_purges_mcp_stderr_by_age() {
203
+ # Task 1721 retired the per-date file and with it mcp-stderr-tee's held write
204
+ # stream. Every remaining mcp sink is appendFileSync, so purging one is safe for
205
+ # the same reason purging rc-child is: no fd is held, and the next write simply
206
+ # recreates the file. The stale `mcp-*-stderr-<date>.log` orphans left by the old
207
+ # writers age out through the same glob.
208
+ case_purges_mcp_sink_older_than_seven_days() {
209
209
  local d; d="$(mk_logs_dir)"
210
- echo quiet > "$d/mcp-memory-stderr-2026-01-01.log"
211
- backdate "$d/mcp-memory-stderr-2026-01-01.log" 90
212
- echo x | gzip -c > "$d/mcp-memory-stderr-2026-01-01.log.1.gz"
213
- backdate "$d/mcp-memory-stderr-2026-01-01.log.1.gz" 90
210
+ echo old > "$d/mcp-memory-sess-old.log"; backdate "$d/mcp-memory-sess-old.log" 9
211
+ echo x | gzip -c > "$d/mcp-memory-sess-old.log.1.gz"; backdate "$d/mcp-memory-sess-old.log.1.gz" 9
212
+ echo legacy > "$d/mcp-memory-stderr-2026-01-01.log"; backdate "$d/mcp-memory-stderr-2026-01-01.log" 90
213
+ echo new > "$d/mcp-memory-sess-new.log" # today
214
214
  "$ROTATE" "$d" >/dev/null 2>&1
215
- [ -f "$d/mcp-memory-stderr-2026-01-01.log" ] \
216
- || { echo " a 90-day-stale mcp stderr log was purged — it may still be held open"; rm -rf "$d"; return 1; }
217
- [ -f "$d/mcp-memory-stderr-2026-01-01.log.1.gz" ] \
218
- || { echo " an mcp generation was purged by age"; rm -rf "$d"; return 1; }
215
+ [ ! -e "$d/mcp-memory-sess-old.log" ] \
216
+ || { echo " 9-day-old mcp sink survived"; rm -rf "$d"; return 1; }
217
+ [ ! -e "$d/mcp-memory-sess-old.log.1.gz" ] \
218
+ || { echo " 9-day-old mcp generation survived"; rm -rf "$d"; return 1; }
219
+ [ ! -e "$d/mcp-memory-stderr-2026-01-01.log" ] \
220
+ || { echo " retired per-date orphan was not swept"; rm -rf "$d"; return 1; }
221
+ [ -f "$d/mcp-memory-sess-new.log" ] \
222
+ || { echo " today's mcp sink was purged"; rm -rf "$d"; return 1; }
219
223
  rm -rf "$d"; return 0
220
224
  }
221
225
 
@@ -235,7 +239,7 @@ case_rc_child_size_rotates() {
235
239
  }
236
240
 
237
241
  run_case "gzip failure preserves generations" case_gzip_failure_preserves_generations
238
- run_case "never purges mcp stderr by age" case_never_purges_mcp_stderr_by_age
242
+ run_case "purges mcp sink older than 7 days" case_purges_mcp_sink_older_than_seven_days
239
243
  run_case "rc-child size-rotates" case_rc_child_size_rotates
240
244
 
241
245
  run_case "under threshold is a no-op" case_under_threshold_is_noop
@@ -248,7 +252,7 @@ run_case "missing logs dir is a no-op, exit 0" case_missing_logs_dir_is_noop_e
248
252
  run_case "lock released on exit" case_lock_released_on_exit
249
253
  run_case "purges rc-child older than 7 days" case_purges_rc_child_older_than_seven_days
250
254
  run_case "purge does not touch server.log" case_purge_does_not_touch_server_log
251
- run_case "mcp stderr live file size-rotates" case_mcp_stderr_live_file_size_rotates
255
+ run_case "mcp sink live file size-rotates" case_mcp_sink_live_file_size_rotates
252
256
 
253
257
  echo ""
254
258
  echo "===================="
@@ -861,6 +861,28 @@ def collect_events(path, source, events, is_sub, rejects=None):
861
861
  events.append((ts, source, 'text', 'user: ' + clip(content, 160)))
862
862
  return n_err
863
863
 
864
+ def version_timeline(path):
865
+ """Task 1724 — every JSONL row carries the CLI `version` that wrote it, and
866
+ this reader dropped the field. A version change mid-session means the binary
867
+ was re-executed (a resume): in the 1724 incident the 2.1.210 -> 2.1.212 flip
868
+ at the resume boundary was the single most load-bearing fact in the whole
869
+ investigation, and no platform instrument showed it — it was found by hand.
870
+
871
+ Records every TRANSITION rather than the distinct set, so a flip back
872
+ (A -> B -> A) is still visible; collapsing to a set would hide it."""
873
+ out = []
874
+ last = None
875
+ for r in load_jsonl(path):
876
+ if not isinstance(r, dict):
877
+ continue
878
+ v = r.get('version')
879
+ if not isinstance(v, str) or not v or v == last:
880
+ continue
881
+ out.append((v, r.get('timestamp') or '-'))
882
+ last = v
883
+ return out
884
+
885
+
864
886
  def timeline(projects_root, sessions_dir, key):
865
887
  uuid, parent_path, via = resolve_uuid(projects_root, sessions_dir, key)
866
888
  if not uuid:
@@ -880,6 +902,15 @@ def timeline(projects_root, sessions_dir, key):
880
902
  print('# session %s (resolved via %s)' % (uuid, via))
881
903
  print('# parent: %s' % (parent_path or '(no parent transcript on disk)'))
882
904
  print('# subagents: %d subagent-errors: %d' % (sub_count, err_count))
905
+ # Task 1724 — the CLI version that wrote each row. One version is the normal
906
+ # case and prints flat; a change means the binary was re-executed mid-session,
907
+ # which is worth a loud line because it silently moves every tool's behaviour.
908
+ vers = version_timeline(parent_path) if parent_path and os.path.exists(parent_path) else []
909
+ if len(vers) == 1:
910
+ print('# cli: %s' % vers[0][0])
911
+ elif len(vers) > 1:
912
+ print('# cli: %s (%d change(s) — the binary was re-executed mid-session)'
913
+ % (' -> '.join('%s @ %s' % (v, ts) for v, ts in vers), len(vers) - 1))
883
914
  # Repetition is the diagnostic fact: one fat-fingered call is a typo, N
884
915
  # identical ones against a single tool is a wedged loop. Counting it here
885
916
  # makes that one greppable line instead of N unrelated ones.
@@ -151,8 +151,9 @@ done
151
151
  # Globbed size targets. nullglob so a brand with none of these yet does not try
152
152
  # to rotate a literal '*' path.
153
153
  #
154
- # mcp-*-stderr-*.log: the tee holds a live write stream, so this is the ONLY
155
- # bound it gets here see the purge note below for why it is never age-purged.
154
+ # mcp-*.log: the raw sinks (mcp-<server>-<sessionId>.log, mcp-<server>-nosession.log)
155
+ # plus any stale mcp-<server>-stderr-<date>.log orphan from before Task 1721. All
156
+ # are appendFileSync writers holding no fd.
156
157
  #
157
158
  # rc-child-*.log: its 16 MiB writer cap does NOT hold. `written`
158
159
  # (rc-child-log.ts:33) is in-memory per manager process, so a manager restart
@@ -161,28 +162,29 @@ done
161
162
  # mtime forever, so the age purge below never reaches it — without size rotation
162
163
  # it is genuinely unbounded.
163
164
  shopt -s nullglob
164
- for f in "$LOGS_DIR"/mcp-*-stderr-*.log "$LOGS_DIR"/rc-child-*.log; do
165
+ for f in "$LOGS_DIR"/mcp-*.log "$LOGS_DIR"/rc-child-*.log; do
165
166
  rotate_file "$f"
166
167
  done
167
168
  shopt -u nullglob
168
169
 
169
- # Age purge — rc-child only.
170
+ # Age purge — rc-child and the mcp sinks.
170
171
  #
171
- # rc-child-*.log is one file per session and the set grows without bound (100 on
172
- # sitedesk-code). Purging it is SAFE because rc-child-log.ts:51 writes with
173
- # appendFileSync: no fd is held, so a purged file is simply recreated on the
174
- # next write.
172
+ # rc-child-*.log and mcp-<server>-<sessionId>.log are one file per session and
173
+ # grow without bound (100 rc-child on sitedesk-code). mcp-<server>-nosession.log
174
+ # is one fixed file per server instead, so the set never grows; like a live
175
+ # rc-child its mtime stays fresh, so the age purge reaps only its rotated
176
+ # generations and size rotation above is its real bound.
175
177
  #
176
- # mcp-*-stderr-*.log is deliberately NOT purged, though an earlier draft did.
177
- # The tee (mcp-stderr-tee/src/index.ts:88) opens a createWriteStream at process
178
- # start and holds it for the process's whole life, writing only when the server
179
- # emits stderr — which a healthy server does not do for days. So a LIVE file's
180
- # mtime DOES go stale, and deleting it would send every later stderr write to an
181
- # unlinked inode: invisible exactly when the fault you are chasing finally
182
- # appears, and its disk unreclaimed until the process exits. Bounding these by
183
- # age needs live-vs-dead discrimination, which needs the writer to stop pinning
184
- # its date at boot that is Task 1721. Size rotation above is safe regardless,
185
- # because truncate-in-place is precisely what a held fd tolerates.
178
+ # Purging is SAFE because every one of them writes with appendFileSync
179
+ # (rc-child-log.ts:51; mcp-spawn-tee appendSafe): no fd is held, so a purged
180
+ # file is simply recreated on the next write.
181
+ #
182
+ # An earlier draft of 1706 could not purge mcp-*, because mcp-stderr-tee opened
183
+ # a createWriteStream at process start and held it for the process's whole life.
184
+ # A live file's mtime went stale, so unlinking it sent every later stderr write
185
+ # to an inode no one could read. Task 1721 retired that held stream along with
186
+ # the per-date file it wrote, which is what makes this purge safe the hazard
187
+ # was the held fd, not the naming.
186
188
  #
187
189
  # The pattern is `.log*` so a purged session's rotated .gz generations go too.
188
190
  # `find` matches each path by its own mtime — there is no sibling relationship —
@@ -200,5 +202,6 @@ purge_old() {
200
202
  }
201
203
 
202
204
  purge_old 'rc-child-*.log*'
205
+ purge_old 'mcp-*.log*'
203
206
 
204
207
  exit 0
@@ -1 +1 @@
1
- {"version":3,"file":"canonical-tool-names.generated.d.ts","sourceRoot":"","sources":["../src/canonical-tool-names.generated.ts"],"names":[],"mappings":"AAQA,+EAA+E;AAC/E,eAAO,MAAM,gBAAgB,EAAE,SAAS,MAAM,EAuB7C,CAAA;AAED,gEAAgE;AAChE,eAAO,MAAM,yBAAyB,EAAE,SAAS,MAAM,EAoStD,CAAA"}
1
+ {"version":3,"file":"canonical-tool-names.generated.d.ts","sourceRoot":"","sources":["../src/canonical-tool-names.generated.ts"],"names":[],"mappings":"AAQA,+EAA+E;AAC/E,eAAO,MAAM,gBAAgB,EAAE,SAAS,MAAM,EAuB7C,CAAA;AAED,gEAAgE;AAChE,eAAO,MAAM,yBAAyB,EAAE,SAAS,MAAM,EAsStD,CAAA"}
@@ -274,6 +274,8 @@ export const CANONICAL_MAXY_TOOL_NAMES = [
274
274
  "mcp__plugin_storage-broker_storage-broker__storage-d1-create",
275
275
  "mcp__plugin_storage-broker_storage-broker__storage-d1-list",
276
276
  "mcp__plugin_storage-broker_storage-broker__storage-d1-query",
277
+ "mcp__plugin_storage-broker_storage-broker__storage-pages-adopt",
278
+ "mcp__plugin_storage-broker_storage-broker__storage-pages-deploy",
277
279
  "mcp__plugin_storage-broker_storage-broker__storage-r2-bucket-create",
278
280
  "mcp__plugin_storage-broker_storage-broker__storage-r2-bucket-list",
279
281
  "mcp__plugin_storage-broker_storage-broker__storage-r2-object-delete",
@@ -1 +1 @@
1
- {"version":3,"file":"canonical-tool-names.generated.js","sourceRoot":"","sources":["../src/canonical-tool-names.generated.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"canonical-tool-names.generated.js","sourceRoot":"","sources":["../src/canonical-tool-names.generated.ts"],"names":[],"mappings":"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"}