@rubytech/create-maxy-code 0.1.298 → 0.1.300
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/cloudflare/references/manual-setup.md +51 -3
- package/payload/platform/plugins/cloudflare/references/reset-guide.md +19 -1
- package/payload/platform/plugins/cloudflare/skills/cloudflare/SKILL.md +16 -3
- package/payload/platform/scripts/check-no-esm-require.mjs +4 -0
- package/payload/server/{chunk-7H4KMTMC.js → chunk-JHSF5VPE.js} +171 -95
- package/payload/server/maxy-edge.js +19 -1
- package/payload/server/public/assets/AdminShell-BFdBxg4P.js +1 -0
- package/payload/server/public/assets/{Checkbox-CVPUf_7I.js → Checkbox-BZ1XbA1t.js} +1 -1
- package/payload/server/public/assets/{Transcript-FYmq-mL1.js → Transcript-CaVix6W0.js} +1 -1
- package/payload/server/public/assets/admin-BK7xIr3o.js +1 -0
- package/payload/server/public/assets/{arc-DmR-LPIx.js → arc-DxSm8tli.js} +1 -1
- package/payload/server/public/assets/architecture-YZFGNWBL-6g9jRVgc.js +1 -0
- package/payload/server/public/assets/{architectureDiagram-Q4EWVU46-IVt2X8Dk.js → architectureDiagram-Q4EWVU46-7JSAh0vL.js} +1 -1
- package/payload/server/public/assets/audio-attachment-mime-CFyc3gpD.js +30 -0
- package/payload/server/public/assets/{blockDiagram-DXYQGD6D-CQDngnsc.js → blockDiagram-DXYQGD6D-DLoVmHKD.js} +1 -1
- package/payload/server/public/assets/{browser-D_hZgtfv.js → browser-ClnGUKp-.js} +1 -1
- package/payload/server/public/assets/{c4Diagram-AHTNJAMY-BjV_YA-L.js → c4Diagram-AHTNJAMY-Nv1G0o9P.js} +1 -1
- package/payload/server/public/assets/channel-BgQLJanG.js +1 -0
- package/payload/server/public/assets/chat-ZTAhSoJV.js +1 -0
- package/payload/server/public/assets/{chunk-2KRD3SAO-BYqpHDvA.js → chunk-2KRD3SAO-BpqPMhoA.js} +1 -1
- package/payload/server/public/assets/chunk-336JU56O-DgXHlVU_.js +2 -0
- package/payload/server/public/assets/chunk-426QAEUC-Dr_XVuUq.js +1 -0
- package/payload/server/public/assets/{chunk-4BX2VUAB-BeDVr5Tb.js → chunk-4BX2VUAB-nwyZSZH8.js} +1 -1
- package/payload/server/public/assets/{chunk-4TB4RGXK-BImQYhPF.js → chunk-4TB4RGXK-Tfxz9LHX.js} +1 -1
- package/payload/server/public/assets/{chunk-55IACEB6-DB18cH4S.js → chunk-55IACEB6-6FMJQGXG.js} +1 -1
- package/payload/server/public/assets/{chunk-5FUZZQ4R-DrDSHQZv.js → chunk-5FUZZQ4R-g2FgZF3D.js} +1 -1
- package/payload/server/public/assets/{chunk-5PVQY5BW-CKX_LIok.js → chunk-5PVQY5BW-DtLwXsPH.js} +1 -1
- package/payload/server/public/assets/{chunk-67CJDMHE-Ca9KwdQm.js → chunk-67CJDMHE-K91CP5ZU.js} +1 -1
- package/payload/server/public/assets/{chunk-7N4EOEYR-BDpzHOmv.js → chunk-7N4EOEYR-BGpCQhqK.js} +1 -1
- package/payload/server/public/assets/{chunk-AA7GKIK3-DXo9fZho.js → chunk-AA7GKIK3-jkDbInck.js} +1 -1
- package/payload/server/public/assets/{chunk-BSJP7CBP-CTqmM6qI.js → chunk-BSJP7CBP-mDosdzGs.js} +1 -1
- package/payload/server/public/assets/{chunk-CIAEETIT-NufEId2j.js → chunk-CIAEETIT-DhBxewpQ.js} +1 -1
- package/payload/server/public/assets/{chunk-EDXVE4YY-D1zHB217.js → chunk-EDXVE4YY-B7c-9Emg.js} +1 -1
- package/payload/server/public/assets/{chunk-ENJZ2VHE-SFpdtszU.js → chunk-ENJZ2VHE-Cqhhncox.js} +1 -1
- package/payload/server/public/assets/{chunk-FMBD7UC4-_4wtKsfc.js → chunk-FMBD7UC4-BpDq6wj1.js} +1 -1
- package/payload/server/public/assets/{chunk-FOC6F5B3-565zaYb3.js → chunk-FOC6F5B3-Ds02-ktu.js} +1 -1
- package/payload/server/public/assets/{chunk-ICPOFSXX-cYdq7RKF.js → chunk-ICPOFSXX-BTX5POFr.js} +2 -2
- package/payload/server/public/assets/{chunk-K5T4RW27-CTZnA5fq.js → chunk-K5T4RW27-Du1PXXBU.js} +1 -1
- package/payload/server/public/assets/{chunk-KGLVRYIC-CeuKp7uR.js → chunk-KGLVRYIC-siasOAf8.js} +1 -1
- package/payload/server/public/assets/{chunk-LIHQZDEY-DXkzlh3_.js → chunk-LIHQZDEY-xf1rbZtf.js} +1 -1
- package/payload/server/public/assets/{chunk-ORNJ4GCN-DcZUCmgM.js → chunk-ORNJ4GCN-DeTLQ_LD.js} +1 -1
- package/payload/server/public/assets/{chunk-OYMX7WX6-B7JLCext.js → chunk-OYMX7WX6-DQ7_oVJn.js} +1 -1
- package/payload/server/public/assets/chunk-QZHKN3VN-DF4o9HRJ.js +1 -0
- package/payload/server/public/assets/{chunk-U2HBQHQK-DWCeFwem.js → chunk-U2HBQHQK-CXmFUKgn.js} +1 -1
- package/payload/server/public/assets/{chunk-X2U36JSP-DGnHsoJ3.js → chunk-X2U36JSP-Bj8-8Wkz.js} +1 -1
- package/payload/server/public/assets/{chunk-XPW4576I-CnU6DVpC.js → chunk-XPW4576I-Con3TXqt.js} +1 -1
- package/payload/server/public/assets/{chunk-YZCP3GAM-sg4lGGJV.js → chunk-YZCP3GAM-Dx8BHGWf.js} +1 -1
- package/payload/server/public/assets/{chunk-ZZ45TVLE-DtUoGmKE.js → chunk-ZZ45TVLE-Dp4Q5Y-f.js} +1 -1
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-DAbPKU6u.js +1 -0
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-BKuFQLcv.js +1 -0
- package/payload/server/public/assets/clone-DnNHGhNe.js +1 -0
- package/payload/server/public/assets/{cose-bilkent-S5V4N54A-C04wkJr7.js → cose-bilkent-S5V4N54A-pZiCv69E.js} +1 -1
- package/payload/server/public/assets/{dagre-Dfj_jbTe.js → dagre-CLqhEgbL.js} +1 -1
- package/payload/server/public/assets/{dagre-KV5264BT-Bd1VlhUJ.js → dagre-KV5264BT-BCxE8iyk.js} +1 -1
- package/payload/server/public/assets/{data-DkbQI40a.js → data-DDjeQQ7e.js} +1 -1
- package/payload/server/public/assets/{diagram-5BDNPKRD-Dqqyk8GE.js → diagram-5BDNPKRD-slUEdZzz.js} +1 -1
- package/payload/server/public/assets/{diagram-G4DWMVQ6-Xk3WKR_U.js → diagram-G4DWMVQ6-DPcraMfu.js} +1 -1
- package/payload/server/public/assets/{diagram-MMDJMWI5-CAdGL9U7.js → diagram-MMDJMWI5-DR6luhGK.js} +1 -1
- package/payload/server/public/assets/{diagram-TYMM5635-DY1iYQVY.js → diagram-TYMM5635-Jap1B4wA.js} +1 -1
- package/payload/server/public/assets/{dist-Pgmncqde.js → dist-Dbh7HrZX.js} +1 -1
- package/payload/server/public/assets/{erDiagram-SMLLAGMA-BJ5HYKeb.js → erDiagram-SMLLAGMA-DJKUs2hO.js} +1 -1
- package/payload/server/public/assets/{file-download-BYJN3Kgm.js → file-download-DBMW0BNz.js} +1 -1
- package/payload/server/public/assets/{flatten-DeFkSYLU.js → flatten-Cl1Bc3dR.js} +1 -1
- package/payload/server/public/assets/{flowDiagram-DWJPFMVM-B-q6x5Q_.js → flowDiagram-DWJPFMVM-C8W-ZZ9W.js} +1 -1
- package/payload/server/public/assets/{ganttDiagram-T4ZO3ILL-DbjwY_bG.js → ganttDiagram-T4ZO3ILL-DYCX4Xu2.js} +1 -1
- package/payload/server/public/assets/gitGraph-7Q5UKJZL-g7mvu6IY.js +1 -0
- package/payload/server/public/assets/{gitGraphDiagram-UUTBAWPF-C3bLrOmb.js → gitGraphDiagram-UUTBAWPF-CZu_fpgS.js} +1 -1
- package/payload/server/public/assets/{graph-DmikPM4A.js → graph-CR74qec3.js} +1 -1
- package/payload/server/public/assets/{graph-labels-CtG6ckdG.js → graph-labels-1Uz0ZBRd.js} +1 -1
- package/payload/server/public/assets/{graphlib-BlOjhixq.js → graphlib-Bdp7TA4y.js} +1 -1
- package/payload/server/public/assets/info-OMHHGYJF-DZqJuIkB.js +1 -0
- package/payload/server/public/assets/infoDiagram-42DDH7IO-cGfGccHz.js +2 -0
- package/payload/server/public/assets/{isEmpty-Bn-Se8yT.js → isEmpty-D1pGOD1J.js} +1 -1
- package/payload/server/public/assets/{ishikawaDiagram-UXIWVN3A-B_DzwK8l.js → ishikawaDiagram-UXIWVN3A-B7KfIX6z.js} +1 -1
- package/payload/server/public/assets/{journeyDiagram-VCZTEJTY-COzTF-qc.js → journeyDiagram-VCZTEJTY-CSDwBfhF.js} +1 -1
- package/payload/server/public/assets/{jsx-runtime-BjFkEGXb.css → jsx-runtime-BqGVUT1h.css} +1 -1
- package/payload/server/public/assets/{jsx-runtime-UQ0Z6nwN.js → jsx-runtime-D3JkFIbi.js} +1 -1
- package/payload/server/public/assets/{kanban-definition-6JOO6SKY-C2cOIZU6.js → kanban-definition-6JOO6SKY-CWzcEKTr.js} +1 -1
- package/payload/server/public/assets/{line-Bwa6aUYZ.js → line-BNQSlbYn.js} +1 -1
- package/payload/server/public/assets/{linear-CgbkJiu6.js → linear-BN6kGN93.js} +1 -1
- package/payload/server/public/assets/mermaid-parser.core-CcFhkElq.js +4 -0
- package/payload/server/public/assets/mermaid.core-BsIeJ7Cc.js +11 -0
- package/payload/server/public/assets/{mindmap-definition-QFDTVHPH-bu0QLO17.js → mindmap-definition-QFDTVHPH-CQVzj6D_.js} +1 -1
- package/payload/server/public/assets/operator-QP_z97s8.js +1 -0
- package/payload/server/public/assets/{ordinal-C-EimP2j.js → ordinal-CBZeH4Yp.js} +1 -1
- package/payload/server/public/assets/packet-4T2RLAQJ-Hn8rlHpy.js +1 -0
- package/payload/server/public/assets/page-CLijftr1.js +1 -0
- package/payload/server/public/assets/pie-ZZUOXDRM-BPGWVqBm.js +1 -0
- package/payload/server/public/assets/{pieDiagram-DEJITSTG-DQUe6W2Z.js → pieDiagram-DEJITSTG-DnrQ9fyn.js} +1 -1
- package/payload/server/public/assets/preload-helper-CQ36nxok.js +1 -0
- package/payload/server/public/assets/public-W-HholkU.js +6 -0
- package/payload/server/public/assets/{quadrantDiagram-34T5L4WZ-ChhcwVRA.js → quadrantDiagram-34T5L4WZ-BQWlCyWi.js} +1 -1
- package/payload/server/public/assets/radar-PYXPWWZC-DMdLrj3E.js +1 -0
- package/payload/server/public/assets/{reduce-B0wq8DtH.js → reduce-PuPlFPRX.js} +1 -1
- package/payload/server/public/assets/{requirementDiagram-MS252O5E-DwQXqTA9.js → requirementDiagram-MS252O5E-Du_vZhU1.js} +1 -1
- package/payload/server/public/assets/{sankeyDiagram-XADWPNL6-zYqdptBM.js → sankeyDiagram-XADWPNL6-Cf6Z8GPQ.js} +1 -1
- package/payload/server/public/assets/{sequenceDiagram-FGHM5R23-x2g84gb4.js → sequenceDiagram-FGHM5R23-CS8GVol8.js} +1 -1
- package/payload/server/public/assets/{src-CozP7LCe.js → src-BoaldmnP.js} +1 -1
- package/payload/server/public/assets/{stateDiagram-FHFEXIEX-CeUrqs2P.js → stateDiagram-FHFEXIEX-Bv1NW2F1.js} +1 -1
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-BGUCxPmp.js +1 -0
- package/payload/server/public/assets/{timeline-definition-GMOUNBTQ-CL-c9XN5.js → timeline-definition-GMOUNBTQ-ClGYAsr0.js} +1 -1
- package/payload/server/public/assets/treeView-SZITEDCU-CWxofUbI.js +1 -0
- package/payload/server/public/assets/treemap-W4RFUUIX-Cfgb_ZG0.js +1 -0
- package/payload/server/public/assets/{useSelectionMode-C1_ky4B6.js → useSelectionMode-geYq13zs.js} +1 -1
- package/payload/server/public/assets/{vennDiagram-DHZGUBPP-By2HBDYr.js → vennDiagram-DHZGUBPP-C2wTcxQT.js} +1 -1
- package/payload/server/public/assets/wardley-RL74JXVD-B45olYjj.js +1 -0
- package/payload/server/public/assets/{wardleyDiagram-NUSXRM2D-iahvFvIS.js → wardleyDiagram-NUSXRM2D-D86-ivEx.js} +1 -1
- package/payload/server/public/assets/{xychartDiagram-5P7HB3ND-33qqdRhI.js → xychartDiagram-5P7HB3ND-Ba5WAN8P.js} +1 -1
- package/payload/server/public/browser.html +7 -7
- package/payload/server/public/chat.html +10 -9
- package/payload/server/public/data.html +6 -6
- package/payload/server/public/graph.html +9 -9
- package/payload/server/public/index.html +11 -10
- package/payload/server/public/operator.html +24 -0
- package/payload/server/public/public.html +8 -7
- package/payload/server/server.js +392 -330
- package/payload/server/public/assets/AdminShell-BnhxfX97.js +0 -1
- package/payload/server/public/assets/admin-CF8K3hqE.js +0 -1
- package/payload/server/public/assets/architecture-YZFGNWBL-CjF2k79a.js +0 -1
- package/payload/server/public/assets/audio-attachment-mime-DaInZ9sa.js +0 -1
- package/payload/server/public/assets/channel-gFnUr8f4.js +0 -1
- package/payload/server/public/assets/chat-COcrNTJi.js +0 -1
- package/payload/server/public/assets/chunk-336JU56O-B0yBhSVq.js +0 -2
- package/payload/server/public/assets/chunk-426QAEUC-BCmWl6vi.js +0 -1
- package/payload/server/public/assets/chunk-QZHKN3VN-CBWmDBHe.js +0 -1
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-C_wlfUTz.js +0 -1
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-Ltv5s3OY.js +0 -1
- package/payload/server/public/assets/clone-D0XoXc_v.js +0 -1
- package/payload/server/public/assets/gitGraph-7Q5UKJZL-DsUTwRUb.js +0 -1
- package/payload/server/public/assets/info-OMHHGYJF-BV9FyUXQ.js +0 -1
- package/payload/server/public/assets/infoDiagram-42DDH7IO-BpaHbiXO.js +0 -2
- package/payload/server/public/assets/mermaid-parser.core-BFAF0BAk.js +0 -4
- package/payload/server/public/assets/mermaid.core-CMOXmawT.js +0 -11
- package/payload/server/public/assets/packet-4T2RLAQJ-SXjQ83Vr.js +0 -1
- package/payload/server/public/assets/pie-ZZUOXDRM-q7TXebDD.js +0 -1
- package/payload/server/public/assets/public-CSEIGhb4.js +0 -35
- package/payload/server/public/assets/radar-PYXPWWZC-CXKUHVMS.js +0 -1
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-B27DBP9X.js +0 -1
- package/payload/server/public/assets/treeView-SZITEDCU-CWuFgUeJ.js +0 -1
- package/payload/server/public/assets/treemap-W4RFUUIX-gKO4rbgo.js +0 -1
- package/payload/server/public/assets/wardley-RL74JXVD-hDEw8pJN.js +0 -1
- /package/payload/server/public/assets/{_baseFor-BV-TyLWt.js → _baseFor-brRjpUOX.js} +0 -0
- /package/payload/server/public/assets/{array-lqrvkwy7.js → array-BGFCBI0e.js} +0 -0
- /package/payload/server/public/assets/{chunk-CWOGyPgy.js → chunk-Pqm5yXtL.js} +0 -0
- /package/payload/server/public/assets/{cytoscape.esm-SmEOayFS.js → cytoscape.esm-TvRJ2tGX.js} +0 -0
- /package/payload/server/public/assets/{defaultLocale-Dl3Sud5K.js → defaultLocale-CRZydyG6.js} +0 -0
- /package/payload/server/public/assets/{init-BukMwkmL.js → init-B8gtcn7T.js} +0 -0
- /package/payload/server/public/assets/{katex-jl-BtNZi.js → katex-RxgSu_dy.js} +0 -0
- /package/payload/server/public/assets/{admin-CWMpccrR.css → page-CWMpccrR.css} +0 -0
- /package/payload/server/public/assets/{path-DPTRcLku.js → path-DZF-JdEe.js} +0 -0
- /package/payload/server/public/assets/{rough.esm-VLpapkIG.js → rough.esm-6CnTHTkH.js} +0 -0
package/package.json
CHANGED
|
@@ -6,14 +6,15 @@ Prerequisites: `cloudflared` installed; the brand's VNC running on its own X dis
|
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
-
## Why
|
|
9
|
+
## Why several hostnames (admin, public, operator)
|
|
10
10
|
|
|
11
|
-
Each Maxy installation exposes
|
|
11
|
+
Each Maxy installation exposes distinct surfaces from the same device and the same local port. The platform UI distinguishes them by the inbound `Host:` header.
|
|
12
12
|
|
|
13
13
|
- **admin hostname** — the operator's private chat + admin panel. PIN-protected. Only the owner uses it.
|
|
14
14
|
- **public hostname** — the public-facing agent (customer chat, marketing agent, WhatsApp webhook target). Reachable by anyone on the internet.
|
|
15
|
+
- **operator hostname** (optional) — a trimmed admin dashboard (sessions, chat, data — no graph, no browser). Admin-gated like the admin host, recognised by membership in `operator-domains.json`. See § "Operator dashboard ingress".
|
|
15
16
|
|
|
16
|
-
|
|
17
|
+
Several tunnel hostnames, one connector, one local service. The tunnel's `ingress:` block routes each hostname to `http://localhost:${PORT}`; the platform UI classifies the host (operator → public → admin) and serves the matching surface.
|
|
17
18
|
|
|
18
19
|
---
|
|
19
20
|
|
|
@@ -596,6 +597,53 @@ systemctl --user restart "cloudflared-${BRAND}.service"
|
|
|
596
597
|
|
|
597
598
|
---
|
|
598
599
|
|
|
600
|
+
## Operator dashboard ingress (operator host)
|
|
601
|
+
|
|
602
|
+
The operator dashboard is a trimmed admin surface (sessions, chat, WhatsApp reader, data — no graph, no browser). It routes to the **same brand UI port** as the admin host (`${MAXY_UI_PORT}`) and is gated by the **same admin gate** (Cloudflare Access / remote-auth + PIN + Claude OAuth) — it is not a public host. A request to the operator host that is unauthenticated hits the identical login flow as the bare admin host; the UI server then classifies the host and serves the operator shell.
|
|
603
|
+
|
|
604
|
+
**The operator hostname is arbitrary** — any FQDN the operator chooses (e.g. `glsops.siteoffice.online`). Task 829 removed the `operator.` prefix rule: the UI classifies a host as operator **only** when the host is listed in `~/.${BRAND}/operator-domains.json`. Provisioning therefore has two scripted parts — the tunnel ingress (so the host reaches the brand UI) and the operator-domains.json write (so the UI serves the operator shell instead of the full admin shell).
|
|
605
|
+
|
|
606
|
+
Take the operator FQDN from chat:
|
|
607
|
+
|
|
608
|
+
```
|
|
609
|
+
OPERATOR_HOSTNAME="glsops.siteoffice.online" # the operator's chosen FQDN
|
|
610
|
+
PORT="${MAXY_UI_PORT}" # the brand UI port — same service as admin/public
|
|
611
|
+
```
|
|
612
|
+
|
|
613
|
+
### 1. Ingress + DNS
|
|
614
|
+
|
|
615
|
+
Run the Multi-ingress flow above with `HOSTNAME="${OPERATOR_HOSTNAME}"` and `PORT="${MAXY_UI_PORT}"`: the awk append (step 1), validate (step 2), create the DNS row (step 3), reload the connector (step 4). After the edit the ingress block carries the operator row before the catch-all (hostnames are illustrative — yours are whatever the operator registered):
|
|
616
|
+
|
|
617
|
+
```yaml
|
|
618
|
+
ingress:
|
|
619
|
+
- hostname: glsmith.siteoffice.online # admin (primary)
|
|
620
|
+
service: http://localhost:<MAXY_UI_PORT>
|
|
621
|
+
- hostname: gls.siteoffice.online # public (also in alias-domains.json)
|
|
622
|
+
service: http://localhost:<MAXY_UI_PORT>
|
|
623
|
+
- hostname: glsops.siteoffice.online # operator (also in operator-domains.json)
|
|
624
|
+
service: http://localhost:<MAXY_UI_PORT>
|
|
625
|
+
- service: http_status:404
|
|
626
|
+
```
|
|
627
|
+
|
|
628
|
+
### 2. Classify the host as operator
|
|
629
|
+
|
|
630
|
+
The ingress only gets the request to the brand UI; without this write the UI serves the **full admin shell** on the operator host. Append the hostname to `operator-domains.json` at the **brand root** (not `${CFG_DIR}` — the platform UI watches the brand root and hot-reloads within ~2 s, no restart):
|
|
631
|
+
|
|
632
|
+
```
|
|
633
|
+
F="${HOME}/.${BRAND}/operator-domains.json"
|
|
634
|
+
[ -f "$F" ] || echo '[]' > "$F"
|
|
635
|
+
jq --arg H "${OPERATOR_HOSTNAME}" 'if index($H) then . else . + [$H] end' "$F" > /tmp/op.json && mv /tmp/op.json "$F"
|
|
636
|
+
cat "$F"
|
|
637
|
+
```
|
|
638
|
+
|
|
639
|
+
The UI logs `[operator-domains] reloaded <n> operator domain(s): …` within ~2 s of the write. A configured brand whose boot/reload log shows `0 operator domain(s)` while an operator host is expected means the file was written to the wrong path (e.g. under `cloudflared/`).
|
|
640
|
+
|
|
641
|
+
**Verification.** `curl -I https://${OPERATOR_HOSTNAME}` returns the admin login (not a 404, not the public agent page). After login the dashboard shows the sessions list and WhatsApp reader, the header menu carries only Dashboard / Chat / Data, and `https://${OPERATOR_HOSTNAME}/graph` returns 404. The standing serve signal is `[host-class] host=${OPERATOR_HOSTNAME} class=operator served=operator.html`; `class=admin served=index.html` for a configured operator host is the full-shell leak signature (the operator-domains.json write was missed or written to the wrong path).
|
|
642
|
+
|
|
643
|
+
> Installer auto-provisioning of this host is out of scope here (documented manual/scripted add only); Task 825 owns wiring it into the installer.
|
|
644
|
+
|
|
645
|
+
---
|
|
646
|
+
|
|
599
647
|
## Full reset
|
|
600
648
|
|
|
601
649
|
If everything is in a bad state and you want to start over. Assumes Step 0 has been run so `${BRAND}` and `${CFG_DIR}` are set.
|
|
@@ -14,7 +14,7 @@ Ask three questions in order. The first `yes` determines the action.
|
|
|
14
14
|
2. **Is `config.yml` referencing a tunnel UUID that no longer exists on the account, or a hostname that the account no longer owns?**
|
|
15
15
|
→ Full reset. The tunnel the config names is unreachable; recovering per-step is slower than starting clean.
|
|
16
16
|
|
|
17
|
-
3. **Is the only problem a stray CNAME in the dashboard, a rogue token-mode connector process, or an out-of-date `alias-domains.json` entry?**
|
|
17
|
+
3. **Is the only problem a stray CNAME in the dashboard, a rogue token-mode connector process, or an out-of-date `alias-domains.json` / `operator-domains.json` entry?**
|
|
18
18
|
→ Patch (see § Patching below). Reset would destroy correct local state alongside the bad record.
|
|
19
19
|
|
|
20
20
|
When no question reaches `yes`, the state is probably recoverable per-step via `references/manual-setup.md`. Re-run the relevant manual setup steps before reaching for reset.
|
|
@@ -102,6 +102,24 @@ jq --arg H "admin.<yourdomain>" 'map(select(. != $H))' "${HOME}/.${BRAND}/alias-
|
|
|
102
102
|
|
|
103
103
|
Replace `<yourdomain>` with the actual domain. The platform UI watches the file and reloads without a restart.
|
|
104
104
|
|
|
105
|
+
### Remove a rogue entry from `operator-domains.json`
|
|
106
|
+
|
|
107
|
+
`operator-domains.json` controls which hostnames the platform UI classifies as **operator** (serving the trimmed operator dashboard — sessions, chat, data, no graph/browser) rather than admin or public. It lives at `${HOME}/.${BRAND}/operator-domains.json` — the brand root, **not** `${CFG_DIR}` — for the same reason as `alias-domains.json`: the platform UI watches the brand root.
|
|
108
|
+
|
|
109
|
+
A host wrongly listed here serves the operator shell instead of the full admin shell (or instead of the public agent, since operator wins over public). Remove it manually:
|
|
110
|
+
|
|
111
|
+
```
|
|
112
|
+
cat "${HOME}/.${BRAND}/operator-domains.json"
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
If the wrong host is listed, strip it:
|
|
116
|
+
|
|
117
|
+
```
|
|
118
|
+
jq --arg H "<host-to-remove>" 'map(select(. != $H))' "${HOME}/.${BRAND}/operator-domains.json" > /tmp/op.json && mv /tmp/op.json "${HOME}/.${BRAND}/operator-domains.json"
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
The platform UI watches the file and reloads without a restart; the next request to the host routes to its corrected surface.
|
|
122
|
+
|
|
105
123
|
### Fix a single wrong DNS record without tearing everything down
|
|
106
124
|
|
|
107
125
|
If a hostname's CNAME is pointing at the wrong tunnel (e.g. after an account switch left old records), `cloudflared` can overwrite it once the correct cert is in place:
|
|
@@ -36,7 +36,19 @@ Every Cloudflare operation proves itself with a live behavioural signal surfaced
|
|
|
36
36
|
|
|
37
37
|
## Inputs (tunnel)
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
Five inputs come from the operator in chat: the admin FQDN, optional public FQDN, optional operator-dashboard FQDN, optional apex FQDN, and the admin password. `BRAND` is derived from disk — never hardcoded — with `BRAND=$(jq -r .hostname ~/.<configDir>/brand.json)`. The same install can host different brands on different ports; `brand.json.hostname` is the only authoritative source.
|
|
40
|
+
|
|
41
|
+
## Host classes — three peers on one brand UI port
|
|
42
|
+
|
|
43
|
+
A brand serves three peer host classes, all routed to the **same brand UI port** (`${MAXY_UI_PORT}`); the platform UI classifies each request by its `Host` header. The hostnames are arbitrary — there is no required `admin.`/`public.`/`operator.` prefix.
|
|
44
|
+
|
|
45
|
+
| Class | How the UI recognises it | What it serves |
|
|
46
|
+
|---|---|---|
|
|
47
|
+
| **admin** (default) | the bare primary host — in neither domains file | full admin shell (chat, data, graph, browser) — admin-gated |
|
|
48
|
+
| **public** | host starts with `public.` **or** is listed in `~/.${BRAND}/alias-domains.json` | the public agent page only — no admin surfaces |
|
|
49
|
+
| **operator** | host is listed in `~/.${BRAND}/operator-domains.json` | the trimmed operator dashboard (sessions, chat, data — no graph, no browser) — admin-gated |
|
|
50
|
+
|
|
51
|
+
Precedence is operator → public → admin: a host listed in `operator-domains.json` is operator even if it also matches a public rule. Both domains files live at the **brand root** `~/.${BRAND}/` (not under `cloudflared/`) because the platform UI watches the brand root and hot-reloads within ~2 s. Provisioning admin needs no domains-file write; public writes `alias-domains.json`; operator writes `operator-domains.json`. See `references/manual-setup.md` § "Operator dashboard ingress".
|
|
40
52
|
|
|
41
53
|
## Execution
|
|
42
54
|
|
|
@@ -48,7 +60,8 @@ Tunnel mutations the agent performs from `references/manual-setup.md` (each one
|
|
|
48
60
|
- `cloudflared tunnel --origincert <cert> create <name>` — produces `<tunnelId>.json` credentials.
|
|
49
61
|
- Write `~/.${BRAND}/cloudflared/config.yml` (ingress block per the runbook).
|
|
50
62
|
- `cloudflared tunnel --origincert <cert> route dns <tunnelId> <hostname>` — one call per non-apex hostname.
|
|
51
|
-
- For
|
|
63
|
+
- For a public hostname not starting with `public.`, append it to `~/.${BRAND}/alias-domains.json` so `isPublicHost()` treats it as public.
|
|
64
|
+
- For an operator-dashboard hostname, append it to `~/.${BRAND}/operator-domains.json` so the UI serves the trimmed operator shell (admin-gated). See `references/manual-setup.md` § "Operator dashboard ingress".
|
|
52
65
|
- Install + start the `${BRAND}-cloudflared.service` user unit (`systemctl --user daemon-reload && systemctl --user enable --now ${BRAND}-cloudflared.service`).
|
|
53
66
|
|
|
54
67
|
After the service is up, the agent runs `curl -I https://<admin-hostname>` and pastes the response. The setup-done claim only fires when a `200` line appears in that response.
|
|
@@ -67,7 +80,7 @@ When the operator's request touches Cloudflare, the agent's permitted actions ar
|
|
|
67
80
|
|
|
68
81
|
- Invoke `cloudflared` via Bash, following `references/manual-setup.md`.
|
|
69
82
|
- Invoke `wrangler` and the Cloudflare API via Bash, following `references/api.md`, `references/hosting-sites.md`, and `references/d1-data-capture.md`, using the reused per-scope narrow token (minted once if absent, then reused).
|
|
70
|
-
- Write `config.yml` and `
|
|
83
|
+
- Write `config.yml`, `alias-domains.json`, and `operator-domains.json` per the runbook.
|
|
71
84
|
- Install and start the brand's cloudflared user service.
|
|
72
85
|
- Quote `references/manual-setup.md`, `references/reset-guide.md`, or `references/dashboard-guide.md` verbatim when a dashboard click-path is the right tool.
|
|
73
86
|
- Verify reachability via `curl -I https://<hostname>` and surface the response.
|
|
@@ -51,6 +51,10 @@ const ALLOWLIST = new Set([
|
|
|
51
51
|
// (server-init-line-stamper.cjs); the test loads it via the sanctioned
|
|
52
52
|
// createRequire(import.meta.url) ESM→CJS bridge, not a raw require.
|
|
53
53
|
'platform/ui/app/lib/__tests__/server-init-line-stamper.test.ts',
|
|
54
|
+
// Same vi.hoisted pattern: Task 829's operator-domains test builds a tmpdir
|
|
55
|
+
// before the module's `../paths` mock fires, to redirect MAXY_DIR off the
|
|
56
|
+
// operator's real home config.
|
|
57
|
+
'platform/ui/app/lib/__tests__/operator-domains.test.ts',
|
|
54
58
|
])
|
|
55
59
|
|
|
56
60
|
const REQUIRE_CALL_RE = /\brequire\s*\(/
|