@rubytech/create-maxy-code 0.1.309 → 0.1.311
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/plugins/admin/skills/platform-architecture/SKILL.md +2 -2
- package/payload/platform/plugins/admin/skills/plugin-management/SKILL.md +1 -1
- package/payload/platform/plugins/admin/skills/specialist-management/SKILL.md +1 -1
- package/payload/platform/plugins/cloudflare/skills/cloudflare/SKILL.md +1 -1
- package/payload/platform/plugins/docs/references/admin-ui.md +1 -1
- package/payload/platform/scripts/check-no-esm-require.mjs +4 -0
- package/payload/platform/services/claude-session-manager/dist/http-server.d.ts +1 -0
- package/payload/platform/services/claude-session-manager/dist/http-server.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/http-server.js +69 -1
- package/payload/platform/services/claude-session-manager/dist/http-server.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/index.js +16 -2
- package/payload/platform/services/claude-session-manager/dist/index.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/rc-daemon.d.ts +10 -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 +22 -2
- package/payload/platform/services/claude-session-manager/dist/rc-daemon.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/reseat-ledger.d.ts +39 -0
- package/payload/platform/services/claude-session-manager/dist/reseat-ledger.d.ts.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/reseat-ledger.js +139 -0
- package/payload/platform/services/claude-session-manager/dist/reseat-ledger.js.map +1 -0
- package/payload/platform/services/webchat-channel/dist/instructions.d.ts +1 -0
- package/payload/platform/services/webchat-channel/dist/instructions.d.ts.map +1 -1
- package/payload/platform/services/webchat-channel/dist/instructions.js +31 -0
- package/payload/platform/services/webchat-channel/dist/instructions.js.map +1 -1
- package/payload/platform/services/webchat-channel/dist/notification.d.ts +8 -3
- package/payload/platform/services/webchat-channel/dist/notification.d.ts.map +1 -1
- package/payload/platform/services/webchat-channel/dist/notification.js +25 -9
- package/payload/platform/services/webchat-channel/dist/notification.js.map +1 -1
- package/payload/platform/services/webchat-channel/dist/server.d.ts.map +1 -1
- package/payload/platform/services/webchat-channel/dist/server.js +5 -3
- package/payload/platform/services/webchat-channel/dist/server.js.map +1 -1
- package/payload/platform/services/whatsapp-channel/dist/notification.d.ts +8 -0
- package/payload/platform/services/whatsapp-channel/dist/notification.d.ts.map +1 -1
- package/payload/platform/services/whatsapp-channel/dist/notification.js +10 -0
- package/payload/platform/services/whatsapp-channel/dist/notification.js.map +1 -1
- package/payload/server/public/assets/AccessGate-ChFLk-rp.js +1 -0
- package/payload/server/public/assets/AdminLoginScreens-DU6zgbk5.js +1 -0
- package/payload/server/public/assets/AdminShell-BJCYb1v5.js +1 -0
- package/payload/server/public/assets/{Checkbox-DMA1hVhn.js → Checkbox-CQGLKMXu.js} +1 -1
- package/payload/server/public/assets/OperatorConversations-CHEQTz20.js +1 -0
- package/payload/server/public/assets/admin-COHPIWdb.js +1 -0
- package/payload/server/public/assets/admin-types-D2qTXuCg.js +1 -0
- package/payload/server/public/assets/{arc-Dl9QFDgW.js → arc-J2g2u5Xv.js} +1 -1
- package/payload/server/public/assets/architecture-YZFGNWBL-C6nkAxzW.js +1 -0
- package/payload/server/public/assets/{architectureDiagram-Q4EWVU46-CNLQUVi9.js → architectureDiagram-Q4EWVU46-CN0BXxpE.js} +1 -1
- package/payload/server/public/assets/audio-attachment-mime-DL06xo72.js +30 -0
- package/payload/server/public/assets/{blockDiagram-DXYQGD6D-B-QxfVjk.js → blockDiagram-DXYQGD6D-HX-8wF2p.js} +1 -1
- package/payload/server/public/assets/brand-CN7uSSKl.css +1 -0
- package/payload/server/public/assets/{browser-eLSiC7_b.js → browser-L7N4tAOl.js} +1 -1
- package/payload/server/public/assets/{c4Diagram-AHTNJAMY-NuYFvPDU.js → c4Diagram-AHTNJAMY-wIuarKF5.js} +1 -1
- package/payload/server/public/assets/channel-Q39xIXyT.js +1 -0
- package/payload/server/public/assets/chat-B_jYIH9a.js +1 -0
- package/payload/server/public/assets/{chunk-2KRD3SAO-l5VL1KQm.js → chunk-2KRD3SAO-Buz7egJZ.js} +1 -1
- package/payload/server/public/assets/{chunk-336JU56O-C5gVznC2.js → chunk-336JU56O-_JcFXJqc.js} +2 -2
- package/payload/server/public/assets/chunk-426QAEUC-CCYjp9C2.js +1 -0
- package/payload/server/public/assets/{chunk-4BX2VUAB-BtMVz_Sq.js → chunk-4BX2VUAB-DUR5Dg3M.js} +1 -1
- package/payload/server/public/assets/{chunk-4TB4RGXK-C8-dmCuT.js → chunk-4TB4RGXK-BRIqQ9st.js} +1 -1
- package/payload/server/public/assets/{chunk-55IACEB6-C5gWvEJW.js → chunk-55IACEB6-CezTHWXL.js} +1 -1
- package/payload/server/public/assets/{chunk-5FUZZQ4R-BZ7VZoAC.js → chunk-5FUZZQ4R-DHYUPzF1.js} +1 -1
- package/payload/server/public/assets/{chunk-5PVQY5BW-C_ajQOGC.js → chunk-5PVQY5BW-BVn4_fI5.js} +1 -1
- package/payload/server/public/assets/{chunk-67CJDMHE-BJOR2dwK.js → chunk-67CJDMHE-BBLA8Mbi.js} +1 -1
- package/payload/server/public/assets/{chunk-7N4EOEYR-DvZLpquX.js → chunk-7N4EOEYR-CdWfEI5c.js} +1 -1
- package/payload/server/public/assets/{chunk-AA7GKIK3-h5tVsPlW.js → chunk-AA7GKIK3-tS11knCR.js} +1 -1
- package/payload/server/public/assets/{chunk-BSJP7CBP-DLOF2-m3.js → chunk-BSJP7CBP-GEu1OOZ6.js} +1 -1
- package/payload/server/public/assets/{chunk-CIAEETIT-CQRQMPCf.js → chunk-CIAEETIT-DKrNbbp_.js} +1 -1
- package/payload/server/public/assets/{chunk-EDXVE4YY-K9-EfuM2.js → chunk-EDXVE4YY-B0InXNyr.js} +1 -1
- package/payload/server/public/assets/{chunk-ENJZ2VHE-DVoy6NvU.js → chunk-ENJZ2VHE-CO7lkHdm.js} +1 -1
- package/payload/server/public/assets/{chunk-FMBD7UC4-CQn_2o2b.js → chunk-FMBD7UC4-CMj74lWo.js} +1 -1
- package/payload/server/public/assets/{chunk-FOC6F5B3-CuN73goS.js → chunk-FOC6F5B3-CLnKQoXw.js} +1 -1
- package/payload/server/public/assets/{chunk-ICPOFSXX-CKhl9J-H.js → chunk-ICPOFSXX-CdiEKIaz.js} +2 -2
- package/payload/server/public/assets/{chunk-K5T4RW27-CBskuQmq.js → chunk-K5T4RW27-B6LA3fiv.js} +1 -1
- package/payload/server/public/assets/{chunk-KGLVRYIC-Chtjt8xK.js → chunk-KGLVRYIC-DrhRrb8Q.js} +1 -1
- package/payload/server/public/assets/{chunk-LIHQZDEY-EOBiBNSH.js → chunk-LIHQZDEY-DVQukevB.js} +1 -1
- package/payload/server/public/assets/{chunk-ORNJ4GCN-uPPq-5MN.js → chunk-ORNJ4GCN-ZMLkoDhP.js} +1 -1
- package/payload/server/public/assets/{chunk-OYMX7WX6-BRzbxJOT.js → chunk-OYMX7WX6-C0dJkynG.js} +1 -1
- package/payload/server/public/assets/chunk-QZHKN3VN-BNBxnHZh.js +1 -0
- package/payload/server/public/assets/{chunk-U2HBQHQK-Bndyn5nF.js → chunk-U2HBQHQK-BQ9BPIFZ.js} +1 -1
- package/payload/server/public/assets/{chunk-X2U36JSP-BspGBHXW.js → chunk-X2U36JSP-CAonGMOd.js} +1 -1
- package/payload/server/public/assets/{chunk-XPW4576I-HgXQ2k9h.js → chunk-XPW4576I-D5C_WNlk.js} +1 -1
- package/payload/server/public/assets/{chunk-YZCP3GAM-C7oTyCnw.js → chunk-YZCP3GAM-Ecdvzekb.js} +1 -1
- package/payload/server/public/assets/{chunk-ZZ45TVLE-CufWa7QL.js → chunk-ZZ45TVLE-BsFZd1cN.js} +1 -1
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-BShusfby.js +1 -0
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-D4ivPLFF.js +1 -0
- package/payload/server/public/assets/clone-CjEM8LwB.js +1 -0
- package/payload/server/public/assets/{cose-bilkent-S5V4N54A-BM3yEbF-.js → cose-bilkent-S5V4N54A-DBWHaIwm.js} +1 -1
- package/payload/server/public/assets/{dagre-C7WHNZO8.js → dagre-Dr7ZJYeS.js} +1 -1
- package/payload/server/public/assets/{dagre-KV5264BT-bcZx3l06.js → dagre-KV5264BT-oIJddk7m.js} +1 -1
- package/payload/server/public/assets/data-BmSTKHR1.js +1 -0
- package/payload/server/public/assets/{diagram-5BDNPKRD-B7VotaMF.js → diagram-5BDNPKRD-CEVxqOZ4.js} +1 -1
- package/payload/server/public/assets/{diagram-G4DWMVQ6-CWWvEsFx.js → diagram-G4DWMVQ6-BovF7Rjx.js} +1 -1
- package/payload/server/public/assets/{diagram-MMDJMWI5-DYHVkTYJ.js → diagram-MMDJMWI5-BhrF8zoF.js} +1 -1
- package/payload/server/public/assets/{diagram-TYMM5635-CHeB6Ama.js → diagram-TYMM5635-DCUYwxtR.js} +1 -1
- package/payload/server/public/assets/{erDiagram-SMLLAGMA-C9gog8QP.js → erDiagram-SMLLAGMA-BS2-HdCg.js} +1 -1
- package/payload/server/public/assets/{flatten-QcJDm7yK.js → flatten-BZMXCpLh.js} +1 -1
- package/payload/server/public/assets/{flowDiagram-DWJPFMVM-B2O9lKTh.js → flowDiagram-DWJPFMVM-BzSFLoea.js} +1 -1
- package/payload/server/public/assets/{ganttDiagram-T4ZO3ILL-DEa4AwbR.js → ganttDiagram-T4ZO3ILL-1-3QU7mT.js} +1 -1
- package/payload/server/public/assets/gitGraph-7Q5UKJZL-Btp3PwZh.js +1 -0
- package/payload/server/public/assets/{gitGraphDiagram-UUTBAWPF-BjXPQpBL.js → gitGraphDiagram-UUTBAWPF-fTrJ35Wk.js} +1 -1
- package/payload/server/public/assets/{graph-C7Hye_vp.js → graph-Cro3-mgY.js} +2 -2
- package/payload/server/public/assets/{graph-labels-YYgGsEVd.js → graph-labels-WQQn6JIJ.js} +1 -1
- package/payload/server/public/assets/{graphlib-CBevn2DP.js → graphlib-rlEzI2qD.js} +1 -1
- package/payload/server/public/assets/info-OMHHGYJF-CPt2y6_L.js +1 -0
- package/payload/server/public/assets/infoDiagram-42DDH7IO-CpXNTMgd.js +2 -0
- package/payload/server/public/assets/{isEmpty-BO6BAEn7.js → isEmpty-DaYIrHay.js} +1 -1
- package/payload/server/public/assets/{ishikawaDiagram-UXIWVN3A-CPLfpvqv.js → ishikawaDiagram-UXIWVN3A-0eU_UtlT.js} +1 -1
- package/payload/server/public/assets/{journeyDiagram-VCZTEJTY-CTHe8MiD.js → journeyDiagram-VCZTEJTY-BKLeZohp.js} +1 -1
- package/payload/server/public/assets/{kanban-definition-6JOO6SKY-Bm9h1O3Y.js → kanban-definition-6JOO6SKY-Dq72xyaN.js} +1 -1
- package/payload/server/public/assets/{line-C31b0rtY.js → line-LQhmDT8k.js} +1 -1
- package/payload/server/public/assets/{linear-Cfm_8_pU.js → linear-BGotDbGs.js} +1 -1
- package/payload/server/public/assets/{mermaid-parser.core-B3tGwOcE.js → mermaid-parser.core-DoLdho1V.js} +2 -2
- package/payload/server/public/assets/{mermaid.core-BM3s85ZW.js → mermaid.core-C1RRyHGm.js} +3 -3
- package/payload/server/public/assets/{mindmap-definition-QFDTVHPH-CaGv_mIB.js → mindmap-definition-QFDTVHPH-vUVVVyV1.js} +1 -1
- package/payload/server/public/assets/operator-B4I25isQ.js +1 -0
- package/payload/server/public/assets/{ordinal-jLCwuvYg.js → ordinal-BqEhkPyh.js} +1 -1
- package/payload/server/public/assets/packet-4T2RLAQJ-Cwc-j_AI.js +1 -0
- package/payload/server/public/assets/page-B-6ZQ4JG.js +1 -0
- package/payload/server/public/assets/pie-ZZUOXDRM-BZ9fjD1_.js +1 -0
- package/payload/server/public/assets/{pieDiagram-DEJITSTG-BhAXps4u.js → pieDiagram-DEJITSTG-B9Pl6Qhc.js} +1 -1
- package/payload/server/public/assets/{public-ViXjC_dA.js → public-CX148JKi.js} +3 -3
- package/payload/server/public/assets/public-next-BCItsUbZ.js +1 -0
- package/payload/server/public/assets/{quadrantDiagram-34T5L4WZ-BWtTdNs8.js → quadrantDiagram-34T5L4WZ-Drn9T81A.js} +1 -1
- package/payload/server/public/assets/radar-PYXPWWZC-BNz5Rt9V.js +1 -0
- package/payload/server/public/assets/{reduce-Dmi_NdVH.js → reduce-T2IuntYP.js} +1 -1
- package/payload/server/public/assets/{requirementDiagram-MS252O5E-CWU0qCcP.js → requirementDiagram-MS252O5E-C0PAItJm.js} +1 -1
- package/payload/server/public/assets/{sankeyDiagram-XADWPNL6-DYvutQld.js → sankeyDiagram-XADWPNL6-BR42Mtwd.js} +1 -1
- package/payload/server/public/assets/{sequenceDiagram-FGHM5R23-Cir0hBWS.js → sequenceDiagram-FGHM5R23-c2lR9UOS.js} +1 -1
- package/payload/server/public/assets/{stateDiagram-FHFEXIEX-Be-h8YSS.js → stateDiagram-FHFEXIEX-BcHhtqsZ.js} +1 -1
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-BUQ_F4eP.js +1 -0
- package/payload/server/public/assets/{timeline-definition-GMOUNBTQ-C3C4Wuyk.js → timeline-definition-GMOUNBTQ-Ax32c10H.js} +1 -1
- package/payload/server/public/assets/treeView-SZITEDCU-DcVCQgp1.js +1 -0
- package/payload/server/public/assets/treemap-W4RFUUIX-Bm12mwGd.js +1 -0
- package/payload/server/public/assets/{useSelectionMode-CG_Iel5F.js → useSelectionMode-BHAAhkDg.js} +1 -1
- package/payload/server/public/assets/{vennDiagram-DHZGUBPP-mDclw0Sa.js → vennDiagram-DHZGUBPP-BxePewPq.js} +1 -1
- package/payload/server/public/assets/wardley-RL74JXVD-47Z3ymtK.js +1 -0
- package/payload/server/public/assets/{wardleyDiagram-NUSXRM2D-mvk-YA9g.js → wardleyDiagram-NUSXRM2D-DmJwZ2f5.js} +1 -1
- package/payload/server/public/assets/{xychartDiagram-5P7HB3ND-9M7k1hmD.js → xychartDiagram-5P7HB3ND-YjHomudv.js} +1 -1
- package/payload/server/public/browser.html +6 -6
- package/payload/server/public/chat.html +10 -9
- package/payload/server/public/data.html +5 -5
- package/payload/server/public/graph.html +8 -8
- package/payload/server/public/index.html +10 -9
- package/payload/server/public/operator.html +12 -11
- package/payload/server/public/public-next.html +11 -10
- package/payload/server/public/public.html +8 -8
- package/payload/server/server.js +269 -64
- package/payload/server/public/assets/AccessGate-CU4Qw6M6.js +0 -1
- package/payload/server/public/assets/AdminLoginScreens-DUpRIM1h.js +0 -1
- package/payload/server/public/assets/AdminShell-DkoQSsqo.js +0 -1
- package/payload/server/public/assets/OperatorConversations-BIHiyyxU.js +0 -1
- package/payload/server/public/assets/admin-BHvOMcCh.js +0 -1
- package/payload/server/public/assets/architecture-YZFGNWBL-Crq5RSDG.js +0 -1
- package/payload/server/public/assets/audio-attachment-mime-DOBET-W1.js +0 -30
- package/payload/server/public/assets/brand-4F9ZXBF8.css +0 -1
- package/payload/server/public/assets/channel-KT66MFN2.js +0 -1
- package/payload/server/public/assets/chat-DedpVKUl.js +0 -1
- package/payload/server/public/assets/chunk-426QAEUC-CWMiOm8Y.js +0 -1
- package/payload/server/public/assets/chunk-QZHKN3VN-DCzpF46A.js +0 -1
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-QOU4HzJJ.js +0 -1
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-DcOUai3Z.js +0 -1
- package/payload/server/public/assets/clone-CHh05KN-.js +0 -1
- package/payload/server/public/assets/data-BcoBY39U.js +0 -1
- package/payload/server/public/assets/gitGraph-7Q5UKJZL-BC-u4jgy.js +0 -1
- package/payload/server/public/assets/info-OMHHGYJF-DPUetTz-.js +0 -1
- package/payload/server/public/assets/infoDiagram-42DDH7IO-q2dl09-M.js +0 -2
- package/payload/server/public/assets/operator-WsXhcbBF.js +0 -1
- package/payload/server/public/assets/packet-4T2RLAQJ-BcfR-ZwA.js +0 -1
- package/payload/server/public/assets/page-BhHTnqv4.js +0 -1
- package/payload/server/public/assets/pie-ZZUOXDRM-BiKgZdNB.js +0 -1
- package/payload/server/public/assets/public-next-BKECyMz2.js +0 -1
- package/payload/server/public/assets/radar-PYXPWWZC-nvCjiW_J.js +0 -1
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-CAnmjSj7.js +0 -1
- package/payload/server/public/assets/treeView-SZITEDCU-BinXCVyM.js +0 -1
- package/payload/server/public/assets/treemap-W4RFUUIX-CSmh20Ze.js +0 -1
- package/payload/server/public/assets/wardley-RL74JXVD-BiCmRKWx.js +0 -1
- /package/payload/server/public/assets/{_baseFor-D8P3gUw3.js → _baseFor-Y5mTRiRv.js} +0 -0
- /package/payload/server/public/assets/{array-CLwNaqU1.js → array-BwJyW1Dp.js} +0 -0
- /package/payload/server/public/assets/{brand-C7kj0USi.js → brand-MKGM8WZp.js} +0 -0
- /package/payload/server/public/assets/{cytoscape.esm-mZ4wTuB7.js → cytoscape.esm-D95TtHqz.js} +0 -0
- /package/payload/server/public/assets/{defaultLocale-D_VMtRaY.js → defaultLocale-kiwRz9Au.js} +0 -0
- /package/payload/server/public/assets/{dist-CjjtmoWL.js → dist-DSsFp0Qd.js} +0 -0
- /package/payload/server/public/assets/{init-vVpfz1D6.js → init-CKZirZ49.js} +0 -0
- /package/payload/server/public/assets/{katex-DaHGEgm7.js → katex-8mXVa4k3.js} +0 -0
- /package/payload/server/public/assets/{path-CuyvWNAH.js → path-B0d9ncVi.js} +0 -0
- /package/payload/server/public/assets/{preload-helper-TKOBYGYD.js → preload-helper-C5gCWwwF.js} +0 -0
- /package/payload/server/public/assets/{rough.esm-JX0wREDd.js → rough.esm-BWqoIFNR.js} +0 -0
- /package/payload/server/public/assets/{src-CwB968DO.js → src-DXUM2BJo.js} +0 -0
package/package.json
CHANGED
|
@@ -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:
|
|
4
|
+
content-hash: sha256:2dbfcb8246f85a6b6adc588c742acaaa57d81196907dc3bcef07a1c6ae2ad013
|
|
5
5
|
brand: maxy-code
|
|
6
6
|
product-name: Maxy
|
|
7
7
|
---
|
|
@@ -2515,7 +2515,7 @@ authoritative. This section names the surfaces and what backs each.
|
|
|
2515
2515
|
| `+ New session` button | Opens `NewSessionModal`, which POSTs `{channel, permissionMode, model, initialMessage}` to `/api/admin/claude-sessions`. | `claude-sessions.ts` |
|
|
2516
2516
|
| Mode trigger | Per-`(accountId, userId)` `SpawnPreference` for `permissionMode` and `model`; persists across reload, tab, device. | `session-defaults.ts` |
|
|
2517
2517
|
| Nav rows (Chat / People / Agents / Projects / Tasks / Artefacts) | People, Agents, Tasks open the artefact-pane Graph filtered to the matching label. Chat selects the active conversation. Artefacts swaps the list to editable documents. | `graph-search.ts`, `graph-subgraph.ts`, `sidebar-artefacts.ts` |
|
|
2518
|
-
| Sessions list (Active / Archived / All) | Live row store driven by SSE; manual reconcile button on the segmented control re-fetches the full id set. Every
|
|
2518
|
+
| Sessions list (Active / Archived / All) | Live row store driven by SSE; manual reconcile button on the segmented control re-fetches the full id set. Every listed row carries two launch actions: the claude.ai/code resume (`ExternalLink`) and a chat-launch (`MessageSquare`) that opens `/chat?session=<full sessionId>` — the admin webchat pointed at that exact session; sending there resumes a stopped session with the webchat channel bound to that id (see `admin-webchat-native-channel.md`, "Session-targeted mode"). At the ≤720 px drawer breakpoint each row stacks into two lines — dot + title + id/stamp, then the action icons — with a divider between rows and actions at full opacity (the desktop hover-gated 0.5 opacity never resolves on touch). | `/claude-sessions/events`, `/claude-sessions` |
|
|
2519
2519
|
| Channel reader nav rows (WhatsApp / Telegram) | One conditional nav row **per interactive channel that has ≥1 admin session**. Each row carries its brand glyph (WhatsApp `#25D366`, Telegram `#229ED9`); a channel with no admin session shows no row, and no install ever shows an always-empty "No conversations" row. The channel list loads **once on sidebar mount** (the per-channel counts must be known before the nav renders), so a failed load shows one muted, non-clickable line instead of channel rows. Clicking a channel row lists that channel's admin conversations; each conversation row shows a **display name** resolved by precedence `operatorName ?? whatsappName ?? senderId ?? title`: the bound `Person givenName familyName` when a `senderId`→`userId` binding exists, else the persisted WhatsApp display name (`pushName`, read from the latest `:Message:WhatsAppMessage.senderName`), else the raw `senderId`, else the agent title; the agent session title is the hover tooltip only. Under the name each row shows a **last-message-time breadcrumb** (`conv-timestamp`, same markup as the Sessions rows) formatted from the row's `lastMessageAt` (the last parseable turn's `ts`); a session with no parseable turn shows no time, never "Invalid Date". A click on a conversation **opens its transcript on the home surface**: on `/` it selects in place, and from any other route (`/graph`, `/data`, `/browser`) it navigates to `/?wa=<sessionId>&projectDir=<dir>`, which the root shell hydrates on mount (then strips the query so a later refresh does not re-pin a closed conversation). Server logs `[wa-reader] op=operator-name-fallback senderId=… source=whatsapp-pushname` when the pushName fallback fires and `[wa-reader] op=conversations count=<n> withTimestamp=<m>` per list build; the client logs `[admin-ui] wa-open route=… via=<in-place\|navigate> …` and `[admin-ui] wa-hydrate route=/ …`. | `/whatsapp-reader/conversations` |
|
|
2520
2520
|
| Channel transcript (`<Transcript>`) | Reads one session's JSONL over SSE (`/whatsapp-reader/stream`) and renders both sides plus tool calls — the turns claude.ai/code hides because channel inbound is stamped `isMeta`. Every turn shows its time-of-day (HH:MM from the turn's `ts`; a null/unparseable `ts` shows no time, never "Invalid Date"). `tool-call`/`tool-result` turns render as **collapsed cards** (chevron + label + time, default collapsed, expandable per card; one card's state never affects another) so the human↔agent text is not buried in JSON; the three conversation kinds always render in full. The thread **follows the tail**: it opens at the newest turn and pins to the bottom on each live append **only while the operator is already within 32 px of the bottom** — a scroll up suppresses the jump so reading history is never yanked. While the operator is scrolled up a **jump-to-bottom control** (`.wa-jump`, bottom-right of the viewport) appears; clicking it scrolls to the newest turn and re-arms follow-tail, and it hides again at the bottom. The thread scrolls inside its grid cell (header/sidebar/footer fixed). The stream sends a 20 s heartbeat so an idle Cloudflare tunnel does not idle-drop, tags each frame with a byte-offset `id:`, and resumes from the client's `Last-Event-ID` on reconnect (no duplicate backlog); the client clears the "Stream disconnected" banner on reopen and latches it only on a terminal CLOSED state. The thread also interleaves a collapsed `⚙ directive injected (N B)` row per turn, sorted by timestamp just before the turn it informed; expanding one fetches the exact stored `prompt-optimiser-directive` bytes for that turn. The entries are listed by `GET /whatsapp-reader/directives?sessionId=` and the bytes served by `GET /whatsapp-reader/directive?sessionId=&name=`, both admin-gated and account-scoped; a missing store degrades to no rows. | `/whatsapp-reader/stream`, `/whatsapp-reader/directives`, `/whatsapp-reader/directive` |
|
|
2521
2521
|
| Conversations row hover actions | Inline rename, archive, delete, JSONL view / download per row. The historical `.conversations-modal` CSS block exists in `globals.css` but is no longer mounted from any TSX — Sidebar.tsx now owns every per-row affordance directly. | `claude-sessions.ts` |
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: plugin-management
|
|
3
|
-
description: "Install, remove, enable, and configure plugins and account settings via conversation."
|
|
3
|
+
description: "Install, remove, enable, and configure plugins and account settings via conversation. This is how an operator turns the assistant's capabilities and integrations on and off — \"turn on email\", \"enable WhatsApp\", \"add a Telegram integration\", \"connect a new integration\", \"what can you connect to\", \"what plugins are available\", \"set up an integration\", \"disable X\", or changing an account setting. Each plugin is an integration or capability the assistant can gain; this skill is the surface for adding, removing, or reconfiguring them."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Plugin Management
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: specialist-management
|
|
3
|
-
description: "Install, remove, and manage specialist subagents and premium plugin agents."
|
|
3
|
+
description: "Install, remove, and manage specialist subagents and premium plugin agents — the dedicated helpers the assistant can hand work to. This is how an operator adds a new helper or worker agent: \"add a content writer\", \"set up a research agent\", \"give me a helper that writes documents\", \"add an agent that does X\", \"hire an assistant for Y\", \"what specialists can I add\", or removing one. Each specialist is a focused agent the assistant delegates a domain to (writing, research, and the like)."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Specialist Management
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: cloudflare
|
|
3
|
-
description: Cloudflare operations for the install — tunnel setup/diagnosis/reset, DNS edits, Pages hosting, and D1 data capture. The agent drives `cloudflared` and `wrangler` directly via Bash and reads the matching reference before each operation class; success is always a live behavioural signal (external HTTP 200, a deployed URL, a D1 round-trip), never an exit code.
|
|
3
|
+
description: Cloudflare operations for the install — tunnel setup/diagnosis/reset, DNS edits, Pages hosting, and D1 data capture. This is the skill behind operator-facing goals like "set up the operator dashboard", "set up the operator host", "give me (or a colleague) a remote dashboard to run the assistant", "let me access the assistant from anywhere", "put my dashboard or site online", "point a custom domain at this", and "why is my site or hostname returning a 404 / 502". It provisions the operator-dashboard host — the trimmed remote control panel (sessions, chat, data; no graph, no browser) — by adding the tunnel ingress and the operator-domains.json classification, stands up admin / public / operator hostnames over the Cloudflare tunnel so the install is reachable on the internet, hosts static sites on Pages, and captures form submissions to D1. The agent drives `cloudflared` and `wrangler` directly via Bash and reads the matching reference before each operation class; success is always a live behavioural signal (external HTTP 200, a deployed URL, a D1 round-trip), never an exit code.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Cloudflare operations
|
|
@@ -284,7 +284,7 @@ authoritative. This section names the surfaces and what backs each.
|
|
|
284
284
|
| `+ New session` button | Opens `NewSessionModal`, which POSTs `{channel, permissionMode, model, initialMessage}` to `/api/admin/claude-sessions`. | `claude-sessions.ts` |
|
|
285
285
|
| Mode trigger | Per-`(accountId, userId)` `SpawnPreference` for `permissionMode` and `model`; persists across reload, tab, device. | `session-defaults.ts` |
|
|
286
286
|
| Nav rows (Chat / People / Agents / Projects / Tasks / Artefacts) | People, Agents, Tasks open the artefact-pane Graph filtered to the matching label. Chat selects the active conversation. Artefacts swaps the list to editable documents. | `graph-search.ts`, `graph-subgraph.ts`, `sidebar-artefacts.ts` |
|
|
287
|
-
| Sessions list (Active / Archived / All) | Live row store driven by SSE; manual reconcile button on the segmented control re-fetches the full id set. Every
|
|
287
|
+
| Sessions list (Active / Archived / All) | Live row store driven by SSE; manual reconcile button on the segmented control re-fetches the full id set. Every listed row carries two launch actions: the claude.ai/code resume (`ExternalLink`) and a chat-launch (`MessageSquare`) that opens `/chat?session=<full sessionId>` — the admin webchat pointed at that exact session; sending there resumes a stopped session with the webchat channel bound to that id (see `admin-webchat-native-channel.md`, "Session-targeted mode"). At the ≤720 px drawer breakpoint each row stacks into two lines — dot + title + id/stamp, then the action icons — with a divider between rows and actions at full opacity (the desktop hover-gated 0.5 opacity never resolves on touch). | `/claude-sessions/events`, `/claude-sessions` |
|
|
288
288
|
| Channel reader nav rows (WhatsApp / Telegram) | One conditional nav row **per interactive channel that has ≥1 admin session**. Each row carries its brand glyph (WhatsApp `#25D366`, Telegram `#229ED9`); a channel with no admin session shows no row, and no install ever shows an always-empty "No conversations" row. The channel list loads **once on sidebar mount** (the per-channel counts must be known before the nav renders), so a failed load shows one muted, non-clickable line instead of channel rows. Clicking a channel row lists that channel's admin conversations; each conversation row shows a **display name** resolved by precedence `operatorName ?? whatsappName ?? senderId ?? title`: the bound `Person givenName familyName` when a `senderId`→`userId` binding exists, else the persisted WhatsApp display name (`pushName`, read from the latest `:Message:WhatsAppMessage.senderName`), else the raw `senderId`, else the agent title; the agent session title is the hover tooltip only. Under the name each row shows a **last-message-time breadcrumb** (`conv-timestamp`, same markup as the Sessions rows) formatted from the row's `lastMessageAt` (the last parseable turn's `ts`); a session with no parseable turn shows no time, never "Invalid Date". A click on a conversation **opens its transcript on the home surface**: on `/` it selects in place, and from any other route (`/graph`, `/data`, `/browser`) it navigates to `/?wa=<sessionId>&projectDir=<dir>`, which the root shell hydrates on mount (then strips the query so a later refresh does not re-pin a closed conversation). Server logs `[wa-reader] op=operator-name-fallback senderId=… source=whatsapp-pushname` when the pushName fallback fires and `[wa-reader] op=conversations count=<n> withTimestamp=<m>` per list build; the client logs `[admin-ui] wa-open route=… via=<in-place\|navigate> …` and `[admin-ui] wa-hydrate route=/ …`. | `/whatsapp-reader/conversations` |
|
|
289
289
|
| Channel transcript (`<Transcript>`) | Reads one session's JSONL over SSE (`/whatsapp-reader/stream`) and renders both sides plus tool calls — the turns claude.ai/code hides because channel inbound is stamped `isMeta`. Every turn shows its time-of-day (HH:MM from the turn's `ts`; a null/unparseable `ts` shows no time, never "Invalid Date"). `tool-call`/`tool-result` turns render as **collapsed cards** (chevron + label + time, default collapsed, expandable per card; one card's state never affects another) so the human↔agent text is not buried in JSON; the three conversation kinds always render in full. The thread **follows the tail**: it opens at the newest turn and pins to the bottom on each live append **only while the operator is already within 32 px of the bottom** — a scroll up suppresses the jump so reading history is never yanked. While the operator is scrolled up a **jump-to-bottom control** (`.wa-jump`, bottom-right of the viewport) appears; clicking it scrolls to the newest turn and re-arms follow-tail, and it hides again at the bottom. The thread scrolls inside its grid cell (header/sidebar/footer fixed). The stream sends a 20 s heartbeat so an idle Cloudflare tunnel does not idle-drop, tags each frame with a byte-offset `id:`, and resumes from the client's `Last-Event-ID` on reconnect (no duplicate backlog); the client clears the "Stream disconnected" banner on reopen and latches it only on a terminal CLOSED state. The thread also interleaves a collapsed `⚙ directive injected (N B)` row per turn, sorted by timestamp just before the turn it informed; expanding one fetches the exact stored `prompt-optimiser-directive` bytes for that turn. The entries are listed by `GET /whatsapp-reader/directives?sessionId=` and the bytes served by `GET /whatsapp-reader/directive?sessionId=&name=`, both admin-gated and account-scoped; a missing store degrades to no rows. | `/whatsapp-reader/stream`, `/whatsapp-reader/directives`, `/whatsapp-reader/directive` |
|
|
290
290
|
| Conversations row hover actions | Inline rename, archive, delete, JSONL view / download per row. The historical `.conversations-modal` CSS block exists in `globals.css` but is no longer mounted from any TSX — Sidebar.tsx now owns every per-row affordance directly. | `claude-sessions.ts` |
|
|
@@ -59,6 +59,10 @@ const ALLOWLIST = new Set([
|
|
|
59
59
|
// before the `../paths` mock fires, to point USERS_FILE/REMOTE_PASSWORD_FILE
|
|
60
60
|
// at a temp dir off the operator's real home config.
|
|
61
61
|
'platform/ui/app/lib/__tests__/remote-auth-per-admin.test.ts',
|
|
62
|
+
// Same vi.hoisted pattern: the files-write test builds a tmp platform/data
|
|
63
|
+
// tree and sets MAXY_PLATFORM_ROOT before the route module (and its
|
|
64
|
+
// data-path/attachments deps) read the env at import.
|
|
65
|
+
'platform/ui/server/routes/admin/__tests__/files-write.test.ts',
|
|
62
66
|
])
|
|
63
67
|
|
|
64
68
|
const REQUIRE_CALL_RE = /\brequire\s*\(/
|
|
@@ -37,6 +37,7 @@ export interface HttpDeps extends Omit<SpawnDeps, 'onSessionReady' | 'watcher'>
|
|
|
37
37
|
}
|
|
38
38
|
export declare function forkArgvSegment(fromSessionId: string, newSessionId: string, model: string): string[];
|
|
39
39
|
export declare function reseatIdentityPrompt(model: string): string;
|
|
40
|
+
export declare function authenticatedIdentityPrompt(name: string | null): string;
|
|
40
41
|
export declare function formatReseatLine(fromModel: string | null, toModel: string, oldSessionId: string, newSessionId: string, observed: string | null): string;
|
|
41
42
|
export declare function firstPostArmAssistantModel(lines: string[], armTimeMs: number): string | null;
|
|
42
43
|
/** Task 189 — Hono instance with the test-only fan-out trigger attached.
|
|
@@ -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;AAY3B,OAAO,EAgBL,KAAK,SAAS,EAEf,MAAM,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"http-server.d.ts","sourceRoot":"","sources":["../src/http-server.ts"],"names":[],"mappings":"AAsBA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAY3B,OAAO,EAgBL,KAAK,SAAS,EAEf,MAAM,kBAAkB,CAAA;AAsBzB,OAAO,KAAK,EAAE,SAAS,EAAyB,MAAM,iBAAiB,CAAA;AAEvE,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;AAwGD,wBAAgB,eAAe,CAAC,aAAa,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAEpG;AAQD,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE1D;AAUD,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAMvE;AAMD,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,MAAM,GAAG,IAAI,EACxB,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpB,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,MAAM,GAAG,IAAI,GACtB,MAAM,CAER;AAkCD,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAe5F;AAwJD;;;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,CAgqEpD"}
|
|
@@ -32,6 +32,7 @@ import { execFileSync } from 'node:child_process';
|
|
|
32
32
|
import { buildRcChildEnv, reapplyAdminLevers } from './rc-daemon.js';
|
|
33
33
|
import { spawnClaudeSession, stopSession, writeInputToPty, isLive, onPtyExit, livePtyCount, liveSessionIds, getPtyTrackerForTests, livePidForSession, priorExitedCountForSession, PERMISSION_MODES, openFdCount, registerRcSpawnPty, } from './pty-spawner.js';
|
|
34
34
|
import { writeScopeRecord, removeScopeRecord } from './scope-record.js';
|
|
35
|
+
import { writeReseatMarker, resolveReseatChain, clearReseatMarker } from './reseat-ledger.js';
|
|
35
36
|
import { getScopeMainPid, defaultProcessSignals, defaultSystemctlRunner } from './systemd-scope.js';
|
|
36
37
|
import { readSidecar, updateSidecar, appendBridgeId, writeSidecar } from './session-sidecar.js';
|
|
37
38
|
import { resolveSettingsPermissionMode } from './settings-permission-mode.js';
|
|
@@ -199,6 +200,21 @@ export function forkArgvSegment(fromSessionId, newSessionId, model) {
|
|
|
199
200
|
export function reseatIdentityPrompt(model) {
|
|
200
201
|
return `This conversation now runs on the model ${model}. Earlier messages may show you identifying as a different model; that is stale context from before a model change — disregard it and state ${model} as your current model if asked.`;
|
|
201
202
|
}
|
|
203
|
+
// Task 889 — the authenticated-admin identity line for a webchat-bound admin
|
|
204
|
+
// rc session. The rc-spawn path composes no fresh-spawn system prompt, so this
|
|
205
|
+
// --append-system-prompt segment is the agent's only signal of who it is
|
|
206
|
+
// talking to. Re-passed on every spawn (fresh and resume) because the append
|
|
207
|
+
// fact is not persisted in the JSONL; without it the agent guesses the
|
|
208
|
+
// Anthropic account email visible in its context. `name` is the resolved
|
|
209
|
+
// `AdminUser` display name, or null/empty when the identity could not be
|
|
210
|
+
// resolved — the not-resolvable line is still injected to suppress the guess.
|
|
211
|
+
export function authenticatedIdentityPrompt(name) {
|
|
212
|
+
const trimmed = name?.trim() ?? '';
|
|
213
|
+
if (trimmed.length > 0) {
|
|
214
|
+
return `This admin webchat session is authenticated as ${trimmed}. If you are asked who you are talking to or who this session is authenticated as, answer ${trimmed}; never infer the operator's identity from an email address or account label visible in your context.`;
|
|
215
|
+
}
|
|
216
|
+
return `This admin webchat session's authenticated identity could not be resolved. If you are asked who you are talking to or who this session is authenticated as, say the identity is not resolvable; never infer it from an email address or account label visible in your context.`;
|
|
217
|
+
}
|
|
202
218
|
// Task 876 — the re-seat post-condition line. Emitted ONLY after a real
|
|
203
219
|
// assistant turn on the fork is read (intention is not logged, per the
|
|
204
220
|
// observability contract): a re-seat that silently lands on the wrong model
|
|
@@ -1767,6 +1783,13 @@ export function buildHttpApp(deps) {
|
|
|
1767
1783
|
const adminUserId = typeof body.adminUserId === 'string' && body.adminUserId.length > 0 && body.adminUserId.length <= 128
|
|
1768
1784
|
? body.adminUserId
|
|
1769
1785
|
: undefined;
|
|
1786
|
+
// Task 889 — the resolved authenticated-admin display name, resolved by the
|
|
1787
|
+
// UI from USER_ID -> AdminUser (the manager holds no Neo4j driver) and
|
|
1788
|
+
// shape-bounded here. Absent => the identity line renders its not-resolvable
|
|
1789
|
+
// form. Only consumed for webchat-bound admin spawns.
|
|
1790
|
+
const authenticatedName = typeof body.authenticatedName === 'string' && body.authenticatedName.length > 0 && body.authenticatedName.length <= 256
|
|
1791
|
+
? body.authenticatedName
|
|
1792
|
+
: undefined;
|
|
1770
1793
|
// Task 682 — per-session userId override. Server-resolved by the UI from the
|
|
1771
1794
|
// authoritative users.json/account.json (never message content) and shape-
|
|
1772
1795
|
// validated here the same way as personId. Absent for owner self-phone and
|
|
@@ -1842,6 +1865,28 @@ export function buildHttpApp(deps) {
|
|
|
1842
1865
|
return c.json({ error: 're-seat target id already exists' }, 400);
|
|
1843
1866
|
}
|
|
1844
1867
|
}
|
|
1868
|
+
// Task 896 — a plain resume (NOT a fork spawn) of a re-seated source id must
|
|
1869
|
+
// not start a second live process beside the fork. Resolve the marker chain
|
|
1870
|
+
// to the deepest live fork and redirect there. A stale marker (the fork's
|
|
1871
|
+
// JSONL is gone) is cleared and the resume proceeds normally.
|
|
1872
|
+
if (forkFromSessionId === null && sessionId) {
|
|
1873
|
+
// The fork must have a LIVE (non-archived) transcript to be a valid
|
|
1874
|
+
// redirect target. findExistingJsonlForSessionId also matches archive/, so
|
|
1875
|
+
// it would redirect to an archived dead-end; the live path is the check.
|
|
1876
|
+
const chain = resolveReseatChain(sessionsDir, sessionId, (id) => existsSync(jsonlPathForSessionId(deps.spawnCwd, id)));
|
|
1877
|
+
if (chain.redirected) {
|
|
1878
|
+
const fork = chain.target;
|
|
1879
|
+
const liveRow = deps.watcher.getBySessionId(fork);
|
|
1880
|
+
const bridgeSessionId = liveRow?.bridgeSessionId ?? `session_${fork}`;
|
|
1881
|
+
deps.logger(`[rc-spawn] op=reseat-redirect from=${sessionId.slice(0, 8)} to=${fork.slice(0, 8)} hops=${chain.hops.length}`);
|
|
1882
|
+
timed(deps.logger, 'POST', '/rc-spawn', 200, Date.now() - start);
|
|
1883
|
+
return c.json({ spawnedPid: liveRow?.pid ?? null, sessionId: fork, bridgeSessionId, slug: bridgeSessionId, outcome: 'reseated', reason: null, redirected: true }, 200);
|
|
1884
|
+
}
|
|
1885
|
+
if (chain.stale) {
|
|
1886
|
+
clearReseatMarker(sessionsDir, sessionId, deps.logger);
|
|
1887
|
+
deps.logger(`[rc-spawn] op=reseat-marker-stale sessionId=${sessionId.slice(0, 8)}`);
|
|
1888
|
+
}
|
|
1889
|
+
}
|
|
1845
1890
|
// Task 702 — never run two processes on one sessionId. If we already own a
|
|
1846
1891
|
// live PTY for this id, the spawn is a no-op (a bridge that lost its
|
|
1847
1892
|
// in-memory index after a restart re-asks; the live PTY takes the next
|
|
@@ -1883,12 +1928,16 @@ export function buildHttpApp(deps) {
|
|
|
1883
1928
|
const argv = ['--remote-control'];
|
|
1884
1929
|
if (name)
|
|
1885
1930
|
argv.push(name);
|
|
1931
|
+
// Task 889 — append-system-prompt segments are accumulated and pushed once
|
|
1932
|
+
// (below, after channel resolution) so the re-seat model line and the
|
|
1933
|
+
// authenticated-identity line share a single flag.
|
|
1934
|
+
const appendSegments = [];
|
|
1886
1935
|
// Task 876 — a re-seat forks the source onto the pre-minted target id; the
|
|
1887
1936
|
// ordinary fresh/resume single-id push is replaced by the fork segment.
|
|
1888
1937
|
if (forkFromSessionId !== null && reseatModel !== null && sessionId) {
|
|
1889
1938
|
argv.push(...forkArgvSegment(forkFromSessionId, sessionId, reseatModel));
|
|
1890
1939
|
// Task 879 — authoritative current-model signal for the fork only.
|
|
1891
|
-
|
|
1940
|
+
appendSegments.push(reseatIdentityPrompt(reseatModel));
|
|
1892
1941
|
}
|
|
1893
1942
|
else if (sessionId) {
|
|
1894
1943
|
argv.push(mode === 'resume' ? '--resume' : '--session-id', sessionId);
|
|
@@ -2010,6 +2059,19 @@ export function buildHttpApp(deps) {
|
|
|
2010
2059
|
}
|
|
2011
2060
|
}
|
|
2012
2061
|
}
|
|
2062
|
+
// Task 889 — a webchat-bound admin rc session is the /chat admin surface.
|
|
2063
|
+
// Inject the authenticated-identity line (resolved name, or the explicit
|
|
2064
|
+
// not-resolvable form) so the agent states who it is talking to instead of
|
|
2065
|
+
// guessing the account email. Gated on the webchat binding + admin role so
|
|
2066
|
+
// public visitor spawns and the one-shot admin jobs are untouched. The
|
|
2067
|
+
// breadcrumb makes a silent resolution regression visible without a chat.
|
|
2068
|
+
if (effectiveWebchatChannel && rcRole === 'admin') {
|
|
2069
|
+
appendSegments.push(authenticatedIdentityPrompt(authenticatedName ?? null));
|
|
2070
|
+
deps.logger(`[rc-spawn] op=identity-injected userId=${adminUserId ? adminUserId.slice(0, 8) : 'none'} resolved=${authenticatedName ? 1 : 0}`);
|
|
2071
|
+
}
|
|
2072
|
+
if (appendSegments.length > 0) {
|
|
2073
|
+
argv.push('--append-system-prompt', appendSegments.join('\n\n'));
|
|
2074
|
+
}
|
|
2013
2075
|
// Task 626 — the initial message is the trailing positional, processed as
|
|
2014
2076
|
// the session's first user turn at PTY startup. One-shot jobs omit `name`
|
|
2015
2077
|
// so the prompt is the sole positional.
|
|
@@ -2441,6 +2503,12 @@ export function buildHttpApp(deps) {
|
|
|
2441
2503
|
catch (err) {
|
|
2442
2504
|
deps.logger(`[webchat:reseat] op=old-session-stop old-session=${forkFromSessionId} result=error err=${JSON.stringify(err instanceof Error ? err.message : String(err))}`);
|
|
2443
2505
|
}
|
|
2506
|
+
// Task 896 — record source -> fork so a later resume of the source id is
|
|
2507
|
+
// redirected to the fork instead of spawning a second live process. The
|
|
2508
|
+
// marker is written whether or not the source had a live PTY to stop (the
|
|
2509
|
+
// removed-model case has no live PTY but the source is still re-seated).
|
|
2510
|
+
writeReseatMarker(sessionsDir, forkFromSessionId, sessionId, Date.now(), deps.logger);
|
|
2511
|
+
deps.logger(`[webchat:reseat] op=reseat-retire from=${forkFromSessionId} fork=${sessionId} outcome=marked`);
|
|
2444
2512
|
}
|
|
2445
2513
|
timed(deps.logger, 'POST', '/rc-spawn', 200, Date.now() - start);
|
|
2446
2514
|
// `slug` is the Task 648 canonical field the client navigates by;
|