@rubytech/create-maxy-code 0.1.462 → 0.1.464

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 (156) hide show
  1. package/package.json +1 -1
  2. package/payload/platform/docs/superpowers/plans/2026-07-17-task-1736-retire-mcp-stderr-tee.md +397 -0
  3. package/payload/platform/docs/superpowers/specs/2026-07-17-task-1736-retire-mcp-stderr-tee-design.md +128 -0
  4. package/payload/platform/lib/graph-mcp/dist/index.js +5 -24
  5. package/payload/platform/lib/graph-mcp/dist/index.js.map +1 -1
  6. package/payload/platform/lib/graph-mcp/src/index.ts +7 -25
  7. package/payload/platform/lib/mcp-spawn-tee/dist/index.d.ts +2 -2
  8. package/payload/platform/lib/mcp-spawn-tee/dist/index.js +2 -2
  9. package/payload/platform/lib/mcp-spawn-tee/src/__tests__/spawn-tee.test.ts +0 -25
  10. package/payload/platform/lib/mcp-spawn-tee/src/index.ts +2 -2
  11. package/payload/platform/package.json +2 -2
  12. package/payload/platform/plugins/admin/lib/mcp-spawn-tee/index.js +2 -2
  13. package/payload/platform/plugins/admin/mcp/dist/index.js +0 -2
  14. package/payload/platform/plugins/admin/mcp/dist/index.js.map +1 -1
  15. package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +12 -30
  16. package/payload/platform/plugins/aeo/lib/mcp-spawn-tee/index.js +2 -2
  17. package/payload/platform/plugins/aeo/mcp/dist/index.js +0 -2
  18. package/payload/platform/plugins/aeo/mcp/dist/index.js.map +1 -1
  19. package/payload/platform/plugins/browser/lib/mcp-spawn-tee/index.js +2 -2
  20. package/payload/platform/plugins/browser/mcp/dist/index.js +0 -2
  21. package/payload/platform/plugins/browser/mcp/dist/index.js.map +1 -1
  22. package/payload/platform/plugins/connector/lib/mcp-spawn-tee/index.js +2 -2
  23. package/payload/platform/plugins/connector/mcp/dist/index.js +0 -2
  24. package/payload/platform/plugins/connector/mcp/dist/index.js.map +1 -1
  25. package/payload/platform/plugins/contacts/lib/mcp-spawn-tee/index.js +2 -2
  26. package/payload/platform/plugins/contacts/mcp/dist/index.js +0 -2
  27. package/payload/platform/plugins/contacts/mcp/dist/index.js.map +1 -1
  28. package/payload/platform/plugins/docs/references/internals.md +1 -1
  29. package/payload/platform/plugins/docs/references/plugins-guide.md +10 -28
  30. package/payload/platform/plugins/email/lib/mcp-spawn-tee/index.js +2 -2
  31. package/payload/platform/plugins/email/mcp/dist/index.js +0 -2
  32. package/payload/platform/plugins/email/mcp/dist/index.js.map +1 -1
  33. package/payload/platform/plugins/filesystem/lib/mcp-spawn-tee/index.js +2 -2
  34. package/payload/platform/plugins/filesystem/mcp/dist/index.js +0 -2
  35. package/payload/platform/plugins/filesystem/mcp/dist/index.js.map +1 -1
  36. package/payload/platform/plugins/graph-viewer/lib/mcp-spawn-tee/index.js +2 -2
  37. package/payload/platform/plugins/graph-viewer/mcp/dist/index.js +0 -2
  38. package/payload/platform/plugins/graph-viewer/mcp/dist/index.js.map +1 -1
  39. package/payload/platform/plugins/memory/lib/mcp-spawn-tee/index.js +2 -2
  40. package/payload/platform/plugins/memory/mcp/dist/index.js +0 -2
  41. package/payload/platform/plugins/memory/mcp/dist/index.js.map +1 -1
  42. package/payload/platform/plugins/memory/mcp/scripts/boot-smoke.sh +0 -1
  43. package/payload/platform/plugins/outlook/lib/mcp-spawn-tee/index.js +2 -2
  44. package/payload/platform/plugins/outlook/mcp/dist/lib/message.d.ts +1 -6
  45. package/payload/platform/plugins/outlook/mcp/dist/lib/message.d.ts.map +1 -1
  46. package/payload/platform/plugins/outlook/mcp/dist/lib/message.js +9 -17
  47. package/payload/platform/plugins/outlook/mcp/dist/lib/message.js.map +1 -1
  48. package/payload/platform/plugins/outlook/mcp/dist/lib/recipients.d.ts +56 -0
  49. package/payload/platform/plugins/outlook/mcp/dist/lib/recipients.d.ts.map +1 -0
  50. package/payload/platform/plugins/outlook/mcp/dist/lib/recipients.js +40 -0
  51. package/payload/platform/plugins/outlook/mcp/dist/lib/recipients.js.map +1 -0
  52. package/payload/platform/plugins/outlook/mcp/dist/tools/draft-edit.d.ts.map +1 -1
  53. package/payload/platform/plugins/outlook/mcp/dist/tools/draft-edit.js +1 -3
  54. package/payload/platform/plugins/outlook/mcp/dist/tools/draft-edit.js.map +1 -1
  55. package/payload/platform/plugins/outlook/mcp/dist/tools/draft.d.ts.map +1 -1
  56. package/payload/platform/plugins/outlook/mcp/dist/tools/draft.js +3 -18
  57. package/payload/platform/plugins/outlook/mcp/dist/tools/draft.js.map +1 -1
  58. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-fetch-body.d.ts.map +1 -1
  59. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-fetch-body.js +1 -3
  60. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-fetch-body.js.map +1 -1
  61. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-reply.d.ts.map +1 -1
  62. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-reply.js +3 -18
  63. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-reply.js.map +1 -1
  64. package/payload/platform/plugins/quickbooks/lib/mcp-spawn-tee/index.js +2 -2
  65. package/payload/platform/plugins/quickbooks/mcp/dist/index.js +0 -2
  66. package/payload/platform/plugins/quickbooks/mcp/dist/index.js.map +1 -1
  67. package/payload/platform/plugins/replicate/lib/mcp-spawn-tee/index.js +2 -2
  68. package/payload/platform/plugins/replicate/mcp/dist/index.js +0 -2
  69. package/payload/platform/plugins/replicate/mcp/dist/index.js.map +1 -1
  70. package/payload/platform/plugins/scheduling/lib/mcp-spawn-tee/index.js +2 -2
  71. package/payload/platform/plugins/scheduling/mcp/dist/index.js +0 -2
  72. package/payload/platform/plugins/scheduling/mcp/dist/index.js.map +1 -1
  73. package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/agent-turn-dispatch.test.js +6 -32
  74. package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/agent-turn-dispatch.test.js.map +1 -1
  75. package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.d.ts.map +1 -1
  76. package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.js +10 -30
  77. package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.js.map +1 -1
  78. package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-cancel.test.js +24 -21
  79. package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-cancel.test.js.map +1 -1
  80. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-cancel.d.ts +27 -18
  81. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-cancel.d.ts.map +1 -1
  82. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-cancel.js +31 -27
  83. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-cancel.js.map +1 -1
  84. package/payload/platform/plugins/storage-broker/lib/mcp-spawn-tee/index.js +2 -2
  85. package/payload/platform/plugins/storage-broker/mcp/dist/index.js +0 -2
  86. package/payload/platform/plugins/storage-broker/mcp/dist/index.js.map +1 -1
  87. package/payload/platform/plugins/telegram/lib/mcp-spawn-tee/index.js +2 -2
  88. package/payload/platform/plugins/telegram/mcp/dist/index.js +0 -2
  89. package/payload/platform/plugins/telegram/mcp/dist/index.js.map +1 -1
  90. package/payload/platform/plugins/url-get/lib/mcp-spawn-tee/index.js +2 -2
  91. package/payload/platform/plugins/url-get/mcp/dist/index.js +0 -2
  92. package/payload/platform/plugins/url-get/mcp/dist/index.js.map +1 -1
  93. package/payload/platform/plugins/voice-mirror/lib/mcp-spawn-tee/index.js +2 -2
  94. package/payload/platform/plugins/voice-mirror/mcp/dist/index.d.ts.map +1 -1
  95. package/payload/platform/plugins/voice-mirror/mcp/dist/index.js +0 -2
  96. package/payload/platform/plugins/voice-mirror/mcp/dist/index.js.map +1 -1
  97. package/payload/platform/plugins/whatsapp/lib/mcp-spawn-tee/index.js +2 -2
  98. package/payload/platform/plugins/whatsapp/mcp/dist/index.js +0 -2
  99. package/payload/platform/plugins/whatsapp/mcp/dist/index.js.map +1 -1
  100. package/payload/platform/plugins/work/lib/mcp-spawn-tee/index.js +2 -2
  101. package/payload/platform/plugins/work/mcp/dist/index.js +0 -2
  102. package/payload/platform/plugins/work/mcp/dist/index.js.map +1 -1
  103. package/payload/platform/plugins/workflows/lib/mcp-spawn-tee/index.js +2 -2
  104. package/payload/platform/plugins/workflows/mcp/dist/index.js +0 -2
  105. package/payload/platform/plugins/workflows/mcp/dist/index.js.map +1 -1
  106. package/payload/platform/scripts/__tests__/logs-rotate.test.sh +2 -2
  107. package/payload/platform/scripts/check-architecture-skill-no-drift.mjs +21 -14
  108. package/payload/platform/scripts/logs-rotate.sh +6 -6
  109. package/payload/platform/services/claude-session-manager/dist/http-server.d.ts.map +1 -1
  110. package/payload/platform/services/claude-session-manager/dist/http-server.js +23 -2
  111. package/payload/platform/services/claude-session-manager/dist/http-server.js.map +1 -1
  112. package/payload/platform/services/claude-session-manager/dist/index.js +27 -2
  113. package/payload/platform/services/claude-session-manager/dist/index.js.map +1 -1
  114. package/payload/platform/services/claude-session-manager/dist/jsonl-path.d.ts +8 -0
  115. package/payload/platform/services/claude-session-manager/dist/jsonl-path.d.ts.map +1 -1
  116. package/payload/platform/services/claude-session-manager/dist/jsonl-path.js +11 -0
  117. package/payload/platform/services/claude-session-manager/dist/jsonl-path.js.map +1 -1
  118. package/payload/platform/services/claude-session-manager/dist/passive-print-surface.d.ts +10 -0
  119. package/payload/platform/services/claude-session-manager/dist/passive-print-surface.d.ts.map +1 -0
  120. package/payload/platform/services/claude-session-manager/dist/passive-print-surface.js +31 -0
  121. package/payload/platform/services/claude-session-manager/dist/passive-print-surface.js.map +1 -0
  122. package/payload/platform/services/claude-session-manager/dist/print-child-launcher.d.ts +8 -0
  123. package/payload/platform/services/claude-session-manager/dist/print-child-launcher.d.ts.map +1 -0
  124. package/payload/platform/services/claude-session-manager/dist/print-child-launcher.js +50 -0
  125. package/payload/platform/services/claude-session-manager/dist/print-child-launcher.js.map +1 -0
  126. package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts +10 -0
  127. package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts.map +1 -1
  128. package/payload/platform/services/claude-session-manager/dist/pty-spawner.js +23 -2
  129. package/payload/platform/services/claude-session-manager/dist/pty-spawner.js.map +1 -1
  130. package/payload/platform/services/claude-session-manager/dist/rc-daemon.d.ts +2 -2
  131. package/payload/platform/services/claude-session-manager/dist/rc-daemon.d.ts.map +1 -1
  132. package/payload/platform/services/telegram-channel/dist/server.d.ts.map +1 -1
  133. package/payload/platform/services/telegram-channel/dist/server.js +0 -4
  134. package/payload/platform/services/telegram-channel/dist/server.js.map +1 -1
  135. package/payload/platform/services/webchat-channel/dist/server.d.ts.map +1 -1
  136. package/payload/platform/services/webchat-channel/dist/server.js +0 -4
  137. package/payload/platform/services/webchat-channel/dist/server.js.map +1 -1
  138. package/payload/platform/services/whatsapp-channel/dist/server.d.ts.map +1 -1
  139. package/payload/platform/services/whatsapp-channel/dist/server.js +0 -4
  140. package/payload/platform/services/whatsapp-channel/dist/server.js.map +1 -1
  141. package/payload/server/public/assets/{chat-CufidiBQ.js → chat-DYT5H81o.js} +1 -1
  142. package/payload/server/public/assets/{operator-Cj0B_usT.js → operator-gm2eP4r6.js} +1 -1
  143. package/payload/server/public/assets/page-BoPorLg-.js +32 -0
  144. package/payload/server/public/assets/{public-BkNW9e9T.js → public-DqJk6qgW.js} +1 -1
  145. package/payload/server/public/chat.html +2 -2
  146. package/payload/server/public/operator.html +2 -2
  147. package/payload/server/public/public.html +2 -2
  148. package/payload/server/server.js +147 -74
  149. package/payload/platform/lib/mcp-stderr-tee/dist/index.d.ts +0 -69
  150. package/payload/platform/lib/mcp-stderr-tee/dist/index.d.ts.map +0 -1
  151. package/payload/platform/lib/mcp-stderr-tee/dist/index.js +0 -189
  152. package/payload/platform/lib/mcp-stderr-tee/dist/index.js.map +0 -1
  153. package/payload/platform/lib/mcp-stderr-tee/package.json +0 -7
  154. package/payload/platform/lib/mcp-stderr-tee/src/index.ts +0 -197
  155. package/payload/platform/lib/mcp-stderr-tee/tsconfig.json +0 -8
  156. package/payload/server/public/assets/page-84Fdwiu_.js +0 -32
@@ -5,7 +5,7 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <title>Chat — Maxy</title>
7
7
  <link rel="icon" href="/favicon.ico">
8
- <script type="module" crossorigin src="/assets/chat-CufidiBQ.js"></script>
8
+ <script type="module" crossorigin src="/assets/chat-DYT5H81o.js"></script>
9
9
  <link rel="modulepreload" crossorigin href="/assets/chunk-Ck5AOu5v.js">
10
10
  <link rel="modulepreload" crossorigin href="/assets/useSubAccountSwitcher-CU-lOxTd.js">
11
11
  <link rel="modulepreload" crossorigin href="/assets/useSelectionMode-DDmLmPph.js">
@@ -17,7 +17,7 @@
17
17
  <link rel="modulepreload" crossorigin href="/assets/useCopyFeedback-rOWd_lzl.js">
18
18
  <link rel="modulepreload" crossorigin href="/assets/chevron-left-BnpVBu51.js">
19
19
  <link rel="modulepreload" crossorigin href="/assets/rotate-ccw-D_5cETGt.js">
20
- <link rel="modulepreload" crossorigin href="/assets/page-84Fdwiu_.js">
20
+ <link rel="modulepreload" crossorigin href="/assets/page-BoPorLg-.js">
21
21
  <link rel="stylesheet" crossorigin href="/assets/useSubAccountSwitcher-pu0jjLCz.css">
22
22
  <link rel="stylesheet" href="/brand-defaults.css">
23
23
  </head>
@@ -5,7 +5,7 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <title>Operator — Maxy</title>
7
7
  <link rel="icon" href="/favicon.ico">
8
- <script type="module" crossorigin src="/assets/operator-Cj0B_usT.js"></script>
8
+ <script type="module" crossorigin src="/assets/operator-gm2eP4r6.js"></script>
9
9
  <link rel="modulepreload" crossorigin href="/assets/chunk-Ck5AOu5v.js">
10
10
  <link rel="modulepreload" crossorigin href="/assets/useSubAccountSwitcher-CU-lOxTd.js">
11
11
  <link rel="modulepreload" crossorigin href="/assets/useSelectionMode-DDmLmPph.js">
@@ -19,7 +19,7 @@
19
19
  <link rel="modulepreload" crossorigin href="/assets/useCopyFeedback-rOWd_lzl.js">
20
20
  <link rel="modulepreload" crossorigin href="/assets/chevron-left-BnpVBu51.js">
21
21
  <link rel="modulepreload" crossorigin href="/assets/rotate-ccw-D_5cETGt.js">
22
- <link rel="modulepreload" crossorigin href="/assets/page-84Fdwiu_.js">
22
+ <link rel="modulepreload" crossorigin href="/assets/page-BoPorLg-.js">
23
23
  <link rel="stylesheet" crossorigin href="/assets/useSubAccountSwitcher-pu0jjLCz.css">
24
24
  <link rel="stylesheet" crossorigin href="/assets/AdminLoginScreens-CWMpccrR.css">
25
25
  <link rel="stylesheet" href="/brand-defaults.css">
@@ -5,7 +5,7 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <title>Maxy</title>
7
7
  <link rel="icon" href="/favicon.ico">
8
- <script type="module" crossorigin src="/assets/public-BkNW9e9T.js"></script>
8
+ <script type="module" crossorigin src="/assets/public-DqJk6qgW.js"></script>
9
9
  <link rel="modulepreload" crossorigin href="/assets/chunk-Ck5AOu5v.js">
10
10
  <link rel="modulepreload" crossorigin href="/assets/useSubAccountSwitcher-CU-lOxTd.js">
11
11
  <link rel="modulepreload" crossorigin href="/assets/useSelectionMode-DDmLmPph.js">
@@ -17,7 +17,7 @@
17
17
  <link rel="modulepreload" crossorigin href="/assets/useCopyFeedback-rOWd_lzl.js">
18
18
  <link rel="modulepreload" crossorigin href="/assets/chevron-left-BnpVBu51.js">
19
19
  <link rel="modulepreload" crossorigin href="/assets/rotate-ccw-D_5cETGt.js">
20
- <link rel="modulepreload" crossorigin href="/assets/page-84Fdwiu_.js">
20
+ <link rel="modulepreload" crossorigin href="/assets/page-BoPorLg-.js">
21
21
  <link rel="stylesheet" crossorigin href="/assets/useSubAccountSwitcher-pu0jjLCz.css">
22
22
  <link rel="stylesheet" href="/brand-defaults.css">
23
23
  </head>
@@ -2188,6 +2188,7 @@ import {
2188
2188
  } from "@whiskeysockets/baileys";
2189
2189
  import { createRequire } from "module";
2190
2190
  var TAG2 = "[whatsapp:session]";
2191
+ var WIRE_TAG = "[whatsapp:wire]";
2191
2192
  var baileysPkgVersion = (() => {
2192
2193
  try {
2193
2194
  const req = createRequire(import.meta.url);
@@ -2408,6 +2409,12 @@ async function createWaSocket(opts) {
2408
2409
  sock.ws.on("error", (err) => {
2409
2410
  console.error(`${TAG2} WebSocket error: ${String(err)}`);
2410
2411
  });
2412
+ sock.ws.on("CB:message", (node) => {
2413
+ const attrs = node?.attrs ?? {};
2414
+ console.error(
2415
+ `${WIRE_TAG} op=stanza msgId=${attrs.id ?? "none"} from=${attrs.from ?? "none"} type=${attrs.type ?? "none"} offline=${attrs.offline ?? "none"} account=${acct}`
2416
+ );
2417
+ });
2411
2418
  }
2412
2419
  return sock;
2413
2420
  }
@@ -3136,6 +3143,12 @@ function readAllConversations(platformAccountId) {
3136
3143
  return out;
3137
3144
  }
3138
3145
 
3146
+ // app/lib/whatsapp/echo-already-recorded.ts
3147
+ function echoAlreadyRecorded(args) {
3148
+ const messageId = `whatsapp-live:${args.accountId}:${args.remoteJid}:${args.msgKeyId}`;
3149
+ return args.readConversation(args.platformAccountId, args.canonicalRemoteJid).some((r) => r.messageId === messageId);
3150
+ }
3151
+
3139
3152
  // app/lib/whatsapp/managed-account.ts
3140
3153
  function normalizeEntry(v) {
3141
3154
  return typeof v === "string" ? { account: v, mode: "active" } : { account: v.managesAccount, mode: v.mode ?? "active" };
@@ -3848,7 +3861,7 @@ async function persistWhatsAppMessage(input) {
3848
3861
  return { messageId, created: false, senderElementId };
3849
3862
  }
3850
3863
  console.error(
3851
- `${TAG7} write messageId=${messageId} accountId=${input.platformAccountId} cacheKey=${input.cacheKey} fromMe=${input.fromMe} dateSent=${dateSentIso} bodyBytes=${Buffer.byteLength(input.body, "utf8")} ms=${ms}`
3864
+ `${TAG7} write messageId=${messageId} accountId=${input.platformAccountId} cacheKey=${input.cacheKey} fromMe=${input.fromMe} dateSent=${dateSentIso} bodyBytes=${Buffer.byteLength(input.body, "utf8")} attachment=${input.attachmentId ?? "none"} ms=${ms}`
3852
3865
  );
3853
3866
  return { messageId, created: true, senderElementId };
3854
3867
  } catch (err) {
@@ -5271,14 +5284,6 @@ async function registerLoginSocket(accountId, sock, authDir) {
5271
5284
  throw err;
5272
5285
  }
5273
5286
  await stopConnection(accountId);
5274
- const selfId = readSelfId(authDir);
5275
- const rawLidMapping = sock.signalRepository?.lidMapping ?? null;
5276
- const lidMapping = withSelfLidShortcut(rawLidMapping, selfId.lid, selfId.jid);
5277
- if (selfId.lid) {
5278
- console.error(`[whatsapp:lid] resolved self-lid accountId=${accountId} selfLid=${selfId.lid} source=creds`);
5279
- } else {
5280
- console.error(`[whatsapp:lid] FAIL self-lid-resolution accountId=${accountId} reason=creds-missing-lid`);
5281
- }
5282
5287
  const conn = {
5283
5288
  accountId,
5284
5289
  platformAccountId,
@@ -5286,16 +5291,18 @@ async function registerLoginSocket(accountId, sock, authDir) {
5286
5291
  authDir,
5287
5292
  sock,
5288
5293
  connected: true,
5289
- selfPhone: selfId.e164,
5290
- selfJid: selfId.jid,
5291
- selfLid: selfId.lid,
5294
+ selfPhone: null,
5295
+ selfJid: null,
5296
+ selfLid: null,
5292
5297
  reconnectAttempts: 0,
5293
5298
  lastConnectedAt: Date.now(),
5294
5299
  abortController: new AbortController(),
5295
5300
  debouncer: null,
5296
- lidMapping
5301
+ lidMapping: null
5297
5302
  };
5303
+ applySelfIdentity(conn, sock, "register");
5298
5304
  connections.set(accountId, conn);
5305
+ monitorInbound(conn);
5299
5306
  try {
5300
5307
  await sock.sendPresenceUpdate("available");
5301
5308
  console.error(`${TAG13} presence set to available account=${accountId}`);
@@ -5309,10 +5316,9 @@ async function registerLoginSocket(accountId, sock, authDir) {
5309
5316
  attempt: 0,
5310
5317
  signal: conn.abortController.signal
5311
5318
  });
5312
- monitorInbound(conn);
5313
5319
  watchForDisconnect(conn);
5314
5320
  attachSelfIdRefreshOnCredsUpdate(conn);
5315
- console.error(`${TAG13} registered login socket for account=${accountId} phone=${selfId.e164 ?? "unknown"}`);
5321
+ console.error(`${TAG13} registered login socket for account=${accountId} phone=${conn.selfPhone ?? "unknown"}`);
5316
5322
  }
5317
5323
  function attachSelfIdRefreshOnCredsUpdate(conn) {
5318
5324
  if (!conn.sock) return;
@@ -5392,30 +5398,27 @@ async function connectWithReconnect(conn) {
5392
5398
  let connectedAt;
5393
5399
  try {
5394
5400
  console.error(`${TAG13} connecting account=${conn.accountId} attempt=${conn.reconnectAttempts}`);
5401
+ if (conn.debouncer) {
5402
+ await conn.debouncer.destroy();
5403
+ conn.debouncer = null;
5404
+ }
5395
5405
  const sock = await createWaSocket({
5396
5406
  authDir: conn.authDir,
5397
- silent: true
5407
+ silent: true,
5408
+ account: conn.accountId
5398
5409
  });
5399
5410
  conn.sock = sock;
5411
+ applySelfIdentity(conn, sock, "pre-listener");
5412
+ monitorInbound(conn);
5400
5413
  console.error(`${TAG13} socket created account=${conn.accountId} \u2014 waiting for connection`);
5401
5414
  await waitForConnection(sock);
5402
- const selfId = readSelfId(conn.authDir);
5403
5415
  connectedAt = Date.now();
5404
5416
  conn.connected = true;
5405
- conn.selfPhone = selfId.e164;
5406
- conn.selfJid = selfId.jid;
5407
- conn.selfLid = selfId.lid;
5408
5417
  conn.lastConnectedAt = connectedAt;
5409
5418
  conn.lastError = void 0;
5410
5419
  conn.terminalReason = void 0;
5411
- const rawLidMapping = sock.signalRepository?.lidMapping ?? null;
5412
- conn.lidMapping = withSelfLidShortcut(rawLidMapping, selfId.lid, selfId.jid);
5413
- if (selfId.lid) {
5414
- console.error(`[whatsapp:lid] resolved self-lid accountId=${conn.accountId} selfLid=${selfId.lid} source=creds`);
5415
- } else {
5416
- console.error(`[whatsapp:lid] FAIL self-lid-resolution accountId=${conn.accountId} reason=creds-missing-lid`);
5417
- }
5418
- console.error(`${TAG13} connected account=${conn.accountId} phone=${selfId.e164 ?? "unknown"}`);
5420
+ applySelfIdentity(conn, sock, "post-connect");
5421
+ console.error(`${TAG13} connected account=${conn.accountId} phone=${conn.selfPhone ?? "unknown"}`);
5419
5422
  try {
5420
5423
  await sock.sendPresenceUpdate("available");
5421
5424
  console.error(`${TAG13} presence set to available account=${conn.accountId}`);
@@ -5429,11 +5432,6 @@ async function connectWithReconnect(conn) {
5429
5432
  attempt: conn.reconnectAttempts,
5430
5433
  signal: conn.abortController.signal
5431
5434
  });
5432
- if (conn.debouncer) {
5433
- await conn.debouncer.destroy();
5434
- conn.debouncer = null;
5435
- }
5436
- monitorInbound(conn);
5437
5435
  attachSelfIdRefreshOnCredsUpdate(conn);
5438
5436
  await waitForDisconnectEvent(conn);
5439
5437
  uptimeMs = Date.now() - connectedAt;
@@ -5526,6 +5524,23 @@ function watchForDisconnect(conn) {
5526
5524
  }
5527
5525
  });
5528
5526
  }
5527
+ function applySelfIdentity(conn, sock, phase) {
5528
+ const selfId = readSelfId(conn.authDir);
5529
+ conn.selfPhone = selfId.e164;
5530
+ conn.selfJid = selfId.jid;
5531
+ conn.selfLid = selfId.lid;
5532
+ const rawLidMapping = sock.signalRepository?.lidMapping ?? null;
5533
+ conn.lidMapping = withSelfLidShortcut(rawLidMapping, selfId.lid, selfId.jid);
5534
+ if (selfId.lid) {
5535
+ console.error(
5536
+ `[whatsapp:lid] resolved self-lid accountId=${conn.accountId} selfLid=${selfId.lid} source=creds phase=${phase}`
5537
+ );
5538
+ } else {
5539
+ console.error(
5540
+ `[whatsapp:lid] FAIL self-lid-resolution accountId=${conn.accountId} reason=creds-missing-lid phase=${phase}`
5541
+ );
5542
+ }
5543
+ }
5529
5544
  function monitorInbound(conn) {
5530
5545
  if (!conn.sock || !onInboundMessage) return;
5531
5546
  const sock = conn.sock;
@@ -5612,7 +5627,20 @@ function monitorInbound(conn) {
5612
5627
  remoteJid,
5613
5628
  conn.lidMapping
5614
5629
  );
5615
- const wantsServableMedia = mediaServable && !fromMe && !!conn.sock;
5630
+ const alreadyRecorded = fromMe && echoAlreadyRecorded({
5631
+ readConversation,
5632
+ platformAccountId: conn.platformAccountId,
5633
+ canonicalRemoteJid,
5634
+ accountId: conn.accountId,
5635
+ remoteJid,
5636
+ msgKeyId: msg.key.id
5637
+ });
5638
+ const wantsServableMedia = mediaServable && !!conn.sock && (!fromMe || !alreadyRecorded);
5639
+ if (fromMe && mediaServable && !!conn.sock) {
5640
+ console.error(
5641
+ `${TAG13} fromMe-media-echo msgKey=${msg.key.id} decision=${alreadyRecorded ? "skip" : "store"} reason=${alreadyRecorded ? "already-recorded" : "no-prior-record"}`
5642
+ );
5643
+ }
5616
5644
  const mediaSeed = `whatsapp-live:${conn.accountId}:${canonicalRemoteJid}:${msg.key.id}`;
5617
5645
  const maxBytes = (whatsAppConfig.mediaMaxMb ?? 50) * 1024 * 1024;
5618
5646
  const basePersist = {
@@ -5730,8 +5758,10 @@ function monitorInbound(conn) {
5730
5758
  }));
5731
5759
  continue;
5732
5760
  }
5761
+ const skippedSenderJid = isGroupJid(remoteJid) ? msg.key.participant ?? remoteJid : remoteJid;
5762
+ const skippedSenderPhone = await resolveJidToE164(skippedSenderJid, conn.lidMapping) ?? skippedSenderJid;
5733
5763
  console.error(
5734
- `${TAG13} append-type message ${msg.key.id ?? "?"} stored, dispatch skipped account=${conn.accountId}`
5764
+ `${TAG13} append-type message ${msg.key.id ?? "?"} dispatch skipped from=${skippedSenderPhone}${msg.pushName ? ` name=${msg.pushName}` : ""} account=${conn.accountId} (persistence not confirmed here)`
5735
5765
  );
5736
5766
  continue;
5737
5767
  }
@@ -6866,7 +6896,6 @@ function parseScheduleProvenance(v) {
6866
6896
 
6867
6897
  // server/routes/channel/schedule-inject.ts
6868
6898
  var TAG16 = "[schedule-inject]";
6869
- var UUID_V4 = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
6870
6899
  function isLoopbackAddr(addr) {
6871
6900
  return addr === "127.0.0.1" || addr === "::1" || addr === "::ffff:127.0.0.1";
6872
6901
  }
@@ -6899,7 +6928,6 @@ function createScheduleInjectRoutes(deps) {
6899
6928
  const prompt = typeof body.prompt === "string" ? body.prompt : "";
6900
6929
  const eventId = typeof body.eventId === "string" ? body.eventId : "";
6901
6930
  const scheduleProvenance = parseScheduleProvenance(body.scheduleProvenance);
6902
- const overrideSessionId = typeof body.sessionId === "string" && UUID_V4.test(body.sessionId) ? body.sessionId : void 0;
6903
6931
  if (channel !== "whatsapp" && channel !== "telegram" || !destination || !prompt) {
6904
6932
  console.error(`${TAG16} reject reason=bad-request channel=${String(channel)} hasDestination=${Boolean(destination)} hasPrompt=${Boolean(prompt)}`);
6905
6933
  return c.json({ ok: false, error: "schedule-inject-bad-request" }, 400);
@@ -6918,7 +6946,7 @@ function createScheduleInjectRoutes(deps) {
6918
6946
  return c.json({ ok: false, error: "account-manager-unresolved" }, 403);
6919
6947
  }
6920
6948
  console.error(`${TAG16} op=effective-account eventId=${eventId} effectiveAccount=${effectiveAccount2}`);
6921
- const sessionId2 = overrideSessionId ?? adminSessionIdFor(effectiveAccount2, destination);
6949
+ const sessionId2 = adminSessionIdFor(effectiveAccount2, normalizeTarget(destination) ?? destination);
6922
6950
  const reply2 = (text) => deps.sendWhatsAppText(houseAccountId, destination, text);
6923
6951
  try {
6924
6952
  await deps.waHandleInbound({
@@ -6936,7 +6964,6 @@ function createScheduleInjectRoutes(deps) {
6936
6964
  media: [],
6937
6965
  source: "schedule",
6938
6966
  scheduleProvenance,
6939
- scheduledSessionId: overrideSessionId,
6940
6967
  reply: reply2
6941
6968
  });
6942
6969
  } catch (err) {
@@ -6954,7 +6981,7 @@ function createScheduleInjectRoutes(deps) {
6954
6981
  return c.json({ ok: false, error: "no-admin-bot-token" }, 400);
6955
6982
  }
6956
6983
  const chatId = Number(destination);
6957
- const sessionId = overrideSessionId ?? adminSessionIdFor(effectiveAccount, destination);
6984
+ const sessionId = adminSessionIdFor(effectiveAccount, destination);
6958
6985
  const reply = (text) => deps.sendTelegramText(botToken, chatId, text);
6959
6986
  try {
6960
6987
  await deps.tgHandleInbound({
@@ -6966,7 +6993,6 @@ function createScheduleInjectRoutes(deps) {
6966
6993
  text: prompt,
6967
6994
  source: "schedule",
6968
6995
  scheduleProvenance,
6969
- scheduledSessionId: overrideSessionId,
6970
6996
  reply
6971
6997
  });
6972
6998
  } catch (err) {
@@ -6980,7 +7006,7 @@ function createScheduleInjectRoutes(deps) {
6980
7006
  }
6981
7007
 
6982
7008
  // server/index.ts
6983
- var import_dist8 = __toESM(require_dist(), 1);
7009
+ var import_dist9 = __toESM(require_dist(), 1);
6984
7010
 
6985
7011
  // app/lib/telegram/outbound/send-text.ts
6986
7012
  async function sendTelegramText(botToken, chatId, text) {
@@ -7803,18 +7829,27 @@ async function sendWhatsAppDocument(input) {
7803
7829
  }
7804
7830
  const filename = basename3(resolvedPath);
7805
7831
  const jid = normalizeJid2(to);
7806
- const sock = getSocket(accountId);
7807
- if (!sock) {
7808
- console.error(`${TAG19} sent document to=${jid} file=${filename} bytes=${fileStat.size} ok=false reason=not-connected`);
7809
- return { ok: false, status: 503, error: `WhatsApp account "${accountId}" is not connected` };
7832
+ const res = resolveSocket(accountId);
7833
+ if (!res.ok) {
7834
+ const reason = res.reason === "key-miss" ? `key-miss presentKeys=${res.presentKeys.join(",") || "none"}` : "disconnected";
7835
+ console.error(`${TAG19} sent document to=${jid} file=${filename} bytes=${fileStat.size} ok=false reason=${reason}`);
7836
+ if (res.reason === "key-miss") {
7837
+ return {
7838
+ ok: false,
7839
+ status: 503,
7840
+ error: `WhatsApp socket key miss: no socket is registered for accountId=${accountId} (present keys: ${res.presentKeys.join(",") || "none"}). This is an account-keying fault, not a dropped link \u2014 do not advise re-pairing.`
7841
+ };
7842
+ }
7843
+ return { ok: false, status: 503, error: `WhatsApp account "${accountId}" is registered but its transport is down.` };
7810
7844
  }
7845
+ const sock = res.sock;
7811
7846
  const buffer = Buffer.from(await readFile(resolvedPath));
7812
7847
  const mimetype = detectMimeType(resolvedPath);
7813
7848
  const result = await sendMediaMessage(
7814
7849
  sock,
7815
7850
  to,
7816
7851
  { type: "document", buffer, mimetype, filename, caption },
7817
- { accountId }
7852
+ { accountId: res.accountId }
7818
7853
  );
7819
7854
  console.error(
7820
7855
  `${TAG19} sent document to=${jid} file=${filename} bytes=${fileStat.size} ok=${result.success}` + (result.messageId ? ` id=${result.messageId}` : "")
@@ -24211,14 +24246,14 @@ var WaGateway = class {
24211
24246
  },
24212
24247
  Date.now()
24213
24248
  );
24249
+ const resolvedSessionId = adminSessionIdFor(
24250
+ input.effectiveAccountId,
24251
+ senderId,
24252
+ input.role === "public" && input.personId ? input.personId : void 0
24253
+ );
24214
24254
  console.error(
24215
- `[whatsapp-native] op=inbound senderId=${senderId} accountId=${input.accountId} bytes=${bytes} ${mediaField} source=${source} delivery=${willDeliverNow ? "immediate" : "queued"}`
24255
+ `[whatsapp-native] op=inbound senderId=${senderId} accountId=${input.accountId} bytes=${bytes} ${mediaField} source=${source} delivery=${willDeliverNow ? "immediate" : "queued"} sessionId=${resolvedSessionId}`
24216
24256
  );
24217
- if (source === "schedule" && (hadSubscriber || this.spawning.has(senderId))) {
24218
- console.error(
24219
- `[whatsapp-native] op=coalesced-onto-live-session eventId=${input.scheduleProvenance?.eventId ?? "-"} senderId=${senderId} droppedSeat=${input.scheduledSessionId ?? "-"} reason=${hadSubscriber ? "live-subscriber" : "spawn-in-flight"}`
24220
- );
24221
- }
24222
24257
  if (!hadSubscriber && !this.spawning.has(senderId)) {
24223
24258
  this.spawning.add(senderId);
24224
24259
  console.error(`[whatsapp-native] op=spawn-trigger senderId=${senderId}`);
@@ -24231,8 +24266,6 @@ var WaGateway = class {
24231
24266
  personId: input.personId ?? null,
24232
24267
  gatewayUrl: this.deps.gatewayUrl,
24233
24268
  serverPath: this.deps.serverPath,
24234
- // Task 1526 — a scheduled firing's per-firing seat id; absent on real inbound.
24235
- sessionIdOverride: input.scheduledSessionId,
24236
24269
  // Task 1575 — the gate's owner-self verdict; drives owner attribution
24237
24270
  // for an unbound owner self-phone at the spawn site.
24238
24271
  ownerSelfPhone: input.ownerSelfPhone
@@ -24286,7 +24319,12 @@ function logDuplicateSenderGroups(groups) {
24286
24319
  function buildWaSpawnRequest(input) {
24287
24320
  const personId = input.role === "public" && input.personId ? input.personId : void 0;
24288
24321
  return {
24289
- sessionId: input.sessionIdOverride && input.sessionIdOverride.length > 0 ? input.sessionIdOverride : adminSessionIdFor(input.accountId, input.senderId, personId),
24322
+ // Task 1746 the deterministic per-sender id is the ONLY id a sender's
24323
+ // session ever has. Task 1526's per-firing seat override used to replace it
24324
+ // on a scheduled cold start, which spawned a second session for the sender;
24325
+ // that session then attached under the sender's own hub key and swallowed
24326
+ // their real messages until it detached, splitting the conversation in two.
24327
+ sessionId: adminSessionIdFor(input.accountId, input.senderId, personId),
24290
24328
  role: input.role,
24291
24329
  channel: "whatsapp",
24292
24330
  personId,
@@ -25773,14 +25811,14 @@ var TelegramGateway = class {
25773
25811
  { key: input.senderId, text: input.text, messageId: `tg-${++this.seq}`, source, standingRules, scheduleProvenance: input.scheduleProvenance },
25774
25812
  Date.now()
25775
25813
  );
25814
+ const resolvedSessionId = adminSessionIdFor(
25815
+ input.accountId,
25816
+ input.senderId,
25817
+ input.role === "public" && input.personId ? input.personId : void 0
25818
+ );
25776
25819
  console.error(
25777
- `[telegram-native] op=inbound key=${input.senderId} accountId=${input.accountId} botType=${input.role} bytes=${bytes} source=${source} delivery=${willDeliverNow ? "immediate" : "queued"}`
25820
+ `[telegram-native] op=inbound key=${input.senderId} accountId=${input.accountId} botType=${input.role} bytes=${bytes} source=${source} delivery=${willDeliverNow ? "immediate" : "queued"} sessionId=${resolvedSessionId}`
25778
25821
  );
25779
- if (source === "schedule" && (hadSubscriber || this.spawning.has(input.senderId))) {
25780
- console.error(
25781
- `[telegram-native] op=coalesced-onto-live-session eventId=${input.scheduleProvenance?.eventId ?? "-"} senderId=${input.senderId} droppedSeat=${input.scheduledSessionId ?? "-"} reason=${hadSubscriber ? "live-subscriber" : "spawn-in-flight"}`
25782
- );
25783
- }
25784
25822
  if (!hadSubscriber && !this.spawning.has(input.senderId)) {
25785
25823
  this.spawning.add(input.senderId);
25786
25824
  console.error(`[telegram-native] op=spawn-trigger key=${input.senderId} role=${input.role}`);
@@ -25792,9 +25830,7 @@ var TelegramGateway = class {
25792
25830
  personId: input.personId ?? null,
25793
25831
  chatId: input.chatId,
25794
25832
  gatewayUrl: this.deps.gatewayUrl,
25795
- serverPath: this.deps.serverPath,
25796
- // Task 1526 — a scheduled firing's per-firing seat id; absent on real inbound.
25797
- sessionIdOverride: input.scheduledSessionId
25833
+ serverPath: this.deps.serverPath
25798
25834
  });
25799
25835
  } finally {
25800
25836
  this.spawning.delete(input.senderId);
@@ -25812,7 +25848,10 @@ var TelegramGateway = class {
25812
25848
  function buildTelegramSpawnRequest(input) {
25813
25849
  const personId = input.role === "public" && input.personId ? input.personId : void 0;
25814
25850
  return {
25815
- sessionId: input.sessionIdOverride && input.sessionIdOverride.length > 0 ? input.sessionIdOverride : adminSessionIdFor(input.accountId, input.senderId, personId),
25851
+ // Task 1746 the deterministic per-sender id is the ONLY id a sender's
25852
+ // session ever has. Mirror of the WhatsApp builder; see its comment for why
25853
+ // Task 1526's per-firing override was removed.
25854
+ sessionId: adminSessionIdFor(input.accountId, input.senderId, personId),
25816
25855
  role: input.role,
25817
25856
  channel: "telegram",
25818
25857
  personId,
@@ -26130,6 +26169,31 @@ async function firePublicSessionEndReview(input) {
26130
26169
  );
26131
26170
  }
26132
26171
 
26172
+ // app/lib/whatsapp/inbound/resolve-client-graph-owner.ts
26173
+ var import_dist8 = __toESM(require_dist(), 1);
26174
+ async function resolveClientOwnerUserId(accountId, deps = {}) {
26175
+ const listAccounts = deps.listAccounts ?? listValidAccounts;
26176
+ const getSession4 = deps.getSession ?? getSession;
26177
+ const resolveOwner2 = deps.resolveOwner ?? import_dist8.resolveOwnerUserId;
26178
+ const role = listAccounts().find((a) => a.accountId === accountId)?.config.role;
26179
+ if (role !== "client") return null;
26180
+ const session = getSession4();
26181
+ try {
26182
+ return await resolveOwner2(session, accountId);
26183
+ } catch (err) {
26184
+ console.error(
26185
+ `[whatsapp-native] op=graph-owner-error account=${accountId} error=${err instanceof Error ? err.message : String(err)}`
26186
+ );
26187
+ return null;
26188
+ } finally {
26189
+ await session.close().catch((err) => {
26190
+ console.error(
26191
+ `[whatsapp-native] op=graph-owner-close-error account=${accountId} error=${err instanceof Error ? err.message : String(err)}`
26192
+ );
26193
+ });
26194
+ }
26195
+ }
26196
+
26133
26197
  // app/lib/whatsapp/inbound/channel-admin-binding-drift.ts
26134
26198
  function findAccountManagerDrift(accountManagers, adminPhones, validAccountIds) {
26135
26199
  const drift = [];
@@ -26547,8 +26611,8 @@ var webchatFileFollowers = /* @__PURE__ */ new Map();
26547
26611
  async function fetchAccountStandingRules(accountId) {
26548
26612
  const session = getSession();
26549
26613
  try {
26550
- const res = await (0, import_dist8.resolveActiveRules)(session, accountId);
26551
- return { block: (0, import_dist8.formatStandingRulesBlock)(res.rules), ownerUserId: res.ownerUserId, source: res.source };
26614
+ const res = await (0, import_dist9.resolveActiveRules)(session, accountId);
26615
+ return { block: (0, import_dist9.formatStandingRulesBlock)(res.rules), ownerUserId: res.ownerUserId, source: res.source };
26552
26616
  } catch (err) {
26553
26617
  console.error(
26554
26618
  `[preference-inject] op=fetch-failed accountId=${accountId} error=${err instanceof Error ? err.message : String(err)}`
@@ -26600,7 +26664,7 @@ var waGateway = new WaGateway({
26600
26664
  });
26601
26665
  return result.ok ? { ok: true, messageId: result.messageId } : { ok: false, error: result.error };
26602
26666
  },
26603
- ensureChannelSession: async ({ accountId, effectiveAccountId, senderId, role, personId, gatewayUrl, serverPath, passive, text, msgId, sessionIdOverride, ownerSelfPhone }) => {
26667
+ ensureChannelSession: async ({ accountId, effectiveAccountId, senderId, role, personId, gatewayUrl, serverPath, passive, text, msgId, ownerSelfPhone }) => {
26604
26668
  if (passive) {
26605
26669
  const phoneHash = createHash7("sha256").update(senderId).digest("hex").slice(0, 12);
26606
26670
  const prompt = (text ?? "").trim();
@@ -26648,11 +26712,20 @@ var waGateway = new WaGateway({
26648
26712
  const managesAccount = effectiveAccountId !== accountId ? effectiveAccountId : "none";
26649
26713
  console.error(`[whatsapp-native] op=account-manager-route senderId=${senderId} managesAccount=${managesAccount} effectiveAccount=${effectiveAccountId} source=gate`);
26650
26714
  }
26651
- const req = buildWaSpawnRequest({ accountId: effectiveAccountId, senderId, role, personId, gatewayUrl, serverPath, sessionIdOverride });
26652
- const userId = role === "admin" ? resolveAdminUserId({ accountId: effectiveAccountId, senderPhone: senderId }) ?? (ownerSelfPhone ? resolveOwnerUserId(effectiveAccountId) ?? void 0 : void 0) : void 0;
26715
+ const req = buildWaSpawnRequest({ accountId: effectiveAccountId, senderId, role, personId, gatewayUrl, serverPath });
26716
+ let userId = role === "admin" ? resolveAdminUserId({ accountId: effectiveAccountId, senderPhone: senderId }) ?? (ownerSelfPhone ? resolveOwnerUserId(effectiveAccountId) ?? void 0 : void 0) : void 0;
26717
+ let graphOwnerResolved = false;
26718
+ if (role === "admin" && userId === void 0) {
26719
+ const graphOwner = await resolveClientOwnerUserId(effectiveAccountId);
26720
+ if (graphOwner) {
26721
+ userId = graphOwner;
26722
+ graphOwnerResolved = true;
26723
+ }
26724
+ }
26653
26725
  if (role === "admin") {
26654
26726
  const attribution = userId ?? (ownerSelfPhone ? "owner-self-unresolved" : "unbound-empty");
26655
- console.error(`[whatsapp-native] op=admin-identity senderId=${senderId} userId=${attribution}`);
26727
+ const sourceSuffix = graphOwnerResolved ? " source=graph-owner" : "";
26728
+ console.error(`[whatsapp-native] op=admin-identity senderId=${senderId} userId=${attribution}${sourceSuffix}`);
26656
26729
  }
26657
26730
  const result = await managerRcSpawn({ ...req, userId });
26658
26731
  if ("error" in result) {
@@ -26804,8 +26877,8 @@ var telegramGateway = new TelegramGateway({
26804
26877
  fetchStandingRules: fetchAccountStandingRules,
26805
26878
  gatewayUrl: telegramGatewayUrl(),
26806
26879
  serverPath: telegramServerPath(),
26807
- ensureChannelSession: async ({ accountId, senderId, role, personId, chatId, gatewayUrl, serverPath, sessionIdOverride }) => {
26808
- const req = buildTelegramSpawnRequest({ accountId, senderId, role, personId, gatewayUrl, serverPath, sessionIdOverride });
26880
+ ensureChannelSession: async ({ accountId, senderId, role, personId, chatId, gatewayUrl, serverPath }) => {
26881
+ const req = buildTelegramSpawnRequest({ accountId, senderId, role, personId, gatewayUrl, serverPath });
26809
26882
  const result = await managerRcSpawn(req);
26810
26883
  if ("error" in result) {
26811
26884
  console.error(`[telegram-native] spawn-failed senderId=${senderId} role=${role} error=${result.error} status=${result.status}`);
@@ -1,69 +0,0 @@
1
- /**
2
- * MCP server stderr tee — per-conversation stream-log capture.
3
- *
4
- * Claude Code spawns MCP servers as child processes and consumes their stderr
5
- * internally. The platform cannot intercept at the spawn level. Each server
6
- * must tee its own stderr so diagnostic output is retrievable.
7
- *
8
- * This module owns ONE destination: the per-conversation stream log. The raw
9
- * per-server sink belongs to mcp-spawn-tee (`mcp-<name>-<SESSION_ID>.log`),
10
- * which is every spawned caller's real parent and writes with appendFileSync.
11
- * Task 1721 retired this module's own raw file: it was date-named after the
12
- * process's boot day, no reader parsed that date, and mcp-spawn-tee wrote the
13
- * same path, so every line landed twice.
14
- *
15
- * ┌─────────────────────────┐
16
- * │ MCP server process │
17
- * │ │
18
- * │ console.error("[x] ..") │
19
- * │ │ │
20
- * │ ▼ │
21
- * │ patched stderr.write() │
22
- * │ │ │
23
- * │ ├──► original stderr (consumed by Claude Code — opaque)
24
- * │ │
25
- * │ └──► $STREAM_LOG_PATH (per-line, prefixed)
26
- * │ "[<iso>] [mcp:{name}] <line>"
27
- * └─────────────────────────┘
28
- *
29
- * $STREAM_LOG_PATH is meant to be set by the spawner to the per-conversation
30
- * stream log file. The MCP server code itself knows nothing about
31
- * conversations — it just trusts the spawner's path. This is the scope
32
- * boundary intended: the tee is attached per spawn, not per MCP-server process
33
- * lifetime. Servers spawned for conversation A write to conversation A's file;
34
- * servers for B write to B's file.
35
- *
36
- * NOTE: no spawner actually sets it. `pty-spawner.ts` and `rc-daemon.ts`'s
37
- * `buildRcChildEnv` stamp LOG_DIR and SESSION_ID but not STREAM_LOG_PATH, and
38
- * the only assignment in the repo is `plugins/memory/mcp/scripts/boot-smoke.sh`
39
- * (a smoke harness). So in production this module takes its skip path and
40
- * patches nothing. The raw bytes are not lost — mcp-spawn-tee writes them to
41
- * the per-session sink regardless. Whether to wire this up or retire the module
42
- * is Task 1736. Do not read the paragraph above as a description of live
43
- * behaviour until that lands.
44
- *
45
- * Every decision is logged via `[mcp-tee-*]` markers on both the target file
46
- * and the original stderr so an investigator can confirm from the stream log
47
- * which tees were wired up, which were skipped, and why.
48
- */
49
- /**
50
- * Patch process.stderr.write to tee to:
51
- * 1. The per-conversation stream log at `STREAM_LOG_PATH` — per-line, prefixed.
52
- * 2. The original stderr (consumed by Claude Code) — always preserved.
53
- *
54
- * STREAM_LOG_PATH absent → skip the stream-log destination (older spawner or
55
- * standalone invocation) and leave stderr entirely unpatched. A
56
- * `[mcp-tee-skip]` marker is written to original stderr so the skip is
57
- * visible to journalctl-level readers.
58
- *
59
- * This module writes NO raw per-server file and holds NO write stream. Task
60
- * 1721 moved the raw sink to mcp-spawn-tee, which is every spawned caller's
61
- * real parent: the two modules were writing the same per-date file, so every
62
- * line landed twice, and the held stream was the sole reason Task 1706 could
63
- * not age-purge these logs.
64
- *
65
- * Safe to call once at MCP server module load. Refused on second call to
66
- * prevent stacking patches.
67
- */
68
- export declare function initStderrTee(serverName: string): void;
69
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AAeH;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAmHtD"}