@rubytech/create-maxy-code 0.1.500 → 0.1.502
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/docs/superpowers/plans/2026-07-25-task-1974-uploads-intake-inbox.md +235 -0
- package/payload/platform/docs/superpowers/plans/2026-07-25-task-1976-intra-folder-hygiene.md +215 -0
- package/payload/platform/lib/graph-style/dist/index.d.ts +9 -0
- package/payload/platform/lib/graph-style/dist/index.d.ts.map +1 -1
- package/payload/platform/lib/graph-style/dist/index.js +152 -6
- package/payload/platform/lib/graph-style/dist/index.js.map +1 -1
- package/payload/platform/lib/graph-style/src/__tests__/caption-coverage.test.ts +69 -0
- package/payload/platform/lib/graph-style/src/__tests__/coverage-source.ts +73 -0
- package/payload/platform/lib/graph-style/src/__tests__/icons.test.ts +20 -3
- package/payload/platform/lib/graph-style/src/index.ts +166 -5
- package/payload/platform/plugins/admin/PLUGIN.md +1 -0
- package/payload/platform/plugins/admin/skills/agent-builder/SKILL.md +15 -0
- package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +52 -2
- package/payload/platform/plugins/admin/skills/summarise/SKILL.md +37 -0
- package/payload/platform/plugins/admin/skills/whats-new/SKILL.md +7 -0
- package/payload/platform/plugins/docs/references/admin-ui.md +50 -0
- package/payload/platform/plugins/docs/references/internals.md +1 -1
- package/payload/platform/plugins/docs/references/summarise-skill.md +7 -0
- package/payload/platform/templates/account-schema/SCHEMA.md +36 -1
- package/payload/platform/templates/specialists/agents/data-manager.md +4 -2
- package/payload/server/public/activity.html +6 -6
- package/payload/server/public/assets/AdminLoginScreens-Bv_bKKeL.js +1 -0
- package/payload/server/public/assets/AdminShell-Gq8DU_ig.js +2 -0
- package/payload/server/public/assets/{activity-CKUYOLd2.js → activity-DZFYDHNA.js} +1 -1
- package/payload/server/public/assets/admin-DLUOixl6.js +1 -0
- package/payload/server/public/assets/{arc-CpWWSum8.js → arc-CvlzUHOf.js} +1 -1
- package/payload/server/public/assets/architecture-YZFGNWBL-BQc779DH.js +1 -0
- package/payload/server/public/assets/{architectureDiagram-Q4EWVU46-D2EzaII0.js → architectureDiagram-Q4EWVU46-I1Hs0RJA.js} +1 -1
- package/payload/server/public/assets/{blockDiagram-DXYQGD6D-8kDpaNSZ.js → blockDiagram-DXYQGD6D-Df5jTGtl.js} +1 -1
- package/payload/server/public/assets/{bot-DESMpxSQ.js → bot-CrEhKW1l.js} +1 -1
- package/payload/server/public/assets/{browser-CpLq_DIo.js → browser-Bt4-LKLU.js} +1 -1
- package/payload/server/public/assets/{c4Diagram-AHTNJAMY-CbwmZpK3.js → c4Diagram-AHTNJAMY-B6WY5IDv.js} +1 -1
- package/payload/server/public/assets/{calendar-ClOwyuz-.js → calendar-D0qIvLUR.js} +1 -1
- package/payload/server/public/assets/channel-AqnC3SHu.js +1 -0
- package/payload/server/public/assets/chat-geSkx0j2.js +1 -0
- package/payload/server/public/assets/chevron-left-CQ8rcBoO.js +1 -0
- package/payload/server/public/assets/chevron-right-CSRSqblN.js +1 -0
- package/payload/server/public/assets/{chunk-2KRD3SAO-PFheZ9mw.js → chunk-2KRD3SAO-BsIIFDkc.js} +1 -1
- package/payload/server/public/assets/{chunk-336JU56O-CCFOp5VK.js → chunk-336JU56O-j9z1VtyC.js} +2 -2
- package/payload/server/public/assets/chunk-426QAEUC-CO02gU5d.js +1 -0
- package/payload/server/public/assets/{chunk-4BX2VUAB-Hz4JWOf2.js → chunk-4BX2VUAB-C9i7prxq.js} +1 -1
- package/payload/server/public/assets/{chunk-4TB4RGXK-4xeV0s85.js → chunk-4TB4RGXK-DH0QVGcv.js} +1 -1
- package/payload/server/public/assets/{chunk-55IACEB6-4QKgBpoh.js → chunk-55IACEB6-Dnd_YCPA.js} +1 -1
- package/payload/server/public/assets/{chunk-5FUZZQ4R-ms3K6Z5z.js → chunk-5FUZZQ4R-D5sSz3yN.js} +1 -1
- package/payload/server/public/assets/{chunk-5PVQY5BW-CIC4GIGi.js → chunk-5PVQY5BW-CJrwWjAT.js} +1 -1
- package/payload/server/public/assets/{chunk-67CJDMHE-B-XrWVmV.js → chunk-67CJDMHE-SjP6_hUw.js} +1 -1
- package/payload/server/public/assets/{chunk-7N4EOEYR-C7ECOUYQ.js → chunk-7N4EOEYR-fAuhVJD0.js} +1 -1
- package/payload/server/public/assets/{chunk-AA7GKIK3-DOZ6Fxwk.js → chunk-AA7GKIK3-DZxa7KVg.js} +1 -1
- package/payload/server/public/assets/{chunk-BSJP7CBP-4cJ_b0c6.js → chunk-BSJP7CBP-DjeG3eQ-.js} +1 -1
- package/payload/server/public/assets/{chunk-CIAEETIT--mhZipWM.js → chunk-CIAEETIT-RYQULNJm.js} +1 -1
- package/payload/server/public/assets/{chunk-EDXVE4YY-jZpVwob_.js → chunk-EDXVE4YY-Cahapnon.js} +1 -1
- package/payload/server/public/assets/{chunk-ENJZ2VHE-Nn-p-xIA.js → chunk-ENJZ2VHE-1146X1L4.js} +1 -1
- package/payload/server/public/assets/{chunk-FMBD7UC4-DyNpcKOS.js → chunk-FMBD7UC4-BCFumtcP.js} +1 -1
- package/payload/server/public/assets/{chunk-FOC6F5B3-C0P8q1uz.js → chunk-FOC6F5B3-CkrtX8Zt.js} +1 -1
- package/payload/server/public/assets/{chunk-ICPOFSXX-CdXQ5SfI.js → chunk-ICPOFSXX-Ba1y3DaW.js} +2 -2
- package/payload/server/public/assets/{chunk-K5T4RW27-BVZJKKsT.js → chunk-K5T4RW27-CF-PI3uQ.js} +1 -1
- package/payload/server/public/assets/{chunk-KGLVRYIC-QlVWTe0V.js → chunk-KGLVRYIC-SFFC6ZC-.js} +1 -1
- package/payload/server/public/assets/{chunk-LIHQZDEY-CpGVZutP.js → chunk-LIHQZDEY-DbOLEP4R.js} +1 -1
- package/payload/server/public/assets/{chunk-ORNJ4GCN-WVcS6fUC.js → chunk-ORNJ4GCN-VB963bkN.js} +1 -1
- package/payload/server/public/assets/{chunk-OYMX7WX6-B7hiSTed.js → chunk-OYMX7WX6-DWYY1pQa.js} +1 -1
- package/payload/server/public/assets/chunk-QZHKN3VN-BiFMbK8t.js +1 -0
- package/payload/server/public/assets/{chunk-U2HBQHQK-DJPnZxGy.js → chunk-U2HBQHQK-DAH1diYP.js} +1 -1
- package/payload/server/public/assets/{chunk-X2U36JSP-DilBs1Yc.js → chunk-X2U36JSP-Dmw9coXz.js} +1 -1
- package/payload/server/public/assets/{chunk-XPW4576I-B5-uyrJ0.js → chunk-XPW4576I-DaAUON1-.js} +1 -1
- package/payload/server/public/assets/{chunk-YZCP3GAM-BNO4z0Mv.js → chunk-YZCP3GAM-BUcfkEef.js} +1 -1
- package/payload/server/public/assets/{chunk-ZZ45TVLE-BzHMQpip.js → chunk-ZZ45TVLE-BLD-vFRO.js} +1 -1
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-BdRqzScB.js +1 -0
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-ChPLgHbS.js +1 -0
- package/payload/server/public/assets/clock-B7Ba8AZL.js +1 -0
- package/payload/server/public/assets/clone-TKtrjWBC.js +1 -0
- package/payload/server/public/assets/{cose-bilkent-S5V4N54A-3DWYmn1o.js → cose-bilkent-S5V4N54A-CoZX0uki.js} +1 -1
- package/payload/server/public/assets/{dagre-Cpy31xJW.js → dagre-Bmjs8zJA.js} +1 -1
- package/payload/server/public/assets/{dagre-KV5264BT-C8fyxHFd.js → dagre-KV5264BT-BZCP2wnq.js} +1 -1
- package/payload/server/public/assets/data-BdlGqjKM.js +1 -0
- package/payload/server/public/assets/{diagram-5BDNPKRD-ycyhnLvr.js → diagram-5BDNPKRD-8Nt9a4xX.js} +1 -1
- package/payload/server/public/assets/{diagram-G4DWMVQ6-BkeYicIt.js → diagram-G4DWMVQ6-vh5tcYqJ.js} +1 -1
- package/payload/server/public/assets/{diagram-MMDJMWI5-BcGZU-Q3.js → diagram-MMDJMWI5-DGf--jc8.js} +1 -1
- package/payload/server/public/assets/{diagram-TYMM5635-DuBDCFb_.js → diagram-TYMM5635-CsO7TIdw.js} +1 -1
- package/payload/server/public/assets/{dist-BYc_arNy.js → dist-cdnE4DqK.js} +1 -1
- package/payload/server/public/assets/{erDiagram-SMLLAGMA-DmkeOzvp.js → erDiagram-SMLLAGMA-4a78yV8_.js} +1 -1
- package/payload/server/public/assets/file-text-BpLcZKld.js +1 -0
- package/payload/server/public/assets/{flatten-QjnJ1Gcl.js → flatten-BtIc9jX7.js} +1 -1
- package/payload/server/public/assets/{flowDiagram-DWJPFMVM-CkE-pjuB.js → flowDiagram-DWJPFMVM-BoQBXs6t.js} +1 -1
- package/payload/server/public/assets/{ganttDiagram-T4ZO3ILL-Cjiy3kvE.js → ganttDiagram-T4ZO3ILL-CvzqwCC8.js} +1 -1
- package/payload/server/public/assets/gitGraph-7Q5UKJZL-DfcaTE9L.js +1 -0
- package/payload/server/public/assets/{gitGraphDiagram-UUTBAWPF-CsI4lKZm.js → gitGraphDiagram-UUTBAWPF-D_nBxay_.js} +1 -1
- package/payload/server/public/assets/graph-HB0199x-.js +51 -0
- package/payload/server/public/assets/graph-labels-Bx19ZYvJ.js +1 -0
- package/payload/server/public/assets/{graphlib-BkXxC6D5.js → graphlib-D0NdsKJI.js} +1 -1
- package/payload/server/public/assets/info-OMHHGYJF-CD-u6gw9.js +1 -0
- package/payload/server/public/assets/infoDiagram-42DDH7IO-C6gPQCvO.js +2 -0
- package/payload/server/public/assets/{isEmpty-BavJI9Cn.js → isEmpty-Bu4fZ8Kf.js} +1 -1
- package/payload/server/public/assets/{ishikawaDiagram-UXIWVN3A-D8lZtjRc.js → ishikawaDiagram-UXIWVN3A-auW-s0i0.js} +1 -1
- package/payload/server/public/assets/{journeyDiagram-VCZTEJTY-kLE7SiR_.js → journeyDiagram-VCZTEJTY-3Q6AWK4A.js} +1 -1
- package/payload/server/public/assets/{kanban-definition-6JOO6SKY-ove6JuD3.js → kanban-definition-6JOO6SKY-B4MPFp98.js} +1 -1
- package/payload/server/public/assets/{line-CZMSoxM6.js → line-26MdeG5Z.js} +1 -1
- package/payload/server/public/assets/{linear-Be8IK9hK.js → linear-Dq9s_bDO.js} +1 -1
- package/payload/server/public/assets/{maximize-2-BbzPm7o8.js → maximize-2-BhR-Ec21.js} +1 -1
- package/payload/server/public/assets/{mermaid-parser.core-BBADqbnp.js → mermaid-parser.core-vLEpOXgf.js} +2 -2
- package/payload/server/public/assets/{mermaid.core-mH3N7K0I.js → mermaid.core-Durk4m6D.js} +3 -3
- package/payload/server/public/assets/{mindmap-definition-QFDTVHPH-BjwwwWil.js → mindmap-definition-QFDTVHPH-DOIg-TyG.js} +1 -1
- package/payload/server/public/assets/operator-DejfJlvi.js +1 -0
- package/payload/server/public/assets/{ordinal-BHeIKG-K.js → ordinal-C2TEWKNu.js} +1 -1
- package/payload/server/public/assets/packet-4T2RLAQJ-BaLYeIrU.js +1 -0
- package/payload/server/public/assets/page-DomkejEB.js +32 -0
- package/payload/server/public/assets/page-FnCmAeHc.js +1 -0
- package/payload/server/public/assets/{pdf-render-fJz4vym9.js → pdf-render-C257cidb.js} +1 -1
- package/payload/server/public/assets/pie-ZZUOXDRM-CL-XJtk-.js +1 -0
- package/payload/server/public/assets/{pieDiagram-DEJITSTG-D-lXWWta.js → pieDiagram-DEJITSTG-DtgBHZfi.js} +1 -1
- package/payload/server/public/assets/{public-DqJjXR4p.js → public-Be_Galv6.js} +1 -1
- package/payload/server/public/assets/{quadrantDiagram-34T5L4WZ-13QyG_AO.js → quadrantDiagram-34T5L4WZ-BTc5Qn2y.js} +1 -1
- package/payload/server/public/assets/radar-PYXPWWZC-Cn-g6F_h.js +1 -0
- package/payload/server/public/assets/{reduce-Fm685to3.js → reduce-BGpN5lgn.js} +1 -1
- package/payload/server/public/assets/{requirementDiagram-MS252O5E-Bx45Bgn4.js → requirementDiagram-MS252O5E-BNgOO5YW.js} +1 -1
- package/payload/server/public/assets/{rotate-ccw-L42fL8ey.js → rotate-ccw-D9qOBLig.js} +1 -1
- package/payload/server/public/assets/routines-lGiYaMiX.js +1 -0
- package/payload/server/public/assets/{sankeyDiagram-XADWPNL6-Cj-Gq25v.js → sankeyDiagram-XADWPNL6-MyUATmVt.js} +1 -1
- package/payload/server/public/assets/{sequenceDiagram-FGHM5R23-B8RDRq93.js → sequenceDiagram-FGHM5R23-CBJrF5Vi.js} +1 -1
- package/payload/server/public/assets/skills-D9nWOqoz.js +1 -0
- package/payload/server/public/assets/{src-D3VYuW_Z.js → src-DekKlUCp.js} +1 -1
- package/payload/server/public/assets/{stateDiagram-FHFEXIEX-DoyFF1Kl.js → stateDiagram-FHFEXIEX-6wbUjn1Q.js} +1 -1
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-BdMdfBeC.js +1 -0
- package/payload/server/public/assets/{tasks-GNtvZL8F.js → tasks-Cyc1EfLA.js} +1 -1
- package/payload/server/public/assets/{time-entry-format-BreNpFLJ.js → time-entry-format-RkCW7hKu.js} +1 -1
- package/payload/server/public/assets/{timeline-definition-GMOUNBTQ-Df4RQXm6.js → timeline-definition-GMOUNBTQ-BHjTMCGY.js} +1 -1
- package/payload/server/public/assets/treeView-SZITEDCU-CmZoOGlC.js +1 -0
- package/payload/server/public/assets/treemap-W4RFUUIX-H27WFS-y.js +1 -0
- package/payload/server/public/assets/{triangle-alert-DumCWC08.js → triangle-alert-k8ulav-N.js} +1 -1
- package/payload/server/public/assets/{useCopyFeedback-DHCtz8qX.js → useCopyFeedback-DN1WA5vU.js} +1 -1
- package/payload/server/public/assets/useSubAccountSwitcher-fvBunpOC.css +1 -0
- package/payload/server/public/assets/useSubAccountSwitcher-iQGqNJhI.js +9 -0
- package/payload/server/public/assets/useVoiceRecorder-v--TIxaM.js +2 -0
- package/payload/server/public/assets/{vennDiagram-DHZGUBPP-D2o5og9l.js → vennDiagram-DHZGUBPP-yo3-cf0U.js} +1 -1
- package/payload/server/public/assets/wardley-RL74JXVD-DNpWIvU4.js +1 -0
- package/payload/server/public/assets/{wardleyDiagram-NUSXRM2D-BDueObbS.js → wardleyDiagram-NUSXRM2D-DZlyFzrg.js} +1 -1
- package/payload/server/public/assets/{wrench-iWkROE1V.js → wrench-CKhz8KnQ.js} +1 -1
- package/payload/server/public/assets/{xychartDiagram-5P7HB3ND-BTYs4Fgh.js → xychartDiagram-5P7HB3ND-B5HV5h80.js} +1 -1
- package/payload/server/public/browser.html +5 -5
- package/payload/server/public/calendar.html +8 -8
- package/payload/server/public/chat.html +16 -15
- package/payload/server/public/data.html +13 -12
- package/payload/server/public/graph.html +10 -10
- package/payload/server/public/index.html +17 -16
- package/payload/server/public/operator.html +17 -16
- package/payload/server/public/public.html +16 -15
- package/payload/server/public/routines.html +7 -7
- package/payload/server/public/skills.html +19 -0
- package/payload/server/public/tasks.html +7 -7
- package/payload/server/server.js +1157 -789
- package/payload/server/public/assets/AdminLoginScreens-CKg_Dlpv.js +0 -1
- package/payload/server/public/assets/AdminShell-BFVVkWFC.js +0 -2
- package/payload/server/public/assets/admin-wtSUU5N0.js +0 -1
- package/payload/server/public/assets/architecture-YZFGNWBL-D-AX2VuA.js +0 -1
- package/payload/server/public/assets/channel-DZ5sh6YQ.js +0 -1
- package/payload/server/public/assets/chat-DRuIxGtE.js +0 -1
- package/payload/server/public/assets/chevron-left-BzIg4in6.js +0 -1
- package/payload/server/public/assets/chevron-right-BcFSa9C3.js +0 -1
- package/payload/server/public/assets/chunk-426QAEUC-CcjBLp4a.js +0 -1
- package/payload/server/public/assets/chunk-QZHKN3VN-B2WjDYBE.js +0 -1
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-CT3jNrze.js +0 -1
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-DJRsjAkC.js +0 -1
- package/payload/server/public/assets/clock-Dr3NGtjR.js +0 -1
- package/payload/server/public/assets/clone-FcEDnoMT.js +0 -1
- package/payload/server/public/assets/data-BdZCvyvN.js +0 -1
- package/payload/server/public/assets/gitGraph-7Q5UKJZL-D1uhnP9U.js +0 -1
- package/payload/server/public/assets/graph-B7niLM97.js +0 -51
- package/payload/server/public/assets/graph-labels-DykmXYHA.js +0 -1
- package/payload/server/public/assets/info-OMHHGYJF-oNm27GAV.js +0 -1
- package/payload/server/public/assets/infoDiagram-42DDH7IO-LxTftqyS.js +0 -2
- package/payload/server/public/assets/operator-DglDYmdV.js +0 -1
- package/payload/server/public/assets/packet-4T2RLAQJ-eQNVGiK3.js +0 -1
- package/payload/server/public/assets/page-C-5sTAE-.js +0 -32
- package/payload/server/public/assets/page-C8G5p4jr.js +0 -1
- package/payload/server/public/assets/pie-ZZUOXDRM-E1u-48rt.js +0 -1
- package/payload/server/public/assets/radar-PYXPWWZC-Cn2cGN90.js +0 -1
- package/payload/server/public/assets/routines-JOV6xdYh.js +0 -1
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-Bml-X4-H.js +0 -1
- package/payload/server/public/assets/treeView-SZITEDCU-CimabhXy.js +0 -1
- package/payload/server/public/assets/treemap-W4RFUUIX-Cg264rpM.js +0 -1
- package/payload/server/public/assets/useSubAccountSwitcher-Bc7XHr0L.js +0 -9
- package/payload/server/public/assets/useSubAccountSwitcher-DPHQJO7E.css +0 -1
- package/payload/server/public/assets/useVoiceRecorder-Cj-VZDKO.js +0 -2
- package/payload/server/public/assets/wardley-RL74JXVD-tbgfCg0E.js +0 -1
- /package/payload/server/public/assets/{_baseFor-Bvwvhrz4.js → _baseFor-Be3EKK3K.js} +0 -0
- /package/payload/server/public/assets/{array-D3d-WgFW.js → array-X0JlPOfd.js} +0 -0
- /package/payload/server/public/assets/{chunk-fQC6bEKA.js → chunk-CCr-iYLO.js} +0 -0
- /package/payload/server/public/assets/{cytoscape.esm-Cun-OM6a.js → cytoscape.esm-CI2IWMLB.js} +0 -0
- /package/payload/server/public/assets/{defaultLocale-CisKV5Ew.js → defaultLocale-B6RGN4id.js} +0 -0
- /package/payload/server/public/assets/{init-D9ZOVaZ3.js → init-BmUWJJHz.js} +0 -0
- /package/payload/server/public/assets/{katex-C-3ZDK8o.js → katex-BjZuzSQn.js} +0 -0
- /package/payload/server/public/assets/{path-BMOgQSLM.js → path-CoPyR7c2.js} +0 -0
- /package/payload/server/public/assets/{preload-helper-DL2DwvxV.js → preload-helper-BQrMkyGX.js} +0 -0
- /package/payload/server/public/assets/{rough.esm-BrTFrov0.js → rough.esm-jSt7UMyi.js} +0 -0
|
@@ -42,11 +42,12 @@ export const GRAPH_LABEL_COLOURS: Record<string, string> = {
|
|
|
42
42
|
// JobLogic service-delivery ontology (Task 1084; supersedes the Task 650/773
|
|
43
43
|
// homegrown set). Muted brick-red / earthy family — the service register sits
|
|
44
44
|
// apart from people-terracotta, viewing-amber, and task-rose bands so
|
|
45
|
-
// sitedesk legends read as their own group.
|
|
46
|
-
// labels
|
|
47
|
-
// JobCost, Contact, PurchaseOrderLine, InvoiceLine,
|
|
48
|
-
//
|
|
49
|
-
//
|
|
45
|
+
// sitedesk legends read as their own group. These are the top-level
|
|
46
|
+
// (operator-entry) labels; the child labels (QuoteLine, Milestone, Valuation,
|
|
47
|
+
// VariationNote, JobCost, Contact, PurchaseOrderLine, InvoiceLine,
|
|
48
|
+
// InvoicePayment, Credit) are coloured in the Task 1965 block appended at the
|
|
49
|
+
// end of this object, not here. :Engineer is an additional label on Person
|
|
50
|
+
// and takes the Person colour; :Supplier is an additional label on
|
|
50
51
|
// Organization and takes the tobacco Organization colour. All hexes here are
|
|
51
52
|
// pairwise-unique across the registry.
|
|
52
53
|
Job: '#8C3B2E',
|
|
@@ -156,6 +157,93 @@ export const GRAPH_LABEL_COLOURS: Record<string, string> = {
|
|
|
156
157
|
// (this object's key order), so a mid-table insert would silently change
|
|
157
158
|
// the rendered shape of every label after it.
|
|
158
159
|
CashEntry: '#7D5A2B',
|
|
160
|
+
|
|
161
|
+
// --- Task 1965: colour every node type that can appear in the graph ---
|
|
162
|
+
// Appended at the END so SHAPE_BY_LABEL indices for the labels above are
|
|
163
|
+
// unchanged. Grouped by family band; each hex is pairwise-unique across the
|
|
164
|
+
// whole registry (except the pre-existing UserMessage/Preference twin).
|
|
165
|
+
|
|
166
|
+
// Ledger / money children (brown-gold, beside Invoice and CashEntry).
|
|
167
|
+
InvoiceLine: '#7A5326',
|
|
168
|
+
InvoicePayment: '#8A6230',
|
|
169
|
+
QuoteLine: '#9A7038',
|
|
170
|
+
PurchaseOrderLine: '#A67E42',
|
|
171
|
+
JobCost: '#6A4A22',
|
|
172
|
+
Credit: '#B48A48',
|
|
173
|
+
Retainer: '#C29A55',
|
|
174
|
+
Sale: '#8E5E2A',
|
|
175
|
+
Valuation: '#A06A34',
|
|
176
|
+
Order: '#B87C3E',
|
|
177
|
+
DiningOrder: '#C9954E',
|
|
178
|
+
|
|
179
|
+
// Documents / content (steel-blue, hue-adjacent to the business slates).
|
|
180
|
+
Content: '#58708C',
|
|
181
|
+
Report: '#6D8299',
|
|
182
|
+
Page: '#849AAF',
|
|
183
|
+
Post: '#93A7BA',
|
|
184
|
+
VariationNote: '#47617B',
|
|
185
|
+
FileArtifact: '#A9BBCC',
|
|
186
|
+
|
|
187
|
+
// Marketing (bright teal-green, apart from workflow and research teals).
|
|
188
|
+
SocialPost: '#2FA69A',
|
|
189
|
+
Campaign: '#3FB8A0',
|
|
190
|
+
BrandDeal: '#57C2AE',
|
|
191
|
+
Recommendation: '#74CDBB',
|
|
192
|
+
|
|
193
|
+
// CRM people (terracotta, beside Person and Customer).
|
|
194
|
+
Contact: '#C97E52',
|
|
195
|
+
Lead: '#A85E38',
|
|
196
|
+
Position: '#96522E',
|
|
197
|
+
Audience: '#E0B088',
|
|
198
|
+
|
|
199
|
+
// Places / transport / retail (forest-emerald, apart from knowledge moss).
|
|
200
|
+
PostalAddress: '#2E8B57',
|
|
201
|
+
Room: '#3A9B63',
|
|
202
|
+
StoreLocation: '#46A96F',
|
|
203
|
+
Vehicle: '#54B77B',
|
|
204
|
+
Route: '#62C187',
|
|
205
|
+
Stop: '#2A7A4C',
|
|
206
|
+
Shipment: '#6FCB93',
|
|
207
|
+
Reservation: '#7ED4A0',
|
|
208
|
+
TableReservation: '#8CDBAC',
|
|
209
|
+
Menu: '#1F6B41',
|
|
210
|
+
MenuItem: '#98E0B6',
|
|
211
|
+
Product: '#34925E',
|
|
212
|
+
StockMovement: '#4CA574',
|
|
213
|
+
|
|
214
|
+
// Work / delivery (indigo, apart from the strategy indigo band).
|
|
215
|
+
Milestone: '#4A5FA8',
|
|
216
|
+
Deliverable: '#6274C0',
|
|
217
|
+
TimeEntry: '#8189CE',
|
|
218
|
+
Engagement: '#9AA0DA',
|
|
219
|
+
Case: '#3B4E92',
|
|
220
|
+
Meeting: '#5566B4',
|
|
221
|
+
|
|
222
|
+
// Idea (amber).
|
|
223
|
+
Idea: '#E0A82E',
|
|
224
|
+
|
|
225
|
+
// Web analytics (sky-cyan, apart from the research teal).
|
|
226
|
+
Session: '#2AA7C4',
|
|
227
|
+
PageView: '#3DB4CE',
|
|
228
|
+
Click: '#55C0D6',
|
|
229
|
+
ScrollMilestone: '#70CCDE',
|
|
230
|
+
TimelineEvent: '#1E93B0',
|
|
231
|
+
AnonVisitor: '#88D6E6',
|
|
232
|
+
AEOAudit: '#46B0CB',
|
|
233
|
+
|
|
234
|
+
// WhatsApp transport (brand green).
|
|
235
|
+
WhatsAppConversation: '#128C7E',
|
|
236
|
+
WhatsAppMessage: '#1FA894',
|
|
237
|
+
|
|
238
|
+
// Cloudflare / chain infra (grey-blue).
|
|
239
|
+
CloudflareHostname: '#5B6E82',
|
|
240
|
+
CloudflareTunnel: '#6E8296',
|
|
241
|
+
Chain: '#47586A',
|
|
242
|
+
ChainLink: '#8496AA',
|
|
243
|
+
|
|
244
|
+
// Voice (violet).
|
|
245
|
+
VoiceProfile: '#9B59B6',
|
|
246
|
+
VoiceEdit: '#B07CC9',
|
|
159
247
|
}
|
|
160
248
|
|
|
161
249
|
export const FALLBACK_LABEL_COLOUR = '#94A3B8'
|
|
@@ -251,6 +339,18 @@ export function shapeForLabel(label: string): GraphNodeShape {
|
|
|
251
339
|
return SHAPE_BY_LABEL[label] ?? FALLBACK_LABEL_SHAPE
|
|
252
340
|
}
|
|
253
341
|
|
|
342
|
+
/**
|
|
343
|
+
* Node labels written by code with no schema node-type-table row and no
|
|
344
|
+
* typed-edge declaration. They still render as graph nodes, so they must carry
|
|
345
|
+
* a colour + glyph like any other node type. The reconciliation gate in
|
|
346
|
+
* __tests__/icons.test.ts folds this set into the node-label universe. Add a
|
|
347
|
+
* label here when the runtime `op=icon-fallback` census names one that no
|
|
348
|
+
* schema table or typed edge declares.
|
|
349
|
+
*/
|
|
350
|
+
export const CODE_EMITTED_NODE_LABELS: ReadonlySet<string> = Object.freeze(
|
|
351
|
+
new Set(['FileArtifact']),
|
|
352
|
+
) as ReadonlySet<string>
|
|
353
|
+
|
|
254
354
|
// ---------------------------------------------------------------------------
|
|
255
355
|
// Icon registry — a third visual channel alongside colour + shape.
|
|
256
356
|
//
|
|
@@ -325,6 +425,67 @@ const LABEL_ICONS: Record<string, string> = {
|
|
|
325
425
|
Finding: '<path d="M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5"></path><path d="M9 18h6"></path><path d="M10 22h4"></path>',
|
|
326
426
|
Hypothesis: '<path d="M14 2v6a2 2 0 0 0 .245.96l5.51 10.08A2 2 0 0 1 18 22H6a2 2 0 0 1-1.755-2.96l5.51-10.08A2 2 0 0 0 10 8V2"></path><path d="M6.453 15h11.094"></path><path d="M8.5 2h7"></path>',
|
|
327
427
|
CashEntry: '<rect width="20" height="12" x="2" y="6" rx="2"></rect><circle cx="12" cy="12" r="2"></circle><path d="M6 12h.01"></path><path d="M18 12h.01"></path>',
|
|
428
|
+
// --- Task 1965: glyphs for the 60 previously-uncovered node labels ---
|
|
429
|
+
InvoiceLine: '<path d="M13 16H8" /><path d="M14 8H8" /><path d="M16 12H8" /><path d="M4 3a1 1 0 0 1 1-1 1.3 1.3 0 0 1 .7.2l.933.6a1.3 1.3 0 0 0 1.4 0l.934-.6a1.3 1.3 0 0 1 1.4 0l.933.6a1.3 1.3 0 0 0 1.4 0l.933-.6a1.3 1.3 0 0 1 1.4 0l.934.6a1.3 1.3 0 0 0 1.4 0l.933-.6A1.3 1.3 0 0 1 19 2a1 1 0 0 1 1 1v18a1 1 0 0 1-1 1 1.3 1.3 0 0 1-.7-.2l-.933-.6a1.3 1.3 0 0 0-1.4 0l-.934.6a1.3 1.3 0 0 1-1.4 0l-.933-.6a1.3 1.3 0 0 0-1.4 0l-.933.6a1.3 1.3 0 0 1-1.4 0l-.934-.6a1.3 1.3 0 0 0-1.4 0l-.933.6a1.3 1.3 0 0 1-.7.2 1 1 0 0 1-1-1z" />',
|
|
430
|
+
InvoicePayment: '<path d="M11 15h2a2 2 0 1 0 0-4h-3c-.6 0-1.1.2-1.4.6L3 17" /><path d="m7 21 1.6-1.4c.3-.4.8-.6 1.4-.6h4c1.1 0 2.1-.4 2.8-1.2l4.6-4.4a2 2 0 0 0-2.75-2.91l-4.2 3.9" /><path d="m2 16 6 6" /><circle cx="16" cy="9" r="2.9" /><circle cx="6" cy="5" r="3" />',
|
|
431
|
+
QuoteLine: '<path d="M3 5h.01" /><path d="M3 12h.01" /><path d="M3 19h.01" /><path d="M8 5h13" /><path d="M8 12h13" /><path d="M8 19h13" />',
|
|
432
|
+
PurchaseOrderLine: '<path d="M11 5h10" /><path d="M11 12h10" /><path d="M11 19h10" /><path d="M4 4h1v5" /><path d="M4 9h2" /><path d="M6.5 20H3.4c0-1 2.6-1.925 2.6-3.5a1.5 1.5 0 0 0-2.6-1.02" />',
|
|
433
|
+
JobCost: '<rect width="20" height="12" x="2" y="6" rx="2" /><circle cx="12" cy="12" r="2" /><path d="M6 12h.01M18 12h.01" />',
|
|
434
|
+
Credit: '<path d="M3.85 8.62a4 4 0 0 1 4.78-4.77 4 4 0 0 1 6.74 0 4 4 0 0 1 4.78 4.78 4 4 0 0 1 0 6.74 4 4 0 0 1-4.77 4.78 4 4 0 0 1-6.75 0 4 4 0 0 1-4.78-4.77 4 4 0 0 1 0-6.76Z" /><path d="M16 8h-6a2 2 0 1 0 0 4h4a2 2 0 1 1 0 4H8" /><path d="M12 18V6" />',
|
|
435
|
+
Retainer: '<path d="M19 7V4a1 1 0 0 0-1-1H5a2 2 0 0 0 0 4h15a1 1 0 0 1 1 1v4h-3a2 2 0 0 0 0 4h3a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1" /><path d="M3 5v14a2 2 0 0 0 2 2h15a1 1 0 0 0 1-1v-4" />',
|
|
436
|
+
Sale: '<path d="M12 17V7" /><path d="M16 8h-6a2 2 0 0 0 0 4h4a2 2 0 0 1 0 4H8" /><path d="M4 3a1 1 0 0 1 1-1 1.3 1.3 0 0 1 .7.2l.933.6a1.3 1.3 0 0 0 1.4 0l.934-.6a1.3 1.3 0 0 1 1.4 0l.933.6a1.3 1.3 0 0 0 1.4 0l.933-.6a1.3 1.3 0 0 1 1.4 0l.934.6a1.3 1.3 0 0 0 1.4 0l.933-.6A1.3 1.3 0 0 1 19 2a1 1 0 0 1 1 1v18a1 1 0 0 1-1 1 1.3 1.3 0 0 1-.7-.2l-.933-.6a1.3 1.3 0 0 0-1.4 0l-.934.6a1.3 1.3 0 0 1-1.4 0l-.933-.6a1.3 1.3 0 0 0-1.4 0l-.933.6a1.3 1.3 0 0 1-1.4 0l-.934-.6a1.3 1.3 0 0 0-1.4 0l-.933.6a1.3 1.3 0 0 1-.7.2 1 1 0 0 1-1-1z" />',
|
|
437
|
+
Valuation: '<path d="M12 3v18" /><path d="m19 8 3 8a5 5 0 0 1-6 0zV7" /><path d="M3 7h1a17 17 0 0 0 8-2 17 17 0 0 0 8 2h1" /><path d="m5 8 3 8a5 5 0 0 1-6 0zV7" /><path d="M7 21h10" />',
|
|
438
|
+
Order: '<path d="M16 10a4 4 0 0 1-8 0" /><path d="M3.103 6.034h17.794" /><path d="M3.4 5.467a2 2 0 0 0-.4 1.2V20a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6.667a2 2 0 0 0-.4-1.2l-2-2.667A2 2 0 0 0 17 2H7a2 2 0 0 0-1.6.8z" />',
|
|
439
|
+
DiningOrder: '<path d="M3 2v7c0 1.1.9 2 2 2h4a2 2 0 0 0 2-2V2" /><path d="M7 2v20" /><path d="M21 15V2a5 5 0 0 0-5 5v6c0 1.1.9 2 2 2h3Zm0 0v7" />',
|
|
440
|
+
Content: '<path d="M15 18h-5" /><path d="M18 14h-8" /><path d="M4 22h16a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2H8a2 2 0 0 0-2 2v16a2 2 0 0 1-4 0v-9a2 2 0 0 1 2-2h2" /><rect width="8" height="4" x="10" y="6" rx="1" />',
|
|
441
|
+
Report: '<rect width="8" height="4" x="8" y="2" rx="1" ry="1" /><path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2" /><path d="M12 11h4" /><path d="M12 16h4" /><path d="M8 11h.01" /><path d="M8 16h.01" />',
|
|
442
|
+
Page: '<path d="M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z" /><path d="M14 2v5a1 1 0 0 0 1 1h5" />',
|
|
443
|
+
Post: '<path d="M12 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7" /><path d="M18.375 2.625a1 1 0 0 1 3 3l-9.013 9.014a2 2 0 0 1-.853.505l-2.873.84a.5.5 0 0 1-.62-.62l.84-2.873a2 2 0 0 1 .506-.852z" />',
|
|
444
|
+
SocialPost: '<path d="M11 6a13 13 0 0 0 8.4-2.8A1 1 0 0 1 21 4v12a1 1 0 0 1-1.6.8A13 13 0 0 0 11 14H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2z" /><path d="M6 14a12 12 0 0 0 2.4 7.2 2 2 0 0 0 3.2-2.4A8 8 0 0 1 10 14" /><path d="M8 6v8" />',
|
|
445
|
+
VariationNote: '<path d="M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z" /><path d="M9 10h6" /><path d="M12 13V7" /><path d="M9 17h6" />',
|
|
446
|
+
Contact: '<path d="M16 2v2" /><path d="M17.915 22a6 6 0 0 0-12 0" /><path d="M8 2v2" /><circle cx="12" cy="12" r="4" /><rect x="3" y="4" width="18" height="18" rx="2" />',
|
|
447
|
+
Lead: '<path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2" /><circle cx="9" cy="7" r="4" /><line x1="19" x2="19" y1="8" y2="14" /><line x1="22" x2="16" y1="11" y2="11" />',
|
|
448
|
+
Position: '<path d="M16 20V4a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v16" /><rect width="20" height="14" x="2" y="6" rx="2" />',
|
|
449
|
+
Audience: '<path d="M18 21a8 8 0 0 0-16 0" /><circle cx="10" cy="8" r="5" /><path d="M22 20c0-3.37-2-6.5-4-8a5 5 0 0 0-.45-8.3" />',
|
|
450
|
+
PostalAddress: '<path d="M18 8c0 3.613-3.869 7.429-5.393 8.795a1 1 0 0 1-1.214 0C9.87 15.429 6 11.613 6 8a6 6 0 0 1 12 0" /><circle cx="12" cy="8" r="2" /><path d="M8.714 14h-3.71a1 1 0 0 0-.948.683l-2.004 6A1 1 0 0 0 3 22h18a1 1 0 0 0 .948-1.316l-2-6a1 1 0 0 0-.949-.684h-3.712" />',
|
|
451
|
+
Room: '<path d="M11 20H2" /><path d="M11 4.562v16.157a1 1 0 0 0 1.242.97L19 20V5.562a2 2 0 0 0-1.515-1.94l-4-1A2 2 0 0 0 11 4.561z" /><path d="M11 4H8a2 2 0 0 0-2 2v14" /><path d="M14 12h.01" /><path d="M22 20h-3" />',
|
|
452
|
+
StoreLocation: '<path d="M15 21v-5a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v5" /><path d="M17.774 10.31a1.12 1.12 0 0 0-1.549 0 2.5 2.5 0 0 1-3.451 0 1.12 1.12 0 0 0-1.548 0 2.5 2.5 0 0 1-3.452 0 1.12 1.12 0 0 0-1.549 0 2.5 2.5 0 0 1-3.77-3.248l2.889-4.184A2 2 0 0 1 7 2h10a2 2 0 0 1 1.653.873l2.895 4.192a2.5 2.5 0 0 1-3.774 3.244" /><path d="M4 10.95V19a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8.05" />',
|
|
453
|
+
Vehicle: '<path d="M19 17h2c.6 0 1-.4 1-1v-3c0-.9-.7-1.7-1.5-1.9C18.7 10.6 16 10 16 10s-1.3-1.4-2.2-2.3c-.5-.4-1.1-.7-1.8-.7H5c-.6 0-1.1.4-1.4.9l-1.4 2.9A3.7 3.7 0 0 0 2 12v4c0 .6.4 1 1 1h2" /><circle cx="7" cy="17" r="2" /><path d="M9 17h6" /><circle cx="17" cy="17" r="2" />',
|
|
454
|
+
Route: '<circle cx="6" cy="19" r="3" /><path d="M9 19h8.5a3.5 3.5 0 0 0 0-7h-11a3.5 3.5 0 0 1 0-7H15" /><circle cx="18" cy="5" r="3" />',
|
|
455
|
+
Stop: '<path d="M20 10c0 4.993-5.539 10.193-7.399 11.799a1 1 0 0 1-1.202 0C9.539 20.193 4 14.993 4 10a8 8 0 0 1 16 0" /><circle cx="12" cy="10" r="3" />',
|
|
456
|
+
Shipment: '<path d="M11 21.73a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73z" /><path d="M12 22V12" /><polyline points="3.29 7 12 12 20.71 7" /><path d="m7.5 4.27 9 5.15" />',
|
|
457
|
+
Reservation: '<path d="M8 2v4" /><path d="M16 2v4" /><rect width="18" height="18" x="3" y="4" rx="2" /><path d="M3 10h18" /><path d="m9 16 2 2 4-4" />',
|
|
458
|
+
TableReservation: '<path d="m16 2-2.3 2.3a3 3 0 0 0 0 4.2l1.8 1.8a3 3 0 0 0 4.2 0L22 8" /><path d="M15 15 3.3 3.3a4.2 4.2 0 0 0 0 6l7.3 7.3c.7.7 2 .7 2.8 0L15 15Zm0 0 7 7" /><path d="m2.1 21.8 6.4-6.3" /><path d="m19 5-7 7" />',
|
|
459
|
+
Menu: '<path d="M12 5v16" /><path d="M20.001 19A2 2 0 0022 17V5a2 2 0 00-1.999-2L16 3.002A5 5 0 0012 5a5 5 0 00-4-2H4a2 2 0 00-2 2v12a2 2 0 001.999 2H8a5 5 0 014 2 5 5 0 014-2z" />',
|
|
460
|
+
MenuItem: '<path d="M7 21h10" /><path d="M12 21a9 9 0 0 0 9-9H3a9 9 0 0 0 9 9Z" /><path d="M11.38 12a2.4 2.4 0 0 1-.4-4.77 2.4 2.4 0 0 1 3.2-2.77 2.4 2.4 0 0 1 3.47-.63 2.4 2.4 0 0 1 3.37 3.37 2.4 2.4 0 0 1-1.1 3.7 2.51 2.51 0 0 1 .03 1.1" /><path d="m13 12 4-4" /><path d="M10.9 7.25A3.99 3.99 0 0 0 4 10c0 .73.2 1.41.54 2" />',
|
|
461
|
+
Product: '<path d="M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z" /><path d="m3.3 7 8.7 5 8.7-5" /><path d="M12 22V12" />',
|
|
462
|
+
StockMovement: '<path d="m16 3 4 4-4 4" /><path d="M20 7H4" /><path d="m8 21-4-4 4-4" /><path d="M4 17h16" />',
|
|
463
|
+
Milestone: '<path d="M4 22V4a1 1 0 0 1 .4-.8A6 6 0 0 1 8 2c3 0 5 2 7.333 2q2 0 3.067-.8A1 1 0 0 1 20 4v10a1 1 0 0 1-.4.8A6 6 0 0 1 16 16c-3 0-5-2-8-2a6 6 0 0 0-4 1.528" />',
|
|
464
|
+
Deliverable: '<path d="M12 22V12" /><path d="m16 17 2 2 4-4" /><path d="M21 11.127V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.729l7 4a2 2 0 0 0 2 .001l1.32-.753" /><path d="M3.29 7 12 12l8.71-5" /><path d="m7.5 4.27 8.997 5.148" />',
|
|
465
|
+
TimeEntry: '<line x1="10" x2="14" y1="2" y2="2" /><line x1="12" x2="15" y1="14" y2="11" /><circle cx="12" cy="14" r="8" />',
|
|
466
|
+
Engagement: '<path d="m11 17 2 2a1 1 0 1 0 3-3" /><path d="m14 14 2.5 2.5a1 1 0 1 0 3-3l-3.88-3.88a3 3 0 0 0-4.24 0l-.88.88a1 1 0 1 1-3-3l2.81-2.81a5.79 5.79 0 0 1 7.06-.87l.47.28a2 2 0 0 0 1.42.25L21 4" /><path d="m21 3 1 11h-2" /><path d="M3 3 2 14l6.5 6.5a1 1 0 1 0 3-3" /><path d="M3 4h8" />',
|
|
467
|
+
Case: '<path d="M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z" />',
|
|
468
|
+
Meeting: '<path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2" /><path d="M16 3.128a4 4 0 0 1 0 7.744" /><path d="M22 21v-2a4 4 0 0 0-3-3.87" /><circle cx="9" cy="7" r="4" />',
|
|
469
|
+
Idea: '<path d="M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5" /><path d="M9 18h6" /><path d="M10 22h4" />',
|
|
470
|
+
Campaign: '<path d="M12 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5" /><path d="M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91-.09" /><path d="M9 12a22 22 0 0 1 2-3.95A12.88 12.88 0 0 1 22 2c0 2.72-.78 7.5-6 11a22.4 22.4 0 0 1-4 2z" /><path d="M9 12H4s.55-3.03 2-4c1.62-1.08 5 .05 5 .05" />',
|
|
471
|
+
BrandDeal: '<path d="M3.85 8.62a4 4 0 0 1 4.78-4.77 4 4 0 0 1 6.74 0 4 4 0 0 1 4.78 4.78 4 4 0 0 1 0 6.74 4 4 0 0 1-4.77 4.78 4 4 0 0 1-6.75 0 4 4 0 0 1-4.78-4.77 4 4 0 0 1 0-6.76Z" /><path d="m9 12 2 2 4-4" />',
|
|
472
|
+
Recommendation: '<path d="M15 5.88 14 10h5.83a2 2 0 0 1 1.92 2.56l-2.33 8A2 2 0 0 1 17.5 22H4a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h2.76a2 2 0 0 0 1.79-1.11L12 2a3.13 3.13 0 0 1 3 3.88Z" /><path d="M7 10v12" />',
|
|
473
|
+
Session: '<rect width="20" height="14" x="2" y="3" rx="2" /><line x1="8" x2="16" y1="21" y2="21" /><line x1="12" x2="12" y1="17" y2="21" />',
|
|
474
|
+
PageView: '<path d="M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0" /><circle cx="12" cy="12" r="3" />',
|
|
475
|
+
Click: '<path d="M14 4.1 12 6" /><path d="m5.1 8-2.9-.8" /><path d="m6 12-1.9 2" /><path d="M7.2 2.2 8 5.1" /><path d="M9.037 9.69a.498.498 0 0 1 .653-.653l11 4.5a.5.5 0 0 1-.074.949l-4.349 1.041a1 1 0 0 0-.74.739l-1.04 4.35a.5.5 0 0 1-.95.074z" />',
|
|
476
|
+
ScrollMilestone: '<path d="m7 6 5 5 5-5" /><path d="m7 13 5 5 5-5" />',
|
|
477
|
+
TimelineEvent: '<path d="M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8" /><path d="M3 3v5h5" /><path d="M12 7v5l4 2" />',
|
|
478
|
+
AnonVisitor: '<path d="M9 10h.01" /><path d="M15 10h.01" /><path d="M12 2a8 8 0 0 0-8 8v12l3-3 2.5 2.5L12 19l2.5 2.5L17 19l3 3V10a8 8 0 0 0-8-8z" />',
|
|
479
|
+
AEOAudit: '<path d="m8 11 2 2 4-4" /><circle cx="11" cy="11" r="8" /><path d="m21 21-4.3-4.3" />',
|
|
480
|
+
WhatsAppConversation: '<path d="M2.992 16.342a2 2 0 0 1 .094 1.167l-1.065 3.29a1 1 0 0 0 1.236 1.168l3.413-.998a2 2 0 0 1 1.099.092 10 10 0 1 0-4.777-4.719" />',
|
|
481
|
+
WhatsAppMessage: '<path d="M22 17a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 21.286V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2z" /><path d="M7 11h10" /><path d="M7 15h6" /><path d="M7 7h8" />',
|
|
482
|
+
CloudflareHostname: '<circle cx="12" cy="12" r="10" /><path d="M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20" /><path d="M2 12h20" />',
|
|
483
|
+
CloudflareTunnel: '<rect x="16" y="16" width="6" height="6" rx="1" /><rect x="2" y="16" width="6" height="6" rx="1" /><rect x="9" y="2" width="6" height="6" rx="1" /><path d="M5 16v-3a1 1 0 0 1 1-1h12a1 1 0 0 1 1 1v3" /><path d="M12 12V8" />',
|
|
484
|
+
Chain: '<path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71" /><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71" />',
|
|
485
|
+
ChainLink: '<path d="M9 17H7A5 5 0 0 1 7 7h2" /><path d="M15 7h2a5 5 0 1 1 0 10h-2" /><line x1="8" x2="16" y1="12" y2="12" />',
|
|
486
|
+
FileArtifact: '<path d="M13.659 22H18a2 2 0 0 0 2-2V8a2.4 2.4 0 0 0-.706-1.706l-3.588-3.588A2.4 2.4 0 0 0 14 2H6a2 2 0 0 0-2 2v11.5" /><path d="M14 2v5a1 1 0 0 0 1 1h5" /><path d="M8 12v-1" /><path d="M8 18v-2" /><path d="M8 7V6" /><circle cx="8" cy="20" r="2" />',
|
|
487
|
+
VoiceProfile: '<path d="M12 19v3" /><path d="M19 10v2a7 7 0 0 1-14 0v-2" /><rect x="9" y="2" width="6" height="13" rx="3" />',
|
|
488
|
+
VoiceEdit: '<path d="M2 10v3" /><path d="M6 6v11" /><path d="M10 3v18" /><path d="M14 8v7" /><path d="M18 5v13" /><path d="M22 10v3" />',
|
|
328
489
|
}
|
|
329
490
|
|
|
330
491
|
/**
|
|
@@ -184,6 +184,7 @@ Tools are available via the `admin` MCP server.
|
|
|
184
184
|
| Investigate a bug or unexpected behaviour | User asks to debug, fix a bug, find the root cause, or investigate an error | `skills/investigate/SKILL.md` |
|
|
185
185
|
| Capture work as a task before implementing | User asks to "task it", create a task, or describes work that should be a task file before a sprint | `skills/task/SKILL.md` |
|
|
186
186
|
| Run an insight pass on this session | Operator asks to run an insight pass, review this session, capture what we learned, or do a retrospective on the conversation | `skills/insight/SKILL.md` |
|
|
187
|
+
| Summarise the last turn | User asks to summarise, recap, or give the "in short" version of what the agent just said or asked | `skills/summarise/SKILL.md` |
|
|
187
188
|
|
|
188
189
|
## Hooks
|
|
189
190
|
|
|
@@ -28,6 +28,21 @@ Load `references/agent-pattern.md`. It is the canonical shape: the two kinds of
|
|
|
28
28
|
deny-by-default tool rule, model-choice guidance, and the three-part contract body. Use it
|
|
29
29
|
throughout. Do not paraphrase the pattern from memory; the reference is the source.
|
|
30
30
|
|
|
31
|
+
## Step 0: Check for a deliverable catalogue
|
|
32
|
+
|
|
33
|
+
When the operator asks what can be built here, rather than naming a specific agent, first look for
|
|
34
|
+
a shipped suggestion catalogue. A premium bundle can ship a `DELIVERABLES.md` at its root listing
|
|
35
|
+
deliverables it supports beyond the agents it already ships. Get the enabled bundles from
|
|
36
|
+
`capabilities-here`, then for each one read `$PLATFORM_ROOT/../premium-plugins/<bundle>/DELIVERABLES.md`
|
|
37
|
+
if it exists, the bundle root where its `BUNDLE.md` and `agents/` live. Offer the operator the entries you find, grouped by bundle. If
|
|
38
|
+
no enabled bundle ships one, skip this step and go to Step 1.
|
|
39
|
+
|
|
40
|
+
The catalogue is a suggestion list, not a shipped roster. Each entry is authored bespoke for this
|
|
41
|
+
account when the operator picks it, because a generic version carries none of the customer's own
|
|
42
|
+
determinism. On a pick, run Steps 1 through 7 to author the skill and agent into the account's own
|
|
43
|
+
plugins tree, and name the agent for the customer's actual deliverable rather than the catalogue's
|
|
44
|
+
ontology label, exactly as the catalogue instructs. The ontology name is grounding, not a file name.
|
|
45
|
+
|
|
31
46
|
## Step 1: Name the deliverable
|
|
32
47
|
|
|
33
48
|
Ask: **"What is the one thing this agent hands back?"**
|
|
@@ -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:f78dfe81d9832fd7197627e1cf770c730bb2d16b4b640f1a47558e86acfe0db8
|
|
5
5
|
brand: maxy-code
|
|
6
6
|
product-name: Maxy
|
|
7
7
|
---
|
|
@@ -3045,6 +3045,37 @@ routines exist for the account is the account-scope-miss signature; the logged
|
|
|
3045
3045
|
`cron=` on `outcome=ok` confirms the persisted expression without opening the
|
|
3046
3046
|
graph.
|
|
3047
3047
|
|
|
3048
|
+
### Skills
|
|
3049
|
+
|
|
3050
|
+
The Skills surface (`/skills`) is the admin view of the account's operator-
|
|
3051
|
+
authored skills — the `SKILL.md` files the store-skill tool writes under
|
|
3052
|
+
`<accountDir>/plugins/<plugin>/skills/<skill>/` (the durable per-account plugin
|
|
3053
|
+
root, never the immutable `PLATFORM_ROOT/plugins` tree). It renders one card per
|
|
3054
|
+
skill (name, owning plugin, frontmatter description, reference count); a card
|
|
3055
|
+
opens a **read-only** detail modal showing the frontmatter, the SKILL.md body,
|
|
3056
|
+
and the reference filenames. The page is read-only by design — skills are
|
|
3057
|
+
authored and edited through the chat interface — with one exception: a **delete**
|
|
3058
|
+
behind an explicit confirm step in the modal. A confirmed delete removes the
|
|
3059
|
+
skill directory, and the whole plugin directory when that was its last skill.
|
|
3060
|
+
|
|
3061
|
+
The route (`server/routes/admin/skills.ts`) walks only the account tree, so
|
|
3062
|
+
shipped platform skills never appear. Plugin and skill path params are kebab-case
|
|
3063
|
+
validated (`/^[a-z0-9][a-z0-9-]*$/`) — the traversal guard; anything else 400s.
|
|
3064
|
+
|
|
3065
|
+
| Route | Behaviour |
|
|
3066
|
+
|-------|-----------|
|
|
3067
|
+
| `GET /api/admin/skills` | Enumerates `plugins/*/skills/*/SKILL.md`, returns `{plugin, skill, description, refCount}` per skill, sorted plugin then skill. A per-entry read error logs `op=list-skip` rather than silently shortening the list. |
|
|
3068
|
+
| `GET /api/admin/skills/:plugin/:skill` | One skill's parsed frontmatter (`name`, `description`, `publicEmbed`), the SKILL.md body, and the reference filenames. Unknown skill 404s. |
|
|
3069
|
+
| `DELETE /api/admin/skills/:plugin/:skill` | Removes the skill dir; removes the plugin dir when its `skills/` empties. Returns `{ok, skillDirGone, pluginDirRemoved}` measured after the rm. |
|
|
3070
|
+
|
|
3071
|
+
Observability rides `[admin:skills]`: `op=list accountId=<8> plugins=<n>
|
|
3072
|
+
skills=<n>` (the surface's own heartbeat — `skills=0` against a populated
|
|
3073
|
+
`plugins/*/skills/` is the broken-walk signature), `op=get plugin=<…> skill=<…>
|
|
3074
|
+
found=<bool>`, and `op=delete plugin=<…> skill=<…> outcome=ok
|
|
3075
|
+
skillDirGone=<bool> pluginDirRemoved=<bool>` (`skillDirGone=false` with
|
|
3076
|
+
`outcome=ok` is a named failure) / `outcome=rejected reason=<invalid-name|
|
|
3077
|
+
not-found|rm-error>`.
|
|
3078
|
+
|
|
3048
3079
|
### Graph
|
|
3049
3080
|
|
|
3050
3081
|
| Mount | Purpose |
|
|
@@ -3056,6 +3087,25 @@ graph.
|
|
|
3056
3087
|
| `/graph-labels-in-graph` | Distinct label list for the filter dropdown. |
|
|
3057
3088
|
| `/graph-default-view` | Account-scoped saved view (zoom, focal id, filters). |
|
|
3058
3089
|
|
|
3090
|
+
**Node visual encoding.** Every node type that can appear on the canvas renders
|
|
3091
|
+
a coloured disc with a white Lucide glyph, sized by incident-edge count, with a
|
|
3092
|
+
matching legend swatch. Colour, shape, and glyph are three per-label registries
|
|
3093
|
+
in `platform/lib/graph-style/src/index.ts`. Coverage is reconciled against the
|
|
3094
|
+
true node-label universe, not the colour registry itself: the standing test
|
|
3095
|
+
`__tests__/icons.test.ts` assembles the universe from the `Neo4j Label` column
|
|
3096
|
+
of every `schema-*.md` node-type table, the `sourceLabel`/`targetLabel` set in
|
|
3097
|
+
`typed-edge-schema.ts`, and the `CODE_EMITTED_NODE_LABELS` list, then fails the
|
|
3098
|
+
build if any member lacks a colour or glyph. Labels that only ever stack on a
|
|
3099
|
+
base node (`ADDITIONAL_BASE_LABELS`) inherit the base node's colour and are
|
|
3100
|
+
excluded. A node type carries a coloured glyph even when its text caption is its
|
|
3101
|
+
bare type: the glyph and the caption are independent channels (caption coverage
|
|
3102
|
+
is the separate `caption-coverage.test.ts` gate). At runtime, a per-session
|
|
3103
|
+
`op=icon-fallback` census (emitted from `app/graph/page.tsx` across the initial
|
|
3104
|
+
render and every live-update poll) names any label that reached the canvas with
|
|
3105
|
+
no glyph; an empty census is the healthy signal, a non-empty one means a
|
|
3106
|
+
code-emitted label that no static source declares and should be added to
|
|
3107
|
+
`CODE_EMITTED_NODE_LABELS`.
|
|
3108
|
+
|
|
3059
3109
|
### Artefacts and files
|
|
3060
3110
|
|
|
3061
3111
|
| Mount | Purpose |
|
|
@@ -4304,7 +4354,7 @@ Standing rules the operator gives over a channel are `Preference` nodes. Two mec
|
|
|
4304
4354
|
|
|
4305
4355
|
**Observability.** `[preference-write] op=reconcile … mode=<reinforce|update|contradict|new> similarity=…` — a stream of `mode=new` for subjects that already exist is the duplicate-minting signature. `[preference-inject] op=inject channel=<wa|tg|web> injected=<N> owner=<8> source=<owner|no-owner|owner-error|fetch-error>` — injection selects only the account owner's admin preferences, so `source=owner injected=0` is a genuinely empty owner, `source=no-owner` is an account with no seeded owner (injects nothing, a missed owner seeding), and `injected=0 source=owner` on an account whose owner holds rules is the write-only regression re-appearing. `[preference-inject] op=reconcile accountId=… stored=… injected=…` — the standing reconciliation audit (claude-session-manager, 5-minute tick) flags any account whose stored active count diverges from what injection surfaces; injection now surfaces every stored active preference verbatim, so `stored == injected` is the healthy signal and any gap is a dropped-row regression (a reintroduced cap, filter, or truncation). A clean pass logs `op=reconcile drifted=0`, the no-event detector.
|
|
4306
4356
|
|
|
4307
|
-
**Consult-before-send gate.** Injection (above) puts the owner's active rules in front of every channel turn, but the growing layer-2 `Preference` set is read on demand with `profile-read`, a per-turn judgement the agent can skip, the miss that dropped a customer signature on a delivered document. `hooks/preference-consult-gate.sh` (admin plugin) is the deliverable-boundary enforcement: a PreToolUse gate on customer-facing document deliverables (`browser-pdf-save`/`SendUserFile` to `memory/users/<phone>/documents/`, and email/Outlook sends carrying attachments) that blocks (exit 2) when no `profile-read` ran after the last user message in the transcript. It fires on documents only, never on casual replies. **Observability:** `[preference-gate] op=allow tool=<name> consulted=true` on an allowed document deliverable, `op=bypass tool=<name> detail=no profile-read this turn` on a block; a stream of `op=bypass` is the un-consulted-send signature. The advisory companion `hooks/preference-consult-directive.sh` injects the two-layer architecture reminder every turn (`[pref-wrapper] op=inject`). The placement half, promoting finished deliverables out of `output/` scratch, is counted by the `data-manager` reconcile audit (`scratch-refs`, `stranded`); making that audit run on a standing periodic cadence is a filed follow-up.
|
|
4357
|
+
**Consult-before-send gate.** Injection (above) puts the owner's active rules in front of every channel turn, but the growing layer-2 `Preference` set is read on demand with `profile-read`, a per-turn judgement the agent can skip, the miss that dropped a customer signature on a delivered document. `hooks/preference-consult-gate.sh` (admin plugin) is the deliverable-boundary enforcement: a PreToolUse gate on customer-facing document deliverables (`browser-pdf-save`/`SendUserFile` to `memory/users/<phone>/documents/`, and email/Outlook sends carrying attachments) that blocks (exit 2) when no `profile-read` ran after the last user message in the transcript. It fires on documents only, never on casual replies. **Observability:** `[preference-gate] op=allow tool=<name> consulted=true` on an allowed document deliverable, `op=bypass tool=<name> detail=no profile-read this turn` on a block; a stream of `op=bypass` is the un-consulted-send signature. The advisory companion `hooks/preference-consult-directive.sh` injects the two-layer architecture reminder every turn (`[pref-wrapper] op=inject`). The placement half, promoting finished deliverables out of `output/` scratch, is counted by the `data-manager` reconcile audit (`scratch-refs`, `stranded`); making that audit run on a standing periodic cadence is a filed follow-up. The inbound mirror is the `uploads/` intake inbox: an uploaded file lands at `uploads/<attachmentId>/` and is promoted to its canonical entity bucket when its graph node is created, so a persisted node reference resolving into `uploads/` is intake drift, counted by the same reconcile audit as `stranded-intake`. Unlike `output/`, `uploads/` is never rebuilt by a tool, so the `data-manager` may promote a file out of it. Beyond placement and intake, the same audit counts intra-folder sprawl inside each operator-data entity folder from disk structure alone: superseded version copies (`<base>.ext` and `<base>-vN.ext` are one deliverable, all but the newest counted `versioned`), format twins (a source `.html`/`.md` render kept beside its delivered `.pdf` of the same basename, counted `format-twins`), and subfolders nested under `projects/<name>/` or `contacts/<name>/` that the flat rule forbids (counted `stray-subdir`). These are read-only counts; removal or flattening happens only on a `data-manager` stewardship dispatch, each paired with a `database-operator` reference update. The reconcile output contract is `unreachable=N broken-refs=M scratch-refs=P stranded=Q stranded-intake=R versioned=S format-twins=T stray-subdir=U`.
|
|
4308
4358
|
|
|
4309
4359
|
---
|
|
4310
4360
|
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: summarise
|
|
3
|
+
description: Use when the user types /summarise, or asks for a summary, recap, or "in short" version of what the agent just said or asked. Restates the agent's own immediately preceding turn under the plainly rules: precise, concise, plain English, every claim already evidenced in that turn. When that turn concluded an investigation, the summary carries exactly two things: the diagnosis and the proposed resolution.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# summarise
|
|
7
|
+
|
|
8
|
+
Invoked by the admin agent directly.
|
|
9
|
+
|
|
10
|
+
The subject is the agent's own last turn, not the codebase, not the conversation as a whole, and not the user's message. Whatever was just said or asked gets restated so a reader who skipped the turn ends up with the same working understanding, in a fraction of the words.
|
|
11
|
+
|
|
12
|
+
## What success looks like
|
|
13
|
+
|
|
14
|
+
The summary is precise, concise, plain English, with every claim already evidenced in the turn being summarised. It also satisfies the shipped `plainly` skill (`skills/plainly/SKILL.md`): spoken register, no acronyms, no formulas, no AI tells, no em-dashes. Read `plainly` before writing; do not summarise from memory of what it says.
|
|
15
|
+
|
|
16
|
+
Three sentences is the ceiling for an ordinary turn. If the turn ended in a question, the summary states the question and what turns on the answer, and nothing else.
|
|
17
|
+
|
|
18
|
+
## Investigations
|
|
19
|
+
|
|
20
|
+
When the preceding turn concluded an investigation, the summary has exactly two parts, in this order:
|
|
21
|
+
|
|
22
|
+
1. **Diagnosis.** What is actually wrong, and the evidence that establishes it. Name the cause, not the layer where the symptom surfaced.
|
|
23
|
+
2. **Proposed resolution.** What would fix that cause, and its scope boundary.
|
|
24
|
+
|
|
25
|
+
Both parts are mandatory. A diagnosis with no proposed resolution is an unfinished summary; a proposed resolution with no diagnosis is speculation wearing a summary's clothes. Neither part introduces a finding, a fix, or a caveat that was absent from the turn being summarised. If the investigation reached a diagnosis but no resolution, say that in the resolution slot rather than inventing one.
|
|
26
|
+
|
|
27
|
+
## Constraints
|
|
28
|
+
|
|
29
|
+
- **No new content.** The summary is a compression, never an extension. Anything not in the turn being summarised does not belong here.
|
|
30
|
+
- **Drop the scaffolding, keep the load.** File paths, tool names, and step-by-step narration go unless the reader needs them to act. The outcome stays.
|
|
31
|
+
- **No hedging.** The original turn either established a claim or it did not. Do not soften a confirmed finding into "appears to", and do not harden a speculation into a fact.
|
|
32
|
+
- **No follow-up offers.** End on the summary.
|
|
33
|
+
|
|
34
|
+
## When NOT to use
|
|
35
|
+
|
|
36
|
+
- The user wants the summary of a document, a file, or someone else's text: that is ordinary reading work, and the `plainly` skill fits better.
|
|
37
|
+
- The last turn was already one or two plain sentences: there is nothing to compress, so say so and stop.
|
|
@@ -9,6 +9,13 @@ Invoked by the admin agent directly.
|
|
|
9
9
|
|
|
10
10
|
This is the platform's release timeline, newest first. Each entry shows the date it shipped and the version it shipped in, so you can tell the operator how current their install is. To compare, read the installed version from `capabilities-here` and match it against the versions below. Keep answers high level and in plain English; this is a summary, not a full commit log.
|
|
11
11
|
|
|
12
|
+
## 2026-07-25 (0.1.502)
|
|
13
|
+
|
|
14
|
+
- Uploading a file from the phone or desktop app now shows as a proper thumbnail in chat, not a raw file path.
|
|
15
|
+
- Switching accounts now shows a loading screen and lands you on the dashboard instead of a blank page.
|
|
16
|
+
- Uploaded files are automatically filed into the right folder instead of sitting in a temporary holding area.
|
|
17
|
+
- Searching your files is more reliable and no longer times out on larger accounts.
|
|
18
|
+
|
|
12
19
|
## 2026-07-21 (0.1.482)
|
|
13
20
|
|
|
14
21
|
- WhatsApp now runs a separate connection for each client account, so one client's messages never mix with another's.
|
|
@@ -118,6 +118,37 @@ routines exist for the account is the account-scope-miss signature; the logged
|
|
|
118
118
|
`cron=` on `outcome=ok` confirms the persisted expression without opening the
|
|
119
119
|
graph.
|
|
120
120
|
|
|
121
|
+
### Skills
|
|
122
|
+
|
|
123
|
+
The Skills surface (`/skills`) is the admin view of the account's operator-
|
|
124
|
+
authored skills — the `SKILL.md` files the store-skill tool writes under
|
|
125
|
+
`<accountDir>/plugins/<plugin>/skills/<skill>/` (the durable per-account plugin
|
|
126
|
+
root, never the immutable `PLATFORM_ROOT/plugins` tree). It renders one card per
|
|
127
|
+
skill (name, owning plugin, frontmatter description, reference count); a card
|
|
128
|
+
opens a **read-only** detail modal showing the frontmatter, the SKILL.md body,
|
|
129
|
+
and the reference filenames. The page is read-only by design — skills are
|
|
130
|
+
authored and edited through the chat interface — with one exception: a **delete**
|
|
131
|
+
behind an explicit confirm step in the modal. A confirmed delete removes the
|
|
132
|
+
skill directory, and the whole plugin directory when that was its last skill.
|
|
133
|
+
|
|
134
|
+
The route (`server/routes/admin/skills.ts`) walks only the account tree, so
|
|
135
|
+
shipped platform skills never appear. Plugin and skill path params are kebab-case
|
|
136
|
+
validated (`/^[a-z0-9][a-z0-9-]*$/`) — the traversal guard; anything else 400s.
|
|
137
|
+
|
|
138
|
+
| Route | Behaviour |
|
|
139
|
+
|-------|-----------|
|
|
140
|
+
| `GET /api/admin/skills` | Enumerates `plugins/*/skills/*/SKILL.md`, returns `{plugin, skill, description, refCount}` per skill, sorted plugin then skill. A per-entry read error logs `op=list-skip` rather than silently shortening the list. |
|
|
141
|
+
| `GET /api/admin/skills/:plugin/:skill` | One skill's parsed frontmatter (`name`, `description`, `publicEmbed`), the SKILL.md body, and the reference filenames. Unknown skill 404s. |
|
|
142
|
+
| `DELETE /api/admin/skills/:plugin/:skill` | Removes the skill dir; removes the plugin dir when its `skills/` empties. Returns `{ok, skillDirGone, pluginDirRemoved}` measured after the rm. |
|
|
143
|
+
|
|
144
|
+
Observability rides `[admin:skills]`: `op=list accountId=<8> plugins=<n>
|
|
145
|
+
skills=<n>` (the surface's own heartbeat — `skills=0` against a populated
|
|
146
|
+
`plugins/*/skills/` is the broken-walk signature), `op=get plugin=<…> skill=<…>
|
|
147
|
+
found=<bool>`, and `op=delete plugin=<…> skill=<…> outcome=ok
|
|
148
|
+
skillDirGone=<bool> pluginDirRemoved=<bool>` (`skillDirGone=false` with
|
|
149
|
+
`outcome=ok` is a named failure) / `outcome=rejected reason=<invalid-name|
|
|
150
|
+
not-found|rm-error>`.
|
|
151
|
+
|
|
121
152
|
### Graph
|
|
122
153
|
|
|
123
154
|
| Mount | Purpose |
|
|
@@ -129,6 +160,25 @@ graph.
|
|
|
129
160
|
| `/graph-labels-in-graph` | Distinct label list for the filter dropdown. |
|
|
130
161
|
| `/graph-default-view` | Account-scoped saved view (zoom, focal id, filters). |
|
|
131
162
|
|
|
163
|
+
**Node visual encoding.** Every node type that can appear on the canvas renders
|
|
164
|
+
a coloured disc with a white Lucide glyph, sized by incident-edge count, with a
|
|
165
|
+
matching legend swatch. Colour, shape, and glyph are three per-label registries
|
|
166
|
+
in `platform/lib/graph-style/src/index.ts`. Coverage is reconciled against the
|
|
167
|
+
true node-label universe, not the colour registry itself: the standing test
|
|
168
|
+
`__tests__/icons.test.ts` assembles the universe from the `Neo4j Label` column
|
|
169
|
+
of every `schema-*.md` node-type table, the `sourceLabel`/`targetLabel` set in
|
|
170
|
+
`typed-edge-schema.ts`, and the `CODE_EMITTED_NODE_LABELS` list, then fails the
|
|
171
|
+
build if any member lacks a colour or glyph. Labels that only ever stack on a
|
|
172
|
+
base node (`ADDITIONAL_BASE_LABELS`) inherit the base node's colour and are
|
|
173
|
+
excluded. A node type carries a coloured glyph even when its text caption is its
|
|
174
|
+
bare type: the glyph and the caption are independent channels (caption coverage
|
|
175
|
+
is the separate `caption-coverage.test.ts` gate). At runtime, a per-session
|
|
176
|
+
`op=icon-fallback` census (emitted from `app/graph/page.tsx` across the initial
|
|
177
|
+
render and every live-update poll) names any label that reached the canvas with
|
|
178
|
+
no glyph; an empty census is the healthy signal, a non-empty one means a
|
|
179
|
+
code-emitted label that no static source declares and should be added to
|
|
180
|
+
`CODE_EMITTED_NODE_LABELS`.
|
|
181
|
+
|
|
132
182
|
### Artefacts and files
|
|
133
183
|
|
|
134
184
|
| Mount | Purpose |
|
|
@@ -408,7 +408,7 @@ Standing rules the operator gives over a channel are `Preference` nodes. Two mec
|
|
|
408
408
|
|
|
409
409
|
**Observability.** `[preference-write] op=reconcile … mode=<reinforce|update|contradict|new> similarity=…` — a stream of `mode=new` for subjects that already exist is the duplicate-minting signature. `[preference-inject] op=inject channel=<wa|tg|web> injected=<N> owner=<8> source=<owner|no-owner|owner-error|fetch-error>` — injection selects only the account owner's admin preferences, so `source=owner injected=0` is a genuinely empty owner, `source=no-owner` is an account with no seeded owner (injects nothing, a missed owner seeding), and `injected=0 source=owner` on an account whose owner holds rules is the write-only regression re-appearing. `[preference-inject] op=reconcile accountId=… stored=… injected=…` — the standing reconciliation audit (claude-session-manager, 5-minute tick) flags any account whose stored active count diverges from what injection surfaces; injection now surfaces every stored active preference verbatim, so `stored == injected` is the healthy signal and any gap is a dropped-row regression (a reintroduced cap, filter, or truncation). A clean pass logs `op=reconcile drifted=0`, the no-event detector.
|
|
410
410
|
|
|
411
|
-
**Consult-before-send gate.** Injection (above) puts the owner's active rules in front of every channel turn, but the growing layer-2 `Preference` set is read on demand with `profile-read`, a per-turn judgement the agent can skip, the miss that dropped a customer signature on a delivered document. `hooks/preference-consult-gate.sh` (admin plugin) is the deliverable-boundary enforcement: a PreToolUse gate on customer-facing document deliverables (`browser-pdf-save`/`SendUserFile` to `memory/users/<phone>/documents/`, and email/Outlook sends carrying attachments) that blocks (exit 2) when no `profile-read` ran after the last user message in the transcript. It fires on documents only, never on casual replies. **Observability:** `[preference-gate] op=allow tool=<name> consulted=true` on an allowed document deliverable, `op=bypass tool=<name> detail=no profile-read this turn` on a block; a stream of `op=bypass` is the un-consulted-send signature. The advisory companion `hooks/preference-consult-directive.sh` injects the two-layer architecture reminder every turn (`[pref-wrapper] op=inject`). The placement half, promoting finished deliverables out of `output/` scratch, is counted by the `data-manager` reconcile audit (`scratch-refs`, `stranded`); making that audit run on a standing periodic cadence is a filed follow-up.
|
|
411
|
+
**Consult-before-send gate.** Injection (above) puts the owner's active rules in front of every channel turn, but the growing layer-2 `Preference` set is read on demand with `profile-read`, a per-turn judgement the agent can skip, the miss that dropped a customer signature on a delivered document. `hooks/preference-consult-gate.sh` (admin plugin) is the deliverable-boundary enforcement: a PreToolUse gate on customer-facing document deliverables (`browser-pdf-save`/`SendUserFile` to `memory/users/<phone>/documents/`, and email/Outlook sends carrying attachments) that blocks (exit 2) when no `profile-read` ran after the last user message in the transcript. It fires on documents only, never on casual replies. **Observability:** `[preference-gate] op=allow tool=<name> consulted=true` on an allowed document deliverable, `op=bypass tool=<name> detail=no profile-read this turn` on a block; a stream of `op=bypass` is the un-consulted-send signature. The advisory companion `hooks/preference-consult-directive.sh` injects the two-layer architecture reminder every turn (`[pref-wrapper] op=inject`). The placement half, promoting finished deliverables out of `output/` scratch, is counted by the `data-manager` reconcile audit (`scratch-refs`, `stranded`); making that audit run on a standing periodic cadence is a filed follow-up. The inbound mirror is the `uploads/` intake inbox: an uploaded file lands at `uploads/<attachmentId>/` and is promoted to its canonical entity bucket when its graph node is created, so a persisted node reference resolving into `uploads/` is intake drift, counted by the same reconcile audit as `stranded-intake`. Unlike `output/`, `uploads/` is never rebuilt by a tool, so the `data-manager` may promote a file out of it. Beyond placement and intake, the same audit counts intra-folder sprawl inside each operator-data entity folder from disk structure alone: superseded version copies (`<base>.ext` and `<base>-vN.ext` are one deliverable, all but the newest counted `versioned`), format twins (a source `.html`/`.md` render kept beside its delivered `.pdf` of the same basename, counted `format-twins`), and subfolders nested under `projects/<name>/` or `contacts/<name>/` that the flat rule forbids (counted `stray-subdir`). These are read-only counts; removal or flattening happens only on a `data-manager` stewardship dispatch, each paired with a `database-operator` reference update. The reconcile output contract is `unreachable=N broken-refs=M scratch-refs=P stranded=Q stranded-intake=R versioned=S format-twins=T stray-subdir=U`.
|
|
412
412
|
|
|
413
413
|
---
|
|
414
414
|
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# summarise skill
|
|
2
|
+
|
|
3
|
+
A workflow skill bundled in the admin plugin on every {{productName}} install.
|
|
4
|
+
|
|
5
|
+
**`summarise`** restates the agent's own immediately-preceding turn under the plainly rules: precise, concise, plain English, every claim already evidenced in the turn. Three-sentence ceiling for an ordinary turn. When that turn concluded an investigation, the summary carries exactly two parts in order: the diagnosis (the cause, with its evidence) and the proposed resolution (or an explicit note that none was reached). Triggers: "/summarise", "summarise", "recap", "in short".
|
|
6
|
+
|
|
7
|
+
It never adds content, never hedges, and never ends on a follow-up offer. For summarising someone else's document or text, `plainly` fits better; a turn already one or two plain sentences needs no compression.
|
|
@@ -26,6 +26,32 @@ the client data portal, and case-sensitive matching. The write guard blocks a ba
|
|
|
26
26
|
name as you create it, and the standing reconcile counts any that predate the
|
|
27
27
|
rule. Renaming an existing bad name goes through the `data-manager` specialist.
|
|
28
28
|
|
|
29
|
+
## Intra-folder hygiene
|
|
30
|
+
|
|
31
|
+
The `projects/<name>/` and `contacts/<name>/` entity folders hold one current
|
|
32
|
+
copy of each deliverable, in one canonical format, with no subtree. Three rules
|
|
33
|
+
keep them that way; the standing reconcile counts any that predate them, and
|
|
34
|
+
`data-manager` clears them on a stewardship dispatch. (`documents/` is exempt: it
|
|
35
|
+
may hold one document-folder deep per the buckets above, so these rules do not
|
|
36
|
+
apply there.)
|
|
37
|
+
|
|
38
|
+
- **Current version only.** `<base>.ext` and `<base>-vN.ext` (for example
|
|
39
|
+
`charlotte-deck.pdf` and `charlotte-deck-v2.pdf` through
|
|
40
|
+
`charlotte-deck-v6.pdf`) are versions of one deliverable, not separate files.
|
|
41
|
+
Keep the highest-numbered version (the unsuffixed base is the original, so any
|
|
42
|
+
`-vN` supersedes it); the superseded copies are removed through `data-manager`.
|
|
43
|
+
- **One canonical format.** A delivered `.pdf` and its source render sharing the
|
|
44
|
+
same basename (`charlotte-deck.html` beside `charlotte-deck.pdf`,
|
|
45
|
+
`invoice-rbt-2026-005.html` beside `invoice-rbt-2026-005.pdf`) are one
|
|
46
|
+
deliverable in two formats. The pdf is the deliverable; the `.html` or `.md`
|
|
47
|
+
render that produced it is not a second one and is removed through
|
|
48
|
+
`data-manager`.
|
|
49
|
+
- **No subfolder.** No folder nests under `projects/<name>/` or
|
|
50
|
+
`contacts/<name>/`; files live directly inside the entity folder. This is the
|
|
51
|
+
flat rule from the buckets above, restated as a standing invariant: the write
|
|
52
|
+
guard blocks the depth as you create it, and the reconcile counts any subtree
|
|
53
|
+
that predates the guard or was created off-path.
|
|
54
|
+
|
|
29
55
|
## Tool-owned (off-limits — never reorganise)
|
|
30
56
|
|
|
31
57
|
Finished deliverables must be promoted out of `output/` into `documents/` or
|
|
@@ -33,8 +59,17 @@ Finished deliverables must be promoted out of `output/` into `documents/` or
|
|
|
33
59
|
last resort, and a graph reference must never point into it (the next tool write
|
|
34
60
|
rebuilds the tree and the reference dangles).
|
|
35
61
|
|
|
62
|
+
`uploads/` is a temporary intake inbox, not rebuilt scratch. A file lands at
|
|
63
|
+
`uploads/<attachmentId>/` on upload and is promoted to its canonical entity
|
|
64
|
+
bucket when its graph node is created: a Person or Organization file to
|
|
65
|
+
`contacts/<name>/`, a Project file to `projects/<name>/`, anything else to
|
|
66
|
+
`documents/`. A persisted graph reference must never point into `uploads/`.
|
|
67
|
+
Unlike `output/`, each upload writes its own `uploads/<attachmentId>/` dir and no
|
|
68
|
+
tool walks or rebuilds the subtree, so promoting a file out of it through the
|
|
69
|
+
`data-manager` specialist is safe.
|
|
70
|
+
|
|
36
71
|
The internal structure of these is owned by the writing tool and is recreated on
|
|
37
|
-
the next write: `url-get/`, `output/`, `generated/`, `extracted/`,
|
|
72
|
+
the next write: `url-get/`, `output/`, `generated/`, `extracted/`,
|
|
38
73
|
any published/served tree (`sites/`, `public/`), `agents/`, `specialists/`, and
|
|
39
74
|
platform-internal areas (`cache/`, `secrets/`, `state/`, `logs/`, `tmp/`).
|
|
40
75
|
`.quarantine/` is a historical store. An earlier version of the schema reconcile
|
|
@@ -14,6 +14,8 @@ You are the steward of this account's data directory. Admin dispatches you throu
|
|
|
14
14
|
- The account data directory is organised consistently with the graph ontology. Before the first move of a session, Read `platform/plugins/memory/references/schema-base.md`; when `brand.json#vertical` is set, also Read `platform/plugins/memory/references/schema-<vertical>.md`. Directory structure and file placement should make sense to someone navigating by the graph: files that belong to a Project, Person, or document node live where the node's references say they live.
|
|
15
15
|
- Every operator file is reachable from a graph node, and every graph file-reference resolves to a real path. `memory-search` is how you resolve which nodes reference a file — search for the filename and the path before deciding anything about it.
|
|
16
16
|
- A file is never moved without the referencing nodes being updated in the same pass. Moves and reference updates are paired operations: for each move, dispatch `database-operator` via the Task tool with a brief naming the node (elementId from your `memory-search`), the property holding the old path, and the new path. You have no graph-write tools by design — every graph mutation flows through database-operator.
|
|
17
|
+
- A file in the `uploads/` intake inbox whose graph node exists is promoted to its canonical bucket (Person or Organization to `contacts/<name>/`, Project to `projects/<name>/`, else `documents/`), paired with a `database-operator` `sourcePath` update in the same pass, exactly as any other move. `uploads/` is a temporary landing area, not a tool-owned tree, so moving a file out of it is not a reorganisation of a system-convention directory.
|
|
18
|
+
- Superseded versions and redundant format twins are removed, and a subfolder nested under `projects/<name>/` or `contacts/<name>/` is flattened or re-filed, when a stewardship brief asks for it. Each removal or move pairs with a `database-operator` reference update in the same pass, exactly as any other move: the surviving current render keeps the node reference, and a removed file's node is repointed or its reference dropped. Removal is destructive, so it happens only on an explicit stewardship dispatch, never in the read-only reconcile audit.
|
|
17
19
|
|
|
18
20
|
## Off-limits: system-convention directories
|
|
19
21
|
|
|
@@ -21,13 +23,13 @@ Directories whose layout is owned by tools are not yours to reorganise — a too
|
|
|
21
23
|
|
|
22
24
|
## The reconcile audit brief
|
|
23
25
|
|
|
24
|
-
When admin's brief names a reconcile audit, the pass is read-only: walk the operator-file areas of the account directory, resolve each file against the graph via `memory-search`, and count (a) files unreachable from any graph node, (b) graph file-references that do not resolve to a real path, (c) graph file-references that resolve into a tool-owned scratch dir (`output/`, `generated/`, `extracted/`, `url-get/`), which the next tool write rebuilds so the reference is fragile by construction,
|
|
26
|
+
When admin's brief names a reconcile audit, the pass is read-only: walk the operator-file areas of the account directory, resolve each file against the graph via `memory-search`, and count (a) files unreachable from any graph node, (b) graph file-references that do not resolve to a real path, (c) graph file-references that resolve into a tool-owned scratch dir (`output/`, `generated/`, `extracted/`, `url-get/`), which the next tool write rebuilds so the reference is fragile by construction, (d) deliverables a node references that resolve only under a scratch dir and were never promoted to `documents/` or `projects/`, and (e) graph file-references that resolve into the `uploads/` intake inbox, which is a temporary landing area a file should have been promoted out of when its node was created. The walk now includes `uploads/`; a file under `uploads/` that no node references counts under (a) unreachable. Then, per operator-data entity folder (`projects/<name>/`, `contacts/<name>/`), count three intra-folder drifts from disk structure alone, no graph resolution needed: (f) files in a version group, where `<base>.ext` and `<base>-vN.ext` share a basename stem and extension and all but the newest are superseded, counting every superseded copy as `versioned`; (g) format twins, a source-render file (`.html`, `.md`) whose delivered `.pdf` twin of the same basename sits in the same folder, counting each such render as `format-twins`; (h) stray subfolders nested under an entity folder, which the flat rule forbids, counting each subfolder as `stray-subdir`. Move nothing, dispatch nothing. The audit exists so a rising count is visible before anyone asks for a cleanup.
|
|
25
27
|
|
|
26
28
|
When the vertical's `schema-<vertical>.md` declares a **published / served tree** with a Filesystem ↔ graph section (e.g. the per-listing site target with a URL ↔ path rule and an artefact → graph-reference table), the audit also walks that tree. The graph references it by hosted URL, not local path, so resolution runs through the section's URL ↔ path rule: for each served file, derive its hosted URL and check that some node references it; for each node URL **that matches the section's hosted-URL prefix**, derive its local path and check the file exists. Count served files matching no node reference in `unreachable` and prefix-matching node URLs resolving to no served file in `broken-refs`. Node URLs the rule cannot resolve — externally-hosted URLs (a CDN image, a third-party portal link) carry no served-tree prefix — are outside this audit and are never counted as broken. Honour the section's "served but intentionally unreferenced (tool / collateral)" list — those classes carry no reference by design and are never orphans, the same exclusion you already apply to the `url-get/` cache. This walk is still read-only: the served tree is a publish write target (off-limits to moves, above); the audit only counts drift, it never reorganises.
|
|
27
29
|
|
|
28
30
|
## Output contract
|
|
29
31
|
|
|
30
|
-
End every dispatch with a one-line machine-greppable summary as the last line of your reply. For stewardship work: `moves=N ref-updates=M skipped=<reason|none>`. For the reconcile audit: `unreachable=N broken-refs=M scratch-refs=P stranded=Q`. If a brief is ambiguous about whether a directory is operator data or a system convention, name the ambiguity in your reply instead of guessing.
|
|
32
|
+
End every dispatch with a one-line machine-greppable summary as the last line of your reply. For stewardship work: `moves=N ref-updates=M skipped=<reason|none>`. For the reconcile audit: `unreachable=N broken-refs=M scratch-refs=P stranded=Q stranded-intake=R versioned=S format-twins=T stray-subdir=U`. If a brief is ambiguous about whether a directory is operator data or a system convention, name the ambiguity in your reply instead of guessing.
|
|
31
33
|
|
|
32
34
|
## Review gates
|
|
33
35
|
|
|
@@ -5,12 +5,12 @@
|
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
6
|
<title>Activity — Maxy</title>
|
|
7
7
|
<link rel="icon" href="/favicon.ico">
|
|
8
|
-
<script type="module" crossorigin src="/assets/activity-
|
|
9
|
-
<link rel="modulepreload" crossorigin href="/assets/chunk-
|
|
10
|
-
<link rel="modulepreload" crossorigin href="/assets/useSubAccountSwitcher-
|
|
11
|
-
<link rel="modulepreload" crossorigin href="/assets/AdminShell-
|
|
12
|
-
<link rel="modulepreload" crossorigin href="/assets/triangle-alert-
|
|
13
|
-
<link rel="stylesheet" crossorigin href="/assets/useSubAccountSwitcher-
|
|
8
|
+
<script type="module" crossorigin src="/assets/activity-DZFYDHNA.js"></script>
|
|
9
|
+
<link rel="modulepreload" crossorigin href="/assets/chunk-CCr-iYLO.js">
|
|
10
|
+
<link rel="modulepreload" crossorigin href="/assets/useSubAccountSwitcher-iQGqNJhI.js">
|
|
11
|
+
<link rel="modulepreload" crossorigin href="/assets/AdminShell-Gq8DU_ig.js">
|
|
12
|
+
<link rel="modulepreload" crossorigin href="/assets/triangle-alert-k8ulav-N.js">
|
|
13
|
+
<link rel="stylesheet" crossorigin href="/assets/useSubAccountSwitcher-fvBunpOC.css">
|
|
14
14
|
<link rel="stylesheet" href="/brand-defaults.css">
|
|
15
15
|
</head>
|
|
16
16
|
<body>
|