@rubytech/create-maxy-code 0.1.290 → 0.1.291

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 (176) hide show
  1. package/dist/index.js +14 -0
  2. package/package.json +1 -1
  3. package/payload/platform/lib/graph-style/dist/index.d.ts +2 -1
  4. package/payload/platform/lib/graph-style/dist/index.d.ts.map +1 -1
  5. package/payload/platform/lib/graph-style/dist/index.js +14 -1
  6. package/payload/platform/lib/graph-style/dist/index.js.map +1 -1
  7. package/payload/platform/lib/graph-style/src/index.ts +15 -1
  8. package/payload/platform/package.json +3 -2
  9. package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +3 -1
  10. package/payload/platform/plugins/business-assistant/skills/e-sign/SKILL.md +21 -0
  11. package/payload/platform/plugins/docs/references/troubleshooting.md +2 -0
  12. package/payload/platform/plugins/whatsapp/PLUGIN.md +4 -0
  13. package/payload/platform/plugins/whatsapp/references/channels-whatsapp.md +28 -1
  14. package/payload/platform/services/claude-session-manager/dist/http-server.d.ts +6 -0
  15. package/payload/platform/services/claude-session-manager/dist/http-server.d.ts.map +1 -1
  16. package/payload/platform/services/claude-session-manager/dist/http-server.js +65 -3
  17. package/payload/platform/services/claude-session-manager/dist/http-server.js.map +1 -1
  18. package/payload/platform/services/claude-session-manager/dist/index.js +8 -0
  19. package/payload/platform/services/claude-session-manager/dist/index.js.map +1 -1
  20. package/payload/platform/services/claude-session-manager/dist/webchat-channel-mcp.d.ts +27 -0
  21. package/payload/platform/services/claude-session-manager/dist/webchat-channel-mcp.d.ts.map +1 -0
  22. package/payload/platform/services/claude-session-manager/dist/webchat-channel-mcp.js +45 -0
  23. package/payload/platform/services/claude-session-manager/dist/webchat-channel-mcp.js.map +1 -0
  24. package/payload/platform/services/claude-session-manager/dist/webchat-channel-store.d.ts +29 -0
  25. package/payload/platform/services/claude-session-manager/dist/webchat-channel-store.d.ts.map +1 -0
  26. package/payload/platform/services/claude-session-manager/dist/webchat-channel-store.js +121 -0
  27. package/payload/platform/services/claude-session-manager/dist/webchat-channel-store.js.map +1 -0
  28. package/payload/platform/services/webchat-channel/dist/notification.d.ts +55 -0
  29. package/payload/platform/services/webchat-channel/dist/notification.d.ts.map +1 -0
  30. package/payload/platform/services/webchat-channel/dist/notification.js +59 -0
  31. package/payload/platform/services/webchat-channel/dist/notification.js.map +1 -0
  32. package/payload/platform/services/webchat-channel/dist/server.d.ts +3 -0
  33. package/payload/platform/services/webchat-channel/dist/server.d.ts.map +1 -0
  34. package/payload/platform/services/webchat-channel/dist/server.js +179 -0
  35. package/payload/platform/services/webchat-channel/dist/server.js.map +1 -0
  36. package/payload/platform/services/webchat-channel/package.json +20 -0
  37. package/payload/platform/services/whatsapp-channel/dist/notification.d.ts +20 -15
  38. package/payload/platform/services/whatsapp-channel/dist/notification.d.ts.map +1 -1
  39. package/payload/platform/services/whatsapp-channel/dist/notification.js +23 -19
  40. package/payload/platform/services/whatsapp-channel/dist/notification.js.map +1 -1
  41. package/payload/server/public/assets/AdminShell-BgPlhiCM.js +1 -0
  42. package/payload/server/public/assets/{Checkbox-Dmc64qme.js → Checkbox-DWx2NcU9.js} +1 -1
  43. package/payload/server/public/assets/SidebarSplitter-CidskiAr.js +1 -0
  44. package/payload/server/public/assets/Transcript-iuM5b4JT.js +1 -0
  45. package/payload/server/public/assets/admin-Cdz561nK.js +1 -0
  46. package/payload/server/public/assets/{arc-BW1WhwmV.js → arc-yRinR5h4.js} +1 -1
  47. package/payload/server/public/assets/architecture-YZFGNWBL-B2UAw-4R.js +1 -0
  48. package/payload/server/public/assets/{architectureDiagram-Q4EWVU46-NkTPStkv.js → architectureDiagram-Q4EWVU46-AtvCAoKj.js} +1 -1
  49. package/payload/server/public/assets/{blockDiagram-DXYQGD6D-DKsRoptY.js → blockDiagram-DXYQGD6D-CwUSTR3t.js} +1 -1
  50. package/payload/server/public/assets/browser-Bwd_rYu9.js +1 -0
  51. package/payload/server/public/assets/{c4Diagram-AHTNJAMY-4SSchEmY.js → c4Diagram-AHTNJAMY-Btkecaf-.js} +1 -1
  52. package/payload/server/public/assets/channel-1MEkxMOf.js +1 -0
  53. package/payload/server/public/assets/chat-wbKqew6m.js +1 -0
  54. package/payload/server/public/assets/{chunk-2KRD3SAO-CKn-bEkI.js → chunk-2KRD3SAO-DAJbbBPY.js} +1 -1
  55. package/payload/server/public/assets/{chunk-336JU56O-C8szFVD5.js → chunk-336JU56O-fJXOXFRr.js} +2 -2
  56. package/payload/server/public/assets/chunk-426QAEUC-28Pgly06.js +1 -0
  57. package/payload/server/public/assets/{chunk-4BX2VUAB-B2mSmC97.js → chunk-4BX2VUAB-BTCTbhtf.js} +1 -1
  58. package/payload/server/public/assets/{chunk-4TB4RGXK-YsoBMSBN.js → chunk-4TB4RGXK-IFvQOpiF.js} +1 -1
  59. package/payload/server/public/assets/{chunk-55IACEB6-JLT9m7Hd.js → chunk-55IACEB6-BY026nUv.js} +1 -1
  60. package/payload/server/public/assets/{chunk-5FUZZQ4R-fvCSUwuQ.js → chunk-5FUZZQ4R-DD-XOAcm.js} +1 -1
  61. package/payload/server/public/assets/{chunk-5PVQY5BW-BKCeZJLg.js → chunk-5PVQY5BW-Ck-5mL2A.js} +1 -1
  62. package/payload/server/public/assets/{chunk-67CJDMHE-CCdP3Pdx.js → chunk-67CJDMHE-Dl7bLJGe.js} +1 -1
  63. package/payload/server/public/assets/{chunk-7N4EOEYR-bXgVzdM9.js → chunk-7N4EOEYR-CFBOyqnD.js} +1 -1
  64. package/payload/server/public/assets/{chunk-AA7GKIK3-CYeDvY8B.js → chunk-AA7GKIK3-BnnqjSlh.js} +1 -1
  65. package/payload/server/public/assets/{chunk-BSJP7CBP-U0Fi-Ers.js → chunk-BSJP7CBP-DKCTDAZE.js} +1 -1
  66. package/payload/server/public/assets/{chunk-CIAEETIT-C8QrV6Gg.js → chunk-CIAEETIT-jjeAEkQy.js} +1 -1
  67. package/payload/server/public/assets/{chunk-EDXVE4YY-DhpopONL.js → chunk-EDXVE4YY-BPqvO0TO.js} +1 -1
  68. package/payload/server/public/assets/{chunk-ENJZ2VHE-CwpQJ9IE.js → chunk-ENJZ2VHE-PN6Hbw2D.js} +1 -1
  69. package/payload/server/public/assets/{chunk-FMBD7UC4-DxAQS3UB.js → chunk-FMBD7UC4-B0zglVlf.js} +1 -1
  70. package/payload/server/public/assets/{chunk-FOC6F5B3-CyIK3zeY.js → chunk-FOC6F5B3-COVX_UuK.js} +1 -1
  71. package/payload/server/public/assets/{chunk-ICPOFSXX-D5p7fCDj.js → chunk-ICPOFSXX-DkmwqyfQ.js} +2 -2
  72. package/payload/server/public/assets/{chunk-K5T4RW27-7GcDzjyJ.js → chunk-K5T4RW27-Bav1KRIS.js} +1 -1
  73. package/payload/server/public/assets/{chunk-KGLVRYIC-B7pAr9hf.js → chunk-KGLVRYIC-nj7A12cJ.js} +1 -1
  74. package/payload/server/public/assets/{chunk-LIHQZDEY-DEoU2jrz.js → chunk-LIHQZDEY-BmMkL9jD.js} +1 -1
  75. package/payload/server/public/assets/{chunk-ORNJ4GCN-BwMFuN24.js → chunk-ORNJ4GCN-BvGwrI3j.js} +1 -1
  76. package/payload/server/public/assets/{chunk-OYMX7WX6-DCXhGWX0.js → chunk-OYMX7WX6-CWyihoif.js} +1 -1
  77. package/payload/server/public/assets/chunk-QZHKN3VN-COXR_N4N.js +1 -0
  78. package/payload/server/public/assets/{chunk-U2HBQHQK-D6lKmEsB.js → chunk-U2HBQHQK-BCWQB0k9.js} +1 -1
  79. package/payload/server/public/assets/{chunk-X2U36JSP-DiKHy0ar.js → chunk-X2U36JSP-CcaCMsL0.js} +1 -1
  80. package/payload/server/public/assets/{chunk-XPW4576I-BA0a8Ygs.js → chunk-XPW4576I-DpLw5_cw.js} +1 -1
  81. package/payload/server/public/assets/{chunk-YZCP3GAM-AqHm3K1O.js → chunk-YZCP3GAM-BUTzrAoG.js} +1 -1
  82. package/payload/server/public/assets/{chunk-ZZ45TVLE-jDPov-Ao.js → chunk-ZZ45TVLE-BD9UGg96.js} +1 -1
  83. package/payload/server/public/assets/classDiagram-6PBFFD2Q-BcD2DnVi.js +1 -0
  84. package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-ChvbGJh0.js +1 -0
  85. package/payload/server/public/assets/clone-DPfDeykW.js +1 -0
  86. package/payload/server/public/assets/{cose-bilkent-S5V4N54A-Df_JmB8E.js → cose-bilkent-S5V4N54A-bCIQHniJ.js} +1 -1
  87. package/payload/server/public/assets/{dagre-KV5264BT-DDGXoEYU.js → dagre-KV5264BT-DcOMoMzF.js} +1 -1
  88. package/payload/server/public/assets/{dagre-Dyawd5Z2.js → dagre-dnTAouT6.js} +1 -1
  89. package/payload/server/public/assets/data-BSt0roMQ.js +1 -0
  90. package/payload/server/public/assets/{diagram-5BDNPKRD-BQ1s5wpz.js → diagram-5BDNPKRD-BuQUC75n.js} +1 -1
  91. package/payload/server/public/assets/{diagram-G4DWMVQ6-BnBA0Ain.js → diagram-G4DWMVQ6-DHiu9U7B.js} +1 -1
  92. package/payload/server/public/assets/{diagram-MMDJMWI5-BrGASMP1.js → diagram-MMDJMWI5-ypu7YJGF.js} +1 -1
  93. package/payload/server/public/assets/{diagram-TYMM5635-iSPhqW2Q.js → diagram-TYMM5635-DIwuWuqN.js} +1 -1
  94. package/payload/server/public/assets/{dist-BmvZ8OaX.js → dist-ePW3hz19.js} +1 -1
  95. package/payload/server/public/assets/{erDiagram-SMLLAGMA-BCRyIkOj.js → erDiagram-SMLLAGMA-CKxGMQZW.js} +1 -1
  96. package/payload/server/public/assets/{flatten-Bo6YRmWl.js → flatten-CpKIi5d2.js} +1 -1
  97. package/payload/server/public/assets/{flowDiagram-DWJPFMVM-BgMtd8aD.js → flowDiagram-DWJPFMVM-CqH2RE7a.js} +1 -1
  98. package/payload/server/public/assets/{ganttDiagram-T4ZO3ILL-BKpI7Sqx.js → ganttDiagram-T4ZO3ILL-BfuGXUUh.js} +1 -1
  99. package/payload/server/public/assets/gitGraph-7Q5UKJZL-CwwaM7ed.js +1 -0
  100. package/payload/server/public/assets/{gitGraphDiagram-UUTBAWPF-CEx6x6gJ.js → gitGraphDiagram-UUTBAWPF-BlpUYLLd.js} +1 -1
  101. package/payload/server/public/assets/{graph-DDJ3p_3N.js → graph-BEu_XQMZ.js} +19 -19
  102. package/payload/server/public/assets/graph-labels-DvO7i7Ez.js +1 -0
  103. package/payload/server/public/assets/{graphlib-Do8h5YVR.js → graphlib-O_QsiopN.js} +1 -1
  104. package/payload/server/public/assets/info-OMHHGYJF-CiiU112m.js +1 -0
  105. package/payload/server/public/assets/infoDiagram-42DDH7IO-tHUu3AX-.js +2 -0
  106. package/payload/server/public/assets/{isEmpty-D6Kr-M1M.js → isEmpty-C3Vxk1It.js} +1 -1
  107. package/payload/server/public/assets/{ishikawaDiagram-UXIWVN3A-BmCNGBwK.js → ishikawaDiagram-UXIWVN3A-CVMbR1ZD.js} +1 -1
  108. package/payload/server/public/assets/{journeyDiagram-VCZTEJTY-C_37fL2K.js → journeyDiagram-VCZTEJTY-7pbwsn7f.js} +1 -1
  109. package/payload/server/public/assets/{kanban-definition-6JOO6SKY-BLFxAQHd.js → kanban-definition-6JOO6SKY-CWFMjHiJ.js} +1 -1
  110. package/payload/server/public/assets/{line-FtY_Ltj6.js → line-B4V-vQdN.js} +1 -1
  111. package/payload/server/public/assets/{linear-COm19-p7.js → linear-Cdt0EBMa.js} +1 -1
  112. package/payload/server/public/assets/{mermaid-parser.core-BIr5bg_O.js → mermaid-parser.core-Ba5Re-_1.js} +2 -2
  113. package/payload/server/public/assets/{mermaid.core-8XmmGzXJ.js → mermaid.core-C39ZL-9e.js} +3 -3
  114. package/payload/server/public/assets/{mindmap-definition-QFDTVHPH-DPKDmfiH.js → mindmap-definition-QFDTVHPH-BrREiATP.js} +1 -1
  115. package/payload/server/public/assets/{ordinal-BDi6f4xk.js → ordinal-BLrOss5K.js} +1 -1
  116. package/payload/server/public/assets/packet-4T2RLAQJ-Bq_zPNb3.js +1 -0
  117. package/payload/server/public/assets/pie-ZZUOXDRM-R-cewHYM.js +1 -0
  118. package/payload/server/public/assets/{pieDiagram-DEJITSTG-DyuI0jFr.js → pieDiagram-DEJITSTG-sJOzKUIf.js} +1 -1
  119. package/payload/server/public/assets/{public-n0sHV8JI.js → public-927mDSLH.js} +3 -3
  120. package/payload/server/public/assets/{quadrantDiagram-34T5L4WZ-B24Cvsjf.js → quadrantDiagram-34T5L4WZ-bxoGUruT.js} +1 -1
  121. package/payload/server/public/assets/radar-PYXPWWZC-CZpBUjmo.js +1 -0
  122. package/payload/server/public/assets/{reduce-CGi9ik8i.js → reduce-C5tBOlxC.js} +1 -1
  123. package/payload/server/public/assets/{requirementDiagram-MS252O5E-DpieLND2.js → requirementDiagram-MS252O5E-C8_uEDnp.js} +1 -1
  124. package/payload/server/public/assets/{sankeyDiagram-XADWPNL6-DFSI4LuL.js → sankeyDiagram-XADWPNL6-CKpSBj6p.js} +1 -1
  125. package/payload/server/public/assets/{sequenceDiagram-FGHM5R23-3babM9wY.js → sequenceDiagram-FGHM5R23-BbVOmtji.js} +1 -1
  126. package/payload/server/public/assets/{src-DLEIsjER.js → src-DssjGmtU.js} +1 -1
  127. package/payload/server/public/assets/{stateDiagram-FHFEXIEX-DKS3fdXm.js → stateDiagram-FHFEXIEX-CLiLypPX.js} +1 -1
  128. package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-Cn6OBfIT.js +1 -0
  129. package/payload/server/public/assets/{timeline-definition-GMOUNBTQ-1nRSO-Z9.js → timeline-definition-GMOUNBTQ-Dzzc-pnB.js} +1 -1
  130. package/payload/server/public/assets/treeView-SZITEDCU-CjsdVrjr.js +1 -0
  131. package/payload/server/public/assets/treemap-W4RFUUIX-BZ8peN4O.js +1 -0
  132. package/payload/server/public/assets/{useSelectionMode-DvBm4di-.js → useSelectionMode-BBvWzgtz.js} +1 -1
  133. package/payload/server/public/assets/useSelectionMode-CzWzToaM.css +1 -0
  134. package/payload/server/public/assets/{vennDiagram-DHZGUBPP-Ds6i6j3g.js → vennDiagram-DHZGUBPP-CEj_ctTP.js} +1 -1
  135. package/payload/server/public/assets/wardley-RL74JXVD-BYLmRSDV.js +1 -0
  136. package/payload/server/public/assets/{wardleyDiagram-NUSXRM2D-IZMQXgw6.js → wardleyDiagram-NUSXRM2D-Cnbz79qd.js} +1 -1
  137. package/payload/server/public/assets/{xychartDiagram-5P7HB3ND-BGZkTooo.js → xychartDiagram-5P7HB3ND-MTjLweae.js} +1 -1
  138. package/payload/server/public/browser.html +6 -5
  139. package/payload/server/public/chat.html +19 -0
  140. package/payload/server/public/data.html +7 -6
  141. package/payload/server/public/graph.html +8 -7
  142. package/payload/server/public/index.html +8 -6
  143. package/payload/server/public/public.html +5 -5
  144. package/payload/server/server.js +785 -338
  145. package/payload/server/public/assets/AdminShell-CnslFKoX.js +0 -1
  146. package/payload/server/public/assets/admin-BJYDe3p8.js +0 -1
  147. package/payload/server/public/assets/architecture-YZFGNWBL-xHbVjatf.js +0 -1
  148. package/payload/server/public/assets/browser-CKxPsTlh.js +0 -1
  149. package/payload/server/public/assets/channel-DPRBU48c.js +0 -1
  150. package/payload/server/public/assets/chunk-426QAEUC-CWj9Y5LE.js +0 -1
  151. package/payload/server/public/assets/chunk-QZHKN3VN-CHE_iZO7.js +0 -1
  152. package/payload/server/public/assets/classDiagram-6PBFFD2Q-BmQz46EF.js +0 -1
  153. package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-DyidaYtj.js +0 -1
  154. package/payload/server/public/assets/clone-D7qj6dUB.js +0 -1
  155. package/payload/server/public/assets/data-BEDsi4bU.js +0 -1
  156. package/payload/server/public/assets/gitGraph-7Q5UKJZL-CmHdoS27.js +0 -1
  157. package/payload/server/public/assets/graph-labels-Cgd3XiNd.js +0 -1
  158. package/payload/server/public/assets/info-OMHHGYJF-DTA9msO-.js +0 -1
  159. package/payload/server/public/assets/infoDiagram-42DDH7IO-DGlZXVKh.js +0 -2
  160. package/payload/server/public/assets/packet-4T2RLAQJ-6GjqIKgu.js +0 -1
  161. package/payload/server/public/assets/pie-ZZUOXDRM-T72DJ5JR.js +0 -1
  162. package/payload/server/public/assets/radar-PYXPWWZC-x-6xW1dE.js +0 -1
  163. package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-Dh0X-qyv.js +0 -1
  164. package/payload/server/public/assets/treeView-SZITEDCU-5-6wEryJ.js +0 -1
  165. package/payload/server/public/assets/treemap-W4RFUUIX-DF48Cc86.js +0 -1
  166. package/payload/server/public/assets/useSelectionMode-CeQtw8Ba.css +0 -1
  167. package/payload/server/public/assets/wardley-RL74JXVD-duKIa6Hq.js +0 -1
  168. /package/payload/server/public/assets/{_baseFor-Cam2PbSt.js → _baseFor-WfS9pKAn.js} +0 -0
  169. /package/payload/server/public/assets/{array-DYRGGQae.js → array-HeX70jSN.js} +0 -0
  170. /package/payload/server/public/assets/{chunk-CnGqDkHZ.js → chunk-CWOGyPgy.js} +0 -0
  171. /package/payload/server/public/assets/{cytoscape.esm-nWsJMTNI.js → cytoscape.esm-CDZo0kst.js} +0 -0
  172. /package/payload/server/public/assets/{defaultLocale-Du1XY3Dp.js → defaultLocale-GJwWH1Jr.js} +0 -0
  173. /package/payload/server/public/assets/{init-B5BXBRcm.js → init-BPLPMQ3Y.js} +0 -0
  174. /package/payload/server/public/assets/{katex-HOUACuRw.js → katex-CKZ-HWMQ.js} +0 -0
  175. /package/payload/server/public/assets/{path-CNO468J-.js → path-YdFzr2W6.js} +0 -0
  176. /package/payload/server/public/assets/{rough.esm-DRO6hWPh.js → rough.esm-HAx67Hnb.js} +0 -0
package/dist/index.js CHANGED
@@ -2216,6 +2216,20 @@ function buildPlatform() {
2216
2216
  console.log(` Installing whatsapp-channel dependencies (${wcDir})...`);
2217
2217
  shellRetry("npm", ["install", "--omit=dev", ...NPM_NET_FLAGS], { cwd: wcDir }, 3, 15);
2218
2218
  }
2219
+ // (maxy-code, Task 772) — webchat-channel service: identical contract to
2220
+ // whatsapp-channel above (ships dist/ + package.json declaring
2221
+ // @modelcontextprotocol/sdk; the per-conversation channel server resolves
2222
+ // the SDK from this node_modules). Wipe + reinstall on upgrade.
2223
+ const webchatDir = join(INSTALL_DIR, "platform", "services", "webchat-channel");
2224
+ if (existsSync(webchatDir)) {
2225
+ const webchatNodeModules = join(webchatDir, "node_modules");
2226
+ if (existsSync(webchatNodeModules)) {
2227
+ console.log(" Wiping previous webchat-channel/node_modules for a clean reinstall...");
2228
+ rmSync(webchatNodeModules, { recursive: true, force: true });
2229
+ }
2230
+ console.log(` Installing webchat-channel dependencies (${webchatDir})...`);
2231
+ shellRetry("npm", ["install", "--omit=dev", ...NPM_NET_FLAGS], { cwd: webchatDir }, 3, 15);
2232
+ }
2219
2233
  // Premium-plugin MCP servers (e.g. real-agent/loop) ship dist/ + package.json
2220
2234
  // in the payload but no node_modules — npm pack strips them, same reason as
2221
2235
  // server/. Discover every <installDir>/premium-plugins/<bundle>/plugins/<plugin>/mcp
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rubytech/create-maxy-code",
3
- "version": "0.1.290",
3
+ "version": "0.1.291",
4
4
  "description": "Install Maxy — AI for Productive People",
5
5
  "bin": {
6
6
  "create-maxy-code": "./dist/index.js"
@@ -12,7 +12,8 @@
12
12
  * unchanged colour-stability tests) keep the surfaces in lockstep.
13
13
  *
14
14
  * Sources of truth:
15
- * - Label list: .docs/neo4j.md "Schema (Phase 0)" + "Standards Compliance"
15
+ * - Label list: platform/neo4j/schema.cypher (constraints + fulltext
16
+ * unions); registry doctrine in .docs/graph-label-registries.md
16
17
  * - Brand colour for LocalBusiness: brand.json defaultColors.primary
17
18
  * (resolved at runtime; this module supplies the schema-default fallback)
18
19
  */
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CA4EtD,CAAA;AAED,eAAO,MAAM,qBAAqB,YAAY,CAAA;AAE9C,eAAO,MAAM,gBAAgB,EAAE,SAAS,MAAM,EAE7C,CAAA;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI,CAOzE;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,MAAM,EAAE,MAAM,CAAA;IACd,eAAe,EAAE,MAAM,CAAA;CACxB;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,kBAAkB,CAU/E;AASD;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACpC;AAKD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAI7D;AAED,iEAAiE;AACjE,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAIjE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,aAAa,GAAG,MAAM,CA0D1D;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,aAAa,GAAG,MAAM,CAmC3D"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAyFtD,CAAA;AAED,eAAO,MAAM,qBAAqB,YAAY,CAAA;AAE9C,eAAO,MAAM,gBAAgB,EAAE,SAAS,MAAM,EAE7C,CAAA;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI,CAOzE;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,MAAM,EAAE,MAAM,CAAA;IACd,eAAe,EAAE,MAAM,CAAA;CACxB;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,kBAAkB,CAU/E;AASD;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACpC;AAKD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAI7D;AAED,iEAAiE;AACjE,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAIjE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,aAAa,GAAG,MAAM,CA0D1D;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,aAAa,GAAG,MAAM,CAmC3D"}
@@ -13,7 +13,8 @@
13
13
  * unchanged colour-stability tests) keep the surfaces in lockstep.
14
14
  *
15
15
  * Sources of truth:
16
- * - Label list: .docs/neo4j.md "Schema (Phase 0)" + "Standards Compliance"
16
+ * - Label list: platform/neo4j/schema.cypher (constraints + fulltext
17
+ * unions); registry doctrine in .docs/graph-label-registries.md
17
18
  * - Brand colour for LocalBusiness: brand.json defaultColors.primary
18
19
  * (resolved at runtime; this module supplies the schema-default fallback)
19
20
  */
@@ -45,6 +46,18 @@ exports.GRAPH_LABEL_COLOURS = {
45
46
  Property: '#5C7A99',
46
47
  Viewing: '#D4A574',
47
48
  Offer: '#B08850',
49
+ // Construction ontology (Task 773; labels registered in schema.cypher by
50
+ // Task 650). Muted brick-red family — the construction register sits
51
+ // apart from people-terracotta, viewing-amber, and task-rose bands so
52
+ // siteoffice legends read as their own group. Top-level (operator-entry)
53
+ // labels only; child labels (LineItem, Milestone, Valuation,
54
+ // VariationNote, TimeLog) intentionally stay fallback-grey.
55
+ Job: '#8C3B2E',
56
+ QuoteDocument: '#A65A4A',
57
+ InboundInvoice: '#6B2A20',
58
+ SubContractor: '#BF7E6E',
59
+ SubInvoice: '#52201A',
60
+ WhatsAppGroup: '#D4A096',
48
61
  // External business entity — schema:Organization, written by memory-write
49
62
  // as the Supplier label. Warm tobacco — distinct hue from internal-business
50
63
  // slates so external entities are scannable at a glance.
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -12,7 +12,8 @@
12
12
  * unchanged colour-stability tests) keep the surfaces in lockstep.
13
13
  *
14
14
  * Sources of truth:
15
- * - Label list: .docs/neo4j.md "Schema (Phase 0)" + "Standards Compliance"
15
+ * - Label list: platform/neo4j/schema.cypher (constraints + fulltext
16
+ * unions); registry doctrine in .docs/graph-label-registries.md
16
17
  * - Brand colour for LocalBusiness: brand.json defaultColors.primary
17
18
  * (resolved at runtime; this module supplies the schema-default fallback)
18
19
  */
@@ -38,6 +39,19 @@ export const GRAPH_LABEL_COLOURS: Record<string, string> = {
38
39
  Viewing: '#D4A574',
39
40
  Offer: '#B08850',
40
41
 
42
+ // Construction ontology (Task 773; labels registered in schema.cypher by
43
+ // Task 650). Muted brick-red family — the construction register sits
44
+ // apart from people-terracotta, viewing-amber, and task-rose bands so
45
+ // siteoffice legends read as their own group. Top-level (operator-entry)
46
+ // labels only; child labels (LineItem, Milestone, Valuation,
47
+ // VariationNote, TimeLog) intentionally stay fallback-grey.
48
+ Job: '#8C3B2E',
49
+ QuoteDocument: '#A65A4A',
50
+ InboundInvoice: '#6B2A20',
51
+ SubContractor: '#BF7E6E',
52
+ SubInvoice: '#52201A',
53
+ WhatsAppGroup: '#D4A096',
54
+
41
55
  // External business entity — schema:Organization, written by memory-write
42
56
  // as the Supplier label. Warm tobacco — distinct hue from internal-business
43
57
  // slates so external entities are scannable at a glance.
@@ -6,7 +6,7 @@
6
6
  "services/*"
7
7
  ],
8
8
  "scripts": {
9
- "build": "tsc -p lib/models/tsconfig.json && tsc -p lib/mcp-stderr-tee/tsconfig.json && tsc -p lib/mcp-spawn-tee/tsconfig.json && tsc -p lib/mcp-eager/tsconfig.json && tsc -p lib/account-enumeration/tsconfig.json && tsc -p lib/graph-write/tsconfig.json && tsc -p lib/embed-client/tsconfig.json && tsc -p lib/graph-mcp/tsconfig.json && tsc -p lib/graph-trash/tsconfig.json && tsc -p lib/admin-conversation-purge/tsconfig.json && tsc -p lib/graph-search/tsconfig.json && tsc -p lib/graph-style/tsconfig.json && tsc -p lib/device-url/tsconfig.json && tsc -p lib/brand-templating/tsconfig.json && tsc -p lib/entitlement/tsconfig.json && tsc -p lib/task-secrets/tsconfig.json && tsc -p lib/admins-write/tsconfig.json && tsc -p lib/persistent-components/tsconfig.json && tsc -p lib/require-port-env/tsconfig.json && tsc -p lib/aeo-llms-txt-writer/tsconfig.json && tsc -p lib/obsidian-parser/tsconfig.json && tsc -p services/claude-session-manager/tsconfig.json && tsc -p services/whatsapp-channel/tsconfig.json && NODE_OPTIONS='--max-old-space-size=8192' tsc -b plugins/*/mcp/tsconfig.json",
9
+ "build": "tsc -p lib/models/tsconfig.json && tsc -p lib/mcp-stderr-tee/tsconfig.json && tsc -p lib/mcp-spawn-tee/tsconfig.json && tsc -p lib/mcp-eager/tsconfig.json && tsc -p lib/account-enumeration/tsconfig.json && tsc -p lib/graph-write/tsconfig.json && tsc -p lib/embed-client/tsconfig.json && tsc -p lib/graph-mcp/tsconfig.json && tsc -p lib/graph-trash/tsconfig.json && tsc -p lib/admin-conversation-purge/tsconfig.json && tsc -p lib/graph-search/tsconfig.json && tsc -p lib/graph-style/tsconfig.json && tsc -p lib/device-url/tsconfig.json && tsc -p lib/brand-templating/tsconfig.json && tsc -p lib/entitlement/tsconfig.json && tsc -p lib/task-secrets/tsconfig.json && tsc -p lib/admins-write/tsconfig.json && tsc -p lib/persistent-components/tsconfig.json && tsc -p lib/require-port-env/tsconfig.json && tsc -p lib/aeo-llms-txt-writer/tsconfig.json && tsc -p lib/obsidian-parser/tsconfig.json && tsc -p services/claude-session-manager/tsconfig.json && tsc -p services/whatsapp-channel/tsconfig.json && tsc -p services/webchat-channel/tsconfig.json && NODE_OPTIONS='--max-old-space-size=8192' tsc -b plugins/*/mcp/tsconfig.json",
10
10
  "build:lib": "tsc -p lib/models/tsconfig.json && tsc -p lib/mcp-stderr-tee/tsconfig.json && tsc -p lib/mcp-spawn-tee/tsconfig.json && tsc -p lib/mcp-eager/tsconfig.json && tsc -p lib/account-enumeration/tsconfig.json && tsc -p lib/graph-write/tsconfig.json && tsc -p lib/embed-client/tsconfig.json && tsc -p lib/graph-mcp/tsconfig.json && tsc -p lib/graph-trash/tsconfig.json && tsc -p lib/admin-conversation-purge/tsconfig.json && tsc -p lib/graph-search/tsconfig.json && tsc -p lib/graph-style/tsconfig.json && tsc -p lib/device-url/tsconfig.json && tsc -p lib/brand-templating/tsconfig.json && tsc -p lib/entitlement/tsconfig.json && tsc -p lib/task-secrets/tsconfig.json && tsc -p lib/admins-write/tsconfig.json && tsc -p lib/persistent-components/tsconfig.json && tsc -p lib/require-port-env/tsconfig.json && tsc -p lib/aeo-llms-txt-writer/tsconfig.json && tsc -p lib/obsidian-parser/tsconfig.json",
11
11
  "gen:canonical-tools": "node scripts/generate-canonical-tool-names.mjs",
12
12
  "build:memory": "tsc -p plugins/memory/mcp/tsconfig.json",
@@ -22,6 +22,7 @@
22
22
  "build:replicate": "tsc -p plugins/replicate/mcp/tsconfig.json",
23
23
  "build:graph-viewer": "tsc -p plugins/graph-viewer/mcp/tsconfig.json",
24
24
  "build:claude-session-manager": "tsc -p services/claude-session-manager/tsconfig.json",
25
- "build:whatsapp-channel": "tsc -p services/whatsapp-channel/tsconfig.json"
25
+ "build:whatsapp-channel": "tsc -p services/whatsapp-channel/tsconfig.json",
26
+ "build:webchat-channel": "tsc -p services/webchat-channel/tsconfig.json"
26
27
  }
27
28
  }
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: platform-architecture
3
3
  description: Use when grounding any documented-surface claim about what Maxy ships — plugins, skills, specialists, install/deploy flows, internals. This is the install catalogue, not evidence of what is enabled on the current account. For install state on this account, call `capabilities-here`; for documented surface, cite the `Source:` URL inline.
4
- content-hash: sha256:a058a1f676b20300c5b0cbba3a8eb4f1ccb4d3e127a19865286b1500a23b9cd0
4
+ content-hash: sha256:a2ef1747514689873975925dd6b1932c0bf45a1a2479fa06b3b6e2fdb2c2c347
5
5
  brand: maxy-code
6
6
  product-name: Maxy
7
7
  ---
@@ -3814,6 +3814,8 @@ tail -200 ~/.maxy/logs/maxy-ui.log | rg '\[remote-auth\].*resolvedKind='
3814
3814
  2. `diff <(jq .claudeAiOauth.accessToken ~/.maxy/.claude/.credentials.json) <(jq .claudeAiOauth.accessToken ~/.realagent/.claude/.credentials.json)` — must be non-empty after each brand's operator has run `claude /login` against distinct Anthropic accounts; if it's empty, both brands are still logged in to the same account (operator action, not a code bug).
3815
3815
  3. `grep "\[install\] claude-creds pickup" ~/.${brand}/logs/install-*.log` — fires once on the first post-Task-923 install of any brand and moves the legacy `~/.claude/.credentials.json` into that brand's path. Subsequent brands install with no credentials and require a fresh `claude /login` inside that brand's chat (which writes to the brand-scoped path because the systemd unit env is in scope).
3816
3816
 
3817
+ To deliberately disconnect the wrong account, use the header menu's **Disconnect Claude account** item (the supported path; no SSH or manual file deletion needed). It runs `claude auth logout`, then verifies the brand's `~/${brand.configDir}/.claude/.credentials.json` is actually gone before reporting success — a disconnect that left the credential in place reports failure in the menu rather than false-confirming. The server logs one line per attempt: `grep '\[onboarding\] op=claude-logout' ~/.${brand}/logs/server.log` — `credentialsPresent=true` after the call is a failed disconnect the operator may believe succeeded.
3818
+
3817
3819
  **All sessions on the brand stopped responding after a token expiry.** Symptom on the operator side: every spawn dies at `pid-file-timeout` and the dashboard health probe reports auth dead. Diagnose the OAuth refresh path before anything else:
3818
3820
 
3819
3821
  1. `tail -n 300 ~/.${brand}/logs/server.log | grep -E 'auth-refresh|auth-health|invalid_grant'` — `op=lock-acquired` proves the cross-process lock is in play (Task 576). `op=skipped-fresh` means a sibling process (the admin server or a `claude` binary) already rotated the tokens during the lock wait — expected, healthy. `op=renewed expiresAt=…` is the only line that means a network refresh actually ran.
@@ -106,12 +106,31 @@ CLOUDFLARE_API_TOKEN="${MINTED_ACCESS}" curl -sS \
106
106
  ```
107
107
 
108
108
  2. **Create the Access application** scoped to the deployed host's **document path(s) `and` `/api/*`** — the signing document's path(s) plus the capture endpoints `POST /api/accept` and `GET /api/status` (§ 4). Leave `/` and the static assets **public**. Gating only the document path is a **bypass**: with `/api/*` open, anyone can `POST /api/accept` and forge an acceptance, and `GET /api/status` is readable ungated. Leaving `/` public is deliberate and load-bearing — it is exactly what lets the neutral root portal (below) load **without a PIN**; the document path(s) and `/api/*` are the only gated destinations.
109
+
110
+ **Same-origin invariant — `/api/*` must be Functions of *this* Pages project.** An Access application gates a **host + path**, never a bare path across hosts. So gating `<host>/api/*` covers `/api/accept` and `/api/status` **only when they are Pages Functions of the same Pages project — the same origin — as the gated document**. The § 2 form posts to the **relative** `/api/accept` and `/api/status`, which keeps them same-origin by construction; that default is the invariant, not a convenience. **Splitting the endpoints onto a separate origin** — a second Pages project, any other host — escapes the gate entirely while every per-document check still passes: the document 302s to login, but `POST /api/accept` on the other origin is **forgeable** by anyone and `GET /api/status` is **world-readable**, because the document's Access app never covered that host. The `gate-probe` of "Verify on live" (below) is the only check that catches this; the per-page redirect does not. If the deploy ever resolves `/api/*` to an origin other than the document's own, that origin mismatch is itself the failure — before any probe runs.
109
111
  3. **Attach a policy** whose `include` allowlist names the **signer's email** (and the business owner's). Only those addresses can authenticate and view the page.
110
112
 
111
113
  The IdP call shapes are given inline above; the Access **app** and **policy** endpoints live in `api.md`'s endpoint map, and the permission-group ids are resolved by the `api.md` method (`GET …/tokens/permission_groups`).
112
114
 
113
115
  **Verify on live.** Loading the gated page **302-redirects to a Cloudflare login page that offers One-Time PIN** — not an empty dead-end. An allowlisted email receives a code, enters it, and reaches the document; a non-allowlisted email is refused after entering its code. Reproduction-before: with **zero** IdPs the same login page offers no method at all — that is the lockout (§ 8.9).
114
116
 
117
+ **Verify on live — `gate-probe` `/api/*`, not just the page.** The page redirect above is necessary but **not sufficient**: it never touches `/api/*`, which is exactly how a separate-origin API (the same-origin invariant, above) deploys green while wide open. Before a gated deploy is "done", hit **both** capture endpoints **unauthenticated, with no Access session**, against the live API origin, and read the status code — each must be **refused** (302 to the Access login, or 403) before it reaches the Function:
118
+
119
+ ```bash
120
+ # No cookies, no Access session. API MUST be the gated document's OWN origin —
121
+ # the canonical host § 7 writes as <project>.pages.dev, or a custom domain mapped to it.
122
+ # An UNGATED accept endpoint inserts a sentinel row (doc_ref=GATE-PROBE); delete it as
123
+ # part of remediation. A gated endpoint 302s before the Function runs, so nothing is written.
124
+ API="https://<host>"
125
+ printf 'op=gate-probe endpoint=/api/accept method=POST code=%s\n' \
126
+ "$(curl -sS -o /dev/null -w '%{http_code}' -X POST -H 'Content-Type: application/json' \
127
+ -d '{"name":"probe","email":"probe@example.com","token":"GATE-PROBE-aaaaa-aaaaaa","doc_ref":"GATE-PROBE"}' "$API/api/accept")"
128
+ printf 'op=gate-probe endpoint=/api/status method=GET code=%s\n' \
129
+ "$(curl -sS -o /dev/null -w '%{http_code}' "$API/api/status?doc_ref=GATE-PROBE")"
130
+ ```
131
+
132
+ **Pass:** both `gate-probe` lines report `302` or `403` — the Access gate refused each request **before** it reached the Function. **Fail:** **any other status.** `200` is the canonical signature (`POST /api/accept` forgeable, `GET /api/status` world-readable), but `400`, `409`, or `500` equally fail — any Function-originated response proves the request **reached the Function unauthenticated**, i.e. the API is ungated. (A repeat accept probe returns `409` on the sentinel's `doc_ref` UNIQUE — still ungated, still a fail; only `302`/`403` is a pass.) The cause is almost always `/api/*` resolving to a different origin than the gated document. A non-`302`/`403` here — not the page redirect — is the only signal that catches the split-origin escape. This `gate-probe` is the **unauthenticated negative** test; it is distinct from the § 7 outcome contract, which exercises the *authenticated functional* flow (POST → D1 row → status flip) and therefore runs pre-gate or from an allowlisted session. After both probes refuse, confirm an **allowlisted** session still reaches the form and accepts once.
133
+
115
134
  **Dispatch is unaffected (§ 6).** The sweep stamps the **persisted base** (`base.pdf`, § 1), never by fetching the gated page, so a gate never turns a dispatched "PDF" into an Access login screen — § 8.3 makes that structural. Keep it in mind whenever a gated document is swept.
116
135
 
117
136
  **Logout links carry `returnTo` — point them at the public root (the primary loop-fix).** Cloudflare Access **does** honour a logout redirect: `GET /cdn-cgi/access/logout?returnTo=<https origin root>` 302s straight to that root and **strips** the stale `__cf_access_message` param. The parameter is **camelCase `returnTo` only** — `return_to` and `redirect_url` are ignored. So build every signer-facing logout link as `/cdn-cgi/access/logout?returnTo=https://<host>/`, with `returnTo` pointing at the **public root**, never at the gated document path (which would just re-challenge for a PIN). A logout link built this way lands the signer cleanly on the public root with no stale param — this is what actually breaks the "enter PIN → logged-out screen" loop.
@@ -168,6 +187,8 @@ Confirming A4 *dimensions* is not proof of fit — **read every rendered page**
168
187
 
169
188
  **Acceptance token** — `<DOC_REF>-<5-char base36 timestamp>-<6-char djb2 hash>`. The hash is djb2 over `name + email + DOC_REF`: it binds the signer's identity to this document, so a UNIQUE collision on the token means *the same signer re-submitting the same document* — a genuine same-signer duplicate, distinct from a *different* signer hitting an already-accepted document (which the `doc_ref` guard catches; § 4).
170
189
 
190
+ **The djb2 hash is not an access control.** It is a deterministic function of `name`, `email` and `DOC_REF` — all public-ish fields a forger can supply — so it is **defence-in-depth obfuscation of the token shape, never a gate**. It makes a token mildly unguessable and lets the database discriminate a same-signer re-submit (above); it does **not** authenticate the POST. The only thing that stops a forged `POST /api/accept` is the § 1a Access gate over a **same-origin** `/api/*`. Never treat the token as a substitute for gating the API.
191
+
171
192
  All confirmation, closed-state, and fallback panels are built with `textContent` and DOM nodes, never `innerHTML` — the signer's own name and email flow back into the page, and `innerHTML` would make that an injection surface.
172
193
 
173
194
  ```html
@@ -121,6 +121,8 @@ tail -200 ~/.maxy/logs/maxy-ui.log | rg '\[remote-auth\].*resolvedKind='
121
121
  2. `diff <(jq .claudeAiOauth.accessToken ~/.maxy/.claude/.credentials.json) <(jq .claudeAiOauth.accessToken ~/.realagent/.claude/.credentials.json)` — must be non-empty after each brand's operator has run `claude /login` against distinct Anthropic accounts; if it's empty, both brands are still logged in to the same account (operator action, not a code bug).
122
122
  3. `grep "\[install\] claude-creds pickup" ~/.${brand}/logs/install-*.log` — fires once on the first post-Task-923 install of any brand and moves the legacy `~/.claude/.credentials.json` into that brand's path. Subsequent brands install with no credentials and require a fresh `claude /login` inside that brand's chat (which writes to the brand-scoped path because the systemd unit env is in scope).
123
123
 
124
+ To deliberately disconnect the wrong account, use the header menu's **Disconnect Claude account** item (the supported path; no SSH or manual file deletion needed). It runs `claude auth logout`, then verifies the brand's `~/${brand.configDir}/.claude/.credentials.json` is actually gone before reporting success — a disconnect that left the credential in place reports failure in the menu rather than false-confirming. The server logs one line per attempt: `grep '\[onboarding\] op=claude-logout' ~/.${brand}/logs/server.log` — `credentialsPresent=true` after the call is a failed disconnect the operator may believe succeeded.
125
+
124
126
  **All sessions on the brand stopped responding after a token expiry.** Symptom on the operator side: every spawn dies at `pid-file-timeout` and the dashboard health probe reports auth dead. Diagnose the OAuth refresh path before anything else:
125
127
 
126
128
  1. `tail -n 300 ~/.${brand}/logs/server.log | grep -E 'auth-refresh|auth-health|invalid_grant'` — `op=lock-acquired` proves the cross-process lock is in play (Task 576). `op=skipped-fresh` means a sibling process (the admin server or a `claude` binary) already rotated the tokens during the lock wait — expected, healthy. `op=renewed expiresAt=…` is the only line that means a network refresh actually ran.
@@ -86,6 +86,10 @@ Observation is fully preserved: group messages are stored in the ring buffer, re
86
86
 
87
87
  A native admin channel session runs a per-sender `whatsapp-channel` MCP server (`platform/services/whatsapp-channel/`) exposing two reply-only tools: `reply` (text) and `reply-document` (one or more files delivered as WhatsApp documents). `reply-document` POSTs to the gateway's `POST /wa-channel/reply-document`, which funnels through `sendWhatsAppDocument` — the single send core that owns account-dir path validation, the 100 MB ceiling, the canonical `[whatsapp:outbound] sent document …` log, and per-file reconciliation (`op=reply-document-reconciled` on delivery, `file-delivery-unreconciled` on a miss — no silent failure). A bare `SendUserFile` is also caught and delivered through the same core by a read-only JSONL follower on the session, so an attachment reaches the sender even when the agent skips the explicit tool. Both surfaces are reply-only: a file reply to a sender with no live conversation is refused. See [channels-whatsapp.md](references/channels-whatsapp.md) and `.docs/whatsapp-inbound-lifeline.md`.
88
88
 
89
+ ## Self-chat command lane (Task 774)
90
+
91
+ The agent links as a companion device on the operator's own WhatsApp account, so the operator cannot DM the agent from the paired handset — those messages arrive as `fromMe=true` / upsert type `append`. The operator's **self-chat** (message-yourself thread) is the command lane from that handset: the `append` branch in `manager.ts` evaluates a six-clause discriminator (`inbound/self-chat.ts`) — fromMe, self-surface jid (selfJid/selfLid/`selfPhone@s.whatsapp.net`, device-suffix normalised), not an agent-sent echo, timestamp strictly after `lastConnectedAt` (excludes reconnect history backfill; restart-safe backstop for the 2-min echo cache), not a duplicate, non-empty text — and dispatches a match to the **admin** agent with raw text; the reply lands back in the self-chat. Every self-chat `fromMe` message emits one `[whatsapp:self-chat] op=seen` line followed by `op=dispatch` or `op=skip reason=echo|backfill|duplicate|no-text`, so a dropped command is never silent. `fromMe` in any other thread is unchanged (`[Owner reply]` mirror). See [channels-whatsapp.md](references/channels-whatsapp.md) §Self-chat command lane.
92
+
89
93
  ## Live persistence
90
94
 
91
95
  Every `messages.upsert` event (both `notify` and `append`, both `fromMe` directions) writes a `:Message:WhatsAppMessage` row to Neo4j attached to the sessionKey-keyed `:Conversation`. A single capture site at `platform/ui/app/lib/whatsapp/manager.ts` covers inbound, outbound (Baileys echoes agent-sent messages back through `messages.upsert` with `fromMe=true`), and owner-mirror — without touching `outbound/send.ts`. `messageId` namespace is `whatsapp-live:<waName>:<remoteJid>:<msg.key.id>` where `<waName>` is the Baileys credential dirname (e.g. `default`); distinct from the `:ConversationArchive` `:Section` chunks written by the source-agnostic `conversation-archive` skill (parent `:ConversationArchive` keyed on `conversationIdentity`, plus `:Section` children) — live and archive live in disjoint shapes. Persist failures are loud (`[whatsapp-persist] FAIL …`) and never block dispatch — silent loss is the worse failure mode.
@@ -150,9 +150,36 @@ The dedupe cache (`agentSentMessages`) has a 2-minute TTL and 500-entry cap, whi
150
150
  | `src/web/inbound/dedupe.ts` | `trackAgentSentMessage` / `isAgentSentMessage` — echo suppression cache |
151
151
  | `src/infra/outbound/cross-agent-echo.ts` | Adapter: agent tool → `mirrorOwnerReplyToSession` |
152
152
 
153
+ ## Self-chat command lane (Task 774)
154
+
155
+ The companion-device link means the operator's paired phone cannot DM the agent — a message typed from the paired number arrives as `fromMe=true` with upsert type `append`, which the manager's append branch historically dropped before dispatch. The operator's **self-chat** (the message-yourself thread, `remoteJid` == the account's own jid/lid) is the exception: the agent never writes there first, so it is an unambiguous admin command surface.
156
+
157
+ The discriminator lives in `platform/ui/app/lib/whatsapp/inbound/self-chat.ts` (`evaluateSelfChatCommand`) and dispatches only when **all** of:
158
+
159
+ 1. `msg.key.fromMe === true`;
160
+ 2. `remoteJid` is the self surface — `selfJid`, `selfLid`, or `${selfPhone}@s.whatsapp.net`, with device suffixes (`447…:12@s.whatsapp.net`) normalised before comparison;
161
+ 3. the message id is not in the agent-sent cache (`isAgentSentMessage`) — suppresses the agent's own self-chat reply echoes within the 2-minute TTL;
162
+ 4. the message timestamp (Unix seconds, normalised to ms) is **strictly after** `conn.lastConnectedAt` — excludes history backfill replayed on reconnect, and is the restart-safe backstop when the in-memory echo cache has expired or been cleared;
163
+ 5. it is not an in-session duplicate (`isDuplicateInbound`);
164
+ 6. it has non-empty extracted text.
165
+
166
+ A match dispatches via `buildSelfChatDispatch` (`manager.ts`): `agentType: "admin"`, raw command text (no `[Owner reply]` prefix), `senderPhone = selfPhone`, the admin cacheKey (`whatsapp:<accountId>`), `reply`/`composing` closures bound to the self jid so the agent's answer returns to the self-chat, and **no `isOwnerMirror` flag** — the inbound route drops owner-mirror payloads before the gateway, and a self-chat message is a command expecting a reply, not a mirror. The reply goes out through `sendTextMessage`, which tracks the id for clause-3 echo suppression.
167
+
168
+ `fromMe` in any **non-self** thread is unchanged: it remains the `[Owner reply]` mirror described above, never a command.
169
+
170
+ **Log grammar** (one decision lineage per self-chat message, greppable by `msgId=`):
171
+
172
+ ```
173
+ [whatsapp:self-chat] op=seen account=… msgId=… tsMs=… connAtMs=… fromMe=true
174
+ [whatsapp:self-chat] op=skip account=… msgId=… reason=echo|backfill|duplicate|no-text
175
+ [whatsapp:self-chat] op=dispatch account=… msgId=… bytes=… agentType=admin
176
+ ```
177
+
178
+ Failure signatures: an `op=dispatch` whose `tsMs ≤ connAtMs` (backfill wrongly dispatched — must never appear; the `op=seen` line carries both fields so this is checkable per message); back-to-back `op=dispatch` with no operator-originated message between (self-reply loop); a self-chat message the operator confirms sending with no `op=seen` at all (silent drop upstream of the discriminator).
179
+
153
180
  ## Offline Message Recovery
154
181
 
155
- Baileys is a WhatsApp Web protocol client. When the gateway is offline, WhatsApp's servers hold incoming messages and push them back as history (`append`-type `messages.upsert` events) when Baileys reconnects — so the system self-recovers automatically on restart. These replayed messages are stored in the UI message cache and marked as read, but **not** dispatched to the agent (no auto-reply on catch-up). The recovery window is determined entirely by WhatsApp's server-side delivery queue (approximately 30 days); `syncFullHistory: false` only prevents requesting full chat history on first pairing and does not restrict this window.
182
+ Baileys is a WhatsApp Web protocol client. When the gateway is offline, WhatsApp's servers hold incoming messages and push them back as history (`append`-type `messages.upsert` events) when Baileys reconnects — so the system self-recovers automatically on restart. These replayed messages are stored in the UI message cache and marked as read, but **not** dispatched to the agent (no auto-reply on catch-up). The self-chat command lane (above) does not weaken this: replayed history fails its strictly-after-`lastConnectedAt` timestamp clause and skips with `reason=backfill`. The recovery window is determined entirely by WhatsApp's server-side delivery queue (approximately 30 days); `syncFullHistory: false` only prevents requesting full chat history on first pairing and does not restrict this window.
156
183
 
157
184
  ## Voice Notes
158
185
 
@@ -5,6 +5,7 @@ import type { RateLimiter } from './spawn-rate-limiter.js';
5
5
  import type { AuditRegistry } from './public-tool-audit.js';
6
6
  import { type UserTitleStore } from './user-title-store.js';
7
7
  import { WaChannelStore } from './wa-channel-store.js';
8
+ import { WebchatChannelStore } from './webchat-channel-store.js';
8
9
  export declare const SESSION_ID_PATTERN: RegExp;
9
10
  export declare const RC_SPAWN_URL_WAIT_DEFAULT_MS = 60000;
10
11
  export interface HttpDeps extends Omit<SpawnDeps, 'onSessionReady' | 'watcher'> {
@@ -24,6 +25,11 @@ export interface HttpDeps extends Omit<SpawnDeps, 'onSessionReady' | 'watcher'>
24
25
  * write-throughs it; every resume path reads it back to re-apply the
25
26
  * channel argv so `reply` is present on every live PTY for the session. */
26
27
  waChannelStore: WaChannelStore;
28
+ /** Task 772 — per-session webchat channel binding, the webchat twin of
29
+ * waChannelStore. Optional so the pre-772 test deps factories (which run
30
+ * the live /rc-spawn handler) keep working unchanged; production index.ts
31
+ * always injects it. */
32
+ webchatChannelStore?: WebchatChannelStore;
27
33
  /** Task 648 — override the `/rc-spawn` pid/bind poll bound. Production
28
34
  * omits this and gets RC_SPAWN_URL_WAIT_DEFAULT_MS (60s); tests inject a
29
35
  * short value to exercise the bind-timeout response without a 60s wait. */
@@ -1 +1 @@
1
- {"version":3,"file":"http-server.d.ts","sourceRoot":"","sources":["../src/http-server.ts"],"names":[],"mappings":"AAsBA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAS3B,OAAO,EAgBL,KAAK,SAAS,EAEf,MAAM,kBAAkB,CAAA;AAoBzB,OAAO,KAAK,EAAE,SAAS,EAAc,MAAM,iBAAiB,CAAA;AAE5D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;AAC1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAA;AAC3D,OAAO,EAAqB,KAAK,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAC9E,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAgFtD,eAAO,MAAM,kBAAkB,QAA2B,CAAA;AAS1D,eAAO,MAAM,4BAA4B,QAAS,CAAA;AAIlD,MAAM,WAAW,QAAS,SAAQ,IAAI,CAAC,SAAS,EAAE,gBAAgB,GAAG,SAAS,CAAC;IAC7E;;qEAEiE;IACjE,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,SAAS,CAAA;IAClB,WAAW,EAAE,MAAM,CAAA;IACnB,iBAAiB,EAAE,MAAM,CAAA;IACzB,kBAAkB,EAAE,WAAW,CAAA;IAC/B,eAAe,EAAE,aAAa,CAAA;IAC9B;kFAC8E;IAC9E,cAAc,EAAE,cAAc,CAAA;IAC9B;;gFAE4E;IAC5E,cAAc,EAAE,cAAc,CAAA;IAC9B;;gFAE4E;IAC5E,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAC1B;AA+MD;;;kEAGkE;AAClE,MAAM,MAAM,OAAO,GAAG,IAAI,GAAG;IAC3B,2BAA2B,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACpD;;;+CAG2C;IAC3C,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;CAChD,CAAA;AAmBD,wBAAgB,YAAY,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAo4DpD"}
1
+ {"version":3,"file":"http-server.d.ts","sourceRoot":"","sources":["../src/http-server.ts"],"names":[],"mappings":"AAsBA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAU3B,OAAO,EAgBL,KAAK,SAAS,EAEf,MAAM,kBAAkB,CAAA;AAoBzB,OAAO,KAAK,EAAE,SAAS,EAAc,MAAM,iBAAiB,CAAA;AAE5D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;AAC1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAA;AAC3D,OAAO,EAAqB,KAAK,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAC9E,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAA;AAgFhE,eAAO,MAAM,kBAAkB,QAA2B,CAAA;AAS1D,eAAO,MAAM,4BAA4B,QAAS,CAAA;AAIlD,MAAM,WAAW,QAAS,SAAQ,IAAI,CAAC,SAAS,EAAE,gBAAgB,GAAG,SAAS,CAAC;IAC7E;;qEAEiE;IACjE,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,SAAS,CAAA;IAClB,WAAW,EAAE,MAAM,CAAA;IACnB,iBAAiB,EAAE,MAAM,CAAA;IACzB,kBAAkB,EAAE,WAAW,CAAA;IAC/B,eAAe,EAAE,aAAa,CAAA;IAC9B;kFAC8E;IAC9E,cAAc,EAAE,cAAc,CAAA;IAC9B;;gFAE4E;IAC5E,cAAc,EAAE,cAAc,CAAA;IAC9B;;;6BAGyB;IACzB,mBAAmB,CAAC,EAAE,mBAAmB,CAAA;IACzC;;gFAE4E;IAC5E,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAC1B;AA+MD;;;kEAGkE;AAClE,MAAM,MAAM,OAAO,GAAG,IAAI,GAAG;IAC3B,2BAA2B,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACpD;;;+CAG2C;IAC3C,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;CAChD,CAAA;AAmBD,wBAAgB,YAAY,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAu8DpD"}
@@ -24,6 +24,7 @@ import { stream } from 'hono/streaming';
24
24
  import { existsSync, statSync, createReadStream, watchFile, unwatchFile, rmSync, mkdirSync, renameSync, readFileSync, writeFileSync } from 'node:fs';
25
25
  import { tmpdir } from 'node:os';
26
26
  import { buildWaChannelMcpServers, buildWaChannelArgv, waChannelMcpConfigPath, isDevChannelPrompt } from './wa-channel-mcp.js';
27
+ import { buildWebchatChannelMcpServers, buildWebchatChannelArgv, webchatChannelMcpConfigPath } from './webchat-channel-mcp.js';
27
28
  import { randomUUID } from 'node:crypto';
28
29
  import { execFileSync } from 'node:child_process';
29
30
  import { buildRcChildEnv } from './rc-daemon.js';
@@ -1305,6 +1306,7 @@ export function buildHttpApp(deps) {
1305
1306
  // doesn't accrete orphans and a recreated session can't inherit a stale
1306
1307
  // binding. Best-effort; the store logs its own failure.
1307
1308
  deps.waChannelStore.remove(sessionId);
1309
+ deps.webchatChannelStore?.remove(sessionId);
1308
1310
  // Task 702 — the transcript is gone; its reattach hint must go too.
1309
1311
  removeScopeRecord(sessionsDir, sessionId, deps.logger);
1310
1312
  deps.logger(`purge sessionId=${sessionId.slice(0, 8)} bytes=${bytes}`);
@@ -1629,6 +1631,18 @@ export function buildHttpApp(deps) {
1629
1631
  typeof waChannelRaw.serverPath === 'string'
1630
1632
  ? waChannelRaw
1631
1633
  : undefined;
1634
+ // Task 772 — optional webchat native-channel attach, the webchat twin of
1635
+ // waChannel. All three fields must be present strings or the attach is
1636
+ // skipped. A session is whatsapp XOR webchat, so at most one of the two
1637
+ // channel blocks below fires.
1638
+ const webchatChannelRaw = body.webchatChannel;
1639
+ const webchatChannel = webchatChannelRaw !== null &&
1640
+ typeof webchatChannelRaw === 'object' &&
1641
+ typeof webchatChannelRaw.key === 'string' &&
1642
+ typeof webchatChannelRaw.gatewayUrl === 'string' &&
1643
+ typeof webchatChannelRaw.serverPath === 'string'
1644
+ ? webchatChannelRaw
1645
+ : undefined;
1632
1646
  // Task 724 — the bridge routes EVERY role=admin channel inbound here, not
1633
1647
  // just WhatsApp, and supplies the real channel (+ role:'admin', senderId) so
1634
1648
  // the classification sidecar below records the actual channel. The WaGateway
@@ -1740,6 +1754,49 @@ export function buildHttpApp(deps) {
1740
1754
  deps.logger(`[rc-spawn] op=wa-channel-write-failed err=${JSON.stringify(err instanceof Error ? err.message : String(err))}`);
1741
1755
  }
1742
1756
  }
1757
+ // Task 772 — webchat native channel, the webchat twin of the waChannel
1758
+ // block above. Same contract: a gateway spawn carries `webchatChannel` and
1759
+ // write-throughs the binding; a bare resume reads it back, so
1760
+ // `mcp__webchat-channel__reply` is present on every live PTY for the
1761
+ // session. A session is whatsapp XOR webchat — enforced here: when a
1762
+ // WhatsApp binding is already effective for this session, the webchat
1763
+ // attach is refused (two channel servers on one PTY is never valid).
1764
+ let effectiveWebchatChannel;
1765
+ if (sessionId && effectiveWaChannel && (webchatChannel || deps.webchatChannelStore?.get(sessionId))) {
1766
+ deps.logger(`[rc-spawn] op=webchat-channel-refused sessionId=${sessionId.slice(0, 8)} reason=wa-channel-already-bound`);
1767
+ }
1768
+ else if (sessionId) {
1769
+ if (webchatChannel) {
1770
+ effectiveWebchatChannel = webchatChannel;
1771
+ deps.webchatChannelStore?.set(sessionId, webchatChannel);
1772
+ }
1773
+ else {
1774
+ const stored = deps.webchatChannelStore?.get(sessionId);
1775
+ if (stored) {
1776
+ effectiveWebchatChannel = { key: stored.key, gatewayUrl: stored.gatewayUrl, serverPath: stored.serverPath };
1777
+ deps.logger(`[rc-spawn] op=webchat-channel-rebind sessionId=${sessionId.slice(0, 8)} key=${stored.key} source=store`);
1778
+ }
1779
+ }
1780
+ }
1781
+ let webchatPath = null;
1782
+ if (effectiveWebchatChannel && sessionId) {
1783
+ const webchatServers = buildWebchatChannelMcpServers({
1784
+ sessionId,
1785
+ key: effectiveWebchatChannel.key,
1786
+ gatewayUrl: effectiveWebchatChannel.gatewayUrl,
1787
+ serverPath: effectiveWebchatChannel.serverPath,
1788
+ });
1789
+ webchatPath = webchatChannelMcpConfigPath(sessionId, tmpdir());
1790
+ try {
1791
+ writeFileSync(webchatPath, JSON.stringify({ mcpServers: webchatServers }, null, 2), 'utf8');
1792
+ argv.push(...buildWebchatChannelArgv(webchatPath));
1793
+ deps.logger(`[rc-spawn] op=webchat-channel key=${effectiveWebchatChannel.key} gateway=${effectiveWebchatChannel.gatewayUrl} path=${webchatPath}`);
1794
+ }
1795
+ catch (err) {
1796
+ webchatPath = null;
1797
+ deps.logger(`[rc-spawn] op=webchat-channel-write-failed err=${JSON.stringify(err instanceof Error ? err.message : String(err))}`);
1798
+ }
1799
+ }
1743
1800
  // Task 626 — the initial message is the trailing positional, processed as
1744
1801
  // the session's first user turn at PTY startup. One-shot jobs omit `name`
1745
1802
  // so the prompt is the sole positional.
@@ -1828,6 +1885,10 @@ export function buildHttpApp(deps) {
1828
1885
  if (sessionId && deps.waChannelStore.get(sessionId) && waPath === null) {
1829
1886
  deps.logger(`[rc-spawn] op=channel-binding-lost sessionId=${sessionId} pid=${pty.pid} reason=resume-without-mcp-config`);
1830
1887
  }
1888
+ // Task 772 — the same post-condition for the webchat binding.
1889
+ if (sessionId && deps.webchatChannelStore?.get(sessionId) && webchatPath === null) {
1890
+ deps.logger(`[rc-spawn] op=webchat-channel-binding-lost sessionId=${sessionId} pid=${pty.pid} reason=resume-without-mcp-config`);
1891
+ }
1831
1892
  // Tracker registration — closes the leak gap the Task 552 path opened.
1832
1893
  // For fresh spawns without a caller-supplied sessionId we register the
1833
1894
  // tracker under the unitToken so the entry has a stable key; the
@@ -1863,7 +1924,7 @@ export function buildHttpApp(deps) {
1863
1924
  // a failed classification sidecar must not tear it down, so it logs and the
1864
1925
  // session keeps running (the pre-fix reader-blind behaviour, no worse).
1865
1926
  const classifyChannel = adminRole === 'admin' ? adminChannel : undefined;
1866
- const classifySenderId = adminSenderId ?? effectiveWaChannel?.senderId;
1927
+ const classifySenderId = adminSenderId ?? effectiveWaChannel?.senderId ?? effectiveWebchatChannel?.key;
1867
1928
  if (sessionId && classifyChannel && classifySenderId) {
1868
1929
  const classifySidecarPath = sidecarPathForSessionId(deps.spawnCwd, sessionId);
1869
1930
  if (!existsSync(classifySidecarPath)) {
@@ -1935,7 +1996,8 @@ export function buildHttpApp(deps) {
1935
1996
  // no literal spaces, so match on the ANSI/space-stripped letter stream.
1936
1997
  // Bounded startup keystroke only — inbound message submission stays a
1937
1998
  // channel event (the whole point of the migration). Armed only when a
1938
- // waChannel is attached, fired at most once.
1999
+ // native channel (waChannel or webchatChannel, Task 772) is attached,
2000
+ // fired at most once — the prompt text is channel-agnostic.
1939
2001
  let devChannelConfirmed = false;
1940
2002
  let devChannelScan = '';
1941
2003
  let resolveStdoutSlug = () => { };
@@ -1943,7 +2005,7 @@ export function buildHttpApp(deps) {
1943
2005
  const BIND_BUF_TAIL = 8 * 1024;
1944
2006
  pty.onData((data) => {
1945
2007
  stdoutBytes += data.length;
1946
- if (effectiveWaChannel && !devChannelConfirmed) {
2008
+ if ((effectiveWaChannel || effectiveWebchatChannel) && !devChannelConfirmed) {
1947
2009
  devChannelScan += data;
1948
2010
  if (devChannelScan.length > 4096)
1949
2011
  devChannelScan = devChannelScan.slice(devChannelScan.length - 4096);