@rubytech/create-siteoffice-code 0.1.263 → 0.1.265

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (169) hide show
  1. package/package.json +1 -1
  2. package/payload/platform/plugins/admin/.claude-plugin/plugin.json +1 -1
  3. package/payload/platform/plugins/admin/PLUGIN.md +7 -2
  4. package/payload/platform/plugins/admin/mcp/dist/__tests__/skill-search.test.d.ts +2 -0
  5. package/payload/platform/plugins/admin/mcp/dist/__tests__/skill-search.test.d.ts.map +1 -0
  6. package/payload/platform/plugins/admin/mcp/dist/__tests__/skill-search.test.js +106 -0
  7. package/payload/platform/plugins/admin/mcp/dist/__tests__/skill-search.test.js.map +1 -0
  8. package/payload/platform/plugins/admin/mcp/dist/index.js +37 -2
  9. package/payload/platform/plugins/admin/mcp/dist/index.js.map +1 -1
  10. package/payload/platform/plugins/admin/mcp/dist/skill-resolution.d.ts +12 -0
  11. package/payload/platform/plugins/admin/mcp/dist/skill-resolution.d.ts.map +1 -1
  12. package/payload/platform/plugins/admin/mcp/dist/skill-resolution.js +175 -1
  13. package/payload/platform/plugins/admin/mcp/dist/skill-resolution.js.map +1 -1
  14. package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +239 -239
  15. package/payload/platform/plugins/admin/skills/superpowers-sprint/SKILL.md +3 -3
  16. package/payload/platform/plugins/admin/skills/upgrade/SKILL.md +2 -2
  17. package/payload/platform/plugins/cloudflare/PLUGIN.md +1 -1
  18. package/payload/platform/plugins/cloudflare/references/manual-setup.md +10 -10
  19. package/payload/platform/plugins/cloudflare/references/reset-guide.md +1 -1
  20. package/payload/platform/plugins/docs/.claude-plugin/plugin.json +1 -1
  21. package/payload/platform/plugins/docs/PLUGIN.md +6 -6
  22. package/payload/platform/plugins/docs/references/admin-session.md +1 -1
  23. package/payload/platform/plugins/docs/references/admin-ui.md +2 -2
  24. package/payload/platform/plugins/docs/references/cloudflare.md +1 -1
  25. package/payload/platform/plugins/docs/references/deployment.md +7 -7
  26. package/payload/platform/plugins/docs/references/linkedin-extension.md +4 -4
  27. package/payload/platform/plugins/docs/references/memory-guide.md +2 -2
  28. package/payload/platform/plugins/docs/references/neo4j.md +1 -1
  29. package/payload/platform/plugins/docs/references/outlook-guide.md +1 -1
  30. package/payload/platform/plugins/docs/references/platform.md +2 -2
  31. package/payload/platform/plugins/docs/references/plugins-guide.md +6 -6
  32. package/payload/platform/plugins/docs/references/troubleshooting.md +1 -1
  33. package/payload/platform/plugins/linkedin-extension/.claude-plugin/plugin.json +1 -1
  34. package/payload/platform/plugins/linkedin-extension/PLUGIN.md +1 -1
  35. package/payload/platform/plugins/linkedin-extension/extension/README.md +4 -4
  36. package/payload/platform/plugins/linkedin-extension/extension/assets/pill.css +1 -1
  37. package/payload/platform/plugins/linkedin-extension/extension/content/profile.js +2 -2
  38. package/payload/platform/plugins/linkedin-extension/extension/content/thread.js +2 -2
  39. package/payload/platform/plugins/linkedin-extension/extension/manifest.json +3 -3
  40. package/payload/platform/plugins/linkedin-extension/extension/options/options.html +3 -3
  41. package/payload/platform/plugins/linkedin-import/.claude-plugin/plugin.json +1 -1
  42. package/payload/platform/plugins/linkedin-import/PLUGIN.md +2 -2
  43. package/payload/platform/plugins/memory/references/graph-primitives.md +1 -1
  44. package/payload/platform/plugins/memory/references/schema-base.md +1 -1
  45. package/payload/platform/plugins/memory/references/schema-construction.md +1 -1
  46. package/payload/platform/plugins/memory/skills/conversation-archive-mcp/SKILL.md +2 -2
  47. package/payload/platform/plugins/notion-import/.claude-plugin/plugin.json +1 -1
  48. package/payload/platform/plugins/notion-import/PLUGIN.md +2 -2
  49. package/payload/platform/plugins/obsidian-import/.claude-plugin/plugin.json +1 -1
  50. package/payload/platform/plugins/obsidian-import/PLUGIN.md +2 -2
  51. package/payload/platform/plugins/obsidian-import/skills/obsidian-import/SKILL.md +1 -1
  52. package/payload/platform/plugins/obsidian-import/skills/obsidian-import/references/attachments.md +1 -1
  53. package/payload/platform/plugins/obsidian-import/skills/obsidian-import/references/daily-notes.md +1 -1
  54. package/payload/platform/plugins/obsidian-import/skills/obsidian-import/references/vault-structure.md +1 -1
  55. package/payload/platform/plugins/obsidian-import/skills/obsidian-import/references/wikilinks.md +1 -1
  56. package/payload/platform/plugins/outlook/mcp/dist/index.js +1 -1
  57. package/payload/platform/plugins/outlook/references/auth.md +2 -2
  58. package/payload/platform/plugins/outlook/skills/outlook/SKILL.md +1 -1
  59. package/payload/platform/plugins/sales/.claude-plugin/plugin.json +1 -1
  60. package/payload/platform/plugins/sales/PLUGIN.md +8 -8
  61. package/payload/platform/plugins/sales/references/comparisons.md +18 -18
  62. package/payload/platform/plugins/sales/references/competitive-positioning.md +5 -5
  63. package/payload/platform/plugins/sales/references/faq.md +22 -22
  64. package/payload/platform/plugins/sales/references/objection-handling.md +3 -3
  65. package/payload/platform/plugins/sales/references/pricing.md +16 -16
  66. package/payload/platform/plugins/slides/PROVENANCE.md +1 -1
  67. package/payload/platform/plugins/substack-import/.claude-plugin/plugin.json +1 -1
  68. package/payload/platform/plugins/substack-import/PLUGIN.md +2 -2
  69. package/payload/platform/plugins/whatsapp/mcp/dist/__tests__/format-login-start.test.d.ts +2 -0
  70. package/payload/platform/plugins/whatsapp/mcp/dist/__tests__/format-login-start.test.d.ts.map +1 -0
  71. package/payload/platform/plugins/whatsapp/mcp/dist/__tests__/format-login-start.test.js +16 -0
  72. package/payload/platform/plugins/whatsapp/mcp/dist/__tests__/format-login-start.test.js.map +1 -0
  73. package/payload/platform/plugins/whatsapp/mcp/dist/format.d.ts +7 -0
  74. package/payload/platform/plugins/whatsapp/mcp/dist/format.d.ts.map +1 -0
  75. package/payload/platform/plugins/whatsapp/mcp/dist/format.js +21 -0
  76. package/payload/platform/plugins/whatsapp/mcp/dist/format.js.map +1 -0
  77. package/payload/platform/plugins/whatsapp/mcp/dist/index.js +11 -19
  78. package/payload/platform/plugins/whatsapp/mcp/dist/index.js.map +1 -1
  79. package/payload/platform/plugins/whatsapp/references/channels-whatsapp.md +1 -1
  80. package/payload/platform/plugins/whatsapp/skills/connect-whatsapp/SKILL.md +15 -13
  81. package/payload/platform/plugins/x-import/.claude-plugin/plugin.json +1 -1
  82. package/payload/platform/plugins/x-import/PLUGIN.md +2 -2
  83. package/payload/platform/scripts/check-skill-frontmatter.mjs +8 -5
  84. package/payload/platform/scripts/wifi-provision-server/server.js +1 -1
  85. package/payload/platform/scripts/wifi-provision.sh +1 -1
  86. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.d.ts.map +1 -1
  87. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js +1 -0
  88. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js.map +1 -1
  89. package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts.map +1 -1
  90. package/payload/platform/services/claude-session-manager/dist/pty-spawner.js +15 -15
  91. package/payload/platform/services/claude-session-manager/dist/pty-spawner.js.map +1 -1
  92. package/payload/platform/templates/agents/admin/IDENTITY.md +3 -3
  93. package/payload/platform/templates/specialists/.claude-plugin/plugin.json +1 -1
  94. package/payload/premium-plugins/venture-studio/skills/prototype-host/SKILL.md +1 -1
  95. package/payload/server/{adminuser-self-heal-YC47O34W.js → adminuser-self-heal-LC7HZAC6.js} +17 -9
  96. package/payload/server/{chunk-HYQNUVGO.js → chunk-PFF6I7KP.js} +1 -8
  97. package/payload/server/{chunk-ET3BKHKR.js → chunk-SOLVVUST.js} +11 -3
  98. package/payload/server/maxy-edge.js +2 -2
  99. package/payload/server/public/assets/{AdminShell-8JLQM1Mz.js → AdminShell-BcHJy_Y2.js} +1 -1
  100. package/payload/server/public/assets/{Checkbox-CuFJh7lI.js → Checkbox-BY2lndUH.js} +1 -1
  101. package/payload/server/public/assets/{admin-D4nsdmKU.js → admin-C364q_-g.js} +1 -1
  102. package/payload/server/public/assets/{architectureDiagram-Q4EWVU46-D-ODjJS5.js → architectureDiagram-Q4EWVU46-B9ik0JyO.js} +1 -1
  103. package/payload/server/public/assets/{blockDiagram-DXYQGD6D-DFuVe8f9.js → blockDiagram-DXYQGD6D-C-w-AMRJ.js} +1 -1
  104. package/payload/server/public/assets/{browser-DIKmvDl5.js → browser-D66JrDpx.js} +1 -1
  105. package/payload/server/public/assets/{c4Diagram-AHTNJAMY-CeVLfznT.js → c4Diagram-AHTNJAMY-BH-b0NZ1.js} +1 -1
  106. package/payload/server/public/assets/channel-5xoW3jfU.js +1 -0
  107. package/payload/server/public/assets/{chunk-336JU56O-BTaLfR3a.js → chunk-336JU56O-CZHLbmJj.js} +2 -2
  108. package/payload/server/public/assets/{chunk-426QAEUC-BzTbm4pP.js → chunk-426QAEUC-Qx6Ggp9s.js} +1 -1
  109. package/payload/server/public/assets/{chunk-4TB4RGXK-SiUyOXVG.js → chunk-4TB4RGXK-J1Raz9l0.js} +1 -1
  110. package/payload/server/public/assets/{chunk-5FUZZQ4R-BcQ33LnT.js → chunk-5FUZZQ4R-D6TFnJVF.js} +1 -1
  111. package/payload/server/public/assets/{chunk-5PVQY5BW-CT7C1Tik.js → chunk-5PVQY5BW-CC5aEdzK.js} +1 -1
  112. package/payload/server/public/assets/{chunk-EDXVE4YY-CK3uI2u6.js → chunk-EDXVE4YY-Bfbcdcbt.js} +1 -1
  113. package/payload/server/public/assets/{chunk-ENJZ2VHE-Ddp8Otnw.js → chunk-ENJZ2VHE-7EKi84Dw.js} +1 -1
  114. package/payload/server/public/assets/{chunk-ICPOFSXX-DHTxymk_.js → chunk-ICPOFSXX-DIH1FT8n.js} +1 -1
  115. package/payload/server/public/assets/{chunk-OYMX7WX6-Heg3hegz.js → chunk-OYMX7WX6-MgP02n7p.js} +1 -1
  116. package/payload/server/public/assets/{chunk-U2HBQHQK-Cw2PR7aJ.js → chunk-U2HBQHQK-Cwmbq3M7.js} +1 -1
  117. package/payload/server/public/assets/{chunk-X2U36JSP-C7vBCAQQ.js → chunk-X2U36JSP-D65N3MkW.js} +1 -1
  118. package/payload/server/public/assets/{chunk-YZCP3GAM-BS8Mybh1.js → chunk-YZCP3GAM-BkCiRhSG.js} +1 -1
  119. package/payload/server/public/assets/{chunk-ZZ45TVLE-DmnbQp47.js → chunk-ZZ45TVLE-3BQY1FWN.js} +1 -1
  120. package/payload/server/public/assets/classDiagram-6PBFFD2Q-DRSNlIL5.js +1 -0
  121. package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-CYvRRfMp.js +1 -0
  122. package/payload/server/public/assets/clone-DvQUt_lq.js +1 -0
  123. package/payload/server/public/assets/{dagre-D4i6r8zi.js → dagre-DVhW13RD.js} +1 -1
  124. package/payload/server/public/assets/{dagre-KV5264BT-znWS6Wh2.js → dagre-KV5264BT-CtfjEgDz.js} +1 -1
  125. package/payload/server/public/assets/{data-CHqF4bkS.js → data-uiOcPh8T.js} +1 -1
  126. package/payload/server/public/assets/{diagram-5BDNPKRD-B6tQBN1Y.js → diagram-5BDNPKRD-C8AXEFch.js} +1 -1
  127. package/payload/server/public/assets/{diagram-G4DWMVQ6-t73WpYIY.js → diagram-G4DWMVQ6-B1P8Cwuz.js} +1 -1
  128. package/payload/server/public/assets/{diagram-MMDJMWI5-Cm63UOJm.js → diagram-MMDJMWI5-QBVBnPmO.js} +1 -1
  129. package/payload/server/public/assets/{diagram-TYMM5635-DuTSLjVB.js → diagram-TYMM5635-D2xE8fN8.js} +1 -1
  130. package/payload/server/public/assets/{erDiagram-SMLLAGMA-sbHunitX.js → erDiagram-SMLLAGMA-DMee1Yih.js} +1 -1
  131. package/payload/server/public/assets/{flowDiagram-DWJPFMVM-BWOrPuqz.js → flowDiagram-DWJPFMVM-DAd3JjoB.js} +1 -1
  132. package/payload/server/public/assets/{ganttDiagram-T4ZO3ILL-WaLMGard.js → ganttDiagram-T4ZO3ILL-Bs33CmKo.js} +1 -1
  133. package/payload/server/public/assets/{gitGraphDiagram-UUTBAWPF-CsbIgKDn.js → gitGraphDiagram-UUTBAWPF-NXc8aeps.js} +1 -1
  134. package/payload/server/public/assets/{graph-kwyPyf_b.js → graph-BSHyF267.js} +1 -1
  135. package/payload/server/public/assets/{graph-labels-pX3uIQys.js → graph-labels-D5ecmK-Z.js} +1 -1
  136. package/payload/server/public/assets/{graphlib-B8yKFZvc.js → graphlib-DN7sm5nK.js} +1 -1
  137. package/payload/server/public/assets/{infoDiagram-42DDH7IO-Bd55TzsD.js → infoDiagram-42DDH7IO-D2g5STFr.js} +1 -1
  138. package/payload/server/public/assets/{ishikawaDiagram-UXIWVN3A-BFdOsA9f.js → ishikawaDiagram-UXIWVN3A-DBgfV-LB.js} +1 -1
  139. package/payload/server/public/assets/{journeyDiagram-VCZTEJTY-CMQ5XWO9.js → journeyDiagram-VCZTEJTY-Chh9lW9P.js} +1 -1
  140. package/payload/server/public/assets/{kanban-definition-6JOO6SKY-_RpNNRN7.js → kanban-definition-6JOO6SKY-buI2AXpi.js} +1 -1
  141. package/payload/server/public/assets/{line-SkFxjGJ8.js → line-C8OFYjrW.js} +1 -1
  142. package/payload/server/public/assets/{mermaid-parser.core-Ddok2IAe.js → mermaid-parser.core-BI5Ythbv.js} +1 -1
  143. package/payload/server/public/assets/{mermaid.core-CihAjXBG.js → mermaid.core-C4dyl1Xw.js} +3 -3
  144. package/payload/server/public/assets/{mindmap-definition-QFDTVHPH-CJsq3hrO.js → mindmap-definition-QFDTVHPH-BbXKSpiv.js} +1 -1
  145. package/payload/server/public/assets/{pieDiagram-DEJITSTG-CSgg8lBB.js → pieDiagram-DEJITSTG-C8-OIoUW.js} +1 -1
  146. package/payload/server/public/assets/{public-BA9P-3ZV.js → public-DGlZwbyw.js} +3 -3
  147. package/payload/server/public/assets/{quadrantDiagram-34T5L4WZ-TtHxMQtS.js → quadrantDiagram-34T5L4WZ-HOEtpu4n.js} +1 -1
  148. package/payload/server/public/assets/{requirementDiagram-MS252O5E-DdYupKtL.js → requirementDiagram-MS252O5E-DLxjohCO.js} +1 -1
  149. package/payload/server/public/assets/{sankeyDiagram-XADWPNL6-BVfdyUnO.js → sankeyDiagram-XADWPNL6-E_O_HiFL.js} +1 -1
  150. package/payload/server/public/assets/{sequenceDiagram-FGHM5R23-aFLOua6n.js → sequenceDiagram-FGHM5R23-C3-hhAup.js} +1 -1
  151. package/payload/server/public/assets/{stateDiagram-FHFEXIEX-_3Ix8SPZ.js → stateDiagram-FHFEXIEX-BhAmQ0XX.js} +1 -1
  152. package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-Dhrf9hq_.js +1 -0
  153. package/payload/server/public/assets/{timeline-definition-GMOUNBTQ-Bs96WqZ7.js → timeline-definition-GMOUNBTQ-DpfZt7xI.js} +1 -1
  154. package/payload/server/public/assets/{useSelectionMode-L9uAHstA.css → useSelectionMode-98jrB9kD.css} +1 -1
  155. package/payload/server/public/assets/{vennDiagram-DHZGUBPP-DE_SxsN2.js → vennDiagram-DHZGUBPP-Ck2Ago5q.js} +1 -1
  156. package/payload/server/public/assets/{wardleyDiagram-NUSXRM2D-DTCdKs6v.js → wardleyDiagram-NUSXRM2D-Dgk8C9kF.js} +1 -1
  157. package/payload/server/public/assets/{xychartDiagram-5P7HB3ND-CNIrxADs.js → xychartDiagram-5P7HB3ND-BRBSl8ID.js} +1 -1
  158. package/payload/server/public/browser.html +4 -4
  159. package/payload/server/public/data.html +5 -5
  160. package/payload/server/public/graph.html +6 -6
  161. package/payload/server/public/index.html +5 -5
  162. package/payload/server/public/public.html +4 -4
  163. package/payload/server/server.js +607 -5064
  164. package/payload/server/public/assets/channel-Db8J_1Rl.js +0 -1
  165. package/payload/server/public/assets/classDiagram-6PBFFD2Q-DjquNGFr.js +0 -1
  166. package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-CcE8sWEP.js +0 -1
  167. package/payload/server/public/assets/clone-xa7JZYoY.js +0 -1
  168. package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-eVQQEyxx.js +0 -1
  169. /package/payload/server/public/assets/{useSelectionMode-Da9Glxvu.js → useSelectionMode-80iYuGPa.js} +0 -0
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: platform-architecture
3
3
  description: Use when grounding any documented-surface claim about what SiteOffice 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:1a53491b6e8b0d6ee4c3e7d648e48e6599de88d5280e7b8b5851c7d2ce3f4b44
4
+ content-hash: sha256:4689ef665b110bf635cf207902292849ab66cb6af548410fe5b49f1364c64d86
5
5
  brand: siteoffice-code
6
6
  product-name: SiteOffice
7
7
  ---
@@ -15,27 +15,27 @@ This skill is generated. Its body is the concatenated source markdown for every
15
15
  When you load this skill to ground a factual claim, cite the `Source:` URL printed above the block you drew from. The URL is the canonical public docs page (https://siteoffice.online); relay it as a markdown link in your reply. Training-data recall is not a permitted source — the body below is.
16
16
 
17
17
  ---
18
- # Maxy Documentation — full corpus
18
+ # SiteOffice Documentation — full corpus
19
19
 
20
- Concatenated source markdown for every public Maxy docs page. Pages are separated by `---` and labelled with their canonical URL.
20
+ Concatenated source markdown for every public SiteOffice docs page. Pages are separated by `---` and labelled with their canonical URL.
21
21
 
22
22
  ---
23
23
  # Getting Started
24
24
  Source: https://docs.getmaxy.com/getting-started.md
25
25
 
26
- # Getting Started with Maxy
26
+ # Getting Started with SiteOffice
27
27
 
28
- ## What Maxy Is
28
+ ## What SiteOffice Is
29
29
 
30
- Maxy is your Operations Manager — an operations layer that runs on a device on your premises. It plays four roles: follows through on your commitments, responds to your customers at any hour, handles your finances (quotes, invoices, chasing), and manages your picture — what's overdue, what's at risk, what needs a decision.
30
+ SiteOffice is your Operations Manager — an operations layer that runs on a device on your premises. It plays four roles: follows through on your commitments, responds to your customers at any hour, handles your finances (quotes, invoices, chasing), and manages your picture — what's overdue, what's at risk, what needs a decision.
31
31
 
32
- You don't adopt a new system. You just talk, and the organisation happens. Maxy connects to your services — WhatsApp, Telegram, email, your contacts, your calendar — and acts proactively. It remembers context across conversations and takes action on your behalf.
32
+ You don't adopt a new system. You just talk, and the organisation happens. SiteOffice connects to your services — WhatsApp, Telegram, email, your contacts, your calendar — and acts proactively. It remembers context across conversations and takes action on your behalf.
33
33
 
34
- Because Maxy runs locally, your data stays in your home. It never passes through someone else's cloud.
34
+ Because SiteOffice runs locally, your data stays in your home. It never passes through someone else's cloud.
35
35
 
36
36
  ## The Two Interfaces
37
37
 
38
- **Admin (you)** — accessed at your local address (e.g. `maxy.local:19200`) or remotely via your Cloudflare domain. The admin interface is protected by a PIN. This is where you manage Maxy: configure settings, manage contacts, review activity, and have full conversations. The admin agent has access to all your plugins and can take action.
38
+ **Admin (you)** — accessed at your local address (e.g. `maxy.local:19200`) or remotely via your Cloudflare domain. The admin interface is protected by a PIN. This is where you manage SiteOffice: configure settings, manage contacts, review activity, and have full conversations. The admin agent has access to all your plugins and can take action.
39
39
 
40
40
  **Public (visitors)** — anyone who reaches your public URL gets the public agent. It handles product enquiries, collects prospect details, and answers questions about your business. It cannot read or write your private data.
41
41
 
@@ -44,7 +44,7 @@ Because Maxy runs locally, your data stays in your home. It never passes through
44
44
  If your device has no WiFi configured and no ethernet cable connected, it creates a temporary WiFi network for setup:
45
45
 
46
46
  1. Power on the device and wait about 60 seconds
47
- 2. On your phone, look for a WiFi network called **{ProductName}-Setup** (e.g. `Maxy-Setup`)
47
+ 2. On your phone, look for a WiFi network called **{ProductName}-Setup** (e.g. `SiteOffice-Setup`)
48
48
  3. Connect to that network — a setup page opens automatically
49
49
  4. Select your home WiFi network from the list and enter the password
50
50
  5. The device connects to your WiFi and the temporary network disappears
@@ -59,15 +59,15 @@ If you already have ethernet connected, the temporary WiFi network does not appe
59
59
  When you first open the admin interface:
60
60
 
61
61
  1. Set your PIN — this protects access to the admin interface
62
- 2. Connect to Claude — Maxy will guide you through connecting to your Claude account
62
+ 2. Connect to Claude — SiteOffice will guide you through connecting to your Claude account
63
63
  3. Enter your PIN to log in
64
- 4. Maxy walks you through onboarding: choosing which plugins to activate, connecting to WiFi (skip if already configured via the setup network above), setting up remote access, and configuring your account
64
+ 4. SiteOffice walks you through onboarding: choosing which plugins to activate, connecting to WiFi (skip if already configured via the setup network above), setting up remote access, and configuring your account
65
65
 
66
- This setup is resumable — if you close the browser mid-setup, Maxy picks up where you left off next time.
66
+ This setup is resumable — if you close the browser mid-setup, SiteOffice picks up where you left off next time.
67
67
 
68
68
  After install, a live admin terminal is available inside the Software Update window — your Pi's shell, accessible through the admin UI, for upgrades and any other shell work without needing to SSH.
69
69
 
70
- ## How to Use Maxy
70
+ ## How to Use SiteOffice
71
71
 
72
72
  Conversation is the only interface. Type or speak what you need:
73
73
 
@@ -77,23 +77,23 @@ Conversation is the only interface. Type or speak what you need:
77
77
  - "Send a Telegram message to the team: standup in 10 minutes"
78
78
  - "Create a one-pager PDF about our new product launch"
79
79
 
80
- Maxy understands plain language. You don't need to learn commands or navigate menus.
80
+ SiteOffice understands plain language. You don't need to learn commands or navigate menus.
81
81
 
82
82
  ### Voice Notes
83
83
 
84
- When the text field is empty, a microphone button appears in place of the send button. Tap it to record a voice note — speak naturally and tap send when done. Maxy transcribes your voice note and responds to what you said, the same as if you had typed it. You can also pause and resume recording, or tap the trash icon to discard and start over.
84
+ When the text field is empty, a microphone button appears in place of the send button. Tap it to record a voice note — speak naturally and tap send when done. SiteOffice transcribes your voice note and responds to what you said, the same as if you had typed it. You can also pause and resume recording, or tap the trash icon to discard and start over.
85
85
 
86
- Voice recording requires a secure connection (HTTPS). When accessing Maxy over the local network via HTTP, use the tunnel URL for voice notes.
86
+ Voice recording requires a secure connection (HTTPS). When accessing SiteOffice over the local network via HTTP, use the tunnel URL for voice notes.
87
87
 
88
- You can also drop, paste, or pick an audio file (`.opus`, `.ogg`, `.m4a`, `.mp3`, `.wav`, `.webm`) into the chat composer — for example a voice note forwarded from WhatsApp. The file is transcribed the same way the in-browser recording is, and only the transcript reaches Maxy; the audio itself is discarded after transcription.
88
+ You can also drop, paste, or pick an audio file (`.opus`, `.ogg`, `.m4a`, `.mp3`, `.wav`, `.webm`) into the chat composer — for example a voice note forwarded from WhatsApp. The file is transcribed the same way the in-browser recording is, and only the transcript reaches SiteOffice; the audio itself is discarded after transcription.
89
89
 
90
- ## What Maxy Remembers
90
+ ## What SiteOffice Remembers
91
91
 
92
- Maxy maintains a memory graph of everything important: contacts, conversations, preferences, relationships, and context. When you tell Maxy something, it stores it. When you ask about something later, it retrieves it.
92
+ SiteOffice maintains a memory graph of everything important: contacts, conversations, preferences, relationships, and context. When you tell SiteOffice something, it stores it. When you ask about something later, it retrieves it.
93
93
 
94
- You can always tell Maxy to remember or forget specific things: "Remember that I prefer morning calls" or "Forget what I said about the Johnson account."
94
+ You can always tell SiteOffice to remember or forget specific things: "Remember that I prefer morning calls" or "Forget what I said about the Johnson account."
95
95
 
96
- ## Reaching Your Data When Maxy Is Unavailable
96
+ ## Reaching Your Data When SiteOffice Is Unavailable
97
97
 
98
98
  If the AI is ever unreachable — network outage, API provider down — you can still access your own data through the **Data** item in the admin header menu. It opens a page with two panels:
99
99
 
@@ -104,21 +104,21 @@ Everything on this page works without calling any AI service. It's there so your
104
104
 
105
105
  ## Getting Help
106
106
 
107
- Ask Maxy anything. If you want to know what it can do, just ask: "What can you help me with?" or "How do I set up Telegram?"
107
+ Ask SiteOffice anything. If you want to know what it can do, just ask: "What can you help me with?" or "How do I set up Telegram?"
108
108
 
109
109
  ---
110
- # How Maxy Works
110
+ # How SiteOffice Works
111
111
  Source: https://docs.getmaxy.com/platform.md
112
112
 
113
- # How Maxy Works
113
+ # How SiteOffice Works
114
114
 
115
115
  ## The Short Version
116
116
 
117
- Maxy runs on a Raspberry Pi in your home. It uses Claude (Anthropic's AI) as its brain and extends it with plugins — modular capabilities like contacts, Telegram, and memory. Everything stays local: your data, your conversations, your memory graph.
117
+ SiteOffice runs on a Raspberry Pi in your home. It uses Claude (Anthropic's AI) as its brain and extends it with plugins — modular capabilities like contacts, Telegram, and memory. Everything stays local: your data, your conversations, your memory graph.
118
118
 
119
119
  ## The Raspberry Pi
120
120
 
121
- Maxy is a server that lives on your local network. It's always on, always available, and accessible:
121
+ SiteOffice is a server that lives on your local network. It's always on, always available, and accessible:
122
122
 
123
123
  - **Locally:** `maxy.local:19200` (or the IP address of your Pi)
124
124
  - **Remotely:** via your personal domain, routed through a Cloudflare tunnel
@@ -127,7 +127,7 @@ The Pi runs the web interface, the AI agent, and all the plugin servers. When yo
127
127
 
128
128
  ## The Two Agents
129
129
 
130
- Maxy runs two agents simultaneously:
130
+ SiteOffice runs two agents simultaneously:
131
131
 
132
132
  **Admin agent (you)** — full access to all tools and plugins. This is the agent you interact with at your local or remote URL. It can read and write contacts, send Telegram messages, manage your account, and perform any task you have plugins for. Protected by your PIN. Your admin agent runs through your own Claude Code OAuth session — it never bills the Anthropic API. Authentication and SDK details are documented in the developer doc `.docs/platform.md` admin-agent section.
133
133
 
@@ -135,7 +135,7 @@ Maxy runs two agents simultaneously:
135
135
 
136
136
  ## Plugins
137
137
 
138
- Everything Maxy can do is provided by a plugin. Each plugin is a self-contained package:
138
+ Everything SiteOffice can do is provided by a plugin. Each plugin is a self-contained package:
139
139
 
140
140
  - Behaviour instructions (how the agent should act)
141
141
  - Tools (specific actions the agent can take, exposed via MCP servers)
@@ -145,13 +145,13 @@ Everything Maxy can do is provided by a plugin. Each plugin is a self-contained
145
145
 
146
146
  **Where premium bundle subs live.** Bundle subs (`loop`, `property-data`, `brochures`, etc. inside `real-agent`) live exclusively at `premium-plugins/<bundle>/plugins/<sub>/` and are registered via the resolver's bundle-descent walk. Standalone premiums (no `BUNDLE.md`, e.g. `writer-craft`, `teaching`, `venture-studio`) live exclusively at `premium-plugins/<name>/` and are registered via the resolver's dual-root scan (`platform/plugins/` and `premium-plugins/` are both `pluginsRoots`). Neither shape is flat-copied into `platform/plugins/<name>/`. A divergent flat copy of a bundle sub is treated as an operator override: the resolver refuses to boot with `boot-failed reason=mcp-plugin-duplicate <plugin> declared by more than one plugins root: <pathA> (sha=…) vs <pathB> (sha=…)` so the operator can `sha256sum` both paths and remove the stale one. Byte-identical bundle-sub flat copies left over from installer versions that flat-copied bundle subs are reaped on the first post-upgrade boot (`[premium-auto-deliver] reaped sub=<name> reason=duplicate-of-premium-tree`). Standalone flat copies (leaked by the pre-fix `autoDeliverPremiumPlugins` standalone branch) are reaped unconditionally — there is no documented override path for standalones at `platform/plugins/<name>/` — and the reaper logs `[premium-auto-deliver] reaped standalone=<name> matches-source=<true|false>` so divergent reaps leave a forensic trail.
147
147
 
148
- Plugins are installed and managed through conversation. You can add marketplace plugins (like Stripe) or use Maxy's built-in ones (contacts, memory, Telegram).
148
+ Plugins are installed and managed through conversation. You can add marketplace plugins (like Stripe) or use SiteOffice's built-in ones (contacts, memory, Telegram).
149
149
 
150
150
  ## Roles
151
151
 
152
- Maxy ships twelve roles it can dispatch for specific tasks — like members of your team. You don't need to configure or manage them — Maxy decides when to use each role and handles everything automatically. You may see activity like "Dispatching personal-assistant..." in the chat timeline when this happens.
152
+ SiteOffice ships twelve roles it can dispatch for specific tasks — like members of your team. You don't need to configure or manage them — SiteOffice decides when to use each role and handles everything automatically. You may see activity like "Dispatching personal-assistant..." in the chat timeline when this happens.
153
153
 
154
- The catalogue below is what the platform ships. It is not evidence of what is installed on the current account. For the live install set on this account, ask Maxy to call `capabilities-here`.
154
+ The catalogue below is what the platform ships. It is not evidence of what is installed on the current account. For the live install set on this account, ask SiteOffice to call `capabilities-here`.
155
155
 
156
156
  | Role | What it does |
157
157
  |------|-------------|
@@ -168,13 +168,13 @@ The catalogue below is what the platform ships. It is not evidence of what is in
168
168
  | Research Assistant | Researches topics online, manages your knowledge graph, and produces supporting visuals. |
169
169
  | Typed Edge Classifier | Reads recently-written prose nodes and writes typed edges from a closed allowlist. |
170
170
 
171
- Roles are installed during setup and listed when Maxy introduces itself. Some premium bundles add their own specialists (e.g. the `real-agent` bundle adds a listing curator, negotiator, valuer, compliance officer, and buyer-enquiry public agent). Roles installed mid-session become active from the next session.
171
+ Roles are installed during setup and listed when SiteOffice introduces itself. Some premium bundles add their own specialists (e.g. the `real-agent` bundle adds a listing curator, negotiator, valuer, compliance officer, and buyer-enquiry public agent). Roles installed mid-session become active from the next session.
172
172
 
173
173
  ## Memory
174
174
 
175
- Maxy maintains a graph database (Neo4j) of everything you've told it. People, conversations, preferences, and context are stored as connected nodes. When you ask Maxy something, it searches this graph to retrieve relevant context before responding.
175
+ SiteOffice maintains a graph database (Neo4j) of everything you've told it. People, conversations, preferences, and context are stored as connected nodes. When you ask SiteOffice something, it searches this graph to retrieve relevant context before responding.
176
176
 
177
- **The recording loop.** Maxy dispatches `database-operator` inline at its own discretion when a write must complete before the assistant response ends. The full graph-completeness sweep runs on demand: when you invoke the `/insight` admin skill, it runs a four-pass instruction and Maxy walks the session for any node, edge, or commitment that was discussed but not written in-flight, dispatches one `database-operator` Task per candidate write, then carries on in the same session.
177
+ **The recording loop.** SiteOffice dispatches `database-operator` inline at its own discretion when a write must complete before the assistant response ends. The full graph-completeness sweep runs on demand: when you invoke the `/insight` admin skill, it runs a four-pass instruction and SiteOffice walks the session for any node, edge, or commitment that was discussed but not written in-flight, dispatches one `database-operator` Task per candidate write, then carries on in the same session.
178
178
 
179
179
  The memory graph is stored on your Pi. It never leaves your network.
180
180
 
@@ -192,9 +192,9 @@ There is no dashboard, no settings panel, no menus. Everything is done through c
192
192
 
193
193
  The chat input auto-grows as you type — it expands to fit your message and shrinks back when you delete text. You can also drag the resize handle above the input to set a custom height.
194
194
 
195
- The admin interface is a three-pane layout: a sidebar on the left with navigation (Sessions, People, Agents, Projects, Tasks, Artefacts) and your recent conversations; the chat in the middle; and an artefact pane on the right that opens when you select a document, click a project, or open Browser, Data, or Graph from the menu, holding the surface side-by-side with the conversation so the chat stays live while you work in it. At the very top of the sidebar — above the nav rows — a borderless row holds two controls: a "+ New session" button on the left that spawns a fresh Claude Code session, and a Mode trigger on the right showing the current permission mode (Ask, Accept edits, Plan, or Auto). The sidebar's vertical order is: new-session strip first, then the nav (Sessions, People, Agents, Projects, Tasks, Artefacts), then the sessions list, then the footer. Both controls render as plain text-plus-icon affordances with no surrounding rectangle. The "+ New session" button is a text-width hit target — its clickable area is exactly the icon plus label, not the whole row — and shows no hover fill; the only hover feedback is the pointer cursor. The Mode trigger is pushed flush to the right edge of the row. Clicking the Mode trigger opens a popover downward from the row whose header reads "Mode" and lists the four permission modes with the current selection check-marked. The sidebar's nav rows swap the list view in place: Sessions shows recent conversations, Projects shows your active work projects, and Artefacts lists every KnowledgeDocument plus this account's agent templates (your admin agent's IDENTITY, SOUL, and KNOWLEDGE files plus one entry per enabled specialist). Each recent session row carries a three-state indicator: three pulsing dots when the session is busy (currently processing a turn), a solid sage dot when it is idle (live PTY waiting for input), and a hollow ring when it is archived (PTY exited, JSONL on disk for audit). The list itself splits into three views via a segmented control above the rows: **Active** shows every live session, **Archived** shows every JSONL on disk whose PTY has exited, and **All** shows both. The view choice persists across reloads. An "Include subagents" toggle inside the Active view surfaces specialist spawns (database-operator, premium-plugin agents, anything spawned with a `--agent` flag) which are hidden by default so the list reflects what you started directly. Each row also carries a small uppercase badge — `admin` for operator-driven sessions, the specialist name (for example `db-op`) for background work — so the source of any row is unambiguous at a glance. The People, Agents, and Tasks rows are graph shortcuts: clicking each opens the artefact-pane Graph filtered to every Person, every public Agent, or every Task in your account respectively, with no side-list, because the graph itself is the result. Public agents become first-class graph entities the moment you create them, with edges to their IDENTITY/SOUL/KNOWLEDGE files, edges to every knowledge document they have access to, and edges from every conversation they have handled, so a single Agents click reveals the whole shape of who knows what and who has been talking to whom. Click an artefact row to open the document. KnowledgeDocuments and your admin agent's templates are editable: type in the document and changes save automatically; specialist agent templates are read-only because they ship with Maxy and your edits would be overwritten on the next install. PDF artefacts render inline so you can read them without leaving the pane. If your browser doesn't have a built-in PDF viewer, a Download button appears instead. Artefacts that have no readable file backing them (orphan rows, files removed from disk, unsupported content types) show a one-line banner explaining the skip instead of opening to a blank pane. Click a project row to open the Graph view focused on that project's neighbourhood; clicking a second project swaps the focus rather than stacking on top. The sidebar's right edge is drag-resizable on every admin page (Sessions root, Graph, and Data): drag the handle to widen or narrow the sidebar, and your chosen width is remembered across reloads and shared across all three pages. The drag handle is mounted by each AdminShell consumer rather than by AdminShell itself, so any new admin route must include `<SidebarSplitter />` as a direct child of its `<AdminShell>` to pick up the shared width. The chat and artefact divider is also drag-resizable: drag the line between the columns to make either side wider; double-click it to reset to half of the available width (viewport minus sidebar), clamped to the chat and artefact min-width floors. Your chosen width is remembered across reloads. On wider screens (>1280px) all three panes are visible. The sidebar narrows at 1280px, the artefact pane hides at 1080px (Browser, Data, and Graph then open as full-window pages instead), and the sidebar collapses to a 56px icon rail at 820px. On every viewport the chat header reads left to right as a triptych: a dedicated sidebar toggle (the panel-right icon, which swaps to panel-right-open when the sidebar is showing), the brand mark next to the title in the centre, and the menu burger on the right. This header toggle is the sole sidebar-toggle button; the sidebar itself no longer carries a duplicate. Tap the sidebar toggle to show or hide the sidebar: on phones (<720px) it slides the drawer in or out, on wider screens it collapses or expands the sidebar column. The brand mark in the centre is decorative; clicks go through the dedicated toggle so the affordance is unambiguous. The drawer animation only fires on tap (220ms slide in or out); resizing your window across the 720px boundary snaps the layout without animation, so you never see a half-open flash. At ≤640px the session metadata pane stacks each label above its value instead of the desktop two-column grid, and the row of action buttons (Open in new tab / Download JSONL / View JSONL / Rename / Pin / Archive / End or Purge) collapses behind a single Actions trigger that opens a popover upward from the foot of the pane. Breakpoint summary: >1280px = full sidebar + chat + artefact pane (drag-resizable divider); 1280px→1080px = sidebar narrows; 1080px→820px = artefact pane hides (Browser/Data/Graph open as full-window pages instead); 820px→720px = sidebar collapses to 56px icon rail; ≤720px = sidebar becomes off-canvas drawer (vertical stack of nav, recents list, foot, the same shape as the desktop sidebar, just on top of the chat instead of beside it).
195
+ The admin interface is a three-pane layout: a sidebar on the left with navigation (Sessions, People, Agents, Projects, Tasks, Artefacts) and your recent conversations; the chat in the middle; and an artefact pane on the right that opens when you select a document, click a project, or open Browser, Data, or Graph from the menu, holding the surface side-by-side with the conversation so the chat stays live while you work in it. At the very top of the sidebar — above the nav rows — a borderless row holds two controls: a "+ New session" button on the left that spawns a fresh Claude Code session, and a Mode trigger on the right showing the current permission mode (Ask, Accept edits, Plan, or Auto). The sidebar's vertical order is: new-session strip first, then the nav (Sessions, People, Agents, Projects, Tasks, Artefacts), then the sessions list, then the footer. Both controls render as plain text-plus-icon affordances with no surrounding rectangle. The "+ New session" button is a text-width hit target — its clickable area is exactly the icon plus label, not the whole row — and shows no hover fill; the only hover feedback is the pointer cursor. The Mode trigger is pushed flush to the right edge of the row. Clicking the Mode trigger opens a popover downward from the row whose header reads "Mode" and lists the four permission modes with the current selection check-marked. The sidebar's nav rows swap the list view in place: Sessions shows recent conversations, Projects shows your active work projects, and Artefacts lists every KnowledgeDocument plus this account's agent templates (your admin agent's IDENTITY, SOUL, and KNOWLEDGE files plus one entry per enabled specialist). Each recent session row carries a three-state indicator: three pulsing dots when the session is busy (currently processing a turn), a solid sage dot when it is idle (live PTY waiting for input), and a hollow ring when it is archived (PTY exited, JSONL on disk for audit). The list itself splits into three views via a segmented control above the rows: **Active** shows every live session, **Archived** shows every JSONL on disk whose PTY has exited, and **All** shows both. The view choice persists across reloads. An "Include subagents" toggle inside the Active view surfaces specialist spawns (database-operator, premium-plugin agents, anything spawned with a `--agent` flag) which are hidden by default so the list reflects what you started directly. Each row also carries a small uppercase badge — `admin` for operator-driven sessions, the specialist name (for example `db-op`) for background work — so the source of any row is unambiguous at a glance. The People, Agents, and Tasks rows are graph shortcuts: clicking each opens the artefact-pane Graph filtered to every Person, every public Agent, or every Task in your account respectively, with no side-list, because the graph itself is the result. Public agents become first-class graph entities the moment you create them, with edges to their IDENTITY/SOUL/KNOWLEDGE files, edges to every knowledge document they have access to, and edges from every conversation they have handled, so a single Agents click reveals the whole shape of who knows what and who has been talking to whom. Click an artefact row to open the document. KnowledgeDocuments and your admin agent's templates are editable: type in the document and changes save automatically; specialist agent templates are read-only because they ship with SiteOffice and your edits would be overwritten on the next install. PDF artefacts render inline so you can read them without leaving the pane. If your browser doesn't have a built-in PDF viewer, a Download button appears instead. Artefacts that have no readable file backing them (orphan rows, files removed from disk, unsupported content types) show a one-line banner explaining the skip instead of opening to a blank pane. Click a project row to open the Graph view focused on that project's neighbourhood; clicking a second project swaps the focus rather than stacking on top. The sidebar's right edge is drag-resizable on every admin page (Sessions root, Graph, and Data): drag the handle to widen or narrow the sidebar, and your chosen width is remembered across reloads and shared across all three pages. The drag handle is mounted by each AdminShell consumer rather than by AdminShell itself, so any new admin route must include `<SidebarSplitter />` as a direct child of its `<AdminShell>` to pick up the shared width. The chat and artefact divider is also drag-resizable: drag the line between the columns to make either side wider; double-click it to reset to half of the available width (viewport minus sidebar), clamped to the chat and artefact min-width floors. Your chosen width is remembered across reloads. On wider screens (>1280px) all three panes are visible. The sidebar narrows at 1280px, the artefact pane hides at 1080px (Browser, Data, and Graph then open as full-window pages instead), and the sidebar collapses to a 56px icon rail at 820px. On every viewport the chat header reads left to right as a triptych: a dedicated sidebar toggle (the panel-right icon, which swaps to panel-right-open when the sidebar is showing), the brand mark next to the title in the centre, and the menu burger on the right. This header toggle is the sole sidebar-toggle button; the sidebar itself no longer carries a duplicate. Tap the sidebar toggle to show or hide the sidebar: on phones (<720px) it slides the drawer in or out, on wider screens it collapses or expands the sidebar column. The brand mark in the centre is decorative; clicks go through the dedicated toggle so the affordance is unambiguous. The drawer animation only fires on tap (220ms slide in or out); resizing your window across the 720px boundary snaps the layout without animation, so you never see a half-open flash. At ≤640px the session metadata pane stacks each label above its value instead of the desktop two-column grid, and the row of action buttons (Open in new tab / Download JSONL / View JSONL / Rename / Pin / Archive / End or Purge) collapses behind a single Actions trigger that opens a popover upward from the foot of the pane. Breakpoint summary: >1280px = full sidebar + chat + artefact pane (drag-resizable divider); 1280px→1080px = sidebar narrows; 1080px→820px = artefact pane hides (Browser/Data/Graph open as full-window pages instead); 820px→720px = sidebar collapses to 56px icon rail; ≤720px = sidebar becomes off-canvas drawer (vertical stack of nav, recents list, foot, the same shape as the desktop sidebar, just on top of the chat instead of beside it).
196
196
 
197
- Page titles are brand-aware: the browser tab shows your product name (e.g. `Real Agent` instead of `Maxy`) on every shell — chat, graph, and data — so a non-default brand never leaks the default name in tab strips or browser history.
197
+ Page titles are brand-aware: the browser tab shows your product name (e.g. `Real Agent` instead of `SiteOffice`) on every shell — chat, graph, and data — so a non-default brand never leaks the default name in tab strips or browser history.
198
198
 
199
199
  **Session lifecycle and reconcile model.** The sidebar Sessions list is driven by a single Server-Sent Events feed at `/api/admin/claude-sessions/events`. The session manager watches the two directories Claude Code writes (`${CLAUDE_CONFIG_DIR}/sessions/<pid>.json` for live state, `${CLAUDE_CONFIG_DIR}/projects/<slug>/<sid>.jsonl` for transcripts) and emits `row-created`, `row-updated`, `row-archived`, or `row-removed` deltas to every connected browser tab. Three real delete shapes map to deltas — there is no fourth: PID file gone with JSONL surviving demotes the row to `row-archived`; PID file gone with no JSONL ever written (a hidden spawn that exits before writing a JSONL) emits `row-removed` against the unindexed sessionId; a JSONL deletion against an already-unindexed row also emits `row-removed`. This branch reconciles transient hidden spawns — without it, ghost rows persist after a hidden spawn exits. On connect the manager replays the current row index so a freshly-opened tab catches up without polling, then streams deltas as files change on disk. Two open tabs see the same list within ~300ms of any spawn, status flip, or exit; no refresh button required for state to be current. The legacy `/list` fetch and `useAdminSessions` hook stay mounted to serve the ConversationsModal and the post-action reconcile path in `session-actions`, but the sidebar's visible rows come from the row store, not from `/list`. Each EventSource open emits `[admin-events] client-connected ip=<…> seeded-rows=<n>` server-side and `[admin-ui] session-row-store connected events-received=<n>` in the browser console; transport drops log `[admin-ui] session-row-store reconnect trigger=<auto|manual> attempt=<n> delay-ms=<n>` until the EventSource reattaches. The small dot at the right edge of the Active/Archived/All segmented control is the live-updates indicator: sage when the SSE feed is connected, grey when the feed has dropped. The grey state is an actionable button — clicking it cancels any pending backoff and re-opens the feed immediately, with the click logged as `trigger=manual` so manual retries are distinguishable from automatic ones in the console. The refresh icon at the top of the Sessions list is the operator-recoverable reconcile path against any SSE gap: it fetches `/api/admin/claude-sessions` and passes the authoritative id set to the row store, which evicts any indexed row that the server no longer reports. SSE replay only re-asserts currently-indexed rows and never emits `row-removed` for a row that vanished while disconnected, so without this manual surface a stale row can persist until the operator reloads the tab. Each click logs `[admin-ui] session-row-store reconcile evicted=<n> kept=<n>` when at least one row is evicted, and is silent otherwise.
200
200
 
@@ -292,7 +292,7 @@ Messages you write yourself (e.g. typing directly in WhatsApp) are not marked
292
292
 
293
293
  ## Session Slot Safeguards
294
294
 
295
- Maxy runs each chat — yours and every visitor's — as a separate `claude` process on your Pi. Three safeguards keep these processes from piling up:
295
+ SiteOffice runs each chat — yours and every visitor's — as a separate `claude` process on your Pi. Three safeguards keep these processes from piling up:
296
296
 
297
297
  - **Specialist cap.** Background specialists (`database-operator`, `content-producer`, etc.) are limited to three running at once. If you ask for a fourth while three are still working, the oldest idle one is shut down first. If all three are actively running, the request is rejected with `specialist-cap-reached`.
298
298
  - **Operator reserve.** Two slots are always held back for *you* — your own chats and one-off tasks. Specialist work that would consume the last reserved slot is rejected with `operator-slots-reserved`. Your interactive chats are never blocked.
@@ -314,17 +314,17 @@ Source: https://docs.getmaxy.com/plugins-guide.md
314
314
 
315
315
  ## What a Plugin Is
316
316
 
317
- A plugin extends what Maxy can do. Each plugin adds a focused capability — contacts management, Telegram messaging, scheduling, email, research. Plugins are modular: you enable only what you need.
317
+ A plugin extends what SiteOffice can do. Each plugin adds a focused capability — contacts management, Telegram messaging, scheduling, email, research. Plugins are modular: you enable only what you need.
318
318
 
319
- Maxy's own capabilities are plugins too. Marketplace plugins (like Stripe) work the same way — Maxy manages all of them through conversation.
319
+ SiteOffice's own capabilities are plugins too. Marketplace plugins (like Stripe) work the same way — SiteOffice manages all of them through conversation.
320
320
 
321
- The tables below are the install catalogue — every plugin the platform can ship. They are not evidence of what is enabled on the current account. For the live install set, ask Maxy to call `capabilities-here`.
321
+ The tables below are the install catalogue — every plugin the platform can ship. They are not evidence of what is enabled on the current account. For the live install set, ask SiteOffice to call `capabilities-here`.
322
322
 
323
323
  ## Plugin Groups
324
324
 
325
325
  ### Core (always active)
326
326
 
327
- These are part of Maxy's foundation and cannot be disabled:
327
+ These are part of SiteOffice's foundation and cannot be disabled:
328
328
 
329
329
  | Plugin | What it does |
330
330
  |--------|-------------|
@@ -341,7 +341,7 @@ These are part of Maxy's foundation and cannot be disabled:
341
341
  | `prompt-optimiser` | Prompt optimiser — two modes. Chat-app mode turns a rough draft or task description into a single finished, copy-pasteable prompt tuned for Opus 4.7 adaptive thinking (claude.ai, Mac, iOS). In-session mode is applied automatically: a standing `UserPromptSubmit` directive hook (`admin/hooks/prompt-optimiser-directive.sh`) injects context every turn telling the admin agent to restate each non-trivial prompt through this skill and act on the restatement, skipped for one-word confirmations, slash-commands, and direct continuations. Compliance is behavioural — the hook steers the agent, it cannot force the skill call. |
342
342
  | `url-get` | Faithful page retrieval — fetches a server-rendered page, writes a verbatim markdown copy to an account-scoped reference file (no model in the path, so no copyright refusal), and returns the cleaned page text (capped) plus the file path. No summary and no subprocess: a caller that wants a summary invokes url-get from a delegated subagent. Use instead of WebFetch when a faithful copy is needed (e.g. ingesting your own published writing). |
343
343
 
344
- ### Maxy Plugins (user-selectable)
344
+ ### SiteOffice Plugins (user-selectable)
345
345
 
346
346
  These are enabled during onboarding and can be added or removed at any time. Some plugins enhance a specific specialist role — when enabled, that specialist gains additional capabilities.
347
347
 
@@ -390,9 +390,9 @@ Install verbatim:
390
390
 
391
391
  Brand decides which premium plugins ship. The brand's `shipsPremiumBundles` field in `brand.json` is the gate; three shapes are supported:
392
392
 
393
- - **omitted / false** — ship nothing from `premium-plugins/` (the legacy Maxy default).
393
+ - **omitted / false** — ship nothing from `premium-plugins/` (the legacy SiteOffice default).
394
394
  - **`true`** — ship every bundle under `premium-plugins/*` (Real Agent / `realagent-code`).
395
- - **`["bundle-a", "bundle-b"]`** — ship only the named bundle directories (Maxy Code's `["venture-studio"]`). Names with no matching directory on disk are silently dropped; non-allowlisted bundles are stripped from any account that was previously stamped with them.
395
+ - **`["bundle-a", "bundle-b"]`** — ship only the named bundle directories (SiteOffice Code's `["venture-studio"]`). Names with no matching directory on disk are silently dropped; non-allowlisted bundles are stripped from any account that was previously stamped with them.
396
396
 
397
397
  There is no per-account purchase record; the brand decides the shipping set.
398
398
 
@@ -403,39 +403,39 @@ There is no per-account purchase record; the brand decides the shipping set.
403
403
  | `writer-craft` | Skills + Agent | Manuscript review and writing craft — story architecture, reader engagement, prose craft, editorial practice, and multi-level review | No — writing craft serves the author |
404
404
  | `venture-studio` | Skills + Agent | Founding-a-business workflow — office-hours discovery, brand pack, zero-to-prototype validation, and the full investor data room (business plan, prospectus, term sheet, deck blueprint, A4 print pipeline). Pre-seeds a `Project` with one `Task` per artefact so nothing gets forgotten. | No — founder-facing only |
405
405
 
406
- **How it works:** Every boot Maxy delivers the brand's premium plugins from staging into `platform/plugins/` and stamps `enabledPlugins` against what is actually on disk. No conversation needed — the brand's full set is active from the first turn after install. Updates and reinstalls re-deliver from staging.
406
+ **How it works:** Every boot SiteOffice delivers the brand's premium plugins from staging into `platform/plugins/` and stamps `enabledPlugins` against what is actually on disk. No conversation needed — the brand's full set is active from the first turn after install. Updates and reinstalls re-deliver from staging.
407
407
 
408
408
  Some premium plugins are **bundles** — multiple sub-plugins shipped under one directory in `premium-plugins/`, each independently activatable. For example, Real Agent ships 10 sub-plugins covering different aspects of estate agency work. They are all enabled by default. Sub-plugins you don't want active can be turned off individually with "disable <name>"; enabling or disabling individual sub-plugins does not affect the others.
409
409
 
410
- If you ask Maxy about a tool from a plugin your brand does not ship (for example, a Maxy install asking about a Real Agent Loop CRM tool), Maxy responds with a structured `<tool-surface-error>` envelope naming the missing plugin and the remedy, rather than improvising with a generic alternative.
410
+ If you ask SiteOffice about a tool from a plugin your brand does not ship (for example, a SiteOffice install asking about a Real Agent Loop CRM tool), SiteOffice responds with a structured `<tool-surface-error>` envelope naming the missing plugin and the remedy, rather than improvising with a generic alternative.
411
411
 
412
412
  **Public agent embedding:** Premium plugins marked as public-eligible have their full content (skills and reference knowledge) embedded in public agent prompts. This means a public agent for a Real Agent member can handle buyer enquiries, book viewings, deliver coaching content, and onboard new applicants — all powered by the premium plugin's domain knowledge. Plugins marked admin-only (listings, vendors, leads, business) are only available to the account owner's admin agent.
413
413
 
414
- Some premium plugins include specialist helpers that Maxy can dispatch for specific tasks (e.g. the writer-craft plugin includes a manuscript reviewer). These are activated automatically when the plugin is enabled.
414
+ Some premium plugins include specialist helpers that SiteOffice can dispatch for specific tasks (e.g. the writer-craft plugin includes a manuscript reviewer). These are activated automatically when the plugin is enabled.
415
415
 
416
- Some premium plugins include pre-built public agent templates — ready-made configurations for customer-facing agents. When you enable the plugin, Maxy shows you what templates are available and offers to create agents from them. You review and approve every file before the agent is created. The template is a starting point — you can edit the identity, personality, plugins, and settings to make it yours. The result is a standard public agent, indistinguishable from one you created from scratch.
416
+ Some premium plugins include pre-built public agent templates — ready-made configurations for customer-facing agents. When you enable the plugin, SiteOffice shows you what templates are available and offers to create agents from them. You review and approve every file before the agent is created. The template is a starting point — you can edit the identity, personality, plugins, and settings to make it yours. The result is a standard public agent, indistinguishable from one you created from scratch.
417
417
 
418
418
  Some premium plugins ship pre-built workflows that are created when the plugin is enabled. These workflows are fully yours — you can inspect, edit, run, and manage them through conversation, exactly like workflows you create yourself. The plugin provides the starting point; you own the result.
419
419
 
420
- **If a premium plugin ever stops working** — `documents`, `teaching`, anything else you've paid for — and Maxy responds as if it doesn't have those tools, the platform's health check (`/api/health.missingPlugins`) will name the affected plugin. Tell Maxy "deliver the {{plugin}} plugin" — it re-runs the same delivery step that fires automatically at session start. If the plugin isn't in the device's staging area, re-run the installer for this brand.
420
+ **If a premium plugin ever stops working** — `documents`, `teaching`, anything else you've paid for — and SiteOffice responds as if it doesn't have those tools, the platform's health check (`/api/health.missingPlugins`) will name the affected plugin. Tell SiteOffice "deliver the {{plugin}} plugin" — it re-runs the same delivery step that fires automatically at session start. If the plugin isn't in the device's staging area, re-run the installer for this brand.
421
421
 
422
422
  ## Choosing Plugins
423
423
 
424
- During first-time setup, Maxy presents a plugin selection screen where you choose which plugins to activate. Core plugins are pre-selected and locked. Recommended plugins are pre-selected but optional. You can change your mind later.
424
+ During first-time setup, SiteOffice presents a plugin selection screen where you choose which plugins to activate. Core plugins are pre-selected and locked. Recommended plugins are pre-selected but optional. You can change your mind later.
425
425
 
426
426
  ## Adding or Removing Plugins
427
427
 
428
- Tell Maxy:
428
+ Tell SiteOffice:
429
429
 
430
430
  - "Enable the Telegram plugin"
431
431
  - "Add the Stripe plugin"
432
432
  - "Disable the deep-research plugin"
433
433
 
434
- Maxy handles the installation or removal. If the plugin requires any setup (API keys, bot tokens, configuration), Maxy will walk you through it.
434
+ SiteOffice handles the installation or removal. If the plugin requires any setup (API keys, bot tokens, configuration), SiteOffice will walk you through it.
435
435
 
436
436
  ## Viewing Your Plugins
437
437
 
438
- Ask Maxy: "What plugins do I have?" or "List my plugins."
438
+ Ask SiteOffice: "What plugins do I have?" or "List my plugins."
439
439
 
440
440
  ## Operator-Authored Plugins (skill-builder output)
441
441
 
@@ -443,15 +443,15 @@ Skills you create at runtime through the admin `skill-builder` skill are saved o
443
443
 
444
444
  These operator-authored plugins survive reinstall because the installer's wipe zone excludes `data/`. At admin session start the platform mirrors `data/accounts/{accountId}/plugins/*` into the runtime plugins directory so the same `parsePluginFrontmatter` / `assemblePublicPluginContent` / `loadEmbeddedPlugins` loaders that read shipped and premium plugins also pick up operator-authored ones — no special-case loader path. The admin agent sees every operator skill by default; per-skill `publicEmbed: true|false` controls which skills surface to the public agent.
445
445
 
446
- To edit an operator-authored skill later, ask Maxy to update it — the admin agent re-runs `store-skill` for the same `pluginName`/`skillName` and the new content overwrites in place. To remove one, delete the directory under `data/accounts/{accountId}/plugins/{pluginName}/skills/{skillName}/` (or the whole plugin) — the next session start re-mirrors the remaining skills only.
446
+ To edit an operator-authored skill later, ask SiteOffice to update it — the admin agent re-runs `store-skill` for the same `pluginName`/`skillName` and the new content overwrites in place. To remove one, delete the directory under `data/accounts/{accountId}/plugins/{pluginName}/skills/{skillName}/` (or the whole plugin) — the next session start re-mirrors the remaining skills only.
447
447
 
448
448
  `pluginName` collisions with shipped plugin names are refused by `store-skill` with a structured error. See [.docs/agents.md](../../../../.docs/agents.md) § "Operator-authored skills as plugin files" for the full contract.
449
449
 
450
450
  ## Brand Templating (for plugin and skill authors)
451
451
 
452
- Skill content, plugin manifests, agent templates, and reference files reference the operator-visible brand name only via the literal `Maxy` placeholder. The platform substitutes from `brand.json.productName` at read time — Maxy installs render `Maxy`, Real Agent installs render `Real Agent`, all from the same source content.
452
+ Skill content, plugin manifests, agent templates, and reference files reference the operator-visible brand name only via the literal `SiteOffice` placeholder. The platform substitutes from `brand.json.productName` at read time — SiteOffice installs render `SiteOffice`, Real Agent installs render `Real Agent`, all from the same source content.
453
453
 
454
- **Author rule:** never write the literal string `Maxy` (or any brand name) in shipped skill, plugin, or template content. Use `Maxy` whenever the operator should see the brand name. The audit grep `grep -rn "\bMaxy\b" platform/plugins/admin/skills/ platform/plugins/*/skills/ platform/templates/agents/` must return zero matches; a literal brand name is a defect, not a stylistic choice.
454
+ **Author rule:** never write the literal string `SiteOffice` (or any brand name) in shipped skill, plugin, or template content. Use `SiteOffice` whenever the operator should see the brand name. The audit grep `grep -rn "\bMaxy\b" platform/plugins/admin/skills/ platform/plugins/*/skills/ platform/templates/agents/` must return zero matches; a literal brand name is a defect, not a stylistic choice.
455
455
 
456
456
  The runtime substitution happens at every read site that flows content into a system prompt or operator-visible UI: the admin agent's `plugin-read` tool (references + `PLUGIN.md`), the `skill-load` tool (SKILL.md by skill name — one-call resolver+reader, the canonical primitive for SKILL.md), the public agent's recursive plugin assembly, and `IDENTITY` / `SOUL` / `AGENTS` / `KNOWLEDGE` markdown reads. Missing or empty `productName` hard-fails — there is no fallback to a default brand string. See [.docs/agents.md](../../.docs/agents.md) § "Brand templating" for the full contract.
457
457
 
@@ -472,7 +472,7 @@ After this, every `console.error("[your-tool]...")` from any tool in the plugin
472
472
 
473
473
  **How the tee decides which file to write to:** the platform sets `STREAM_LOG_PATH` as an environment variable on every MCP server spawn, pointing to the conversation-scoped stream log. The MCP server does not know about conversations — it just trusts `STREAM_LOG_PATH`. Multiple concurrent conversations produce multiple concurrent MCP server processes, each teeing to its own file; no cross-conversation leakage.
474
474
 
475
- **Bash commands stream straight into the PTY.** Maxy Code's admin and public chat run on the native Claude Code PTY (Task 287). The per-conversation server-side stream log that the retired web-UI dispatcher tailed is gone; agent-invoked Bash commands (including direct `cloudflared` invocations for Cloudflare setup — Task 288) print their stdout and stderr directly, and the PTY renders the output in chat verbatim.
475
+ **Bash commands stream straight into the PTY.** SiteOffice Code's admin and public chat run on the native Claude Code PTY (Task 287). The per-conversation server-side stream log that the retired web-UI dispatcher tailed is gone; agent-invoked Bash commands (including direct `cloudflared` invocations for Cloudflare setup — Task 288) print their stdout and stderr directly, and the PTY renders the output in chat verbatim.
476
476
 
477
477
  **Retrieve MCP diagnostic lines for a conversation:**
478
478
 
@@ -503,9 +503,9 @@ A third layer closes the same gap from the platform side: when `claude-agent.ts`
503
503
  # Install Overview
504
504
  Source: https://docs.getmaxy.com/install.md
505
505
 
506
- # Installing Maxy Code
506
+ # Installing SiteOffice Code
507
507
 
508
- Maxy Code installs from one npm one-liner on every supported host. The host you choose determines the supervisor (systemd vs launchd), the Cloudflare flow (provisioned vs operator-opt-in), and the VNC requirement (Pi/cloud VM only).
508
+ SiteOffice Code installs from one npm one-liner on every supported host. The host you choose determines the supervisor (systemd vs launchd), the Cloudflare flow (provisioned vs operator-opt-in), and the VNC requirement (Pi/cloud VM only).
509
509
 
510
510
  | Host | Doc | Supervisor | Cloudflare tunnel | Hostname flag |
511
511
  |---|---|---|---|---|
@@ -521,7 +521,7 @@ Engineers reading the codebase should also see [../deployment.md](../deployment.
521
521
  # macOS Install
522
522
  Source: https://docs.getmaxy.com/install/macos.md
523
523
 
524
- # Installing Maxy Code on macOS
524
+ # Installing SiteOffice Code on macOS
525
525
 
526
526
  End-to-end install for a fresh macOS account on Apple Silicon (M-series). Every command is copy-pasteable and uses auto-yes flags so nothing prompts interactively.
527
527
 
@@ -653,7 +653,7 @@ macOS is the lightweight surface. Compared with the Pi install, the macOS path d
653
653
 
654
654
  The full operator-side fresh-Mac smoke is tracked separately (see `.tasks/339-macos-installer-smoke-task-297.md`). The headline pass criteria:
655
655
 
656
- 1. Install on a clean account with no prior Maxy footprint completes and prints an admin URL.
656
+ 1. Install on a clean account with no prior SiteOffice footprint completes and prints an admin URL.
657
657
  2. The admin UI opens at that URL and the chat surface is interactive.
658
658
  3. Reboot — the URL is reachable again after login without any manual action.
659
659
  4. Run `--hostname <name>` on a second install path; the URL switches to `<name>.local`.
@@ -665,7 +665,7 @@ If any step fails, attach `$HOME/.<brand>/logs/create-maxy-<timestamp>.log` to t
665
665
  # Raspberry Pi Install
666
666
  Source: https://docs.getmaxy.com/install/pi.md
667
667
 
668
- # Installing Maxy Code on a Raspberry Pi
668
+ # Installing SiteOffice Code on a Raspberry Pi
669
669
 
670
670
  End-to-end install for a fresh Raspberry Pi 5 (16GB) on Ubuntu Server 24.04 (64-bit). Every command is copy-pasteable and uses auto-yes flags so nothing prompts interactively. The same flow works on a Pi 4 (8GB). For a Hetzner Cloud install (CAX31 ARM64 ~€13/mo), see [hetzner.md](hetzner.md) — same installer, slightly different bootstrap for the Cloudflare tunnel because there is no LAN to the operator.
671
671
 
@@ -807,7 +807,7 @@ npx -y @rubytech/create-realagent-code@latest --uninstall
807
807
 
808
808
  Fresh-Pi smoke pass criteria:
809
809
 
810
- 1. Install on a clean Ubuntu Server 24.04 image with no prior Maxy footprint completes, prints a LAN URL, and the systemd user-service is `active (running)`.
810
+ 1. Install on a clean Ubuntu Server 24.04 image with no prior SiteOffice footprint completes, prints a LAN URL, and the systemd user-service is `active (running)`.
811
811
  2. The LAN URL `http://<hostname>.local:<port>` opens the admin UI and the chat surface is interactive.
812
812
  3. Cloudflare setup driven by the `cloudflare` plugin's `cloudflare` skill ends with `curl -I https://<hostname>.<your-zone>` returning `HTTP/2 200` from outside the LAN.
813
813
  4. Reboot — both URLs are reachable again after boot without any manual action.
@@ -820,7 +820,7 @@ If any step fails, attach `$HOME/.<brand>/logs/install-<timestamp>.log` to the r
820
820
  # Hetzner Cloud Install
821
821
  Source: https://docs.getmaxy.com/install/hetzner.md
822
822
 
823
- # Installing Maxy Code on a Hetzner Cloud server
823
+ # Installing SiteOffice Code on a Hetzner Cloud server
824
824
 
825
825
  End-to-end install for a fresh Hetzner Cloud server on the **CAX31** tier (8 vCPU Ampere Altra ARM64, 16 GB RAM, 160 GB NVMe, ~€13/mo). CAX is the right tier because it is ARM64, identical chip family to the Raspberry Pi 5, so every binary built by the installer compiles the same way it does on the Pi. Every command is copy-pasteable and uses auto-yes flags so nothing prompts interactively.
826
826
 
@@ -1025,7 +1025,7 @@ Each installation has its own Cloudflare account. The **tunnel** sign-in is OAut
1025
1025
 
1026
1026
  | Concept | Source |
1027
1027
  |------|--------|
1028
- | **Product identity** (Maxy vs Real Agent) | `brand.json` (`productName`, `configDir`) — known at install. |
1028
+ | **Product identity** (SiteOffice vs Real Agent) | `brand.json` (`productName`, `configDir`) — known at install. |
1029
1029
  | **Cloudflare account identity** | `cert.pem` from OAuth. One account per brand per device. |
1030
1030
  | **Domain scope** (which zones the operator can route) | The operator picks the zone in the dashboard during OAuth or names it in chat; the agent can also enumerate zones via the API with a minted read-scoped token. |
1031
1031
  | **Local tunnel state** | `~/{configDir}/cloudflared/` — `cert.pem`, `<UUID>.json`, `config.yml`, `alias-domains.json`. |
@@ -1141,15 +1141,15 @@ Each public agent has one of two access modes:
1141
1141
 
1142
1142
  ## How to Set It Up
1143
1143
 
1144
- Tell Maxy: "Set my public agent to gated access" or "Make the coaching agent invitation-only."
1144
+ Tell SiteOffice: "Set my public agent to gated access" or "Make the coaching agent invitation-only."
1145
1145
 
1146
- Maxy flips the agent's access mode. The next visitor to your public URL sees a sign-in screen instead of the chat.
1146
+ SiteOffice flips the agent's access mode. The next visitor to your public URL sees a sign-in screen instead of the chat.
1147
1147
 
1148
1148
  ## Inviting Visitors
1149
1149
 
1150
- Tell Maxy: "Invite sarah@client.co to the coaching agent."
1150
+ Tell SiteOffice: "Invite sarah@client.co to the coaching agent."
1151
1151
 
1152
- Maxy creates an invitation and emails the visitor a magic link. At creation time the invitation is stamped with a one-off `sliceToken` — that token is what binds every per-visitor memory write to this specific invitation for the life of the invite.
1152
+ SiteOffice creates an invitation and emails the visitor a magic link. At creation time the invitation is stamped with a one-off `sliceToken` — that token is what binds every per-visitor memory write to this specific invitation for the life of the invite.
1153
1153
 
1154
1154
  Only email invitations are supported. Phone, OTP, and password flows are not part of the current build.
1155
1155
 
@@ -1170,7 +1170,7 @@ You can read what's in a visitor's slice via the cypher tools in conversation
1170
1170
 
1171
1171
  ## Managing Access
1172
1172
 
1173
- All access management is done through conversation with Maxy:
1173
+ All access management is done through conversation with SiteOffice:
1174
1174
 
1175
1175
  - "Who has access to my coaching agent?" — lists active visitors and their `sliceToken`.
1176
1176
  - "Revoke Sarah's access" — flips her grant to revoked AND immediately drops her active session, so she cannot continue talking on a live cookie. Her slice's historical memory stays in the graph; you can purge it separately if needed.
@@ -1185,19 +1185,19 @@ When a visitor is authenticated, your public agent knows their name and contact
1185
1185
 
1186
1186
  ## Action Approval
1187
1187
 
1188
- External-facing actions — sending emails, WhatsApp messages, Telegram messages, and erasing contacts — require your approval before Maxy executes them. This is human oversight as required by the EU AI Act.
1188
+ External-facing actions — sending emails, WhatsApp messages, Telegram messages, and erasing contacts — require your approval before SiteOffice executes them. This is human oversight as required by the EU AI Act.
1189
1189
 
1190
- When Maxy needs to send a message or perform a consequential action, it drafts the action and queues it for your review. You'll see it in your next chat turn:
1190
+ When SiteOffice needs to send a message or perform a consequential action, it drafts the action and queues it for your review. You'll see it in your next chat turn:
1191
1191
 
1192
- - "Approve it" — Maxy executes the action immediately
1192
+ - "Approve it" — SiteOffice executes the action immediately
1193
1193
  - "Reject it" — the action is cancelled
1194
- - "Change the subject to X" — Maxy modifies the action and executes the edited version
1194
+ - "Change the subject to X" — SiteOffice modifies the action and executes the edited version
1195
1195
 
1196
1196
  Internal operations (creating tasks, updating contacts, searching memory) execute automatically without approval.
1197
1197
 
1198
1198
  ### Changing the Policy
1199
1199
 
1200
- Tell Maxy to change which actions require approval:
1200
+ Tell SiteOffice to change which actions require approval:
1201
1201
 
1202
1202
  - "Auto-send follow-up emails from now on" — emails execute without approval
1203
1203
  - "Require approval for all WhatsApp messages" — restores the default gating
@@ -1207,7 +1207,7 @@ Changes are per-account and take effect immediately.
1207
1207
 
1208
1208
  ## Filesystem Access (SMB Share)
1209
1209
 
1210
- Brand isolation extends to the device filesystem. Every Maxy install provisions an SMB share scoped to that brand's install folder, credentialled by the brand's install owner and the Maxy PIN. A device that hosts more than one brand carries one share per brand; tearing one brand down never exposes another brand's files. See [Samba Share](./samba.md) for the credential model, per-OS mount syntax, and peer-brand lifecycle.
1210
+ Brand isolation extends to the device filesystem. Every SiteOffice install provisions an SMB share scoped to that brand's install folder, credentialled by the brand's install owner and the SiteOffice PIN. A device that hosts more than one brand carries one share per brand; tearing one brand down never exposes another brand's files. See [Samba Share](./samba.md) for the credential model, per-OS mount syntax, and peer-brand lifecycle.
1211
1211
 
1212
1212
  ---
1213
1213
  # Settings
@@ -1217,36 +1217,36 @@ Source: https://docs.getmaxy.com/settings.md
1217
1217
 
1218
1218
  ## Output Style
1219
1219
 
1220
- Controls how Maxy communicates with you.
1220
+ Controls how SiteOffice communicates with you.
1221
1221
 
1222
1222
  | Style | Behaviour |
1223
1223
  |-------|-----------|
1224
1224
  | `default` | Concise, direct responses — gets to the point |
1225
1225
  | `explanatory` | More detailed responses with educational context — explains reasoning and trade-offs |
1226
1226
 
1227
- **Changing output style:** Tell Maxy "Switch to explanatory mode" or "Use default output style."
1227
+ **Changing output style:** Tell SiteOffice "Switch to explanatory mode" or "Use default output style."
1228
1228
 
1229
1229
  Changes take effect on the next session. The current session continues with the existing style.
1230
1230
 
1231
1231
  ## Effort Level
1232
1232
 
1233
- Controls how much work Maxy puts into each task — specifically, how many steps it takes before stopping and checking with you.
1233
+ Controls how much work SiteOffice puts into each task — specifically, how many steps it takes before stopping and checking with you.
1234
1234
 
1235
1235
  | Level | Max turns | Use when |
1236
1236
  |-------|-----------|----------|
1237
1237
  | `low` | 5 | Quick questions, simple lookups |
1238
1238
  | `medium` | 10 | Standard tasks — most daily use |
1239
1239
  | `high` | 20 | Complex multi-step tasks |
1240
- | `auto` | 20 | Let Maxy decide (same ceiling as high) |
1240
+ | `auto` | 20 | Let SiteOffice decide (same ceiling as high) |
1241
1241
  | `max` | 40 | Long autonomous workflows |
1242
1242
 
1243
- **Changing effort level:** Tell Maxy "Set effort to high" or "Use low effort mode."
1243
+ **Changing effort level:** Tell SiteOffice "Set effort to high" or "Use low effort mode."
1244
1244
 
1245
1245
  Changes take effect on the next session.
1246
1246
 
1247
1247
  ## Thinking View
1248
1248
 
1249
- Controls how Maxy's thinking process is displayed in the chat.
1249
+ Controls how SiteOffice's thinking process is displayed in the chat.
1250
1250
 
1251
1251
  | Mode | Behaviour |
1252
1252
  |------|-----------|
@@ -1254,25 +1254,25 @@ Controls how Maxy's thinking process is displayed in the chat.
1254
1254
  | `expanded` | Everything shown expanded — thinking, tool use, and results |
1255
1255
  | `collapsed` | Everything collapsed — compact view, expand on tap |
1256
1256
 
1257
- **Changing thinking view:** Tell Maxy "Show thinking by default", "Show everything expanded", or "Hide thinking."
1257
+ **Changing thinking view:** Tell SiteOffice "Show thinking by default", "Show everything expanded", or "Hide thinking."
1258
1258
 
1259
1259
  Changes take effect on the next session.
1260
1260
 
1261
1261
  ## Viewing Current Settings
1262
1262
 
1263
- Ask Maxy: "What are my current settings?" or "What output style am I using?"
1263
+ Ask SiteOffice: "What are my current settings?" or "What output style am I using?"
1264
1264
 
1265
1265
  ## Default Agent
1266
1266
 
1267
1267
  Controls which public agent serves the root URL (`/`). Visitors who go to your public site without specifying an agent slug see this agent.
1268
1268
 
1269
- **Changing the default agent:** Tell Maxy "Make sales the default agent" or "Set the default to support."
1269
+ **Changing the default agent:** Tell SiteOffice "Make sales the default agent" or "Set the default to support."
1270
1270
 
1271
1271
  The change takes effect on the next page load. The previous default agent remains accessible at its `/{slug}` URL.
1272
1272
 
1273
1273
  ## Account Preferences
1274
1274
 
1275
- You can ask Maxy to show or change any of the following:
1275
+ You can ask SiteOffice to show or change any of the following:
1276
1276
 
1277
1277
  - Default agent (which public agent serves the root URL)
1278
1278
  - Admin model (which Claude model powers the admin agent)
@@ -1282,19 +1282,19 @@ You can ask Maxy to show or change any of the following:
1282
1282
  - Context mode
1283
1283
  - Enabled plugins
1284
1284
 
1285
- Tell Maxy what you want to change and it handles the rest.
1285
+ Tell SiteOffice what you want to change and it handles the rest.
1286
1286
 
1287
1287
  ## PIN
1288
1288
 
1289
- Your admin PIN is set during initial setup. To change it, ask Maxy: "Change my admin PIN."
1289
+ Your admin PIN is set during initial setup. To change it, ask SiteOffice: "Change my admin PIN."
1290
1290
 
1291
- Maxy will ask for your current PIN to verify, then set the new one.
1291
+ SiteOffice will ask for your current PIN to verify, then set the new one.
1292
1292
 
1293
1293
  ## Adding admins
1294
1294
 
1295
- To add another admin to your account, tell Maxy: "Add {name} as an admin with PIN {pin}." Maxy creates the device-level user entry (`users.json`), the account-level role entry (`account.json` admins[]), and the graph identity (Neo4j AdminUser node) — the three stores stay in lockstep. If any leg fails, Maxy returns an error naming exactly which store is dirty and what was already written; the admin record is partial and may need manual reconciliation. PINs are unique across all users on the device — a new admin needs a PIN no one else on the device is using.
1295
+ To add another admin to your account, tell SiteOffice: "Add {name} as an admin with PIN {pin}." SiteOffice creates the device-level user entry (`users.json`), the account-level role entry (`account.json` admins[]), and the graph identity (Neo4j AdminUser node) — the three stores stay in lockstep. If any leg fails, SiteOffice returns an error naming exactly which store is dirty and what was already written; the admin record is partial and may need manual reconciliation. PINs are unique across all users on the device — a new admin needs a PIN no one else on the device is using.
1296
1296
 
1297
- If you ask Maxy to add an admin with a specific PIN and it returns a tier-cap or PIN-collision error, repeat the request with the same PIN every time you retry — otherwise Maxy auto-generates a different 4-digit PIN, silently substituting what you asked for.
1297
+ If you ask SiteOffice to add an admin with a specific PIN and it returns a tier-cap or PIN-collision error, repeat the request with the same PIN every time you retry — otherwise SiteOffice auto-generates a different 4-digit PIN, silently substituting what you asked for.
1298
1298
 
1299
1299
  ---
1300
1300
  # Contacts
@@ -1304,17 +1304,17 @@ Source: https://docs.getmaxy.com/contacts-guide.md
1304
1304
 
1305
1305
  ## What a Contact Is
1306
1306
 
1307
- A contact is a Person node in Maxy's memory graph. Each person has a first name and at least one identifier — email address, phone number, or both. Optional fields include last name and job title. Contacts are linked to conversations, other people, and business context.
1307
+ A contact is a Person node in SiteOffice's memory graph. Each person has a first name and at least one identifier — email address, phone number, or both. Optional fields include last name and job title. Contacts are linked to conversations, other people, and business context.
1308
1308
 
1309
1309
  ## Adding a Contact
1310
1310
 
1311
- Tell Maxy naturally:
1311
+ Tell SiteOffice naturally:
1312
1312
 
1313
1313
  - "Add John Smith to my contacts — he's a potential client I met at the conference"
1314
1314
  - "Create a contact for sarah@acme.com, her name is Sarah Chen, she's the head of procurement at Acme"
1315
1315
  - "Add Hazel to contacts, phone +27747309676, she's a virtual assistant"
1316
1316
 
1317
- Maxy will extract the details and confirm the record before saving.
1317
+ SiteOffice will extract the details and confirm the record before saving.
1318
1318
 
1319
1319
  Required: first name and at least one of email or phone number. Everything else is optional but useful.
1320
1320
 
@@ -1327,11 +1327,11 @@ Ask naturally:
1327
1327
  - "Find the contact from Acme procurement"
1328
1328
  - "Look up +27747309676"
1329
1329
 
1330
- Maxy searches by name, email, phone number, or any detail you provide.
1330
+ SiteOffice searches by name, email, phone number, or any detail you provide.
1331
1331
 
1332
1332
  ## Updating a Contact
1333
1333
 
1334
- Tell Maxy what changed:
1334
+ Tell SiteOffice what changed:
1335
1335
 
1336
1336
  - "Update John Smith's email to john@newcompany.com"
1337
1337
  - "Add a note to Sarah Chen's record: prefers evening calls"
@@ -1351,27 +1351,27 @@ To remove a single contact from the graph:
1351
1351
  - "Remove the duplicate contact for Sarah Chen"
1352
1352
  - "Delete the contact with email dan@example.com"
1353
1353
 
1354
- Maxy will confirm which Person record matches, then remove the Person node and its direct relationships (e.g. links to conversations, other people) using a graph detach-delete. The contact is gone after confirmation — this cannot be undone.
1354
+ SiteOffice will confirm which Person record matches, then remove the Person node and its direct relationships (e.g. links to conversations, other people) using a graph detach-delete. The contact is gone after confirmation — this cannot be undone.
1355
1355
 
1356
1356
  This is different from GDPR erasure (`contact-erase`). Deleting a contact removes the Person node from the graph only. GDPR erasure cascades across all data stores — access credentials, conversations, messages, and emails — to satisfy an Article 17 right-to-erasure request. Use "delete" for routine contact cleanup; use "erase all data" when fulfilling a data subject's erasure request.
1357
1357
 
1358
1358
  ## Exporting Contact Data (GDPR Subject Access)
1359
1359
 
1360
- When a person requests a copy of all data held about them, ask Maxy:
1360
+ When a person requests a copy of all data held about them, ask SiteOffice:
1361
1361
 
1362
1362
  - "Export all data we hold on john@example.com"
1363
1363
  - "Show me everything we know about +447700900123"
1364
1364
 
1365
- Maxy gathers the Person record, access credentials, conversation history, and emails into a single structured document. The output is self-contained — it can be handed directly to the data subject to satisfy an Article 15 request.
1365
+ SiteOffice gathers the Person record, access credentials, conversation history, and emails into a single structured document. The output is self-contained — it can be handed directly to the data subject to satisfy an Article 15 request.
1366
1366
 
1367
1367
  ## Erasing Contact Data (GDPR Right to Erasure)
1368
1368
 
1369
- When a person requests deletion of all their data, ask Maxy:
1369
+ When a person requests deletion of all their data, ask SiteOffice:
1370
1370
 
1371
1371
  - "Delete all data we hold on john@example.com"
1372
1372
  - "Erase everything for Sarah Chen"
1373
1373
 
1374
- Maxy first shows a preview of what would be deleted (counts per data type). Confirm the deletion to proceed. The erasure cascade covers:
1374
+ SiteOffice first shows a preview of what would be deleted (counts per data type). Confirm the deletion to proceed. The erasure cascade covers:
1375
1375
 
1376
1376
  - The Person record itself
1377
1377
  - All access credentials (AccessGrant nodes)
@@ -1407,24 +1407,24 @@ The graph is the brain, and every turn that needs to know something runs the sam
1407
1407
 
1408
1408
  ## How Memory Works
1409
1409
 
1410
- Maxy maintains a graph of everything you've told it. Contacts, conversations, preferences, relationships, business context — all stored as connected nodes in a local Neo4j database on your Raspberry Pi.
1410
+ SiteOffice maintains a graph of everything you've told it. Contacts, conversations, preferences, relationships, business context — all stored as connected nodes in a local Neo4j database on your Raspberry Pi.
1411
1411
 
1412
- When you ask Maxy about something, it searches this graph first. It retrieves relevant context before responding, which is why Maxy can pick up where you left off even across separate sessions.
1412
+ When you ask SiteOffice about something, it searches this graph first. It retrieves relevant context before responding, which is why SiteOffice can pick up where you left off even across separate sessions.
1413
1413
 
1414
1414
  The graph lives entirely on your hardware. Nothing is sent to the cloud.
1415
1415
 
1416
1416
  ## What Gets Remembered
1417
1417
 
1418
- Maxy stores:
1418
+ SiteOffice stores:
1419
1419
 
1420
1420
  - **Contacts** — people, companies, relationships between them
1421
1421
  - **Conversations** — key decisions, commitments, follow-ups mentioned in chat
1422
- - **Preferences** — things you've told Maxy about how you like to work
1422
+ - **Preferences** — things you've told SiteOffice about how you like to work
1423
1423
  - **Context** — project status, ongoing threads, background you've shared
1424
1424
 
1425
- Maxy remembers details you mention naturally: "I'm meeting with Sarah on Thursday" creates a memory that Thursday has a meeting with Sarah.
1425
+ SiteOffice remembers details you mention naturally: "I'm meeting with Sarah on Thursday" creates a memory that Thursday has a meeting with Sarah.
1426
1426
 
1427
- ## Telling Maxy to Remember Something
1427
+ ## Telling SiteOffice to Remember Something
1428
1428
 
1429
1429
  Just say it naturally:
1430
1430
 
@@ -1432,13 +1432,13 @@ Just say it naturally:
1432
1432
  - "Note that the Johnson account is on hold until March"
1433
1433
  - "My wife's name is Emma, keep that in mind"
1434
1434
 
1435
- Maxy will confirm and store it.
1435
+ SiteOffice will confirm and store it.
1436
1436
 
1437
- ## How Maxy learns how you work
1437
+ ## How SiteOffice learns how you work
1438
1438
 
1439
- Maxy also learns how you work without you having to teach it deliberately. Six broad areas cover the way most operators run a business — communication, scheduling, decisions, workflow, content, and interaction. Inside each area sits a small set of concrete fields (Maxy tracks around 28 in total) such as your preferred channel, quiet hours, workday start time, risk tolerance, content tonality, or address form. Maxy tracks which of these specific fields you have spoken into and which are still empty. While any are empty, it folds one organic question per turn into the conversation aimed at the next gap — never a list, never a form, never the same question twice. If you tell Maxy a field doesn't apply to you ("I work weekends, weekend availability isn't a thing for me"), it marks that field as covered and never re-asks. Once every field is either set or marked not-applicable, the proactive questions stop and Maxy answers what you ask without volunteering more. This is why session 300 should feel sharper than session 3: the longer you work together, the less Maxy needs to ask.
1439
+ SiteOffice also learns how you work without you having to teach it deliberately. Six broad areas cover the way most operators run a business — communication, scheduling, decisions, workflow, content, and interaction. Inside each area sits a small set of concrete fields (SiteOffice tracks around 28 in total) such as your preferred channel, quiet hours, workday start time, risk tolerance, content tonality, or address form. SiteOffice tracks which of these specific fields you have spoken into and which are still empty. While any are empty, it folds one organic question per turn into the conversation aimed at the next gap — never a list, never a form, never the same question twice. If you tell SiteOffice a field doesn't apply to you ("I work weekends, weekend availability isn't a thing for me"), it marks that field as covered and never re-asks. Once every field is either set or marked not-applicable, the proactive questions stop and SiteOffice answers what you ask without volunteering more. This is why session 300 should feel sharper than session 3: the longer you work together, the less SiteOffice needs to ask.
1440
1440
 
1441
- ## Telling Maxy to Forget Something
1441
+ ## Telling SiteOffice to Forget Something
1442
1442
 
1443
1443
  Be direct:
1444
1444
 
@@ -1447,7 +1447,7 @@ Be direct:
1447
1447
  - "Clear what you know about my pricing preferences"
1448
1448
  - "Delete that pricing guide I uploaded"
1449
1449
 
1450
- Maxy will confirm before deleting anything significant. Documents are soft-deleted first (excluded from search but recoverable for 7 days). Say "permanently delete" to remove immediately.
1450
+ SiteOffice will confirm before deleting anything significant. Documents are soft-deleted first (excluded from search but recoverable for 7 days). Say "permanently delete" to remove immediately.
1451
1451
 
1452
1452
  ## Managing Documents
1453
1453
 
@@ -1455,27 +1455,27 @@ Maxy will confirm before deleting anything significant. Documents are soft-delet
1455
1455
 
1456
1456
  Ask: "What files do I have stored?" or "List my attachments"
1457
1457
 
1458
- Maxy shows all uploaded files with their ingestion status — whether they've been processed into the knowledge graph.
1458
+ SiteOffice shows all uploaded files with their ingestion status — whether they've been processed into the knowledge graph.
1459
1459
 
1460
- When you upload something for ingestion, Maxy emits a one-line size estimate before it starts: short documents (<5K chars) classify in ~10s; mid-size (10K–20K chars) take ~45–90s; very large (>20K) up to ~3 minutes. If the classifier exceeds its 3-minute ceiling Maxy aborts loudly with a "Classifier unavailable — timeout" blocker and writes nothing — you can re-upload or split the document.
1460
+ When you upload something for ingestion, SiteOffice emits a one-line size estimate before it starts: short documents (<5K chars) classify in ~10s; mid-size (10K–20K chars) take ~45–90s; very large (>20K) up to ~3 minutes. If the classifier exceeds its 3-minute ceiling SiteOffice aborts loudly with a "Classifier unavailable — timeout" blocker and writes nothing — you can re-upload or split the document.
1461
1461
 
1462
1462
  ### Reading files
1463
1463
 
1464
1464
  Ask: "Show me what's in the pricing guide" or "Read the quarterly report"
1465
1465
 
1466
- Maxy returns the full content of text and markdown files, extracted text from PDFs, and metadata for images.
1466
+ SiteOffice returns the full content of text and markdown files, extracted text from PDFs, and metadata for images.
1467
1467
 
1468
1468
  ### Editing files
1469
1469
 
1470
1470
  Ask: "Update the pricing in that document" or "Change the introduction paragraph"
1471
1471
 
1472
- Maxy reads the file, makes the edit, and prepares it for re-ingestion into the knowledge graph. Only text and markdown files can be edited — PDFs and images cannot.
1472
+ SiteOffice reads the file, makes the edit, and prepares it for re-ingestion into the knowledge graph. Only text and markdown files can be edited — PDFs and images cannot.
1473
1473
 
1474
1474
  ### Renaming files
1475
1475
 
1476
1476
  Ask: "Rename that file to quarterly-report-q1.pdf"
1477
1477
 
1478
- Maxy updates the filename in both the stored metadata and the knowledge graph.
1478
+ SiteOffice updates the filename in both the stored metadata and the knowledge graph.
1479
1479
 
1480
1480
  ### Deleting documents
1481
1481
 
@@ -1495,15 +1495,15 @@ Ask naturally:
1495
1495
 
1496
1496
  Three slash commands that apply analysis to what's already in your graph:
1497
1497
 
1498
- **`/challenge <claim>`** — stress-tests an assertion. Maxy searches your graph for nodes that contradict or qualify the claim — nodes that assert the opposite, name exceptions, or add significant caveats — and presents the strongest counter-case it finds. If nothing in your graph challenges the claim, it says so rather than inventing one. Results cite node IDs and relevance scores so you can inspect the sources directly.
1498
+ **`/challenge <claim>`** — stress-tests an assertion. SiteOffice searches your graph for nodes that contradict or qualify the claim — nodes that assert the opposite, name exceptions, or add significant caveats — and presents the strongest counter-case it finds. If nothing in your graph challenges the claim, it says so rather than inventing one. Results cite node IDs and relevance scores so you can inspect the sources directly.
1499
1499
 
1500
- **`/connect <topic-A> <topic-B>`** — finds the bridge. Maxy searches both topics, collects their immediate graph neighborhoods, and looks for nodes they share. If a direct bridge exists it names it in one sentence. If not, it surfaces the closest approach — the two nodes that are semantically nearest across the two sides — and proposes the connection you could draw.
1500
+ **`/connect <topic-A> <topic-B>`** — finds the bridge. SiteOffice searches both topics, collects their immediate graph neighborhoods, and looks for nodes they share. If a direct bridge exists it names it in one sentence. If not, it surfaces the closest approach — the two nodes that are semantically nearest across the two sides — and proposes the connection you could draw.
1501
1501
 
1502
- **`/emerge`** — names the unnamed clusters. Maxy retrieves your KnowledgeDocument and Section nodes that are not yet connected to a Concept node, groups them by shared theme, and proposes a Concept name for each cluster. You approve or skip each proposal one at a time; nothing is written without your confirmation. Clusters of fewer than three nodes are listed at the end as "too small to cluster."
1502
+ **`/emerge`** — names the unnamed clusters. SiteOffice retrieves your KnowledgeDocument and Section nodes that are not yet connected to a Concept node, groups them by shared theme, and proposes a Concept name for each cluster. You approve or skip each proposal one at a time; nothing is written without your confirmation. Clusters of fewer than three nodes are listed at the end as "too small to cluster."
1503
1503
 
1504
1504
  ## Listing and counting
1505
1505
 
1506
- Maxy answers relational questions — "list all my people", "how many tasks do I have", "find the person with email X", "show me the 20 most recently created nodes" — via direct read-only Cypher against your Neo4j. This is faster and more precise than semantic search when the question is "the exact set where", not "things similar to".
1506
+ SiteOffice answers relational questions — "list all my people", "how many tasks do I have", "find the person with email X", "show me the 20 most recently created nodes" — via direct read-only Cypher against your Neo4j. This is faster and more precise than semantic search when the question is "the exact set where", not "things similar to".
1507
1507
 
1508
1508
  You can also open a visual view of your graph at any time from the burger menu → **Graph**. Click the **Filter** button in the toolbar to open the filter menu — it lists only the top-level entity types in your schema (Conversation, Person, Task, KnowledgeDocument, …), one row per type, showing your per-type node count and sorted so the most-connected types sit at the top. Child types (messages inside a conversation, sections inside a document), conversation channel variants (admin vs public), message role variants (user vs assistant), and workflow execution plumbing (`ToolCall`, `WorkflowRun`, `WorkflowStep`, `StepResult`) never appear as filter rows — you reach children by clicking the parent and exploring its neighbourhood. Active rows render a force-directed map, coloured by label. Click a node to pivot into its 1-hop neighbourhood; click another node inside that neighbourhood to pivot again. Clicking a Message shows its details in the side panel; the Conversation view stays put — you read sibling messages without losing the chain on canvas. A breadcrumb strip above the canvas shows where you are (`Filter › Conversation › AssistantMessage`). The **Back** control pops one level — three clicks in always undoes with three Back presses; the filter view is the irreducible root. Click the **×** inside the filter menu to clear your chip selection. Type in the search box to highlight matches; submitting a search also widens the filter to include any node types the hits belong to, so relevant matches render instead of disappearing into a "not in current view" banner.
1509
1509
 
@@ -1511,17 +1511,17 @@ Conversations and Messages carry role/channel sublabels so you can read the chat
1511
1511
 
1512
1512
  **Save a default view:** once you have the rows you want, click **Set default view** in the filter menu. Next time you open **Graph**, those rows are pre-selected and your data renders immediately. The default is per-admin, per-account — each admin on each account has their own.
1513
1513
 
1514
- **Delete a node:** drag it to the trash icon top-right of the canvas. No confirmation — deletes are reversible for 30 days. To restore, toggle **Show trashed** inside the filter menu and click **Restore** on the node, or ask Maxy in chat ("restore the <label> I just deleted"). Deleting a conversation also trashes its messages in the same step, so they reappear together on restore.
1514
+ **Delete a node:** drag it to the trash icon top-right of the canvas. No confirmation — deletes are reversible for 30 days. To restore, toggle **Show trashed** inside the filter menu and click **Restore** on the node, or ask SiteOffice in chat ("restore the <label> I just deleted"). Deleting a conversation also trashes its messages in the same step, so they reappear together on restore.
1515
1515
 
1516
- **Bulk cleanup of conversations in chat:** when you ask Maxy to clean up conversations in bulk ("trash all empty conversations," "clean up the single-assistant tests"), the agent uses a deterministic selector with a fixed set of filter names — it cannot author custom delete queries. The server re-runs the same filter on every candidate before it trashes, so a stale list can't destroy something the filter wouldn't match now. If the filter matches nothing, Maxy reports "no candidates" and nothing happens.
1516
+ **Bulk cleanup of conversations in chat:** when you ask SiteOffice to clean up conversations in bulk ("trash all empty conversations," "clean up the single-assistant tests"), the agent uses a deterministic selector with a fixed set of filter names — it cannot author custom delete queries. The server re-runs the same filter on every candidate before it trashes, so a stale list can't destroy something the filter wouldn't match now. If the filter matches nothing, SiteOffice reports "no candidates" and nothing happens.
1517
1517
 
1518
- The page reads only your own brand's Neo4j — a Maxy device and a Real Agent device share no graph state even when on the same laptop. No credentials are required; the view inherits your admin session.
1518
+ The page reads only your own brand's Neo4j — a SiteOffice device and a Real Agent device share no graph state even when on the same laptop. No credentials are required; the view inherits your admin session.
1519
1519
 
1520
- **Typo-proof cypher.** When Maxy runs direct Cypher to answer a relational question, the query is checked against your Neo4j's live label and relationship-type taxonomy before it executes. Cypher that references an unknown name (an edge or label that does not exist in your graph) is rejected for writes and flagged with a warnings header for reads, so Maxy never silently acts on a query that targeted the wrong set of nodes. You should not see this — it runs invisibly — but it is the safety net that stops a fabricated edge name from producing "empty" results that are really just unreachable. Before acting on a bulk operation Maxy surfaces the result count and a sample; if it ever describes a cypher rejection, that means its first attempt was malformed and it corrected itself.
1520
+ **Typo-proof cypher.** When SiteOffice runs direct Cypher to answer a relational question, the query is checked against your Neo4j's live label and relationship-type taxonomy before it executes. Cypher that references an unknown name (an edge or label that does not exist in your graph) is rejected for writes and flagged with a warnings header for reads, so SiteOffice never silently acts on a query that targeted the wrong set of nodes. You should not see this — it runs invisibly — but it is the safety net that stops a fabricated edge name from producing "empty" results that are really just unreachable. Before acting on a bulk operation SiteOffice surfaces the result count and a sample; if it ever describes a cypher rejection, that means its first attempt was malformed and it corrected itself.
1521
1521
 
1522
1522
  ## Bi-temporal timeline events
1523
1523
 
1524
- Every factual statement Maxy extracts from your conversations is stored as a `:TimelineEvent` node. Each event carries two separate timestamps:
1524
+ Every factual statement SiteOffice extracts from your conversations is stored as a `:TimelineEvent` node. Each event carries two separate timestamps:
1525
1525
 
1526
1526
  - **`occurredAt`** (valid-time) — when the fact was true in the world. Set from the text itself; can reference a date in the past ("Alice joined in 1990" stores `occurredAt = 1990-01-01`).
1527
1527
  - **`learnedAt`** (transaction-time) — when the system ingested this event. Always the wall-clock time of the write; never back-dated.
@@ -1529,7 +1529,7 @@ Every factual statement Maxy extracts from your conversations is stored as a `:T
1529
1529
  This distinction lets you ask two qualitatively different questions:
1530
1530
 
1531
1531
  - *"What happened to Alice in 1990?"* — query by `occurredAt`.
1532
- - *"What did Maxy learn about Alice last Tuesday?"* — query by `learnedAt`.
1532
+ - *"What did SiteOffice learn about Alice last Tuesday?"* — query by `learnedAt`.
1533
1533
 
1534
1534
  `memory-compiled-truth-history` returns both fields for every timeline event on an entity under the `timelineEvents` array, alongside the compiled-truth revision history in the `revisions` array.
1535
1535
 
@@ -1537,31 +1537,31 @@ This distinction lets you ask two qualitatively different questions:
1537
1537
 
1538
1538
  ## Write doctrine
1539
1539
 
1540
- Every new node in Maxy's graph is created with at least one connection to an existing node. A contact connects to the conversation or organisation it came from; a task connects to the session that raised it or the entities it will affect; a session summary connects to the conversation it summarises. A node with no connection is noise — it cannot be attributed, traversed, or explained — so the graph refuses to create one. If Maxy ever tries to record something without a link, the write is rejected and Maxy asks you to clarify where it belongs.
1540
+ Every new node in SiteOffice's graph is created with at least one connection to an existing node. A contact connects to the conversation or organisation it came from; a task connects to the session that raised it or the entities it will affect; a session summary connects to the conversation it summarises. A node with no connection is noise — it cannot be attributed, traversed, or explained — so the graph refuses to create one. If SiteOffice ever tries to record something without a link, the write is rejected and SiteOffice asks you to clarify where it belongs.
1541
1541
 
1542
1542
  Every node also carries a provenance stamp — which agent wrote it, in which session, via which tool. You never see these fields, but they are how operators trace unusual growth back to the code path that produced it, and why your graph stays clean over time.
1543
1543
 
1544
- **Two write surfaces, one substrate.** General agents write through schema-aware helpers — Maxy can record a new contact, a new commitment, a new preference without ever typing a database query, and the helper enforces the connection-and-provenance rule above structurally. The graph-steward role (the specialist Maxy dispatches when you ask for graph hygiene — "merge those two duplicate contacts," "wire those four tasks to the meeting," "rename the legacy label across the graph") additionally has a raw Cypher write tool for the multi-step operations the helpers cannot express. The steward role internalises the same connection-and-provenance discipline in its prompt; a post-write audit emits a warning on every breach so the same rules apply to both surfaces. Both paths feed the same hourly orphan trend and the same forensic provenance fields — read-side, you cannot tell the two apart, and that is the point.
1544
+ **Two write surfaces, one substrate.** General agents write through schema-aware helpers — SiteOffice can record a new contact, a new commitment, a new preference without ever typing a database query, and the helper enforces the connection-and-provenance rule above structurally. The graph-steward role (the specialist SiteOffice dispatches when you ask for graph hygiene — "merge those two duplicate contacts," "wire those four tasks to the meeting," "rename the legacy label across the graph") additionally has a raw Cypher write tool for the multi-step operations the helpers cannot express. The steward role internalises the same connection-and-provenance discipline in its prompt; a post-write audit emits a warning on every breach so the same rules apply to both surfaces. Both paths feed the same hourly orphan trend and the same forensic provenance fields — read-side, you cannot tell the two apart, and that is the point.
1545
1545
 
1546
1546
  ## Vertical schemas
1547
1547
 
1548
- On top of the base graph, each brand boots one optional **vertical** — an extra set of entity types tailored to a trade. The vertical is named by `brand.json#vertical` and defined in a `schema-<name>.md` reference; the memory plugin loads it at startup and validates every write against base + the active vertical. Real Agent boots `schema-estate-agent` (Listing, Property, Viewing, Offer). SiteOffice boots `schema-construction`, which adds the building-contractor entities — `Job`, `LineItem`, `Valuation`, `Milestone`, `QuoteDocument`, `VariationNote`, `InboundInvoice`, `SubContractor`, `TimeLog`, `SubInvoice`, `WhatsAppGroup` — grounded in real builder job folders so a job's quote, valuations, variations, supplier invoices, and subcontractor timesheets all hang off one `Job` node. The default Maxy brand boots no vertical (base graph only).
1548
+ On top of the base graph, each brand boots one optional **vertical** — an extra set of entity types tailored to a trade. The vertical is named by `brand.json#vertical` and defined in a `schema-<name>.md` reference; the memory plugin loads it at startup and validates every write against base + the active vertical. Real Agent boots `schema-estate-agent` (Listing, Property, Viewing, Offer). SiteOffice boots `schema-construction`, which adds the building-contractor entities — `Job`, `LineItem`, `Valuation`, `Milestone`, `QuoteDocument`, `VariationNote`, `InboundInvoice`, `SubContractor`, `TimeLog`, `SubInvoice`, `WhatsAppGroup` — grounded in real builder job folders so a job's quote, valuations, variations, supplier invoices, and subcontractor timesheets all hang off one `Job` node. The default SiteOffice brand boots no vertical (base graph only).
1549
1549
 
1550
1550
  ## Public-facing summaries for customer-readable subjects
1551
1551
 
1552
- Some entities in your graph are knowable by people outside your team — companies you work with, projects you've delivered, the business itself. For those entities (Maxy treats `:Organization`, `:Concept`, `:Project`, and `:LocalBusiness` this way), Maxy maintains two summaries: a private one only you and your specialist agents see, and a customer-facing public one your public agents are allowed to surface.
1552
+ Some entities in your graph are knowable by people outside your team — companies you work with, projects you've delivered, the business itself. For those entities (SiteOffice treats `:Organization`, `:Concept`, `:Project`, and `:LocalBusiness` this way), SiteOffice maintains two summaries: a private one only you and your specialist agents see, and a customer-facing public one your public agents are allowed to surface.
1553
1553
 
1554
- Whenever Maxy updates the private summary on one of these entities, it automatically rewrites the public summary in the same step using a separate prompt that strips operator-voice ("needs follow-up", "action: chase next week"), internal sentiment, and anything that reads like a note-to-self. The two summaries stay in lockstep without you doing anything.
1554
+ Whenever SiteOffice updates the private summary on one of these entities, it automatically rewrites the public summary in the same step using a separate prompt that strips operator-voice ("needs follow-up", "action: chase next week"), internal sentiment, and anything that reads like a note-to-self. The two summaries stay in lockstep without you doing anything.
1555
1555
 
1556
- If you want to write the public summary yourself — for instance, because the auto-generated version misses something you want customers to see — just tell Maxy the wording you want for the public summary on that entity, and Maxy will write it directly. It stays locked in for seven days; after that, the next automatic refresh can take over again, unless you re-pin it.
1556
+ If you want to write the public summary yourself — for instance, because the auto-generated version misses something you want customers to see — just tell SiteOffice the wording you want for the public summary on that entity, and SiteOffice will write it directly. It stays locked in for seven days; after that, the next automatic refresh can take over again, unless you re-pin it.
1557
1557
 
1558
1558
  People entries (`:Person`) are deliberately excluded from this dual-summary system. Notes about contacts are private by definition and never get a public-facing form.
1559
1559
 
1560
1560
  ## Privacy
1561
1561
 
1562
- All memory is stored on your local Raspberry Pi. The Neo4j database never leaves your network. Maxy does not sync memory to any cloud service or third party.
1562
+ All memory is stored on your local Raspberry Pi. The Neo4j database never leaves your network. SiteOffice does not sync memory to any cloud service or third party.
1563
1563
 
1564
- If you want to wipe everything and start fresh, ask: "Reset my memory graph." Maxy will ask for confirmation before doing so.
1564
+ If you want to wipe everything and start fresh, ask: "Reset my memory graph." SiteOffice will ask for confirmation before doing so.
1565
1565
 
1566
1566
  ---
1567
1567
  # Projects
@@ -1577,13 +1577,13 @@ Projects are ideal when the user has work involving multiple people, sequential
1577
1577
 
1578
1578
  ## Creating a Project
1579
1579
 
1580
- Tell Maxy naturally:
1580
+ Tell SiteOffice naturally:
1581
1581
 
1582
1582
  - "Create a project for Mrs. Chen's kitchen refit — strip the old kitchen, plumbing first fix, electrical first fix, install units, then tiling and finishing"
1583
1583
  - "Set up a project for the bathroom renovation, standard tier, due by end of June"
1584
1584
  - "Start a project: boiler install for Sarah Thompson, quick job, just order parts, install, and test"
1585
1585
 
1586
- Maxy creates the project and all work items in one step. Dependencies between steps (e.g., "install units after plumbing and electrical") are set up automatically based on the order and relationships you describe.
1586
+ SiteOffice creates the project and all work items in one step. Dependencies between steps (e.g., "install units after plumbing and electrical") are set up automatically based on the order and relationships you describe.
1587
1587
 
1588
1588
  Each project has a tier that reflects its complexity:
1589
1589
  - **Quick** — straightforward, few steps (e.g., boiler install)
@@ -1599,32 +1599,32 @@ Ask naturally:
1599
1599
  - "Show me the Davies bathroom project"
1600
1600
  - "What should I focus on?"
1601
1601
 
1602
- Maxy shows project health at a glance:
1602
+ SiteOffice shows project health at a glance:
1603
1603
  - **Green** — on track, no issues
1604
1604
  - **Amber** — warning signs (overdue task or blocker)
1605
1605
  - **Red** — at risk (multiple overdue, critical blocker, or stale)
1606
1606
 
1607
- When you start a new conversation, Maxy automatically shows active project summaries so you know where things stand without asking.
1607
+ When you start a new conversation, SiteOffice automatically shows active project summaries so you know where things stand without asking.
1608
1608
 
1609
1609
  ## Updating a Project
1610
1610
 
1611
- Tell Maxy when things change:
1611
+ Tell SiteOffice when things change:
1612
1612
 
1613
1613
  - "Move the kitchen refit to the active phase"
1614
1614
  - "The materials for the kitchen refit are delayed by a week"
1615
1615
  - "Update the Davies bathroom target date to July 15th"
1616
1616
  - "Change the boiler install to a standard tier — it's more complex than we thought"
1617
1617
 
1618
- Maxy records phase changes and issues as part of the project's history, creating an audit trail.
1618
+ SiteOffice records phase changes and issues as part of the project's history, creating an audit trail.
1619
1619
 
1620
1620
  ## Completing a Project
1621
1621
 
1622
- Tell Maxy:
1622
+ Tell SiteOffice:
1623
1623
 
1624
1624
  - "Mark the boiler install as done"
1625
1625
  - "Complete the kitchen refit project"
1626
1626
 
1627
- If any work items are still pending, Maxy will let you know and ask how to handle them — cancel, defer, or keep working on them.
1627
+ If any work items are still pending, SiteOffice will let you know and ask how to handle them — cancel, defer, or keep working on them.
1628
1628
 
1629
1629
  ## Abandoning a Project
1630
1630
 
@@ -1633,24 +1633,24 @@ If a project is no longer needed:
1633
1633
  - "Abandon the Davies bathroom — client cancelled"
1634
1634
  - "Stop the kitchen refit project"
1635
1635
 
1636
- Maxy records the reason and marks the project as abandoned.
1636
+ SiteOffice records the reason and marks the project as abandoned.
1637
1637
 
1638
1638
  ## Projects vs. Tasks
1639
1639
 
1640
1640
  Use a **task** for standalone work — a single action, a reminder, a follow-up. Use a **project** when the work has multiple steps that depend on each other, a client or stakeholder, and a lifecycle that progresses through phases.
1641
1641
 
1642
- When you describe multi-step work, Maxy will ask if you'd like to structure it as a project. Over time, it learns your preference and stops asking.
1642
+ When you describe multi-step work, SiteOffice will ask if you'd like to structure it as a project. Over time, it learns your preference and stops asking.
1643
1643
 
1644
1644
  ## Working a Task End to End
1645
1645
 
1646
- Ask Maxy naturally:
1646
+ Ask SiteOffice naturally:
1647
1647
 
1648
1648
  - "What's outstanding?"
1649
1649
  - "What's on my plate?"
1650
1650
  - "What should I work on next?"
1651
1651
  - "Pick something to do"
1652
1652
 
1653
- Maxy reads the ready set for your account, groups the open Tasks under their parent Projects, and asks you to pick one. You pick — it never auto-selects.
1653
+ SiteOffice reads the ready set for your account, groups the open Tasks under their parent Projects, and asks you to pick one. You pick — it never auto-selects.
1654
1654
 
1655
1655
  Once you pick, the loop runs end to end:
1656
1656
 
@@ -1660,7 +1660,7 @@ Once you pick, the loop runs end to end:
1660
1660
 
1661
1661
  This means you can always trace a finished piece of work back to the Task that asked for it, and a Task that says "complete" always has its output attached.
1662
1662
 
1663
- Cross-account access is refused. A Task that belongs to a different account on the same install is invisible to this loop — Maxy will not read it, name it, or surface it.
1663
+ Cross-account access is refused. A Task that belongs to a different account on the same install is invisible to this loop — SiteOffice will not read it, name it, or surface it.
1664
1664
 
1665
1665
  ---
1666
1666
  # Slides
@@ -1706,11 +1706,11 @@ Source: https://docs.getmaxy.com/telegram-guide.md
1706
1706
 
1707
1707
  ## What the Telegram Plugin Does
1708
1708
 
1709
- The Telegram plugin connects Maxy to a Telegram bot. Once set up, you can:
1709
+ The Telegram plugin connects SiteOffice to a Telegram bot. Once set up, you can:
1710
1710
 
1711
- - Send messages to individuals or groups via Maxy ("Send a message to the team: standup in 10 minutes")
1712
- - Receive messages from your Telegram bot and have Maxy respond
1713
- - Use Telegram as a channel for Maxy notifications and alerts
1711
+ - Send messages to individuals or groups via SiteOffice ("Send a message to the team: standup in 10 minutes")
1712
+ - Receive messages from your Telegram bot and have SiteOffice respond
1713
+ - Use Telegram as a channel for SiteOffice notifications and alerts
1714
1714
 
1715
1715
  ## Setup
1716
1716
 
@@ -1723,39 +1723,39 @@ The Telegram plugin connects Maxy to a Telegram bot. Once set up, you can:
1723
1723
 
1724
1724
  ### Step 2: Connect the plugin
1725
1725
 
1726
- Tell Maxy: "Set up Telegram" or "Configure the Telegram bot."
1726
+ Tell SiteOffice: "Set up Telegram" or "Configure the Telegram bot."
1727
1727
 
1728
- Maxy will ask for your bot token, then save it and activate the plugin. The bot is now connected.
1728
+ SiteOffice will ask for your bot token, then save it and activate the plugin. The bot is now connected.
1729
1729
 
1730
1730
  ### Step 3: Start the bot
1731
1731
 
1732
1732
  In Telegram, open your bot and send `/start`. The bot is now active and listening.
1733
1733
 
1734
- ## Sending Messages via Maxy
1734
+ ## Sending Messages via SiteOffice
1735
1735
 
1736
- Once connected, tell Maxy to send messages on your behalf:
1736
+ Once connected, tell SiteOffice to send messages on your behalf:
1737
1737
 
1738
1738
  - "Send a Telegram message to John: I'll be 10 minutes late"
1739
1739
  - "Message the team channel: server maintenance at 11pm"
1740
1740
  - "Tell Sarah via Telegram that the proposal is ready"
1741
1741
 
1742
- Maxy needs a chat ID or username to target a specific person or group. For groups, you'll need to add the bot to the group first.
1742
+ SiteOffice needs a chat ID or username to target a specific person or group. For groups, you'll need to add the bot to the group first.
1743
1743
 
1744
1744
  ## Getting a Chat ID
1745
1745
 
1746
- To message a specific person or group, Maxy needs their chat ID. The easiest way:
1746
+ To message a specific person or group, SiteOffice needs their chat ID. The easiest way:
1747
1747
 
1748
1748
  1. Have the person (or yourself) send any message to your bot
1749
- 2. Ask Maxy: "What chat IDs have messaged the bot recently?"
1750
- 3. Maxy will look up the message history and show you the IDs
1749
+ 2. Ask SiteOffice: "What chat IDs have messaged the bot recently?"
1750
+ 3. SiteOffice will look up the message history and show you the IDs
1751
1751
 
1752
1752
  ## Message History
1753
1753
 
1754
- Ask Maxy: "What messages has the bot received?" or "Show recent Telegram activity."
1754
+ Ask SiteOffice: "What messages has the bot received?" or "Show recent Telegram activity."
1755
1755
 
1756
1756
  ## Troubleshooting
1757
1757
 
1758
- **Bot not responding:** Check that the bot token is correct — ask Maxy "What's my Telegram bot token configured as?" and verify it matches BotFather.
1758
+ **Bot not responding:** Check that the bot token is correct — ask SiteOffice "What's my Telegram bot token configured as?" and verify it matches BotFather.
1759
1759
 
1760
1760
  **Can't send to a group:** The bot must be a member of the group. Add it via the group settings in Telegram, then try again.
1761
1761
 
@@ -1771,7 +1771,7 @@ The `outlook` plugin gives the admin agent read-only access to Microsoft 365 / O
1771
1771
 
1772
1772
  ## Quickstart
1773
1773
 
1774
- 1. **Register an Entra app once per Maxy install** — see `platform/plugins/outlook/references/auth.md` for full steps. Set `OUTLOOK_CLIENT_ID` (and `OUTLOOK_TENANT_ID`, default `common`) in the operator's environment.
1774
+ 1. **Register an Entra app once per SiteOffice install** — see `platform/plugins/outlook/references/auth.md` for full steps. Set `OUTLOOK_CLIENT_ID` (and `OUTLOOK_TENANT_ID`, default `common`) in the operator's environment.
1775
1775
  2. **Per account: register the Outlook account** — in admin chat, ask the agent to "register my Outlook account". The agent runs `outlook-account-register`, which prints an authorization URL.
1776
1776
  3. **Open the URL in the VNC browser** — sign in to your Microsoft account, consent to the requested scopes (`offline_access`, `User.Read`, `Mail.Read`, `Calendars.Read`, `Contacts.Read`).
1777
1777
  4. **Done.** Subsequent tool calls (mail, calendar, contacts) use the persisted refresh token transparently.
@@ -1841,7 +1841,7 @@ Source: https://docs.getmaxy.com/linkedin-extension.md
1841
1841
 
1842
1842
  # LinkedIn Extension — operator guide
1843
1843
 
1844
- Capture a LinkedIn profile or DM thread to your Maxy graph with one click. The plugin ships a small Chrome extension; the admin already knows how to receive its payloads.
1844
+ Capture a LinkedIn profile or DM thread to your SiteOffice graph with one click. The plugin ships a small Chrome extension; the admin already knows how to receive its payloads.
1845
1845
 
1846
1846
  ## Install (one time)
1847
1847
 
@@ -1849,7 +1849,7 @@ Capture a LinkedIn profile or DM thread to your Maxy graph with one click. The p
1849
1849
  2. Toggle **Developer mode** on (top right).
1850
1850
  3. Click **Load unpacked**.
1851
1851
  4. Select `platform/plugins/linkedin-extension/extension/` on disk.
1852
- 5. Click the puzzle icon → pin **Maxy LinkedIn Ingest** → open its options.
1852
+ 5. Click the puzzle icon → pin **SiteOffice LinkedIn Ingest** → open its options.
1853
1853
  6. Paste two values:
1854
1854
  - **Admin host** — your tunnel URL, e.g. `https://your-tunnel.example.com`.
1855
1855
  - **Session key** — open your admin browser, copy the value of `session_key` from the cookie. (Same key the admin uses to authenticate every other admin request.)
@@ -1857,7 +1857,7 @@ Capture a LinkedIn profile or DM thread to your Maxy graph with one click. The p
1857
1857
 
1858
1858
  ## Use
1859
1859
 
1860
- - **Profile** — open any `https://www.linkedin.com/in/<slug>/` page. An **Add to Maxy** pill appears in the top section. Click it. Within a few seconds the pill turns green: the profile is in your graph.
1860
+ - **Profile** — open any `https://www.linkedin.com/in/<slug>/` page. An **Add to SiteOffice** pill appears in the top section. Click it. Within a few seconds the pill turns green: the profile is in your graph.
1861
1861
  - **DM thread** — open any `https://www.linkedin.com/messaging/thread/<id>/` conversation. The same pill appears. Click it; the full transcript is captured plus the participants and any explicit commitments (meetings booked, actions promised, prices discussed).
1862
1862
  - **Re-click** — the pill is idempotent. Re-clicking the same URL refreshes the document body and regenerates the summary; identities and entities `MERGE` rather than duplicate.
1863
1863
 
@@ -1877,7 +1877,7 @@ The plugin will never create `:Communication`, `:ConversationArchive` rows (i.e.
1877
1877
 
1878
1878
  ## When the pill turns amber
1879
1879
 
1880
- The pill shows **Sign in to Maxy** when your session key has expired. Click it to open the options page; paste a fresh `session_key` from your admin browser; save. The next click on the LinkedIn pill will succeed.
1880
+ The pill shows **Sign in to SiteOffice** when your session key has expired. Click it to open the options page; paste a fresh `session_key` from your admin browser; save. The next click on the LinkedIn pill will succeed.
1881
1881
 
1882
1882
  ## When the pill turns red
1883
1883
 
@@ -2145,7 +2145,7 @@ Source: https://docs.getmaxy.com/voice-mirror-guide.md
2145
2145
 
2146
2146
  ## What It Does
2147
2147
 
2148
- Maxy reads emails, posts, documents, and your own chat messages, and uses them to make sure agent-drafted copy reads like you wrote it — not like generic AI prose.
2148
+ SiteOffice reads emails, posts, documents, and your own chat messages, and uses them to make sure agent-drafted copy reads like you wrote it — not like generic AI prose.
2149
2149
 
2150
2150
  Anthropic models cannot be fine-tuned. Voice mirror works by feeding the model two things alongside every drafting task:
2151
2151
 
@@ -2156,24 +2156,24 @@ The model conditions on both and produces copy that reads as yours.
2156
2156
 
2157
2157
  Voice mirror maintains a separate profile for each type of content you write: plain text, email, social posts, articles, notes, and marketing copy. The right profile is applied automatically based on what you're drafting.
2158
2158
 
2159
- When Maxy produces anything that will go out under your name (a document, public-facing copy, anything you will send onward), it applies your voice before it writes the first line, not after you ask for a rewrite. You do not have to request it.
2159
+ When SiteOffice produces anything that will go out under your name (a document, public-facing copy, anything you will send onward), it applies your voice before it writes the first line, not after you ask for a rewrite. You do not have to request it.
2160
2160
 
2161
2161
  ## How Your Voice Is Captured
2162
2162
 
2163
2163
  ### Automatically — from chat
2164
2164
 
2165
- Every admin chat session feeds your writing into the `text` profile automatically. When the session ends, Maxy reads the transcript, filters out slash commands, system messages, and large paste blocks, and adds each genuine turn as a corpus entry. This happens in the background with no action needed from you.
2165
+ Every admin chat session feeds your writing into the `text` profile automatically. When the session ends, SiteOffice reads the transcript, filters out slash commands, system messages, and large paste blocks, and adds each genuine turn as a corpus entry. This happens in the background with no action needed from you.
2166
2166
 
2167
2167
  ### Via backfill — from historical content
2168
2168
 
2169
- Use the backfill flow to teach Maxy your writing from emails, documents, and social posts you've already written.
2169
+ Use the backfill flow to teach SiteOffice your writing from emails, documents, and social posts you've already written.
2170
2170
 
2171
2171
  In the admin chat, ask: **"Start the voice-mirror backfill."**
2172
2172
 
2173
- Maxy asks which stream to backfill first — discrete documents (emails, posts, PDFs) or chat archives (WhatsApp, Telegram, etc.). **Pick chat archives first if you have any imported.** Chat is where your unguarded voice lives; email is the same voice in dress clothes.
2173
+ SiteOffice asks which stream to backfill first — discrete documents (emails, posts, PDFs) or chat archives (WhatsApp, Telegram, etc.). **Pick chat archives first if you have any imported.** Chat is where your unguarded voice lives; email is the same voice in dress clothes.
2174
2174
 
2175
- - **Chat archives** — tag a whole conversation in one click. Maxy doesn't ask about individual messages because chunks within a conversation almost always share the same voice. Options per conversation: yours, mixed (multiple authors on your side — rare), or not yours (e.g. a Slack channel where you only forwarded other people's messages).
2176
- - **Documents and posts** — paginated 10 at a time. Maxy shows each item with its detected format (email, article, note, social-post). Tag the whole batch, a subset by number, or per-item if you want a precise label like `human-led-agent-assisted` (you wrote the content, Maxy polished). Override the detected format if one is wrong.
2175
+ - **Chat archives** — tag a whole conversation in one click. SiteOffice doesn't ask about individual messages because chunks within a conversation almost always share the same voice. Options per conversation: yours, mixed (multiple authors on your side — rare), or not yours (e.g. a Slack channel where you only forwarded other people's messages).
2176
+ - **Documents and posts** — paginated 10 at a time. SiteOffice shows each item with its detected format (email, article, note, social-post). Tag the whole batch, a subset by number, or per-item if you want a precise label like `human-led-agent-assisted` (you wrote the content, SiteOffice polished). Override the detected format if one is wrong.
2177
2177
 
2178
2178
  Skip a batch if none qualify, or stop at any time — the next session resumes where you left off.
2179
2179
 
@@ -2181,13 +2181,13 @@ Skip a batch if none qualify, or stop at any time — the next session resumes w
2181
2181
 
2182
2182
  Once you have corpus entries tagged (or after automatic PTY ingestion fills the `text` profile), ask: **"Build my voice profile."**
2183
2183
 
2184
- Maxy reads the corpus for each format, summarises your style as a YAML card, and saves it to the graph. It picks up your sentence rhythms, the constructions you reach for, the words you avoid — separately for email, articles, social posts, and so on.
2184
+ SiteOffice reads the corpus for each format, summarises your style as a YAML card, and saves it to the graph. It picks up your sentence rhythms, the constructions you reach for, the words you avoid — separately for email, articles, social posts, and so on.
2185
2185
 
2186
2186
  The profile re-runs automatically when your corpus grows by ≥20% for any format or every 30 days, whichever comes first.
2187
2187
 
2188
2188
  ## Feedback Loop
2189
2189
 
2190
- When you edit an agent draft before sending — shorten a sentence, change a sign-off, swap a phrase — Maxy captures the edit and feeds it into the next distillation. The more you edit, the closer the voice gets.
2190
+ When you edit an agent draft before sending — shorten a sentence, change a sign-off, swap a phrase — SiteOffice captures the edit and feeds it into the next distillation. The more you edit, the closer the voice gets.
2191
2191
 
2192
2192
  This happens silently as part of the edit-loop in any drafting skill (email composition is the first wired surface).
2193
2193
 
@@ -2200,7 +2200,7 @@ Voice mirror is on by default for every drafting skill. To opt out for one, set
2200
2200
  - **Blend voices** — one profile set per person, no "Joel + Neo combined".
2201
2201
  - **Copy public figures** — voice mirror only learns from your own writing.
2202
2202
  - **Clone audio** — text only, no speech synthesis.
2203
- - **Guess** — historical content stays `unknown` until you mark it. Maxy never auto-classifies your writing. (Automatic ingestion applies only to your live PTY sessions where authorship is certain.)
2203
+ - **Guess** — historical content stays `unknown` until you mark it. SiteOffice never auto-classifies your writing. (Automatic ingestion applies only to your live PTY sessions where authorship is certain.)
2204
2204
 
2205
2205
  ## Status
2206
2206
 
@@ -2223,7 +2223,7 @@ SDK-resume contract). This file is the index that points at them.
2223
2223
 
2224
2224
  The `maxy-code/` tree does **not** ship a `.docs/platform.md` developer
2225
2225
  doc. The legacy root tree (`getmaxy/`) carries one at
2226
- `.docs/platform.md` for the original Maxy installer; the Maxy Code tree
2226
+ `.docs/platform.md` for the original SiteOffice installer; the SiteOffice Code tree
2227
2227
  keeps its architecture surface in two places:
2228
2228
 
2229
2229
  - `maxy-code-prd.md` at the repo root — product requirements and the
@@ -2444,7 +2444,7 @@ chat stays live.
2444
2444
  SOUL / KNOWLEDGE) auto-save on type via
2445
2445
  `POST /api/admin/sidebar-artefact-save`.
2446
2446
  - Read-only artefacts (specialist agent templates) cannot be edited
2447
- because they ship with Maxy and would be overwritten on the next
2447
+ because they ship with SiteOffice and would be overwritten on the next
2448
2448
  install.
2449
2449
  - PDF artefacts render inline; non-PDF binaries fall back to a Download
2450
2450
  button when the browser has no native viewer.
@@ -2658,7 +2658,7 @@ Source: https://docs.getmaxy.com/neo4j.md
2658
2658
 
2659
2659
  # Neo4j edge types — operator reference
2660
2660
 
2661
- How Maxy's graph wires itself.
2661
+ How SiteOffice's graph wires itself.
2662
2662
 
2663
2663
  ## Typed-edge auto-extraction
2664
2664
 
@@ -2726,9 +2726,9 @@ Source: https://docs.getmaxy.com/internals.md
2726
2726
 
2727
2727
  # Platform Internals — Retrieval Architecture
2728
2728
 
2729
- Technical architecture reference for the retrieval pipeline, knowledge delivery, and supporting infrastructure. This document covers how information moves from the Neo4j graph into an agent's context — the mechanics behind "Maxy searches this graph to retrieve relevant context."
2729
+ Technical architecture reference for the retrieval pipeline, knowledge delivery, and supporting infrastructure. This document covers how information moves from the Neo4j graph into an agent's context — the mechanics behind "SiteOffice searches this graph to retrieve relevant context."
2730
2730
 
2731
- Use this reference when assessing capabilities, diagnosing retrieval behaviour, or answering questions about how the platform works internally. When a question asks "does Maxy have X?" — check here before asserting a gap.
2731
+ Use this reference when assessing capabilities, diagnosing retrieval behaviour, or answering questions about how the platform works internally. When a question asks "does SiteOffice have X?" — check here before asserting a gap.
2732
2732
 
2733
2733
  ---
2734
2734
 
@@ -3051,13 +3051,13 @@ This tool is read-only and available to both public and admin agents.
3051
3051
 
3052
3052
  ### When conversations are created
3053
3053
 
3054
- `:Conversation` nodes on webchat (admin login, "New conversation" in the burger, a new public visitor) are created lazily. Opening the chat or logging in does not write anything to the graph — Maxy only records the conversation once the user sends a second message. This keeps `conversation-search` and the Conversations modal free of one-turn abandoned threads. WhatsApp and Telegram take the opposite posture: every inbound — DM or group, allowed or activation-off, agent-invoked or gated — MERGEs the `:Conversation` and writes a forensic `:Message:WhatsAppMessage` row before any access-control decision. The graph is the durable record of every message the device received, not just the ones the agent replied to. See `.docs/web-chat.md` "Deferred conversation persistence" and `.docs/whatsapp.md` "Session continuity" for the full contract.
3054
+ `:Conversation` nodes on webchat (admin login, "New conversation" in the burger, a new public visitor) are created lazily. Opening the chat or logging in does not write anything to the graph — SiteOffice only records the conversation once the user sends a second message. This keeps `conversation-search` and the Conversations modal free of one-turn abandoned threads. WhatsApp and Telegram take the opposite posture: every inbound — DM or group, allowed or activation-off, agent-invoked or gated — MERGEs the `:Conversation` and writes a forensic `:Message:WhatsAppMessage` row before any access-control decision. The graph is the durable record of every message the device received, not just the ones the agent replied to. See `.docs/web-chat.md` "Deferred conversation persistence" and `.docs/whatsapp.md` "Session continuity" for the full contract.
3055
3055
 
3056
3056
  Each row in the Conversations modal exposes a `View logs` row-action that opens a popover with three links — **Stream**, **Errors**, **SSE** — each of which targets `/api/admin/logs?type={stream|error|sse}&sessionId={full-id}` in a new tab. The row's 8-char id chip is click-to-copy; hover reveals the full `sessionId` as a tooltip. See `.docs/web-chat.md` "In-chat retrieval" for the route contract and `console.debug` observability.
3057
3057
 
3058
3058
  ### Static publish surface — `/sites/*`
3059
3059
 
3060
- Maxy hosts a generic per-account static-tree publish surface at `https://public.<brand>/sites/<...>/<file>`. The route serves files from `<accountDir>/sites/<...>` with URL=disk mirroring — operator drops the tree on disk, no upload API. Extended MIME covers HTML/CSS/JS/woff2/fonts on top of images. Path traversal (`..`, encoded `..`, segments failing `SAFE_SEG_RE`) returns 403; symlinks escaping the sites root are rejected via a `realpathSync` re-check. `.html` responses carry `Content-Security-Policy: default-src 'self' https: data:; script-src 'none'` and `Cache-Control: no-cache`; assets are cached for an hour; every response carries `X-Content-Type-Options: nosniff`. Per-account isolation comes from `resolveAccount` — every brand's install sees only its own tree.
3060
+ SiteOffice hosts a generic per-account static-tree publish surface at `https://public.<brand>/sites/<...>/<file>`. The route serves files from `<accountDir>/sites/<...>` with URL=disk mirroring — operator drops the tree on disk, no upload API. Extended MIME covers HTML/CSS/JS/woff2/fonts on top of images. Path traversal (`..`, encoded `..`, segments failing `SAFE_SEG_RE`) returns 403; symlinks escaping the sites root are rejected via a `realpathSync` re-check. `.html` responses carry `Content-Security-Policy: default-src 'self' https: data:; script-src 'none'` and `Cache-Control: no-cache`; assets are cached for an hour; every response carries `X-Content-Type-Options: nosniff`. Per-account isolation comes from `resolveAccount` — every brand's install sees only its own tree.
3061
3061
 
3062
3062
  **Directory canonicalisation.** A request whose disk target is a directory is `301`'d to the trailing-slash form (query string preserved) before any body is served — RFC 3986 §5.3 base resolution requires the trailing slash so relative refs in the served HTML resolve under the directory, not its parent. After the redirect the route serves `<dir>/index.html` if it exists on disk; otherwise `404`. There is **no** implicit-`index.html` invention for missing paths — the publisher owns canonical URLs. A brochure shipped without `index.html` is reached at `/sites/<slug>/<file>.html`, and the admin skill `publish-site` is the sanctioned surface that moves the extracted tree under `<accountDir>/sites/<slug>/` and emits the canonical path slug. Operator-side: drop a brochure at `<accountDir>/sites/properties/<id>/brochure/output/` and it serves at `<public-host>/sites/properties/<id>/brochure/output/brochure.html` (or `<public-host>/sites/properties/<id>/brochure/output/` if that directory contains an `index.html`). See `.docs/web-chat.md` `/sites/*` route entry for the wire contract and `[sites]` log lines (`serve|redirect-trailing-slash|not-found|path-traversal-rejected|symlink-escape-rejected|no-account`).
3063
3063
 
@@ -3065,7 +3065,7 @@ Maxy hosts a generic per-account static-tree publish surface at `https://public.
3065
3065
 
3066
3066
  ### Cross-tab session rotation
3067
3067
 
3068
- When you click "New conversation" in the chat tab, Maxy mints a fresh admin session key on the server and clears the old one. Sibling admin tabs (`/graph`, `/data`) opened in the same browser keep working without re-login: the chat tab broadcasts the new key on a same-origin channel so each sibling tab updates its captured key instantly, and any in-flight admin request that 401s with the rotation-orphan code retries once after re-reading the latest key from per-tab storage. If neither path recovers (browser locked down, second 401 after retry, session expired), the tab shows a single banner — "Your admin session was renewed in another tab. Click to reload." — and one click sends you back through login. No silent 401s; no re-clicking through the same trash icon hoping it sticks. See `.docs/web-chat.md` "Cross-tab rotation contract" for the wire-level `code` taxonomy and observability surfaces.
3068
+ When you click "New conversation" in the chat tab, SiteOffice mints a fresh admin session key on the server and clears the old one. Sibling admin tabs (`/graph`, `/data`) opened in the same browser keep working without re-login: the chat tab broadcasts the new key on a same-origin channel so each sibling tab updates its captured key instantly, and any in-flight admin request that 401s with the rotation-orphan code retries once after re-reading the latest key from per-tab storage. If neither path recovers (browser locked down, second 401 after retry, session expired), the tab shows a single banner — "Your admin session was renewed in another tab. Click to reload." — and one click sends you back through login. No silent 401s; no re-clicking through the same trash icon hoping it sticks. See `.docs/web-chat.md` "Cross-tab rotation contract" for the wire-level `code` taxonomy and observability surfaces.
3069
3069
 
3070
3070
  ---
3071
3071
 
@@ -3227,7 +3227,7 @@ Each ToolCall record contains:
3227
3227
  | startedAt / completedAt | Timestamps for the invocation |
3228
3228
  | sessionId | Links back to the originating conversation |
3229
3229
 
3230
- Records persist indefinitely and are queryable by the admin agent. Ask Maxy "what tools ran in the last session?" or "show me all tool calls from today" to review the audit trail.
3230
+ Records persist indefinitely and are queryable by the admin agent. Ask SiteOffice "what tools ran in the last session?" or "show me all tool calls from today" to review the audit trail.
3231
3231
 
3232
3232
  Workflow-dispatched tool calls are tracked separately via `StepResult` nodes (part of the workflow execution system) and are not duplicated as ToolCall nodes.
3233
3233
 
@@ -3258,7 +3258,7 @@ See `.docs/neo4j.md § Process provenance doctrine` for the full enforcement con
3258
3258
 
3259
3259
  ## Context compaction
3260
3260
 
3261
- When an admin turn crosses 75% of the model's context window, Maxy runs a silent compaction turn that asks the agent to call the `session-compact` MCP tool with a structured briefing (what you asked for, what was done, decisions made, work-in-progress, things you've shared about yourself). The briefing is written to Neo4j; the next admin turn injects it back into the system prompt, so continuity survives across the compaction boundary without re-sending the full transcript.
3261
+ When an admin turn crosses 75% of the model's context window, SiteOffice runs a silent compaction turn that asks the agent to call the `session-compact` MCP tool with a structured briefing (what you asked for, what was done, decisions made, work-in-progress, things you've shared about yourself). The briefing is written to Neo4j; the next admin turn injects it back into the system prompt, so continuity survives across the compaction boundary without re-sending the full transcript.
3262
3262
 
3263
3263
  The compaction runs against a transient one-shot pool entry separate from the long-lived admin Query. Operator-visible side effects:
3264
3264
  - Compaction logs land in `claude-agent-compaction-stream-YYYY-MM-DD.log` alongside the main stream log. Look for `[compaction-start]`, `[compaction-summary-captured]`, `[compaction-failed]`, `[compaction-timeout]`, `[compaction-crashed]`, or `[compaction-spawn-error]` to triage. Subprocess stderr is captured inline as `[subproc-stderr] <line>` — there is no longer a separate `claude-agent-compaction-stderr-…log` file.
@@ -3290,7 +3290,7 @@ npx -y @rubytech/create-realagent-code # realagent brand
3290
3290
 
3291
3291
  **Hostname / printed URL.** Without `--hostname`, the installer reads `scutil --get LocalHostName` and prints the completion URL as `http://<that-name>.local:<port>`. No sudo, no system change — your Mac's existing local network name is what mDNS will resolve. With `--hostname <h>`, the installer sets `HostName` / `LocalHostName` / `ComputerName` to `<h>` via `sudo scutil` (one password prompt, all-or-nothing rollback within the three-call batch) so the URL becomes `http://<h>.local:<port>`. Grep `~/.<brand>/logs/install-*.log` for `[create-maxy] darwin-hostname-mode=` to confirm which path ran (`scutil-get`, `scutil-set`, or `brand-fallback`).
3292
3292
 
3293
- **LaunchAgent.** The installer registers `Maxy` as a launchd LaunchAgent at `~/Library/LaunchAgents/com.rubytech.<brand-hostname>.plist` — for example `com.rubytech.maxy-code.plist`. Survives logout/login and reboot via `KeepAlive=true` and `RunAtLoad=true`. Two brands on the same Mac get two distinct plists (brand-hostname-keyed), so install order is independent. Use `launchctl print gui/$UID/com.rubytech.<brand-hostname>` for service state. The `[create-maxy] launchd-plist=<path> loaded=true` line in the install log confirms `launchctl bootstrap` accepted the plist; `loaded=false exit=<n>` is the failure signal (run `plutil -lint <path>` to diagnose).
3293
+ **LaunchAgent.** The installer registers `SiteOffice` as a launchd LaunchAgent at `~/Library/LaunchAgents/com.rubytech.<brand-hostname>.plist` — for example `com.rubytech.maxy-code.plist`. Survives logout/login and reboot via `KeepAlive=true` and `RunAtLoad=true`. Two brands on the same Mac get two distinct plists (brand-hostname-keyed), so install order is independent. Use `launchctl print gui/$UID/com.rubytech.<brand-hostname>` for service state. The `[create-maxy] launchd-plist=<path> loaded=true` line in the install log confirms `launchctl bootstrap` accepted the plist; `loaded=false exit=<n>` is the failure signal (run `plutil -lint <path>` to diagnose).
3294
3294
 
3295
3295
  **Cloudflare on darwin.** The installer brew-installs the `cloudflared` binary so it is on PATH, but does not invoke `cloudflared service install` or `cloudflared tunnel route dns` — public reach is opt-in. After install, the operator runs `cloudflared tunnel login` (browser-driven) followed by the existing tunnel-setup flow if they want a public address. Grep `[create-maxy] darwin-cloudflare-skip=true` in the install log to confirm the installer took the documented skip path.
3296
3296
 
@@ -3309,7 +3309,7 @@ Every successful Mac install contains, in order: `platform=darwin`, `darwin-host
3309
3309
 
3310
3310
  ## Initial Setup
3311
3311
 
3312
- The Maxy installer handles the full setup. Run it on your Pi:
3312
+ The SiteOffice installer handles the full setup. Run it on your Pi:
3313
3313
 
3314
3314
  ```bash
3315
3315
  npx -y @rubytech/create-maxy
@@ -3324,7 +3324,7 @@ This installs all dependencies (Node.js, Neo4j, Cloudflare tunnel, Claude Code),
3324
3324
  3. Installs and starts Neo4j (the memory database)
3325
3325
  4. Installs and configures the Cloudflare tunnel for remote access
3326
3326
  5. Creates your account and sets your PIN
3327
- 6. Starts the Maxy web server on port 19200
3327
+ 6. Starts the SiteOffice web server on port 19200
3328
3328
  7. Configures systemd so everything restarts automatically if the Pi reboots
3329
3329
 
3330
3330
  ## First admin session — install-time defaults
@@ -3378,7 +3378,7 @@ Diagnostic line per spawn (`~/.<brand>/logs/server.log`):
3378
3378
 
3379
3379
  The `pty-spawn-start` line additionally carries `hooksResolved=<event1,event2,…>` — the hook event names Claude Code would actually load for that PTY (resolved by walking the same `$CLAUDE_CONFIG_DIR/settings.json` plus the cwd-to-.git path Claude Code itself uses). A Stop hook registered in a settings file outside the loader's scope shows up as a missing event in this list.
3380
3380
 
3381
- Zero `aboutOwnerBytes` on any admin spawn is a regression: the upstream resolver dropped the field entirely. The prose body always carries the unconditional MAXIMISE imperative on line two, so the byte count is positive even on a fresh-account spawn whose line one is `NOTHING`. Zero `dormantPluginsBytes` on a Maxy install with `cloudflare` not enabled is likewise a regression. Zero `pluginManifestBytes` on any account with enabled plugins means the upstream walker failed silently.
3381
+ Zero `aboutOwnerBytes` on any admin spawn is a regression: the upstream resolver dropped the field entirely. The prose body always carries the unconditional MAXIMISE imperative on line two, so the byte count is positive even on a fresh-account spawn whose line one is `NOTHING`. Zero `dormantPluginsBytes` on a SiteOffice install with `cloudflare` not enabled is likewise a regression. Zero `pluginManifestBytes` on any account with enabled plugins means the upstream walker failed silently.
3382
3382
 
3383
3383
  The manager also runs a boot-time self-test that renders a fixture compose call against synthetic inputs and refuses to start if any sentinel is missing:
3384
3384
 
@@ -3398,9 +3398,9 @@ Companion lint: `platform/scripts/check-no-esm-require.mjs` rejects `require(` c
3398
3398
 
3399
3399
  ## Service Management
3400
3400
 
3401
- Maxy runs via systemd and starts automatically on boot. You don't need to start it manually. To check if it's running, ask Maxy "Check system status."
3401
+ SiteOffice runs via systemd and starts automatically on boot. You don't need to start it manually. To check if it's running, ask SiteOffice "Check system status."
3402
3402
 
3403
- If you need to restart the service manually (rare), ask Maxy to do it for you.
3403
+ If you need to restart the service manually (rare), ask SiteOffice to do it for you.
3404
3404
 
3405
3405
  ## Browsing the brand filesystem on your LAN (SMB)
3406
3406
 
@@ -3408,23 +3408,23 @@ Every install provisions a per-brand SMB share against the brand's install folde
3408
3408
 
3409
3409
  ## Remote Access via Cloudflare
3410
3410
 
3411
- Maxy uses a Cloudflare tunnel to make your local Pi accessible from anywhere without opening router ports. The tunnel is configured during setup and runs as a background service.
3411
+ SiteOffice uses a Cloudflare tunnel to make your local Pi accessible from anywhere without opening router ports. The tunnel is configured during setup and runs as a background service.
3412
3412
 
3413
- Setting it up: say "Set up remote access." Maxy walks you through signing into Cloudflare, picking your domain (if you have more than one on your Cloudflare account), and then shows a form where you pick a short name that becomes your admin address. For example, entering `joel` gives you `https://joel.your-domain.com` for admin access. You can also pick a separate address for the public chat, or leave it blank to skip public access. The form only accepts valid address characters (lowercase letters, numbers, hyphens) — Maxy never asks you to type your full URL in chat.
3413
+ Setting it up: say "Set up remote access." SiteOffice walks you through signing into Cloudflare, picking your domain (if you have more than one on your Cloudflare account), and then shows a form where you pick a short name that becomes your admin address. For example, entering `joel` gives you `https://joel.your-domain.com` for admin access. You can also pick a separate address for the public chat, or leave it blank to skip public access. The form only accepts valid address characters (lowercase letters, numbers, hyphens) — SiteOffice never asks you to type your full URL in chat.
3414
3414
 
3415
3415
  Your admin URL looks like: `https://joel.maxy.chat` (the short name is whatever you picked in the form).
3416
3416
 
3417
- To check the tunnel status: ask Maxy "Check Cloudflare tunnel status."
3417
+ To check the tunnel status: ask SiteOffice "Check Cloudflare tunnel status."
3418
3418
 
3419
- To restart the tunnel: ask Maxy "Restart the Cloudflare tunnel."
3419
+ To restart the tunnel: ask SiteOffice "Restart the Cloudflare tunnel."
3420
3420
 
3421
3421
  ## Checking Service Status
3422
3422
 
3423
- Ask Maxy: "Check system status."
3423
+ Ask SiteOffice: "Check system status."
3424
3424
 
3425
3425
  The `system-status` tool reports the health of all services: Neo4j, the web server, the Cloudflare tunnel, and all active MCP servers.
3426
3426
 
3427
- ## If Maxy Won't Start
3427
+ ## If SiteOffice Won't Start
3428
3428
 
3429
3429
  From the Pi directly:
3430
3430
 
@@ -3466,9 +3466,9 @@ A separate operator-side harness at `platform/scripts/installer-device-verify.sh
3466
3466
 
3467
3467
  ## Plugin registration at install time
3468
3468
 
3469
- The installer registers Claude Code plugins on the device as the last step before the brand service starts. After registration, `claude plugin list` on the Pi shows every Maxy platform plugin shipped by the brand, every premium sub-plugin shipped by the brand, and any external plugins the brand declares (e.g. Telegram, Discord, iMessage from `claude-plugins-official`). Spawned `claude` sessions inherit those plugins from `~/.claude/` — the session manager passes no `--mcp-config` argv.
3469
+ The installer registers Claude Code plugins on the device as the last step before the brand service starts. After registration, `claude plugin list` on the Pi shows every SiteOffice platform plugin shipped by the brand, every premium sub-plugin shipped by the brand, and any external plugins the brand declares (e.g. Telegram, Discord, iMessage from `claude-plugins-official`). Spawned `claude` sessions inherit those plugins from `~/.claude/` — the session manager passes no `--mcp-config` argv.
3470
3470
 
3471
- **Where the manifests come from.** The Maxy plugin source tree uses `PLUGIN.md` (YAML frontmatter) for plugin metadata, not Claude Code's native `.claude-plugin/plugin.json`. At bundle time, `scripts/generate-plugin-manifests.mjs` walks the payload and synthesises a Claude-Code-native `plugin.json` per plugin plus a `marketplace.json` at each tree root. The generator runs in `packages/create-maxy-code/scripts/bundle.js` after platform + premium plugins are copied into the payload, so the deployed install directory carries:
3471
+ **Where the manifests come from.** The SiteOffice plugin source tree uses `PLUGIN.md` (YAML frontmatter) for plugin metadata, not Claude Code's native `.claude-plugin/plugin.json`. At bundle time, `scripts/generate-plugin-manifests.mjs` walks the payload and synthesises a Claude-Code-native `plugin.json` per plugin plus a `marketplace.json` at each tree root. The generator runs in `packages/create-maxy-code/scripts/bundle.js` after platform + premium plugins are copied into the payload, so the deployed install directory carries:
3472
3472
 
3473
3473
  - `<INSTALL_DIR>/platform/plugins/<name>/.claude-plugin/plugin.json` per platform plugin
3474
3474
  - `<INSTALL_DIR>/platform/plugins/.claude-plugin/marketplace.json` (marketplace `maxy-platform`)
@@ -3517,17 +3517,17 @@ External channel plugins (telegram, discord) are installed but not configured at
3517
3517
 
3518
3518
  ## Running multiple brands on one device
3519
3519
 
3520
- A single Pi or laptop can host more than one brand (for example Maxy and Real Agent) side by side. Each brand runs as its own service on its own port, with its own install directory and its own data. Installing one brand does not touch the other.
3520
+ A single Pi or laptop can host more than one brand (for example SiteOffice and Real Agent) side by side. Each brand runs as its own service on its own port, with its own install directory and its own data. Installing one brand does not touch the other.
3521
3521
 
3522
- - **Separate:** each brand has its own install folder (`~/maxy/`, `~/realagent/`), its own config folder (`~/.maxy/`, `~/.realagent/`), its own web port, its own Cloudflare tunnel state, its own edge systemd unit (`maxy-edge.service` vs `realagent-edge.service`), and by default its own Neo4j database (Maxy on bolt port 7687, Real Agent on 7688). Action runner units are transient and per-invocation, not per-brand, so no naming conflict is possible.
3522
+ - **Separate:** each brand has its own install folder (`~/maxy/`, `~/realagent/`), its own config folder (`~/.maxy/`, `~/.realagent/`), its own web port, its own Cloudflare tunnel state, its own edge systemd unit (`maxy-edge.service` vs `realagent-edge.service`), and by default its own Neo4j database (SiteOffice on bolt port 7687, Real Agent on 7688). Action runner units are transient and per-invocation, not per-brand, so no naming conflict is possible.
3523
3523
  - **Brand-isolated Neo4j:** when a brand provisions a dedicated Neo4j instance (any port other than 7687), the installer stops and disables the apt-package's system `neo4j.service` after enabling the brand-dedicated unit, so only one Neo4j process holds the shared `/var/lib/neo4j/run/` PID file. The seed step receives the brand-correct `NEO4J_URI` and `NEO4J_PASSWORD` as explicit environment variables — the seed script no longer carries a `bolt://localhost:7687` default. A failed dedicated start aborts the install loudly with a journalctl tail; there is no silent fallback to the system instance. Stop/disable targets the literal `neo4j.service` only, so peer brands running their own `neo4j-{brand}.service` are unaffected.
3524
- - **Peer-aware system-unit guard:** before stopping the system `neo4j.service`, the installer checks whether any other brand on the device still depends on it — that is, has `NEO4J_URI=bolt://localhost:7687` in its `~/.<peer>/.env`. If so, the system unit is left enabled and active, and the install log shows `[neo4j] system unit kept active — peer brand <name> depends on port 7687` instead of the usual `[neo4j] disabling system unit` line. This prevents a `create-realagent` install from disabling Maxy's database on a host where Maxy still uses the shared system instance (the earlier platform fixes reproducer on Neo's laptop, 2026-04-28). On single-brand hosts and on multi-brand hosts where every peer runs a dedicated port, behaviour is unchanged. The dedicated unit exports `NEO4J_HOME=<per-brand-data-dir>` alongside `NEO4J_CONF`, so `server.directories.run`, `server.directories.plugins`, and `server.directories.import` resolve per-brand — no collision with `/var/lib/neo4j/run/neo4j.pid`. The conf sed-overrides, mkdir-p, chown, and unit-write are idempotent and re-run on every install, so a host whose prior install left a broken unit recovers on retry.
3524
+ - **Peer-aware system-unit guard:** before stopping the system `neo4j.service`, the installer checks whether any other brand on the device still depends on it — that is, has `NEO4J_URI=bolt://localhost:7687` in its `~/.<peer>/.env`. If so, the system unit is left enabled and active, and the install log shows `[neo4j] system unit kept active — peer brand <name> depends on port 7687` instead of the usual `[neo4j] disabling system unit` line. This prevents a `create-realagent` install from disabling SiteOffice's database on a host where SiteOffice still uses the shared system instance (the earlier platform fixes reproducer on Neo's laptop, 2026-04-28). On single-brand hosts and on multi-brand hosts where every peer runs a dedicated port, behaviour is unchanged. The dedicated unit exports `NEO4J_HOME=<per-brand-data-dir>` alongside `NEO4J_CONF`, so `server.directories.run`, `server.directories.plugins`, and `server.directories.import` resolve per-brand — no collision with `/var/lib/neo4j/run/neo4j.pid`. The conf sed-overrides, mkdir-p, chown, and unit-write are idempotent and re-run on every install, so a host whose prior install left a broken unit recovers on retry.
3525
3525
  - **Shared:** both brands share the system Chromium/VNC stack, the Ollama model server, and the `cloudflared` command itself. Browser automation is serialised — one admin session at a time across both brands.
3526
3526
 
3527
3527
  To install a second brand on a device that already runs the first, just run the other installer. No flags needed for isolation:
3528
3528
 
3529
3529
  ```bash
3530
- # Already running Maxy on port 20000. Install Real Agent on a different port:
3530
+ # Already running SiteOffice on port 20000. Install Real Agent on a different port:
3531
3531
  npx -y @rubytech/create-realagent --port 19500
3532
3532
  ```
3533
3533
 
@@ -3560,13 +3560,13 @@ Empty output from step 3 = brand.json resolved cleanly and the badge reflects th
3560
3560
 
3561
3561
  ## Upgrading
3562
3562
 
3563
- To upgrade Maxy to the latest version, ask Maxy: "Upgrade Maxy." The platform checks the current device identity (hostname and port via `system-status`), then re-runs the installer with explicit `--hostname` and `--port` flags to preserve them across the upgrade.
3563
+ To upgrade SiteOffice to the latest version, ask SiteOffice: "Upgrade SiteOffice." The platform checks the current device identity (hostname and port via `system-status`), then re-runs the installer with explicit `--hostname` and `--port` flags to preserve them across the upgrade.
3564
3564
 
3565
3565
  The docs plugin (this plugin) is upgraded in the same step — you always have the documentation that matches your installed version.
3566
3566
 
3567
3567
  ### Automatic upgrade alert
3568
3568
 
3569
- Maxy checks for new releases on every admin session start — whenever you log in, reload the page, or return to the admin chat. When a newer version is available, the Software Update window opens automatically showing your current and the latest version, with a one-click Upgrade button. Dismissing the window (click outside or the close button) defers the alert until your next login or reload; no alert is shown when you are already on the latest version.
3569
+ SiteOffice checks for new releases on every admin session start — whenever you log in, reload the page, or return to the admin chat. When a newer version is available, the Software Update window opens automatically showing your current and the latest version, with a one-click Upgrade button. Dismissing the window (click outside or the close button) defers the alert until your next login or reload; no alert is shown when you are already on the latest version.
3570
3570
 
3571
3571
  The upgrade runs inside a live terminal embedded in the Software Update window — you see each installation step stream as it happens, and any password prompts from `sudo` appear directly in the terminal for you to answer. Closing the window does not cancel the upgrade; re-opening it reattaches to the same shell so you can see what happened while disconnected.
3572
3572
 
@@ -3578,7 +3578,7 @@ Source: https://docs.getmaxy.com/samba.md
3578
3578
 
3579
3579
  # Samba Share
3580
3580
 
3581
- Every Maxy install provisions a per-brand SMB network share so you can read and write the brand's install folder from Finder, File Explorer, the Files app on iOS, or any SMB-capable client on Android or Linux. No client install required — every modern OS speaks SMB natively.
3581
+ Every SiteOffice install provisions a per-brand SMB network share so you can read and write the brand's install folder from Finder, File Explorer, the Files app on iOS, or any SMB-capable client on Android or Linux. No client install required — every modern OS speaks SMB natively.
3582
3582
 
3583
3583
  The share lives next to the rest of the brand. On a device that runs more than one brand, each brand gets its own stanza, its own credentials, and its own lifecycle. Tearing one brand down never touches another brand's share.
3584
3584
 
@@ -3610,7 +3610,7 @@ If `<hostname>.local` does not resolve from your client (some networks do not ro
3610
3610
  ## Credentials
3611
3611
 
3612
3612
  - **Username** — the Unix user that owns the install on the device. On a Pi or Hetzner box this is `admin`; on a self-hosted Linux laptop it is whatever Linux user ran the installer (for example `neo`). The installer persists this value to `~/.<brand>/.install-owner` so every later read uses the same identity the installer wrote.
3613
- - **Password** — your current Maxy PIN. The same PIN that unlocks the admin UI unlocks the SMB share.
3613
+ - **Password** — your current SiteOffice PIN. The same PIN that unlocks the admin UI unlocks the SMB share.
3614
3614
 
3615
3615
  Both halves are required. SMB never accepts a guest connection; `map to guest = bad user` is set in the global stanza.
3616
3616
 
@@ -3760,8 +3760,8 @@ tail -200 ~/.maxy/logs/maxy-ui.log | rg '\[remote-auth\].*resolvedKind='
3760
3760
  **Symptom:** You send a message and nothing comes back, or the response never arrives.
3761
3761
 
3762
3762
  **Check:**
3763
- 1. Ask Maxy: "Check system status" — the `system-status` tool will report whether all services are running
3764
- 2. Check the platform logs: ask Maxy "Show me the recent logs"
3763
+ 1. Ask SiteOffice: "Check system status" — the `system-status` tool will report whether all services are running
3764
+ 2. Check the platform logs: ask SiteOffice "Show me the recent logs"
3765
3765
  3. If the admin agent itself won't start: restart the platform (see below)
3766
3766
 
3767
3767
  **Common causes:**
@@ -3769,17 +3769,17 @@ tail -200 ~/.maxy/logs/maxy-ui.log | rg '\[remote-auth\].*resolvedKind='
3769
3769
  - Platform process has stopped — restart it
3770
3770
  - Network issue if accessing remotely — check your Cloudflare tunnel is running
3771
3771
 
3772
- **If the chat shows a single `[agent-loop-stop] same error twice — aborting` line and stops:** Maxy hit the same structured tool failure twice in a row inside one turn (e.g. a permission gate refused the same write twice, or two `Read` calls hit the same missing file). The runtime aborted the turn after the second occurrence to save tokens instead of running until the SDK turn budget exhausted. The blocker text names the tool and the first line of the error. Resolve the underlying cause (re-run the named skill, fix the missing prerequisite, etc.) and tap "Continue" — the next turn truly resumes the prior SDK session via the synthetic-tool-result contract, so Maxy picks up where it aborted instead of cold-querying its own session list. To see the diagnostic, ask Maxy: "Show me the most recent stall-recovery log line." Greppable post-deploy invariants: `[agent-loop-stop] reason=identical-tool-failure tool=<name> errorSignature=<sha8> toolInputDigest=<sha8>` followed by `[stall-recovery] kind=agent_loop_stop … handoff=resume-first` and on the next turn `[stall-resume] consumed kind=agent_loop_stop toolUseId=<8> priorSessionId=<8>`. The fallback path (when the SDK session id was lost) emits `handoff=metadata-only` + `[recovery-handoff] generated/consumed reason=agent-loop-stop` and the chat button reads "Start over" instead of "Continue". A `[recovery-handoff] WARN missing-on-cold-create` line means the fallback briefing wasn't persisted — surface to support.
3772
+ **If the chat shows a single `[agent-loop-stop] same error twice — aborting` line and stops:** SiteOffice hit the same structured tool failure twice in a row inside one turn (e.g. a permission gate refused the same write twice, or two `Read` calls hit the same missing file). The runtime aborted the turn after the second occurrence to save tokens instead of running until the SDK turn budget exhausted. The blocker text names the tool and the first line of the error. Resolve the underlying cause (re-run the named skill, fix the missing prerequisite, etc.) and tap "Continue" — the next turn truly resumes the prior SDK session via the synthetic-tool-result contract, so SiteOffice picks up where it aborted instead of cold-querying its own session list. To see the diagnostic, ask SiteOffice: "Show me the most recent stall-recovery log line." Greppable post-deploy invariants: `[agent-loop-stop] reason=identical-tool-failure tool=<name> errorSignature=<sha8> toolInputDigest=<sha8>` followed by `[stall-recovery] kind=agent_loop_stop … handoff=resume-first` and on the next turn `[stall-resume] consumed kind=agent_loop_stop toolUseId=<8> priorSessionId=<8>`. The fallback path (when the SDK session id was lost) emits `handoff=metadata-only` + `[recovery-handoff] generated/consumed reason=agent-loop-stop` and the chat button reads "Start over" instead of "Continue". A `[recovery-handoff] WARN missing-on-cold-create` line means the fallback briefing wasn't persisted — surface to support.
3773
3773
 
3774
- **If a background task goes silent and the chat shows "A background task went silent — K of M completed":** Maxy's subagent stopped emitting progress for over 2 minutes. Tap "Continue" — the next turn resumes the prior session and reads a synthetic tool_result describing what completed before the pause, so the agent re-plans without losing the work it had done. Most stalls are upstream API latency rather than the subagent's approach failing — the resume-first path treats both correctly. Greppable post-deploy invariants: `[stall-recovery] kind=subagent_stalled … completed=<K>/? handoff=resume-first` followed by `[stall-resume] consumed kind=subagent_stalled toolUseId=<8>` on the next turn. If the button reads "Start over" instead, the parent's pending tool_use_id was not captured — the fallback path took over; the prior conversation is preserved as a `<recovery-context>` block in the cold-started session.
3774
+ **If a background task goes silent and the chat shows "A background task went silent — K of M completed":** SiteOffice's subagent stopped emitting progress for over 2 minutes. Tap "Continue" — the next turn resumes the prior session and reads a synthetic tool_result describing what completed before the pause, so the agent re-plans without losing the work it had done. Most stalls are upstream API latency rather than the subagent's approach failing — the resume-first path treats both correctly. Greppable post-deploy invariants: `[stall-recovery] kind=subagent_stalled … completed=<K>/? handoff=resume-first` followed by `[stall-resume] consumed kind=subagent_stalled toolUseId=<8>` on the next turn. If the button reads "Start over" instead, the parent's pending tool_use_id was not captured — the fallback path took over; the prior conversation is preserved as a `<recovery-context>` block in the cold-started session.
3775
3775
 
3776
3776
  **Agent searches the filesystem after uploading a zip.** If you uploaded a zip and the agent burns several turns running `find` / `Glob` instead of unzipping, that is the symptom of the recovery-retry attachment-context regression (now closed by the recovery context preservation contract in `.docs/agents.md`). Greppable confirmation is the `[context-overflow-recovery] retry … attachmentsCarried=<n>` line in the conversation stream log. If you see `[context-overflow-recovery] WARN attachment-context-lost`, the regression has returned — surface to support.
3777
3777
 
3778
- **Turn budget exhausted with a horizontal rule separating two assistant turns.** When Maxy reaches its turn budget and the doubled retry also runs out, the chat now shows a one-paragraph assistant message that opens with `error_max_turns turns=A→B` (initial budget → final budget) followed by the recovery copy: "I reached my turn budget of N before I could finish this request. Try sending a smaller or more focused request, or ask me to use higher effort." That message is persisted to the graph, so the next page-refresh still shows it. The thin horizontal rule labelled "Session restored after timeout." that appears above your following turn signals that the prior turn forced a cold SDK-session restart inside the same conversation (pool eviction) — the agent's response after the rule is from a fresh SDK session even though the conversation thread is unchanged. Greppable post-deploy invariants: `[context-overflow-recovery] exhausted cause=max-turns-interrupted` count equals `[admin-persist] writer=persistMessageExhaust outcome=ok` count for the same sessionId window, and one `[session-store] storeAgentSessionId` line marks the cold-restart that drove the on-screen rule.
3778
+ **Turn budget exhausted with a horizontal rule separating two assistant turns.** When SiteOffice reaches its turn budget and the doubled retry also runs out, the chat now shows a one-paragraph assistant message that opens with `error_max_turns turns=A→B` (initial budget → final budget) followed by the recovery copy: "I reached my turn budget of N before I could finish this request. Try sending a smaller or more focused request, or ask me to use higher effort." That message is persisted to the graph, so the next page-refresh still shows it. The thin horizontal rule labelled "Session restored after timeout." that appears above your following turn signals that the prior turn forced a cold SDK-session restart inside the same conversation (pool eviction) — the agent's response after the rule is from a fresh SDK session even though the conversation thread is unchanged. Greppable post-deploy invariants: `[context-overflow-recovery] exhausted cause=max-turns-interrupted` count equals `[admin-persist] writer=persistMessageExhaust outcome=ok` count for the same sessionId window, and one `[session-store] storeAgentSessionId` line marks the cold-restart that drove the on-screen rule.
3779
3779
 
3780
3780
 
3781
3781
  **A turn rendered in chat is missing on next page-refresh.** Pre-the 2026-05-07 mandate this was a class of silent failure — Neo4j persists were wrapped in a no-op error catch and a write that threw left the artefact "rendered then disappeared on resume". The 2026-05-07 mandate makes JSONL canonical: the resume route reads the SDK transcript file at `~/.claude/projects/<project-key>/<sessionId>.jsonl` first, supplements from Neo4j, and triggers async heal-on-resume writes for any turn the JSONL has but Neo4j does not. So a refreshed conversation always renders what the SDK saw, regardless of write outcome. If a heal write itself fails, the chat shows a top-of-conversation banner naming the count; if every heal succeeds the resume is silent and the missing rows are quietly restored to Neo4j. Greppable post-deploy invariants in the per-session stream log (`logs/claude-agent-stream-<sessionKey>.log`): `[admin-resume] reason=<…> source=<jsonl|jsonl-missing|neo4j-only>` (one per resume), `[admin-persist] convId=<8> writer=<…> outcome=<ok|fail|skip>` (per persist site), `[admin-persist-heal] convId=<8> turnIndex=<n> outcome=<ok|fail>` (per heal write). To force-audit a specific conversation against its Neo4j projection without re-executing it, run `tsx platform/scripts/admin-persist-audit.ts --conversation-id=<uuid> --account-id=<uuid> --session-id=<uuid>` — non-zero exit + per-divergence `[admin-persist-audit] expected=<message|component> missing reason=neo4j-row-absent` lines name what would have been silently lost pre-mandate.
3782
- **Wrong Claude account answering on a multi-brand device.** On a host running both Maxy and Real Agent, each brand's admin agent reads its own `~/${brand.configDir}/.claude/.credentials.json`; there is no longer a shared `~/.claude/` thrashing them against one another. If a brand reports auth failures or appears to be operating against the wrong subscription, check three things:
3782
+ **Wrong Claude account answering on a multi-brand device.** On a host running both SiteOffice and Real Agent, each brand's admin agent reads its own `~/${brand.configDir}/.claude/.credentials.json`; there is no longer a shared `~/.claude/` thrashing them against one another. If a brand reports auth failures or appears to be operating against the wrong subscription, check three things:
3783
3783
  1. `grep "\[claude-auth\] init" ~/.${brand}/logs/server.log | tail -1` — the resolved path must end with `~/.${brand}/.claude/.credentials.json`. If a `[claude-auth] WARN cross-brand-path-detected` line is present, the runtime is still pointing at `~/.claude/`; the brand main service did not pick up the `Environment=CLAUDE_CONFIG_DIR=` setting (re-run the brand installer to refresh the unit file).
3784
3784
  2. `diff <(jq .claudeAiOauth.accessToken ~/.maxy/.claude/.credentials.json) <(jq .claudeAiOauth.accessToken ~/.realagent/.claude/.credentials.json)` — must be non-empty after each brand's operator has run `claude /login` against distinct Anthropic accounts; if it's empty, both brands are still logged in to the same account (operator action, not a code bug).
3785
3785
  3. `grep "\[install\] claude-creds pickup" ~/.${brand}/logs/install-*.log` — fires once on the first post-Task-923 install of any brand and moves the legacy `~/.claude/.credentials.json` into that brand's path. Subsequent brands install with no credentials and require a fresh `claude /login` inside that brand's chat (which writes to the brand-scoped path because the systemd unit env is in scope).
@@ -3795,15 +3795,15 @@ tail -200 ~/.maxy/logs/maxy-ui.log | rg '\[remote-auth\].*resolvedKind='
3795
3795
 
3796
3796
  ## Memory Not Working
3797
3797
 
3798
- **Symptom:** Maxy doesn't remember things you've told it, or search returns nothing.
3798
+ **Symptom:** SiteOffice doesn't remember things you've told it, or search returns nothing.
3799
3799
 
3800
3800
  **Check:**
3801
- 1. Ask Maxy: "Check the Neo4j connection"
3802
- 2. Ask Maxy: "Search memory for [something you know was stored]"
3801
+ 1. Ask SiteOffice: "Check the Neo4j connection"
3802
+ 2. Ask SiteOffice: "Search memory for [something you know was stored]"
3803
3803
 
3804
3804
  **Common causes:**
3805
3805
  - Neo4j service stopped — restart the platform, which restarts Neo4j
3806
- - Memory index is stale — ask Maxy: "Reindex memory"
3806
+ - Memory index is stale — ask SiteOffice: "Reindex memory"
3807
3807
 
3808
3808
  ---
3809
3809
 
@@ -3812,12 +3812,12 @@ tail -200 ~/.maxy/logs/maxy-ui.log | rg '\[remote-auth\].*resolvedKind='
3812
3812
  **Symptom:** You send a message to the bot and nothing happens.
3813
3813
 
3814
3814
  **Check:**
3815
- 1. Confirm the bot token is correct: ask Maxy "What Telegram bot token is configured?"
3815
+ 1. Confirm the bot token is correct: ask SiteOffice "What Telegram bot token is configured?"
3816
3816
  2. Verify the bot is running: send `/start` to the bot in Telegram
3817
- 3. Check the MCP server logs: ask Maxy "Show Telegram plugin logs"
3817
+ 3. Check the MCP server logs: ask SiteOffice "Show Telegram plugin logs"
3818
3818
 
3819
3819
  **Common causes:**
3820
- - Bot token changed (if you regenerated it in BotFather) — update it by telling Maxy "Update my Telegram bot token"
3820
+ - Bot token changed (if you regenerated it in BotFather) — update it by telling SiteOffice "Update my Telegram bot token"
3821
3821
  - Webhook not connected — restart the platform
3822
3822
 
3823
3823
  ---
@@ -3827,11 +3827,11 @@ tail -200 ~/.maxy/logs/maxy-ui.log | rg '\[remote-auth\].*resolvedKind='
3827
3827
  **Symptom:** A tool fails with an error, or a plugin says it can't connect.
3828
3828
 
3829
3829
  **Check:**
3830
- 1. Ask Maxy: "Show me recent errors"
3831
- 2. Ask Maxy: "Restart the [plugin name] plugin"
3830
+ 1. Ask SiteOffice: "Show me recent errors"
3831
+ 2. Ask SiteOffice: "Restart the [plugin name] plugin"
3832
3832
 
3833
3833
  **Common causes:**
3834
- - Missing environment variable (API key, token) — the error message will name it; ask Maxy to help configure it
3834
+ - Missing environment variable (API key, token) — the error message will name it; ask SiteOffice to help configure it
3835
3835
  - MCP server crashed — restarting the platform restarts all MCP servers
3836
3836
 
3837
3837
  ---
@@ -3842,7 +3842,7 @@ tail -200 ~/.maxy/logs/maxy-ui.log | rg '\[remote-auth\].*resolvedKind='
3842
3842
 
3843
3843
  **Check:**
3844
3844
  1. Confirm you have set a PIN in the admin UI at least once. On a fresh Pi or Hetzner box the `smbpasswd` entry does not exist until the first set-pin runs — mounts before that point always fail.
3845
- 2. Use the install owner as the username (`admin` on a Pi or Hetzner box; the Linux user that ran the installer on a self-hosted laptop) and the current Maxy PIN as the password. The SMB password is not stored separately — it is the PIN.
3845
+ 2. Use the install owner as the username (`admin` on a Pi or Hetzner box; the Linux user that ran the installer on a self-hosted laptop) and the current SiteOffice PIN as the password. The SMB password is not stored separately — it is the PIN.
3846
3846
  3. If `<hostname>.local` does not resolve from your client, mount by LAN IP instead (`smb://192.168.1.50` on macOS, `\\192.168.1.50\<brand>` on Windows).
3847
3847
  4. Rotate the PIN in the admin UI. That re-triggers the `smbpasswd` sync on the device. If the resync log line reads `[set-pin] smbpasswd sync failed owner=<unknown> rc=-1 reason=install-owner-file-missing`, restore `~/.<brand>/.install-owner` from the installer log.
3848
3848
 
@@ -3852,35 +3852,35 @@ See [Samba Share](./samba.md) for the full credential model and per-OS mount syn
3852
3852
 
3853
3853
  ## Restarting the Platform
3854
3854
 
3855
- From the admin interface, ask Maxy: "Restart the platform."
3855
+ From the admin interface, ask SiteOffice: "Restart the platform."
3856
3856
 
3857
- If Maxy itself isn't responding (the page loads but the agent won't connect), try refreshing the browser. If the page itself won't load, the platform process may have stopped — power-cycle the Raspberry Pi by unplugging and reconnecting power, then wait a minute for services to restart automatically.
3857
+ If SiteOffice itself isn't responding (the page loads but the agent won't connect), try refreshing the browser. If the page itself won't load, the platform process may have stopped — power-cycle the Raspberry Pi by unplugging and reconnecting power, then wait a minute for services to restart automatically.
3858
3858
 
3859
3859
  ---
3860
3860
 
3861
3861
  ## Checking Logs
3862
3862
 
3863
- Ask Maxy: "Show me the logs" or "Show errors from the last hour."
3863
+ Ask SiteOffice: "Show me the logs" or "Show errors from the last hour."
3864
3864
 
3865
3865
  For specific plugin logs: "Show Telegram logs" or "Show contacts plugin logs."
3866
3866
 
3867
- Maxy has access to all platform logs and can filter them for you.
3867
+ SiteOffice has access to all platform logs and can filter them for you.
3868
3868
 
3869
3869
  ---
3870
3870
 
3871
3871
  ## Cloudflare Tunnel Down (Remote Access Broken)
3872
3872
 
3873
- **Symptom:** You can reach Maxy on your local network but not via your public domain.
3873
+ **Symptom:** You can reach SiteOffice on your local network but not via your public domain.
3874
3874
 
3875
- **Check:** Ask Maxy "Check the Cloudflare tunnel status."
3875
+ **Check:** Ask SiteOffice "Check the Cloudflare tunnel status."
3876
3876
 
3877
- **Fix:** Ask Maxy "Restart the Cloudflare tunnel."
3877
+ **Fix:** Ask SiteOffice "Restart the Cloudflare tunnel."
3878
3878
 
3879
- If the tunnel won't reconnect, re-run the Cloudflare setup: ask Maxy "Reconnect Cloudflare."
3879
+ If the tunnel won't reconnect, re-run the Cloudflare setup: ask SiteOffice "Reconnect Cloudflare."
3880
3880
 
3881
- If the initial Cloudflare login fails during setup, Maxy will fall back to asking you for a connection key. You can create one in the Cloudflare dashboard (Maxy will guide you through this in the browser).
3881
+ If the initial Cloudflare login fails during setup, SiteOffice will fall back to asking you for a connection key. You can create one in the Cloudflare dashboard (SiteOffice will guide you through this in the browser).
3882
3882
 
3883
- **If you switched Cloudflare accounts or are stuck on the wrong one:** ask Maxy "Reset my Cloudflare login and start over." This is a clean reset — Maxy clears every stored credential, then opens a fresh browser sign-in. The next sign-in binds to whichever Cloudflare account you choose, with no risk of the previous account's stored credentials silently coming back.
3883
+ **If you switched Cloudflare accounts or are stuck on the wrong one:** ask SiteOffice "Reset my Cloudflare login and start over." This is a clean reset — SiteOffice clears every stored credential, then opens a fresh browser sign-in. The next sign-in binds to whichever Cloudflare account you choose, with no risk of the previous account's stored credentials silently coming back.
3884
3884
 
3885
3885
  ---
3886
3886
 
@@ -3888,9 +3888,9 @@ If the initial Cloudflare login fails during setup, Maxy will fall back to askin
3888
3888
 
3889
3889
  `maxy-edge.service` (always-on front door) classifies upstream errors and serves a brand-aware response. There are two distinct user-visible shapes; the right one depends on what failed.
3890
3890
 
3891
- **Branded holding page (brand logo + "Starting") for ~10 s during an upgrade — this is expected and self-healing.** The edge process binds the public port immediately, but `maxy.service` (the upstream UI) takes ~10 s after restart to apply the neo4j schema and mount its 11 routes. Any browser navigation that lands during that window gets a self-contained HTML holding page that polls `/api/health` and reloads automatically once the upstream binds. The page renders the brand logo (inlined as a base64 data URI at edge boot from `<install>/server/public/brand/<assets.logo>`) and the brand display/body fonts (loaded from fonts.googleapis.com) — both paths bypass the unavailable upstream so the page never makes a same-origin asset fetch. When `brand.logoContainsName` is true the logo replaces the productName text; otherwise the page falls back to "Maxy is starting". No operator action required. The diagnostic line in `~/.maxy/logs/edge.log` is `[edge] upstream http error path=… err=connect ECONNREFUSED 127.0.0.1:<UPSTREAM_PORT> err-class=econnrefused-coldstart upstream=…` and disappears as soon as upstream binds. Boot-time confirmation that the logo resolved: `[edge] brand=<name> holding-logo=inlined assets-dir=<path>` — `holding-logo=missing` means the logo file wasn't found at `assets-dir`, the page degrades to text-only.
3891
+ **Branded holding page (brand logo + "Starting") for ~10 s during an upgrade — this is expected and self-healing.** The edge process binds the public port immediately, but `maxy.service` (the upstream UI) takes ~10 s after restart to apply the neo4j schema and mount its 11 routes. Any browser navigation that lands during that window gets a self-contained HTML holding page that polls `/api/health` and reloads automatically once the upstream binds. The page renders the brand logo (inlined as a base64 data URI at edge boot from `<install>/server/public/brand/<assets.logo>`) and the brand display/body fonts (loaded from fonts.googleapis.com) — both paths bypass the unavailable upstream so the page never makes a same-origin asset fetch. When `brand.logoContainsName` is true the logo replaces the productName text; otherwise the page falls back to "SiteOffice is starting". No operator action required. The diagnostic line in `~/.maxy/logs/edge.log` is `[edge] upstream http error path=… err=connect ECONNREFUSED 127.0.0.1:<UPSTREAM_PORT> err-class=econnrefused-coldstart upstream=…` and disappears as soon as upstream binds. Boot-time confirmation that the logo resolved: `[edge] brand=<name> holding-logo=inlined assets-dir=<path>` — `holding-logo=missing` means the logo file wasn't found at `assets-dir`, the page degrades to text-only.
3892
3892
 
3893
- **Branded plain-text 502 ("Bad Gateway (Maxy unavailable)") — real upstream failure, not cold-start.** Any error class other than `ECONNREFUSED` (timeouts, resets, host-unreachable) returns the existing 502 path. The diagnostic line carries `err-class=other`. Read the log with `tail -200 ~/.maxy/logs/edge.log | rg 'err-class=other'` and check `~/.maxy/logs/server.log` for upstream stack traces — the upstream itself is the source.
3893
+ **Branded plain-text 502 ("Bad Gateway (SiteOffice unavailable)") — real upstream failure, not cold-start.** Any error class other than `ECONNREFUSED` (timeouts, resets, host-unreachable) returns the existing 502 path. The diagnostic line carries `err-class=other`. Read the log with `tail -200 ~/.maxy/logs/edge.log | rg 'err-class=other'` and check `~/.maxy/logs/server.log` for upstream stack traces — the upstream itself is the source.
3894
3894
 
3895
3895
  **Continuous `err-class=econnrefused-coldstart` for >30 s past the last `[edge] listening` line** indicates the upstream never binds — the upgrade or boot has stalled. Recover via `sudo systemctl --user status maxy.service` and check the action runner log per the next section. Permanent-failure UI escalation (turning the holding page into an error after N seconds) is intentionally deferred.
3896
3896