@rubytech/create-maxy-code 0.1.296 → 0.1.298
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/payload/platform/lib/models/dist/index.d.ts +7 -0
- package/payload/platform/lib/models/dist/index.d.ts.map +1 -1
- package/payload/platform/lib/models/dist/index.js +16 -1
- package/payload/platform/lib/models/dist/index.js.map +1 -1
- package/payload/platform/lib/models/src/index.ts +16 -0
- package/payload/platform/plugins/admin/.claude-plugin/plugin.json +5 -1
- package/payload/platform/plugins/admin/lib/mcp-spawn-tee/index.js +159 -0
- package/payload/platform/plugins/admin/lib/mcp-spawn-tee/package.json +3 -0
- package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +4 -14
- package/payload/platform/plugins/aeo/.claude-plugin/plugin.json +5 -1
- package/payload/platform/plugins/aeo/lib/mcp-spawn-tee/index.js +159 -0
- package/payload/platform/plugins/aeo/lib/mcp-spawn-tee/package.json +3 -0
- package/payload/platform/plugins/browser/.claude-plugin/plugin.json +5 -1
- package/payload/platform/plugins/browser/lib/mcp-spawn-tee/index.js +159 -0
- package/payload/platform/plugins/browser/lib/mcp-spawn-tee/package.json +3 -0
- package/payload/platform/plugins/contacts/.claude-plugin/plugin.json +5 -1
- package/payload/platform/plugins/contacts/lib/mcp-spawn-tee/index.js +159 -0
- package/payload/platform/plugins/contacts/lib/mcp-spawn-tee/package.json +3 -0
- package/payload/platform/plugins/docs/references/admin-ui.md +1 -1
- package/payload/platform/plugins/docs/references/getting-started.md +1 -1
- package/payload/platform/plugins/docs/references/platform.md +1 -11
- package/payload/platform/plugins/email/.claude-plugin/plugin.json +6 -2
- package/payload/platform/plugins/email/PLUGIN.md +14 -2
- package/payload/platform/plugins/email/lib/mcp-spawn-tee/index.js +159 -0
- package/payload/platform/plugins/email/lib/mcp-spawn-tee/package.json +3 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/email-draft-edit.test.d.ts +2 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/email-draft-edit.test.d.ts.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/email-draft-edit.test.js +71 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/email-draft-edit.test.js.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/email-draft-send.test.d.ts +2 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/email-draft-send.test.d.ts.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/email-draft-send.test.js +95 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/email-draft-send.test.js.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/email-draft.test.d.ts +2 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/email-draft.test.d.ts.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/email-draft.test.js +129 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/email-draft.test.js.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/email-setup.test.js +58 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/email-setup.test.js.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/__tests__/imap-drafts.test.d.ts +2 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/imap-drafts.test.d.ts.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/imap-drafts.test.js +165 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/imap-drafts.test.js.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/imap-probe.test.d.ts +2 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/imap-probe.test.d.ts.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/imap-probe.test.js +69 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/imap-probe.test.js.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/mail-options.test.d.ts +2 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/mail-options.test.d.ts.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/mail-options.test.js +46 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/mail-options.test.js.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/send-raw.test.d.ts +2 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/send-raw.test.d.ts.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/send-raw.test.js +38 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/send-raw.test.js.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/setup-probe.test.d.ts +2 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/setup-probe.test.d.ts.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/setup-probe.test.js +56 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/setup-probe.test.js.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/smtp-probe.test.d.ts +2 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/smtp-probe.test.d.ts.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/smtp-probe.test.js +46 -0
- package/payload/platform/plugins/email/mcp/dist/__tests__/smtp-probe.test.js.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/index.js +118 -0
- package/payload/platform/plugins/email/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/lib/compose.d.ts +47 -0
- package/payload/platform/plugins/email/mcp/dist/lib/compose.d.ts.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/lib/compose.js +75 -0
- package/payload/platform/plugins/email/mcp/dist/lib/compose.js.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/lib/imap.d.ts +53 -3
- package/payload/platform/plugins/email/mcp/dist/lib/imap.d.ts.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/lib/imap.js +179 -5
- package/payload/platform/plugins/email/mcp/dist/lib/imap.js.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/lib/setup-probe.d.ts +42 -0
- package/payload/platform/plugins/email/mcp/dist/lib/setup-probe.d.ts.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/lib/setup-probe.js +72 -0
- package/payload/platform/plugins/email/mcp/dist/lib/setup-probe.js.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/lib/smtp.d.ts +34 -6
- package/payload/platform/plugins/email/mcp/dist/lib/smtp.d.ts.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/lib/smtp.js +62 -20
- package/payload/platform/plugins/email/mcp/dist/lib/smtp.js.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/scripts/send-transactional.js +1 -2
- package/payload/platform/plugins/email/mcp/dist/scripts/send-transactional.js.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/tools/email-draft-edit.d.ts +9 -0
- package/payload/platform/plugins/email/mcp/dist/tools/email-draft-edit.d.ts.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/tools/email-draft-edit.js +23 -0
- package/payload/platform/plugins/email/mcp/dist/tools/email-draft-edit.js.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/tools/email-draft-send.d.ts +8 -0
- package/payload/platform/plugins/email/mcp/dist/tools/email-draft-send.d.ts.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/tools/email-draft-send.js +52 -0
- package/payload/platform/plugins/email/mcp/dist/tools/email-draft-send.js.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/tools/email-draft.d.ts +7 -0
- package/payload/platform/plugins/email/mcp/dist/tools/email-draft.d.ts.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/tools/email-draft.js +17 -0
- package/payload/platform/plugins/email/mcp/dist/tools/email-draft.js.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/tools/email-reply.d.ts.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/tools/email-reply.js +1 -8
- package/payload/platform/plugins/email/mcp/dist/tools/email-reply.js.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/tools/email-send.d.ts.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/tools/email-send.js +2 -8
- package/payload/platform/plugins/email/mcp/dist/tools/email-send.js.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/tools/email-setup.d.ts.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/tools/email-setup.js +25 -3
- package/payload/platform/plugins/email/mcp/dist/tools/email-setup.js.map +1 -1
- package/payload/platform/plugins/email/references/email-reference.md +15 -0
- package/payload/platform/plugins/email/skills/email-composition/SKILL.md +26 -4
- package/payload/platform/plugins/memory/.claude-plugin/plugin.json +5 -1
- package/payload/platform/plugins/memory/lib/mcp-spawn-tee/index.js +159 -0
- package/payload/platform/plugins/memory/lib/mcp-spawn-tee/package.json +3 -0
- package/payload/platform/plugins/outlook/.claude-plugin/plugin.json +5 -1
- package/payload/platform/plugins/outlook/lib/mcp-spawn-tee/index.js +159 -0
- package/payload/platform/plugins/outlook/lib/mcp-spawn-tee/package.json +3 -0
- package/payload/platform/plugins/replicate/.claude-plugin/plugin.json +5 -1
- package/payload/platform/plugins/replicate/lib/mcp-spawn-tee/index.js +159 -0
- package/payload/platform/plugins/replicate/lib/mcp-spawn-tee/package.json +3 -0
- package/payload/platform/plugins/scheduling/.claude-plugin/plugin.json +5 -1
- package/payload/platform/plugins/scheduling/lib/mcp-spawn-tee/index.js +159 -0
- package/payload/platform/plugins/scheduling/lib/mcp-spawn-tee/package.json +3 -0
- package/payload/platform/plugins/telegram/.claude-plugin/plugin.json +5 -1
- package/payload/platform/plugins/telegram/lib/mcp-spawn-tee/index.js +159 -0
- package/payload/platform/plugins/telegram/lib/mcp-spawn-tee/package.json +3 -0
- package/payload/platform/plugins/url-get/.claude-plugin/plugin.json +5 -1
- package/payload/platform/plugins/url-get/lib/mcp-spawn-tee/index.js +159 -0
- package/payload/platform/plugins/url-get/lib/mcp-spawn-tee/package.json +3 -0
- package/payload/platform/plugins/whatsapp/.claude-plugin/plugin.json +5 -1
- package/payload/platform/plugins/whatsapp/lib/mcp-spawn-tee/index.js +159 -0
- package/payload/platform/plugins/whatsapp/lib/mcp-spawn-tee/package.json +3 -0
- package/payload/platform/plugins/work/.claude-plugin/plugin.json +5 -1
- package/payload/platform/plugins/work/lib/mcp-spawn-tee/index.js +159 -0
- package/payload/platform/plugins/work/lib/mcp-spawn-tee/package.json +3 -0
- package/payload/platform/plugins/workflows/.claude-plugin/plugin.json +5 -1
- package/payload/platform/plugins/workflows/lib/mcp-spawn-tee/index.js +159 -0
- package/payload/platform/plugins/workflows/lib/mcp-spawn-tee/package.json +3 -0
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js +3 -0
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/http-server.js +1 -1
- package/payload/platform/services/claude-session-manager/dist/http-server.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/rc-daemon.d.ts +13 -0
- package/payload/platform/services/claude-session-manager/dist/rc-daemon.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/rc-daemon.js +71 -1
- package/payload/platform/services/claude-session-manager/dist/rc-daemon.js.map +1 -1
- package/payload/platform/services/whatsapp-channel/dist/jsonl-watch.d.ts +10 -0
- package/payload/platform/services/whatsapp-channel/dist/jsonl-watch.d.ts.map +1 -0
- package/payload/platform/services/whatsapp-channel/dist/jsonl-watch.js +70 -0
- package/payload/platform/services/whatsapp-channel/dist/jsonl-watch.js.map +1 -0
- package/payload/platform/services/whatsapp-channel/dist/server.d.ts +6 -1
- package/payload/platform/services/whatsapp-channel/dist/server.d.ts.map +1 -1
- package/payload/platform/services/whatsapp-channel/dist/server.js +38 -1
- package/payload/platform/services/whatsapp-channel/dist/server.js.map +1 -1
- package/payload/platform/templates/specialists/agents/personal-assistant.md +1 -1
- package/payload/premium-plugins/writer-craft/.claude-plugin/plugin.json +5 -1
- package/payload/premium-plugins/writer-craft/lib/mcp-spawn-tee/index.js +159 -0
- package/payload/premium-plugins/writer-craft/lib/mcp-spawn-tee/package.json +3 -0
- package/payload/server/public/assets/AdminShell-BnhxfX97.js +1 -0
- package/payload/server/public/assets/{Checkbox-DTrIyIFP.js → Checkbox-CVPUf_7I.js} +1 -1
- package/payload/server/public/assets/{Transcript-C3aDVJ-n.js → Transcript-FYmq-mL1.js} +1 -1
- package/payload/server/public/assets/{admin-DVdyV-Q6.js → admin-CF8K3hqE.js} +1 -1
- package/payload/server/public/assets/{architectureDiagram-Q4EWVU46-DR9W0q1P.js → architectureDiagram-Q4EWVU46-IVt2X8Dk.js} +1 -1
- package/payload/server/public/assets/audio-attachment-mime-DaInZ9sa.js +1 -0
- package/payload/server/public/assets/{blockDiagram-DXYQGD6D-C3uwaI7p.js → blockDiagram-DXYQGD6D-CQDngnsc.js} +1 -1
- package/payload/server/public/assets/browser-D_hZgtfv.js +1 -0
- package/payload/server/public/assets/{c4Diagram-AHTNJAMY-C8hmUDdd.js → c4Diagram-AHTNJAMY-BjV_YA-L.js} +1 -1
- package/payload/server/public/assets/channel-gFnUr8f4.js +1 -0
- package/payload/server/public/assets/chat-COcrNTJi.js +1 -0
- package/payload/server/public/assets/{chunk-336JU56O-BRCubMCb.js → chunk-336JU56O-B0yBhSVq.js} +2 -2
- package/payload/server/public/assets/{chunk-426QAEUC-BNINkVsL.js → chunk-426QAEUC-BCmWl6vi.js} +1 -1
- package/payload/server/public/assets/{chunk-4TB4RGXK-DSMj_AZh.js → chunk-4TB4RGXK-BImQYhPF.js} +1 -1
- package/payload/server/public/assets/{chunk-5FUZZQ4R-6DNGaUkf.js → chunk-5FUZZQ4R-DrDSHQZv.js} +1 -1
- package/payload/server/public/assets/{chunk-5PVQY5BW-DPhkkS4p.js → chunk-5PVQY5BW-CKX_LIok.js} +1 -1
- package/payload/server/public/assets/{chunk-EDXVE4YY-BjWSqn7_.js → chunk-EDXVE4YY-D1zHB217.js} +1 -1
- package/payload/server/public/assets/{chunk-ENJZ2VHE-BX1ZnU4A.js → chunk-ENJZ2VHE-SFpdtszU.js} +1 -1
- package/payload/server/public/assets/{chunk-ICPOFSXX-DvYSWH7x.js → chunk-ICPOFSXX-cYdq7RKF.js} +1 -1
- package/payload/server/public/assets/{chunk-OYMX7WX6-7_m3mEOK.js → chunk-OYMX7WX6-B7JLCext.js} +1 -1
- package/payload/server/public/assets/{chunk-U2HBQHQK-Bl1a895I.js → chunk-U2HBQHQK-DWCeFwem.js} +1 -1
- package/payload/server/public/assets/{chunk-X2U36JSP-WkSpBPYx.js → chunk-X2U36JSP-DGnHsoJ3.js} +1 -1
- package/payload/server/public/assets/{chunk-YZCP3GAM-DpWRmPUo.js → chunk-YZCP3GAM-sg4lGGJV.js} +1 -1
- package/payload/server/public/assets/{chunk-ZZ45TVLE-D9Dgmeso.js → chunk-ZZ45TVLE-DtUoGmKE.js} +1 -1
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-C_wlfUTz.js +1 -0
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-Ltv5s3OY.js +1 -0
- package/payload/server/public/assets/clone-D0XoXc_v.js +1 -0
- package/payload/server/public/assets/{dagre-PrVfCcSt.js → dagre-Dfj_jbTe.js} +1 -1
- package/payload/server/public/assets/{dagre-KV5264BT-DPq3dcLH.js → dagre-KV5264BT-Bd1VlhUJ.js} +1 -1
- package/payload/server/public/assets/data-DkbQI40a.js +1 -0
- package/payload/server/public/assets/{diagram-5BDNPKRD-DoszElKb.js → diagram-5BDNPKRD-Dqqyk8GE.js} +1 -1
- package/payload/server/public/assets/{diagram-G4DWMVQ6-BRuqosix.js → diagram-G4DWMVQ6-Xk3WKR_U.js} +1 -1
- package/payload/server/public/assets/{diagram-MMDJMWI5-CpigG1d_.js → diagram-MMDJMWI5-CAdGL9U7.js} +1 -1
- package/payload/server/public/assets/{diagram-TYMM5635-BS0eYiq9.js → diagram-TYMM5635-DY1iYQVY.js} +1 -1
- package/payload/server/public/assets/{erDiagram-SMLLAGMA-VEQyXCFl.js → erDiagram-SMLLAGMA-BJ5HYKeb.js} +1 -1
- package/payload/server/public/assets/{file-download-C3pBZjt9.js → file-download-BYJN3Kgm.js} +1 -1
- package/payload/server/public/assets/{flowDiagram-DWJPFMVM-2NYMfqHX.js → flowDiagram-DWJPFMVM-B-q6x5Q_.js} +1 -1
- package/payload/server/public/assets/{ganttDiagram-T4ZO3ILL-AAAa2sqE.js → ganttDiagram-T4ZO3ILL-DbjwY_bG.js} +1 -1
- package/payload/server/public/assets/{gitGraphDiagram-UUTBAWPF-d8NUAIz5.js → gitGraphDiagram-UUTBAWPF-C3bLrOmb.js} +1 -1
- package/payload/server/public/assets/{graph-Bx9_2qbJ.js → graph-DmikPM4A.js} +2 -2
- package/payload/server/public/assets/{graph-labels-Cc1nU1_f.js → graph-labels-CtG6ckdG.js} +1 -1
- package/payload/server/public/assets/{graphlib-DUlqr2mr.js → graphlib-BlOjhixq.js} +1 -1
- package/payload/server/public/assets/{infoDiagram-42DDH7IO-D4dh4-0g.js → infoDiagram-42DDH7IO-BpaHbiXO.js} +1 -1
- package/payload/server/public/assets/{ishikawaDiagram-UXIWVN3A-DPTmm2IE.js → ishikawaDiagram-UXIWVN3A-B_DzwK8l.js} +1 -1
- package/payload/server/public/assets/{journeyDiagram-VCZTEJTY-B85vjqkE.js → journeyDiagram-VCZTEJTY-COzTF-qc.js} +1 -1
- package/payload/server/public/assets/{jsx-runtime-D3PZpOAF.css → jsx-runtime-BjFkEGXb.css} +1 -1
- package/payload/server/public/assets/{kanban-definition-6JOO6SKY-C2Lfb5Xh.js → kanban-definition-6JOO6SKY-C2cOIZU6.js} +1 -1
- package/payload/server/public/assets/{line-CODKFpwO.js → line-Bwa6aUYZ.js} +1 -1
- package/payload/server/public/assets/{mermaid-parser.core-DYdFZnXH.js → mermaid-parser.core-BFAF0BAk.js} +1 -1
- package/payload/server/public/assets/{mermaid.core-Bamjzahu.js → mermaid.core-CMOXmawT.js} +3 -3
- package/payload/server/public/assets/{mindmap-definition-QFDTVHPH-CLK90bKJ.js → mindmap-definition-QFDTVHPH-bu0QLO17.js} +1 -1
- package/payload/server/public/assets/{pieDiagram-DEJITSTG-DEsnxhqP.js → pieDiagram-DEJITSTG-DQUe6W2Z.js} +1 -1
- package/payload/server/public/assets/{public-BFMu-jux.js → public-CSEIGhb4.js} +5 -5
- package/payload/server/public/assets/{quadrantDiagram-34T5L4WZ-uIP9V2jZ.js → quadrantDiagram-34T5L4WZ-ChhcwVRA.js} +1 -1
- package/payload/server/public/assets/{requirementDiagram-MS252O5E-CVS6t5tv.js → requirementDiagram-MS252O5E-DwQXqTA9.js} +1 -1
- package/payload/server/public/assets/{sankeyDiagram-XADWPNL6-BIsmtyZA.js → sankeyDiagram-XADWPNL6-zYqdptBM.js} +1 -1
- package/payload/server/public/assets/{sequenceDiagram-FGHM5R23-Cu8TfQiW.js → sequenceDiagram-FGHM5R23-x2g84gb4.js} +1 -1
- package/payload/server/public/assets/{stateDiagram-FHFEXIEX-ax4vYGft.js → stateDiagram-FHFEXIEX-CeUrqs2P.js} +1 -1
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-B27DBP9X.js +1 -0
- package/payload/server/public/assets/{timeline-definition-GMOUNBTQ-3l7ojkMA.js → timeline-definition-GMOUNBTQ-CL-c9XN5.js} +1 -1
- package/payload/server/public/assets/{useSelectionMode-C_EBRd2k.js → useSelectionMode-C1_ky4B6.js} +1 -1
- package/payload/server/public/assets/{vennDiagram-DHZGUBPP-C_sv0qMD.js → vennDiagram-DHZGUBPP-By2HBDYr.js} +1 -1
- package/payload/server/public/assets/{wardleyDiagram-NUSXRM2D-C7u4IHMB.js → wardleyDiagram-NUSXRM2D-iahvFvIS.js} +1 -1
- package/payload/server/public/assets/{xychartDiagram-5P7HB3ND-A-uLXr1a.js → xychartDiagram-5P7HB3ND-33qqdRhI.js} +1 -1
- package/payload/server/public/browser.html +6 -6
- package/payload/server/public/chat.html +8 -8
- package/payload/server/public/data.html +5 -5
- package/payload/server/public/graph.html +8 -8
- package/payload/server/public/index.html +8 -8
- package/payload/server/public/public.html +6 -6
- package/payload/server/public/whatsapp-wallpaper.webp +0 -0
- package/payload/server/server.js +17 -9
- package/payload/server/public/assets/AdminShell-DDieHnzi.js +0 -1
- package/payload/server/public/assets/audio-attachment-mime-DGEfApkA.js +0 -1
- package/payload/server/public/assets/browser-DrJReVEG.js +0 -1
- package/payload/server/public/assets/channel-drVqp11B.js +0 -1
- package/payload/server/public/assets/chat-rJYaCD6C.js +0 -1
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-Dplkw_pj.js +0 -1
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-sJXv1Ihp.js +0 -1
- package/payload/server/public/assets/clone-Q_B6oO0c.js +0 -1
- package/payload/server/public/assets/data-CYyR2m_B.js +0 -1
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-BRv1By5g.js +0 -1
- /package/payload/server/public/assets/{jsx-runtime-5auA0FEj.js → jsx-runtime-UQ0Z6nwN.js} +0 -0
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
/**
|
|
4
|
+
* MCP spawn-tee — parent-side stderr capture + lifecycle observability.
|
|
5
|
+
*
|
|
6
|
+
* Claude Code spawns each MCP server itself; the platform never holds a
|
|
7
|
+
* ChildProcess handle. This wrapper sits between Claude Code and the real
|
|
8
|
+
* MCP server: Claude Code runs `node <this> <real-entry>`, and the wrapper
|
|
9
|
+
* spawns the real entry with `stdio:['inherit','inherit','pipe']` so stdin
|
|
10
|
+
* and stdout (the JSON-RPC channel) pass through byte-identical. Only stderr
|
|
11
|
+
* is intercepted, and only for logging.
|
|
12
|
+
*
|
|
13
|
+
* Because the wrapper IS the helper's parent, it observes the helper's true
|
|
14
|
+
* exit code, signal, and lifetime for every death mode — including a SIGKILL
|
|
15
|
+
* or a transport-layer crash that an in-process handler would miss.
|
|
16
|
+
*
|
|
17
|
+
* Claude Code CLI → wrapper (this file) → child = node <real-entry>
|
|
18
|
+
* child stdin/stdout : inherited (Claude Code pipe, untouched)
|
|
19
|
+
* child stderr : piped → per-date log + per-session log + passthrough
|
|
20
|
+
*
|
|
21
|
+
* Destinations (Task 706):
|
|
22
|
+
* - `${LOG_DIR}/mcp-<name>-stderr-<date>.log` — per-date raw (back-compat;
|
|
23
|
+
* the in-process mcp-stderr-tee and the [mcp-init-error] probe read it).
|
|
24
|
+
* - `${LOG_DIR}/mcp-<name>-<SESSION_ID>.log` — per-session raw + lifecycle
|
|
25
|
+
* lines; wrapper-only, so it never mixes the enumeration copy with the
|
|
26
|
+
* live copy. Authoritative sink. Absent when SESSION_ID is unset
|
|
27
|
+
* (enumeration spawn) — then the per-date file is the fallback.
|
|
28
|
+
* - `server.log` via the loopback log-ingest route — best-effort mirror of
|
|
29
|
+
* the [mcp-helper] lifecycle lines. A dropped POST loses nothing because
|
|
30
|
+
* the per-session file already holds the line (written synchronously).
|
|
31
|
+
*
|
|
32
|
+
* Lifecycle lines, correlation key `session=<id8> server=<name>`:
|
|
33
|
+
* [mcp-helper] op=spawn ... pid= entry=
|
|
34
|
+
* [mcp-helper] op=boot ... head=<first stderr bytes>
|
|
35
|
+
* [mcp-helper] op=exit ... code= signal= lifetimeMs= stderr-tail= (always)
|
|
36
|
+
*
|
|
37
|
+
* The wrapper never writes to fd 1 (stdout) — that is the JSON-RPC channel.
|
|
38
|
+
* SIGTERM/SIGINT are forwarded to the child so a Claude Code shutdown does
|
|
39
|
+
* not orphan it; the child exit code/signal is propagated verbatim.
|
|
40
|
+
*/
|
|
41
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
+
const node_child_process_1 = require("node:child_process");
|
|
43
|
+
const node_fs_1 = require("node:fs");
|
|
44
|
+
const node_path_1 = require("node:path");
|
|
45
|
+
const SERVER_NAME = process.env.MCP_SPAWN_TEE_NAME ?? "unknown";
|
|
46
|
+
const LOG_DIR = process.env.LOG_DIR;
|
|
47
|
+
const SESSION_ID = process.env.SESSION_ID;
|
|
48
|
+
const PLATFORM_PORT = process.env.PLATFORM_PORT;
|
|
49
|
+
const ENTRY = process.argv[2];
|
|
50
|
+
const SESSION_ID8 = SESSION_ID ? SESSION_ID.slice(0, 8) : "—";
|
|
51
|
+
const spawnStamp = Date.now();
|
|
52
|
+
// Per-session raw + lifecycle log (Task 706). Wrapper-only. Empty SESSION_ID
|
|
53
|
+
// (enumeration 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`)
|
|
59
|
+
: undefined;
|
|
60
|
+
// Rolling tail of child stderr for op=exit. Capped so a chatty child cannot
|
|
61
|
+
// grow the buffer without bound.
|
|
62
|
+
const TAIL_CAP = 2048;
|
|
63
|
+
let stderrTail = "";
|
|
64
|
+
let bootEmitted = false;
|
|
65
|
+
function appendSafe(path, data) {
|
|
66
|
+
if (!path || !LOG_DIR)
|
|
67
|
+
return;
|
|
68
|
+
try {
|
|
69
|
+
(0, node_fs_1.mkdirSync)(LOG_DIR, { recursive: true });
|
|
70
|
+
(0, node_fs_1.appendFileSync)(path, data);
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
/* unwritable destination — never mask primary output */
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
// Best-effort mirror of a lifecycle line to server.log via the loopback
|
|
77
|
+
// log-ingest route. Fire-and-forget: the per-session file is authoritative,
|
|
78
|
+
// so a dropped POST (unreachable port, process exiting) loses nothing.
|
|
79
|
+
function postToServerLog(suffix, level) {
|
|
80
|
+
if (!PLATFORM_PORT)
|
|
81
|
+
return;
|
|
82
|
+
try {
|
|
83
|
+
const ctrl = new AbortController();
|
|
84
|
+
const t = setTimeout(() => ctrl.abort(), 500);
|
|
85
|
+
t.unref?.(); // never let the abort timer keep the wrapper's event loop alive
|
|
86
|
+
void fetch(`http://127.0.0.1:${PLATFORM_PORT}/api/admin/log-ingest`, {
|
|
87
|
+
method: "POST",
|
|
88
|
+
headers: { "content-type": "application/json" },
|
|
89
|
+
body: JSON.stringify({ tag: "mcp-helper", level, line: suffix }),
|
|
90
|
+
signal: ctrl.signal,
|
|
91
|
+
}).then(() => clearTimeout(t)).catch(() => clearTimeout(t));
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
/* fetch threw synchronously — best-effort only */
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
// Emit one [mcp-helper] lifecycle line: authoritative per-session file (sync,
|
|
98
|
+
// survives process.exit), the wrapper's own stderr (journald / Claude Code
|
|
99
|
+
// visibility), and a best-effort server.log mirror. `suffix` is the line body
|
|
100
|
+
// after the tag and carries no newline (the log-ingest route rejects newlines).
|
|
101
|
+
function emitLifecycle(suffix, level) {
|
|
102
|
+
const line = `[mcp-helper] ${suffix}\n`;
|
|
103
|
+
appendSafe(perSessionPath, line);
|
|
104
|
+
try {
|
|
105
|
+
process.stderr.write(line);
|
|
106
|
+
}
|
|
107
|
+
catch { /* stderr closed */ }
|
|
108
|
+
postToServerLog(suffix, level);
|
|
109
|
+
}
|
|
110
|
+
if (!ENTRY) {
|
|
111
|
+
emitLifecycle(`op=error session=${SESSION_ID8} server=${SERVER_NAME} reason="no entry given (argv[2] missing)"`, "error");
|
|
112
|
+
process.exit(2);
|
|
113
|
+
}
|
|
114
|
+
const child = (0, node_child_process_1.spawn)(process.execPath, [ENTRY], {
|
|
115
|
+
stdio: ["inherit", "inherit", "pipe"],
|
|
116
|
+
env: process.env,
|
|
117
|
+
});
|
|
118
|
+
emitLifecycle(`op=spawn session=${SESSION_ID8} server=${SERVER_NAME} pid=${child.pid ?? -1} entry=${ENTRY}`, "info");
|
|
119
|
+
child.on("error", (err) => {
|
|
120
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
121
|
+
emitLifecycle(`op=error session=${SESSION_ID8} server=${SERVER_NAME} reason=${JSON.stringify(`spawn error: ${msg}`)}`, "error");
|
|
122
|
+
process.exit(127);
|
|
123
|
+
});
|
|
124
|
+
if (child.stderr) {
|
|
125
|
+
child.stderr.on("data", (chunk) => {
|
|
126
|
+
appendSafe(perDatePath, chunk); // per-date raw (back-compat)
|
|
127
|
+
appendSafe(perSessionPath, chunk); // per-session raw (Task 706)
|
|
128
|
+
try {
|
|
129
|
+
process.stderr.write(chunk);
|
|
130
|
+
}
|
|
131
|
+
catch { /* stderr closed */ } // passthrough
|
|
132
|
+
stderrTail = (stderrTail + chunk.toString("utf8")).slice(-TAIL_CAP);
|
|
133
|
+
if (!bootEmitted) {
|
|
134
|
+
bootEmitted = true;
|
|
135
|
+
const head = chunk.toString("utf8").split("\n")[0].slice(0, 200);
|
|
136
|
+
emitLifecycle(`op=boot session=${SESSION_ID8} server=${SERVER_NAME} head=${JSON.stringify(head)}`, "info");
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
const forward = (signal) => { if (!child.killed)
|
|
141
|
+
child.kill(signal); };
|
|
142
|
+
process.on("SIGTERM", () => forward("SIGTERM"));
|
|
143
|
+
process.on("SIGINT", () => forward("SIGINT"));
|
|
144
|
+
// Signal → number, so a signal-killed child propagates as 128+signum (the
|
|
145
|
+
// shell convention). `code` is null on a signal exit, so `128 + (code ?? 0)`
|
|
146
|
+
// would collapse every signal to 128 and lose the signal identity in the
|
|
147
|
+
// wrapper's own exit status.
|
|
148
|
+
const SIGNUM = { SIGHUP: 1, SIGINT: 2, SIGQUIT: 3, SIGKILL: 9, SIGTERM: 15 };
|
|
149
|
+
child.on("exit", (code, signal) => {
|
|
150
|
+
const lifetimeMs = Date.now() - spawnStamp;
|
|
151
|
+
const tail = stderrTail.slice(-200);
|
|
152
|
+
const level = signal || (code ?? 0) !== 0 ? "error" : "info";
|
|
153
|
+
emitLifecycle(`op=exit session=${SESSION_ID8} server=${SERVER_NAME} pid=${child.pid ?? -1} ` +
|
|
154
|
+
`code=${code ?? "—"} signal=${signal ?? "—"} lifetimeMs=${lifetimeMs} stderr-tail=${JSON.stringify(tail)}`, level);
|
|
155
|
+
if (signal)
|
|
156
|
+
process.exit(128 + (SIGNUM[signal] ?? 0));
|
|
157
|
+
process.exit(code ?? 0);
|
|
158
|
+
});
|
|
159
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
/**
|
|
4
|
+
* MCP spawn-tee — parent-side stderr capture + lifecycle observability.
|
|
5
|
+
*
|
|
6
|
+
* Claude Code spawns each MCP server itself; the platform never holds a
|
|
7
|
+
* ChildProcess handle. This wrapper sits between Claude Code and the real
|
|
8
|
+
* MCP server: Claude Code runs `node <this> <real-entry>`, and the wrapper
|
|
9
|
+
* spawns the real entry with `stdio:['inherit','inherit','pipe']` so stdin
|
|
10
|
+
* and stdout (the JSON-RPC channel) pass through byte-identical. Only stderr
|
|
11
|
+
* is intercepted, and only for logging.
|
|
12
|
+
*
|
|
13
|
+
* Because the wrapper IS the helper's parent, it observes the helper's true
|
|
14
|
+
* exit code, signal, and lifetime for every death mode — including a SIGKILL
|
|
15
|
+
* or a transport-layer crash that an in-process handler would miss.
|
|
16
|
+
*
|
|
17
|
+
* Claude Code CLI → wrapper (this file) → child = node <real-entry>
|
|
18
|
+
* child stdin/stdout : inherited (Claude Code pipe, untouched)
|
|
19
|
+
* child stderr : piped → per-date log + per-session log + passthrough
|
|
20
|
+
*
|
|
21
|
+
* Destinations (Task 706):
|
|
22
|
+
* - `${LOG_DIR}/mcp-<name>-stderr-<date>.log` — per-date raw (back-compat;
|
|
23
|
+
* the in-process mcp-stderr-tee and the [mcp-init-error] probe read it).
|
|
24
|
+
* - `${LOG_DIR}/mcp-<name>-<SESSION_ID>.log` — per-session raw + lifecycle
|
|
25
|
+
* lines; wrapper-only, so it never mixes the enumeration copy with the
|
|
26
|
+
* live copy. Authoritative sink. Absent when SESSION_ID is unset
|
|
27
|
+
* (enumeration spawn) — then the per-date file is the fallback.
|
|
28
|
+
* - `server.log` via the loopback log-ingest route — best-effort mirror of
|
|
29
|
+
* the [mcp-helper] lifecycle lines. A dropped POST loses nothing because
|
|
30
|
+
* the per-session file already holds the line (written synchronously).
|
|
31
|
+
*
|
|
32
|
+
* Lifecycle lines, correlation key `session=<id8> server=<name>`:
|
|
33
|
+
* [mcp-helper] op=spawn ... pid= entry=
|
|
34
|
+
* [mcp-helper] op=boot ... head=<first stderr bytes>
|
|
35
|
+
* [mcp-helper] op=exit ... code= signal= lifetimeMs= stderr-tail= (always)
|
|
36
|
+
*
|
|
37
|
+
* The wrapper never writes to fd 1 (stdout) — that is the JSON-RPC channel.
|
|
38
|
+
* SIGTERM/SIGINT are forwarded to the child so a Claude Code shutdown does
|
|
39
|
+
* not orphan it; the child exit code/signal is propagated verbatim.
|
|
40
|
+
*/
|
|
41
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
+
const node_child_process_1 = require("node:child_process");
|
|
43
|
+
const node_fs_1 = require("node:fs");
|
|
44
|
+
const node_path_1 = require("node:path");
|
|
45
|
+
const SERVER_NAME = process.env.MCP_SPAWN_TEE_NAME ?? "unknown";
|
|
46
|
+
const LOG_DIR = process.env.LOG_DIR;
|
|
47
|
+
const SESSION_ID = process.env.SESSION_ID;
|
|
48
|
+
const PLATFORM_PORT = process.env.PLATFORM_PORT;
|
|
49
|
+
const ENTRY = process.argv[2];
|
|
50
|
+
const SESSION_ID8 = SESSION_ID ? SESSION_ID.slice(0, 8) : "—";
|
|
51
|
+
const spawnStamp = Date.now();
|
|
52
|
+
// Per-session raw + lifecycle log (Task 706). Wrapper-only. Empty SESSION_ID
|
|
53
|
+
// (enumeration 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`)
|
|
59
|
+
: undefined;
|
|
60
|
+
// Rolling tail of child stderr for op=exit. Capped so a chatty child cannot
|
|
61
|
+
// grow the buffer without bound.
|
|
62
|
+
const TAIL_CAP = 2048;
|
|
63
|
+
let stderrTail = "";
|
|
64
|
+
let bootEmitted = false;
|
|
65
|
+
function appendSafe(path, data) {
|
|
66
|
+
if (!path || !LOG_DIR)
|
|
67
|
+
return;
|
|
68
|
+
try {
|
|
69
|
+
(0, node_fs_1.mkdirSync)(LOG_DIR, { recursive: true });
|
|
70
|
+
(0, node_fs_1.appendFileSync)(path, data);
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
/* unwritable destination — never mask primary output */
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
// Best-effort mirror of a lifecycle line to server.log via the loopback
|
|
77
|
+
// log-ingest route. Fire-and-forget: the per-session file is authoritative,
|
|
78
|
+
// so a dropped POST (unreachable port, process exiting) loses nothing.
|
|
79
|
+
function postToServerLog(suffix, level) {
|
|
80
|
+
if (!PLATFORM_PORT)
|
|
81
|
+
return;
|
|
82
|
+
try {
|
|
83
|
+
const ctrl = new AbortController();
|
|
84
|
+
const t = setTimeout(() => ctrl.abort(), 500);
|
|
85
|
+
t.unref?.(); // never let the abort timer keep the wrapper's event loop alive
|
|
86
|
+
void fetch(`http://127.0.0.1:${PLATFORM_PORT}/api/admin/log-ingest`, {
|
|
87
|
+
method: "POST",
|
|
88
|
+
headers: { "content-type": "application/json" },
|
|
89
|
+
body: JSON.stringify({ tag: "mcp-helper", level, line: suffix }),
|
|
90
|
+
signal: ctrl.signal,
|
|
91
|
+
}).then(() => clearTimeout(t)).catch(() => clearTimeout(t));
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
/* fetch threw synchronously — best-effort only */
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
// Emit one [mcp-helper] lifecycle line: authoritative per-session file (sync,
|
|
98
|
+
// survives process.exit), the wrapper's own stderr (journald / Claude Code
|
|
99
|
+
// visibility), and a best-effort server.log mirror. `suffix` is the line body
|
|
100
|
+
// after the tag and carries no newline (the log-ingest route rejects newlines).
|
|
101
|
+
function emitLifecycle(suffix, level) {
|
|
102
|
+
const line = `[mcp-helper] ${suffix}\n`;
|
|
103
|
+
appendSafe(perSessionPath, line);
|
|
104
|
+
try {
|
|
105
|
+
process.stderr.write(line);
|
|
106
|
+
}
|
|
107
|
+
catch { /* stderr closed */ }
|
|
108
|
+
postToServerLog(suffix, level);
|
|
109
|
+
}
|
|
110
|
+
if (!ENTRY) {
|
|
111
|
+
emitLifecycle(`op=error session=${SESSION_ID8} server=${SERVER_NAME} reason="no entry given (argv[2] missing)"`, "error");
|
|
112
|
+
process.exit(2);
|
|
113
|
+
}
|
|
114
|
+
const child = (0, node_child_process_1.spawn)(process.execPath, [ENTRY], {
|
|
115
|
+
stdio: ["inherit", "inherit", "pipe"],
|
|
116
|
+
env: process.env,
|
|
117
|
+
});
|
|
118
|
+
emitLifecycle(`op=spawn session=${SESSION_ID8} server=${SERVER_NAME} pid=${child.pid ?? -1} entry=${ENTRY}`, "info");
|
|
119
|
+
child.on("error", (err) => {
|
|
120
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
121
|
+
emitLifecycle(`op=error session=${SESSION_ID8} server=${SERVER_NAME} reason=${JSON.stringify(`spawn error: ${msg}`)}`, "error");
|
|
122
|
+
process.exit(127);
|
|
123
|
+
});
|
|
124
|
+
if (child.stderr) {
|
|
125
|
+
child.stderr.on("data", (chunk) => {
|
|
126
|
+
appendSafe(perDatePath, chunk); // per-date raw (back-compat)
|
|
127
|
+
appendSafe(perSessionPath, chunk); // per-session raw (Task 706)
|
|
128
|
+
try {
|
|
129
|
+
process.stderr.write(chunk);
|
|
130
|
+
}
|
|
131
|
+
catch { /* stderr closed */ } // passthrough
|
|
132
|
+
stderrTail = (stderrTail + chunk.toString("utf8")).slice(-TAIL_CAP);
|
|
133
|
+
if (!bootEmitted) {
|
|
134
|
+
bootEmitted = true;
|
|
135
|
+
const head = chunk.toString("utf8").split("\n")[0].slice(0, 200);
|
|
136
|
+
emitLifecycle(`op=boot session=${SESSION_ID8} server=${SERVER_NAME} head=${JSON.stringify(head)}`, "info");
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
const forward = (signal) => { if (!child.killed)
|
|
141
|
+
child.kill(signal); };
|
|
142
|
+
process.on("SIGTERM", () => forward("SIGTERM"));
|
|
143
|
+
process.on("SIGINT", () => forward("SIGINT"));
|
|
144
|
+
// Signal → number, so a signal-killed child propagates as 128+signum (the
|
|
145
|
+
// shell convention). `code` is null on a signal exit, so `128 + (code ?? 0)`
|
|
146
|
+
// would collapse every signal to 128 and lose the signal identity in the
|
|
147
|
+
// wrapper's own exit status.
|
|
148
|
+
const SIGNUM = { SIGHUP: 1, SIGINT: 2, SIGQUIT: 3, SIGKILL: 9, SIGTERM: 15 };
|
|
149
|
+
child.on("exit", (code, signal) => {
|
|
150
|
+
const lifetimeMs = Date.now() - spawnStamp;
|
|
151
|
+
const tail = stderrTail.slice(-200);
|
|
152
|
+
const level = signal || (code ?? 0) !== 0 ? "error" : "info";
|
|
153
|
+
emitLifecycle(`op=exit session=${SESSION_ID8} server=${SERVER_NAME} pid=${child.pid ?? -1} ` +
|
|
154
|
+
`code=${code ?? "—"} signal=${signal ?? "—"} lifetimeMs=${lifetimeMs} stderr-tail=${JSON.stringify(tail)}`, level);
|
|
155
|
+
if (signal)
|
|
156
|
+
process.exit(128 + (SIGNUM[signal] ?? 0));
|
|
157
|
+
process.exit(code ?? 0);
|
|
158
|
+
});
|
|
159
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
/**
|
|
4
|
+
* MCP spawn-tee — parent-side stderr capture + lifecycle observability.
|
|
5
|
+
*
|
|
6
|
+
* Claude Code spawns each MCP server itself; the platform never holds a
|
|
7
|
+
* ChildProcess handle. This wrapper sits between Claude Code and the real
|
|
8
|
+
* MCP server: Claude Code runs `node <this> <real-entry>`, and the wrapper
|
|
9
|
+
* spawns the real entry with `stdio:['inherit','inherit','pipe']` so stdin
|
|
10
|
+
* and stdout (the JSON-RPC channel) pass through byte-identical. Only stderr
|
|
11
|
+
* is intercepted, and only for logging.
|
|
12
|
+
*
|
|
13
|
+
* Because the wrapper IS the helper's parent, it observes the helper's true
|
|
14
|
+
* exit code, signal, and lifetime for every death mode — including a SIGKILL
|
|
15
|
+
* or a transport-layer crash that an in-process handler would miss.
|
|
16
|
+
*
|
|
17
|
+
* Claude Code CLI → wrapper (this file) → child = node <real-entry>
|
|
18
|
+
* child stdin/stdout : inherited (Claude Code pipe, untouched)
|
|
19
|
+
* child stderr : piped → per-date log + per-session log + passthrough
|
|
20
|
+
*
|
|
21
|
+
* Destinations (Task 706):
|
|
22
|
+
* - `${LOG_DIR}/mcp-<name>-stderr-<date>.log` — per-date raw (back-compat;
|
|
23
|
+
* the in-process mcp-stderr-tee and the [mcp-init-error] probe read it).
|
|
24
|
+
* - `${LOG_DIR}/mcp-<name>-<SESSION_ID>.log` — per-session raw + lifecycle
|
|
25
|
+
* lines; wrapper-only, so it never mixes the enumeration copy with the
|
|
26
|
+
* live copy. Authoritative sink. Absent when SESSION_ID is unset
|
|
27
|
+
* (enumeration spawn) — then the per-date file is the fallback.
|
|
28
|
+
* - `server.log` via the loopback log-ingest route — best-effort mirror of
|
|
29
|
+
* the [mcp-helper] lifecycle lines. A dropped POST loses nothing because
|
|
30
|
+
* the per-session file already holds the line (written synchronously).
|
|
31
|
+
*
|
|
32
|
+
* Lifecycle lines, correlation key `session=<id8> server=<name>`:
|
|
33
|
+
* [mcp-helper] op=spawn ... pid= entry=
|
|
34
|
+
* [mcp-helper] op=boot ... head=<first stderr bytes>
|
|
35
|
+
* [mcp-helper] op=exit ... code= signal= lifetimeMs= stderr-tail= (always)
|
|
36
|
+
*
|
|
37
|
+
* The wrapper never writes to fd 1 (stdout) — that is the JSON-RPC channel.
|
|
38
|
+
* SIGTERM/SIGINT are forwarded to the child so a Claude Code shutdown does
|
|
39
|
+
* not orphan it; the child exit code/signal is propagated verbatim.
|
|
40
|
+
*/
|
|
41
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
+
const node_child_process_1 = require("node:child_process");
|
|
43
|
+
const node_fs_1 = require("node:fs");
|
|
44
|
+
const node_path_1 = require("node:path");
|
|
45
|
+
const SERVER_NAME = process.env.MCP_SPAWN_TEE_NAME ?? "unknown";
|
|
46
|
+
const LOG_DIR = process.env.LOG_DIR;
|
|
47
|
+
const SESSION_ID = process.env.SESSION_ID;
|
|
48
|
+
const PLATFORM_PORT = process.env.PLATFORM_PORT;
|
|
49
|
+
const ENTRY = process.argv[2];
|
|
50
|
+
const SESSION_ID8 = SESSION_ID ? SESSION_ID.slice(0, 8) : "—";
|
|
51
|
+
const spawnStamp = Date.now();
|
|
52
|
+
// Per-session raw + lifecycle log (Task 706). Wrapper-only. Empty SESSION_ID
|
|
53
|
+
// (enumeration 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`)
|
|
59
|
+
: undefined;
|
|
60
|
+
// Rolling tail of child stderr for op=exit. Capped so a chatty child cannot
|
|
61
|
+
// grow the buffer without bound.
|
|
62
|
+
const TAIL_CAP = 2048;
|
|
63
|
+
let stderrTail = "";
|
|
64
|
+
let bootEmitted = false;
|
|
65
|
+
function appendSafe(path, data) {
|
|
66
|
+
if (!path || !LOG_DIR)
|
|
67
|
+
return;
|
|
68
|
+
try {
|
|
69
|
+
(0, node_fs_1.mkdirSync)(LOG_DIR, { recursive: true });
|
|
70
|
+
(0, node_fs_1.appendFileSync)(path, data);
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
/* unwritable destination — never mask primary output */
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
// Best-effort mirror of a lifecycle line to server.log via the loopback
|
|
77
|
+
// log-ingest route. Fire-and-forget: the per-session file is authoritative,
|
|
78
|
+
// so a dropped POST (unreachable port, process exiting) loses nothing.
|
|
79
|
+
function postToServerLog(suffix, level) {
|
|
80
|
+
if (!PLATFORM_PORT)
|
|
81
|
+
return;
|
|
82
|
+
try {
|
|
83
|
+
const ctrl = new AbortController();
|
|
84
|
+
const t = setTimeout(() => ctrl.abort(), 500);
|
|
85
|
+
t.unref?.(); // never let the abort timer keep the wrapper's event loop alive
|
|
86
|
+
void fetch(`http://127.0.0.1:${PLATFORM_PORT}/api/admin/log-ingest`, {
|
|
87
|
+
method: "POST",
|
|
88
|
+
headers: { "content-type": "application/json" },
|
|
89
|
+
body: JSON.stringify({ tag: "mcp-helper", level, line: suffix }),
|
|
90
|
+
signal: ctrl.signal,
|
|
91
|
+
}).then(() => clearTimeout(t)).catch(() => clearTimeout(t));
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
/* fetch threw synchronously — best-effort only */
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
// Emit one [mcp-helper] lifecycle line: authoritative per-session file (sync,
|
|
98
|
+
// survives process.exit), the wrapper's own stderr (journald / Claude Code
|
|
99
|
+
// visibility), and a best-effort server.log mirror. `suffix` is the line body
|
|
100
|
+
// after the tag and carries no newline (the log-ingest route rejects newlines).
|
|
101
|
+
function emitLifecycle(suffix, level) {
|
|
102
|
+
const line = `[mcp-helper] ${suffix}\n`;
|
|
103
|
+
appendSafe(perSessionPath, line);
|
|
104
|
+
try {
|
|
105
|
+
process.stderr.write(line);
|
|
106
|
+
}
|
|
107
|
+
catch { /* stderr closed */ }
|
|
108
|
+
postToServerLog(suffix, level);
|
|
109
|
+
}
|
|
110
|
+
if (!ENTRY) {
|
|
111
|
+
emitLifecycle(`op=error session=${SESSION_ID8} server=${SERVER_NAME} reason="no entry given (argv[2] missing)"`, "error");
|
|
112
|
+
process.exit(2);
|
|
113
|
+
}
|
|
114
|
+
const child = (0, node_child_process_1.spawn)(process.execPath, [ENTRY], {
|
|
115
|
+
stdio: ["inherit", "inherit", "pipe"],
|
|
116
|
+
env: process.env,
|
|
117
|
+
});
|
|
118
|
+
emitLifecycle(`op=spawn session=${SESSION_ID8} server=${SERVER_NAME} pid=${child.pid ?? -1} entry=${ENTRY}`, "info");
|
|
119
|
+
child.on("error", (err) => {
|
|
120
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
121
|
+
emitLifecycle(`op=error session=${SESSION_ID8} server=${SERVER_NAME} reason=${JSON.stringify(`spawn error: ${msg}`)}`, "error");
|
|
122
|
+
process.exit(127);
|
|
123
|
+
});
|
|
124
|
+
if (child.stderr) {
|
|
125
|
+
child.stderr.on("data", (chunk) => {
|
|
126
|
+
appendSafe(perDatePath, chunk); // per-date raw (back-compat)
|
|
127
|
+
appendSafe(perSessionPath, chunk); // per-session raw (Task 706)
|
|
128
|
+
try {
|
|
129
|
+
process.stderr.write(chunk);
|
|
130
|
+
}
|
|
131
|
+
catch { /* stderr closed */ } // passthrough
|
|
132
|
+
stderrTail = (stderrTail + chunk.toString("utf8")).slice(-TAIL_CAP);
|
|
133
|
+
if (!bootEmitted) {
|
|
134
|
+
bootEmitted = true;
|
|
135
|
+
const head = chunk.toString("utf8").split("\n")[0].slice(0, 200);
|
|
136
|
+
emitLifecycle(`op=boot session=${SESSION_ID8} server=${SERVER_NAME} head=${JSON.stringify(head)}`, "info");
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
const forward = (signal) => { if (!child.killed)
|
|
141
|
+
child.kill(signal); };
|
|
142
|
+
process.on("SIGTERM", () => forward("SIGTERM"));
|
|
143
|
+
process.on("SIGINT", () => forward("SIGINT"));
|
|
144
|
+
// Signal → number, so a signal-killed child propagates as 128+signum (the
|
|
145
|
+
// shell convention). `code` is null on a signal exit, so `128 + (code ?? 0)`
|
|
146
|
+
// would collapse every signal to 128 and lose the signal identity in the
|
|
147
|
+
// wrapper's own exit status.
|
|
148
|
+
const SIGNUM = { SIGHUP: 1, SIGINT: 2, SIGQUIT: 3, SIGKILL: 9, SIGTERM: 15 };
|
|
149
|
+
child.on("exit", (code, signal) => {
|
|
150
|
+
const lifetimeMs = Date.now() - spawnStamp;
|
|
151
|
+
const tail = stderrTail.slice(-200);
|
|
152
|
+
const level = signal || (code ?? 0) !== 0 ? "error" : "info";
|
|
153
|
+
emitLifecycle(`op=exit session=${SESSION_ID8} server=${SERVER_NAME} pid=${child.pid ?? -1} ` +
|
|
154
|
+
`code=${code ?? "—"} signal=${signal ?? "—"} lifetimeMs=${lifetimeMs} stderr-tail=${JSON.stringify(tail)}`, level);
|
|
155
|
+
if (signal)
|
|
156
|
+
process.exit(128 + (SIGNUM[signal] ?? 0));
|
|
157
|
+
process.exit(code ?? 0);
|
|
158
|
+
});
|
|
159
|
+
//# sourceMappingURL=index.js.map
|