@rubytech/create-maxy-code 0.1.33 → 0.1.34

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 (444) hide show
  1. package/dist/__tests__/account-id-env.test.js +1 -1
  2. package/dist/__tests__/apt-resolve.test.js +7 -7
  3. package/dist/__tests__/brew-install.test.js +1 -1
  4. package/dist/__tests__/brew-resolve.test.js +1 -1
  5. package/dist/__tests__/cdp-port-no-silent-fallback.test.js +4 -4
  6. package/dist/__tests__/init-logging.test.js +1 -1
  7. package/dist/__tests__/launchd-plist.test.js +1 -1
  8. package/dist/__tests__/macos-version.test.js +1 -1
  9. package/dist/__tests__/peer-brand-detect.test.js +1 -1
  10. package/dist/__tests__/platform-detect.test.js +2 -2
  11. package/dist/__tests__/port-canonicalisation.test.js +1 -1
  12. package/dist/__tests__/preflight-port-classifier.test.js +6 -6
  13. package/dist/__tests__/samba-provision.test.js +1 -1
  14. package/dist/__tests__/snap-chromium.test.js +1 -1
  15. package/dist/apt-resolve.js +5 -5
  16. package/dist/brew-install.js +1 -1
  17. package/dist/brew-resolve.js +3 -3
  18. package/dist/index.js +146 -122
  19. package/dist/init-logging.js +1 -1
  20. package/dist/launchd-plist.js +1 -1
  21. package/dist/macos-version.js +2 -2
  22. package/dist/peer-brand-detect.js +1 -1
  23. package/dist/pinned-binaries.js +1 -1
  24. package/dist/platform-detect.js +1 -1
  25. package/dist/port-resolution.js +2 -2
  26. package/dist/preflight-port-classifier.js +3 -3
  27. package/dist/samba-provision.js +1 -1
  28. package/dist/snap-chromium.js +3 -3
  29. package/dist/uninstall.js +28 -28
  30. package/package.json +1 -1
  31. package/payload/platform/lib/account-enumeration/dist/__tests__/validate-env.test.js +1 -1
  32. package/payload/platform/lib/account-enumeration/dist/__tests__/validate-env.test.js.map +1 -1
  33. package/payload/platform/lib/account-enumeration/dist/index.d.ts +1 -1
  34. package/payload/platform/lib/account-enumeration/src/__tests__/validate-env.test.ts +1 -1
  35. package/payload/platform/lib/account-enumeration/src/index.ts +1 -1
  36. package/payload/platform/lib/admins-write/dist/index.js +3 -3
  37. package/payload/platform/lib/admins-write/dist/index.js.map +1 -1
  38. package/payload/platform/lib/admins-write/src/index.ts +4 -4
  39. package/payload/platform/lib/entitlement/dist/index.d.ts +1 -1
  40. package/payload/platform/lib/entitlement/dist/index.js +2 -2
  41. package/payload/platform/lib/entitlement/dist/index.js.map +1 -1
  42. package/payload/platform/lib/graph-mcp/dist/__tests__/warnings-envelope.test.js +1 -1
  43. package/payload/platform/lib/graph-mcp/dist/__tests__/warnings-envelope.test.js.map +1 -1
  44. package/payload/platform/lib/graph-mcp/dist/cypher-rewrite-stamp.d.ts +3 -3
  45. package/payload/platform/lib/graph-mcp/dist/cypher-rewrite-stamp.js +3 -3
  46. package/payload/platform/lib/graph-mcp/dist/cypher-shim-read.d.ts +1 -1
  47. package/payload/platform/lib/graph-mcp/dist/cypher-shim-read.js +1 -1
  48. package/payload/platform/lib/graph-mcp/dist/cypher-shim-write.d.ts +1 -1
  49. package/payload/platform/lib/graph-mcp/dist/cypher-shim-write.js +1 -1
  50. package/payload/platform/lib/graph-mcp/dist/cypher-validate.d.ts +1 -1
  51. package/payload/platform/lib/graph-mcp/dist/cypher-validate.js +1 -1
  52. package/payload/platform/lib/graph-mcp/dist/index.d.ts +1 -1
  53. package/payload/platform/lib/graph-mcp/dist/index.js +24 -24
  54. package/payload/platform/lib/graph-mcp/dist/index.js.map +1 -1
  55. package/payload/platform/lib/graph-mcp/dist/schema-cache.d.ts +1 -1
  56. package/payload/platform/lib/graph-mcp/dist/schema-cache.js +2 -2
  57. package/payload/platform/lib/graph-mcp/dist/schema-cypher-parser.d.ts +3 -3
  58. package/payload/platform/lib/graph-mcp/dist/schema-cypher-parser.js +3 -3
  59. package/payload/platform/lib/graph-mcp/src/__tests__/warnings-envelope.test.ts +1 -1
  60. package/payload/platform/lib/graph-mcp/src/cypher-rewrite-stamp.ts +3 -3
  61. package/payload/platform/lib/graph-mcp/src/cypher-shim-read.ts +1 -1
  62. package/payload/platform/lib/graph-mcp/src/cypher-shim-write.ts +1 -1
  63. package/payload/platform/lib/graph-mcp/src/cypher-validate.ts +1 -1
  64. package/payload/platform/lib/graph-mcp/src/index.ts +29 -29
  65. package/payload/platform/lib/graph-mcp/src/schema-cache.ts +2 -2
  66. package/payload/platform/lib/graph-mcp/src/schema-cypher-parser.ts +3 -3
  67. package/payload/platform/lib/graph-search/dist/index.d.ts +12 -12
  68. package/payload/platform/lib/graph-search/dist/index.js +11 -11
  69. package/payload/platform/lib/graph-search/dist/index.js.map +1 -1
  70. package/payload/platform/lib/graph-search/src/__tests__/bm25-label-gate.test.ts +2 -2
  71. package/payload/platform/lib/graph-search/src/__tests__/bm25-strong-bypass-threshold.test.ts +2 -2
  72. package/payload/platform/lib/graph-search/src/__tests__/brochure-threshold.test.ts +3 -3
  73. package/payload/platform/lib/graph-search/src/__tests__/expand-batch.test.ts +2 -2
  74. package/payload/platform/lib/graph-search/src/__tests__/fulltext-coverage.test.ts +6 -6
  75. package/payload/platform/lib/graph-search/src/__tests__/hybrid.test.ts +5 -5
  76. package/payload/platform/lib/graph-search/src/__tests__/vector-threshold.test.ts +2 -2
  77. package/payload/platform/lib/graph-search/src/index.ts +18 -18
  78. package/payload/platform/lib/graph-trash/dist/index.d.ts +3 -3
  79. package/payload/platform/lib/graph-trash/dist/index.js +3 -3
  80. package/payload/platform/lib/graph-trash/src/index.ts +3 -3
  81. package/payload/platform/lib/graph-write/dist/__tests__/action-provenance-gate.test.js +4 -4
  82. package/payload/platform/lib/graph-write/dist/__tests__/action-provenance-gate.test.js.map +1 -1
  83. package/payload/platform/lib/graph-write/dist/audit.d.ts +2 -2
  84. package/payload/platform/lib/graph-write/dist/audit.js +2 -2
  85. package/payload/platform/lib/graph-write/dist/conversation-provenance.js +1 -1
  86. package/payload/platform/lib/graph-write/dist/conversation-provenance.js.map +1 -1
  87. package/payload/platform/lib/graph-write/dist/index.d.ts +5 -5
  88. package/payload/platform/lib/graph-write/dist/index.js +12 -12
  89. package/payload/platform/lib/graph-write/dist/index.js.map +1 -1
  90. package/payload/platform/lib/graph-write/src/__tests__/action-provenance-gate.test.ts +4 -4
  91. package/payload/platform/lib/graph-write/src/audit.ts +2 -2
  92. package/payload/platform/lib/graph-write/src/conversation-provenance.ts +1 -1
  93. package/payload/platform/lib/graph-write/src/index.ts +13 -13
  94. package/payload/platform/lib/mcp-eager/dist/index.d.ts +2 -2
  95. package/payload/platform/lib/mcp-eager/dist/index.js +2 -2
  96. package/payload/platform/lib/mcp-eager/src/index.ts +2 -2
  97. package/payload/platform/lib/mcp-spawn-tee/dist/index.d.ts +2 -2
  98. package/payload/platform/lib/mcp-spawn-tee/dist/index.js +2 -2
  99. package/payload/platform/lib/mcp-spawn-tee/src/index.ts +2 -2
  100. package/payload/platform/lib/mcp-stderr-tee/dist/index.d.ts +1 -1
  101. package/payload/platform/lib/mcp-stderr-tee/dist/index.js +4 -4
  102. package/payload/platform/lib/mcp-stderr-tee/dist/index.js.map +1 -1
  103. package/payload/platform/lib/mcp-stderr-tee/src/index.ts +4 -4
  104. package/payload/platform/lib/oauth-llm/dist/index.d.ts +4 -4
  105. package/payload/platform/lib/oauth-llm/dist/index.js +3 -3
  106. package/payload/platform/lib/oauth-llm/dist/index.js.map +1 -1
  107. package/payload/platform/lib/oauth-llm/src/index.ts +6 -6
  108. package/payload/platform/lib/persistent-components/dist/index.d.ts +1 -1
  109. package/payload/platform/lib/persistent-components/dist/index.js +1 -1
  110. package/payload/platform/lib/persistent-components/src/index.ts +1 -1
  111. package/payload/platform/lib/task-secrets/dist/index.js +1 -1
  112. package/payload/platform/lib/task-secrets/dist/index.js.map +1 -1
  113. package/payload/platform/lib/task-secrets/src/__tests__/redact-secrets.test.ts +1 -1
  114. package/payload/platform/lib/task-secrets/src/index.ts +1 -1
  115. package/payload/platform/neo4j/edge-annotations.json +9 -9
  116. package/payload/platform/neo4j/schema.cypher +32 -33
  117. package/payload/platform/package.json +2 -2
  118. package/payload/platform/plugins/admin/PLUGIN.md +0 -2
  119. package/payload/platform/plugins/admin/hooks/__tests__/archive-ingest-surface-gate.test.sh +4 -4
  120. package/payload/platform/plugins/admin/hooks/__tests__/playwright-file-guard.test.sh +1 -1
  121. package/payload/platform/plugins/admin/hooks/__tests__/pre-tool-use-base64-guard.test.sh +1 -1
  122. package/payload/platform/plugins/admin/hooks/archive-ingest-surface-gate.sh +13 -13
  123. package/payload/platform/plugins/admin/hooks/pre-tool-use.sh +7 -7
  124. package/payload/platform/plugins/admin/mcp/dist/__tests__/plugin-read-skill-resolution.test.js +2 -2
  125. package/payload/platform/plugins/admin/mcp/dist/__tests__/plugin-read-skill-resolution.test.js.map +1 -1
  126. package/payload/platform/plugins/admin/mcp/dist/__tests__/public-hostname.test.js +1 -1
  127. package/payload/platform/plugins/admin/mcp/dist/__tests__/public-hostname.test.js.map +1 -1
  128. package/payload/platform/plugins/admin/mcp/dist/__tests__/skill-load-required-inputs.test.js +2 -2
  129. package/payload/platform/plugins/admin/mcp/dist/__tests__/skill-load-required-inputs.test.js.map +1 -1
  130. package/payload/platform/plugins/admin/mcp/dist/__tests__/skill-load.test.js +1 -1
  131. package/payload/platform/plugins/admin/mcp/dist/__tests__/skill-load.test.js.map +1 -1
  132. package/payload/platform/plugins/admin/mcp/dist/index.js +38 -65
  133. package/payload/platform/plugins/admin/mcp/dist/index.js.map +1 -1
  134. package/payload/platform/plugins/admin/mcp/dist/lib/neo4j.js +2 -2
  135. package/payload/platform/plugins/admin/mcp/dist/lib/neo4j.js.map +1 -1
  136. package/payload/platform/plugins/admin/mcp/dist/lib/public-hostname.js +2 -2
  137. package/payload/platform/plugins/admin/mcp/dist/lib/public-hostname.js.map +1 -1
  138. package/payload/platform/plugins/admin/mcp/dist/skill-resolution.js +5 -5
  139. package/payload/platform/plugins/admin/mcp/dist/skill-resolution.js.map +1 -1
  140. package/payload/platform/plugins/admin/skills/plugin-management/SKILL.md +1 -1
  141. package/payload/platform/plugins/admin/skills/public-agent-manager/SKILL.md +0 -1
  142. package/payload/platform/plugins/admin/skills/publish-site/SKILL.md +1 -1
  143. package/payload/platform/plugins/admin/skills/unzip-attachment/SKILL.md +2 -2
  144. package/payload/platform/plugins/cloudflare/mcp/dist/index.js +1 -1
  145. package/payload/platform/plugins/cloudflare/mcp/dist/index.js.map +1 -1
  146. package/payload/platform/plugins/cloudflare/mcp/dist/lib/cloudflared.d.ts +1 -1
  147. package/payload/platform/plugins/cloudflare/mcp/dist/lib/cloudflared.js +6 -6
  148. package/payload/platform/plugins/cloudflare/mcp/dist/lib/cloudflared.js.map +1 -1
  149. package/payload/platform/plugins/cloudflare/mcp/dist/lib/setup-orchestrator.d.ts +2 -2
  150. package/payload/platform/plugins/cloudflare/mcp/dist/lib/setup-orchestrator.js +2 -2
  151. package/payload/platform/plugins/cloudflare/references/dashboard-guide.md +1 -1
  152. package/payload/platform/plugins/cloudflare/references/manual-setup.md +4 -4
  153. package/payload/platform/plugins/cloudflare/scripts/__tests__/tunnel-ingress.test.ts +1 -1
  154. package/payload/platform/plugins/cloudflare/scripts/_stream-log.sh +8 -8
  155. package/payload/platform/plugins/cloudflare/scripts/list-cf-domains.sh +2 -2
  156. package/payload/platform/plugins/cloudflare/scripts/list-cf-domains.ts +16 -16
  157. package/payload/platform/plugins/cloudflare/scripts/reset-tunnel.sh +1 -1
  158. package/payload/platform/plugins/cloudflare/scripts/setup-tunnel.sh +28 -28
  159. package/payload/platform/plugins/cloudflare/scripts/tunnel-ingress.ts +5 -5
  160. package/payload/platform/plugins/cloudflare/skills/setup-tunnel/SKILL.md +3 -3
  161. package/payload/platform/plugins/contacts/mcp/dist/lib/neo4j.js +2 -2
  162. package/payload/platform/plugins/contacts/mcp/dist/lib/neo4j.js.map +1 -1
  163. package/payload/platform/plugins/contacts/mcp/dist/lib/resolve-person.d.ts +1 -1
  164. package/payload/platform/plugins/contacts/mcp/dist/lib/resolve-person.js +1 -1
  165. package/payload/platform/plugins/contacts/mcp/dist/tools/contact-create.js +2 -2
  166. package/payload/platform/plugins/contacts/mcp/dist/tools/contact-create.js.map +1 -1
  167. package/payload/platform/plugins/contacts/mcp/dist/tools/group-create.js +1 -1
  168. package/payload/platform/plugins/contacts/mcp/dist/tools/group-create.js.map +1 -1
  169. package/payload/platform/plugins/docs/references/deployment.md +30 -1
  170. package/payload/platform/plugins/docs/references/plugins-guide.md +2 -5
  171. package/payload/platform/plugins/docs/references/troubleshooting.md +3 -3
  172. package/payload/platform/plugins/email/mcp/dist/index.js +1 -1
  173. package/payload/platform/plugins/email/mcp/dist/index.js.map +1 -1
  174. package/payload/platform/plugins/email/mcp/dist/lib/claude-bridge.js +2 -2
  175. package/payload/platform/plugins/email/mcp/dist/lib/claude-bridge.js.map +1 -1
  176. package/payload/platform/plugins/email/mcp/dist/lib/credentials.d.ts +1 -1
  177. package/payload/platform/plugins/email/mcp/dist/lib/credentials.js +1 -1
  178. package/payload/platform/plugins/email/mcp/dist/lib/neo4j.js +2 -2
  179. package/payload/platform/plugins/email/mcp/dist/lib/neo4j.js.map +1 -1
  180. package/payload/platform/plugins/email/mcp/dist/lib/screening.d.ts +1 -1
  181. package/payload/platform/plugins/email/mcp/dist/lib/screening.js +1 -1
  182. package/payload/platform/plugins/email/mcp/dist/scripts/email-auto-respond.js +6 -6
  183. package/payload/platform/plugins/email/mcp/dist/scripts/email-auto-respond.js.map +1 -1
  184. package/payload/platform/plugins/email/mcp/dist/scripts/email-fetch.d.ts +1 -1
  185. package/payload/platform/plugins/email/mcp/dist/scripts/email-fetch.js +2 -2
  186. package/payload/platform/plugins/email/mcp/dist/scripts/email-fetch.js.map +1 -1
  187. package/payload/platform/plugins/email/references/email-reference.md +2 -2
  188. package/payload/platform/plugins/loop/mcp/dist/lib/neo4j.js +3 -3
  189. package/payload/platform/plugins/loop/mcp/dist/lib/neo4j.js.map +1 -1
  190. package/payload/platform/plugins/loop/mcp/src/lib/neo4j.ts +3 -3
  191. package/payload/platform/plugins/memory/bin/conversation-archive-ingest.mjs +24 -24
  192. package/payload/platform/plugins/memory/bin/conversation-archive-ingest.sh +6 -6
  193. package/payload/platform/plugins/memory/mcp/dist/index.js +8 -8
  194. package/payload/platform/plugins/memory/mcp/dist/index.js.map +1 -1
  195. package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/llm-classifier.test.js +33 -33
  196. package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/llm-classifier.test.js.map +1 -1
  197. package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/schema-loader.test.js +12 -12
  198. package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/schema-loader.test.js.map +1 -1
  199. package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/schema-validator.test.js +3 -3
  200. package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/schema-validator.test.js.map +1 -1
  201. package/payload/platform/plugins/memory/mcp/dist/lib/conversation-normalisers/types.js +2 -2
  202. package/payload/platform/plugins/memory/mcp/dist/lib/conversation-normalisers/types.js.map +1 -1
  203. package/payload/platform/plugins/memory/mcp/dist/lib/conversation-normalisers/whatsapp-text.d.ts.map +1 -1
  204. package/payload/platform/plugins/memory/mcp/dist/lib/conversation-normalisers/whatsapp-text.js +1 -1
  205. package/payload/platform/plugins/memory/mcp/dist/lib/conversation-normalisers/whatsapp-text.js.map +1 -1
  206. package/payload/platform/plugins/memory/mcp/dist/lib/conversation-pipeline/derive-keys.d.ts.map +1 -1
  207. package/payload/platform/plugins/memory/mcp/dist/lib/conversation-pipeline/derive-keys.js +1 -2
  208. package/payload/platform/plugins/memory/mcp/dist/lib/conversation-pipeline/derive-keys.js.map +1 -1
  209. package/payload/platform/plugins/memory/mcp/dist/lib/conversation-pipeline/sender-bind.js +2 -2
  210. package/payload/platform/plugins/memory/mcp/dist/lib/conversation-pipeline/sender-bind.js.map +1 -1
  211. package/payload/platform/plugins/memory/mcp/dist/lib/conversation-pipeline/to-turn-text.js +1 -1
  212. package/payload/platform/plugins/memory/mcp/dist/lib/conversation-pipeline/to-turn-text.js.map +1 -1
  213. package/payload/platform/plugins/memory/mcp/dist/lib/document-chunker.d.ts +2 -2
  214. package/payload/platform/plugins/memory/mcp/dist/lib/document-chunker.js +2 -2
  215. package/payload/platform/plugins/memory/mcp/dist/lib/document-hierarchy.js +6 -6
  216. package/payload/platform/plugins/memory/mcp/dist/lib/document-hierarchy.js.map +1 -1
  217. package/payload/platform/plugins/memory/mcp/dist/lib/graph-prune.d.ts +1 -1
  218. package/payload/platform/plugins/memory/mcp/dist/lib/graph-prune.js +1 -1
  219. package/payload/platform/plugins/memory/mcp/dist/lib/graph-write-gate.d.ts +2 -2
  220. package/payload/platform/plugins/memory/mcp/dist/lib/graph-write-gate.js +7 -7
  221. package/payload/platform/plugins/memory/mcp/dist/lib/graph-write-gate.js.map +1 -1
  222. package/payload/platform/plugins/memory/mcp/dist/lib/live-schema-source.d.ts +2 -2
  223. package/payload/platform/plugins/memory/mcp/dist/lib/live-schema-source.js +2 -2
  224. package/payload/platform/plugins/memory/mcp/dist/lib/llm-classifier.d.ts +9 -9
  225. package/payload/platform/plugins/memory/mcp/dist/lib/llm-classifier.d.ts.map +1 -1
  226. package/payload/platform/plugins/memory/mcp/dist/lib/llm-classifier.js +25 -25
  227. package/payload/platform/plugins/memory/mcp/dist/lib/llm-classifier.js.map +1 -1
  228. package/payload/platform/plugins/memory/mcp/dist/lib/llm-ranker.d.ts +1 -1
  229. package/payload/platform/plugins/memory/mcp/dist/lib/llm-ranker.js +5 -5
  230. package/payload/platform/plugins/memory/mcp/dist/lib/llm-ranker.js.map +1 -1
  231. package/payload/platform/plugins/memory/mcp/dist/lib/neo4j.js +2 -2
  232. package/payload/platform/plugins/memory/mcp/dist/lib/neo4j.js.map +1 -1
  233. package/payload/platform/plugins/memory/mcp/dist/lib/schema-loader.d.ts +4 -4
  234. package/payload/platform/plugins/memory/mcp/dist/lib/schema-loader.js +3 -3
  235. package/payload/platform/plugins/memory/mcp/dist/lib/schema-loader.js.map +1 -1
  236. package/payload/platform/plugins/memory/mcp/dist/lib/schema-validator.d.ts +3 -3
  237. package/payload/platform/plugins/memory/mcp/dist/lib/schema-validator.js +5 -5
  238. package/payload/platform/plugins/memory/mcp/dist/lib/schema-validator.js.map +1 -1
  239. package/payload/platform/plugins/memory/mcp/dist/lib/uuid.js +1 -1
  240. package/payload/platform/plugins/memory/mcp/dist/lib/uuid.js.map +1 -1
  241. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/conversation-archive-derive-insights.test.js +5 -5
  242. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/conversation-archive-derive-insights.test.js.map +1 -1
  243. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/conversation-archive-enrich-rejection.test.js +1 -1
  244. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/conversation-archive-enrich-rejection.test.js.map +1 -1
  245. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/conversation-normalisers-source-agnosticism.test.js +2 -2
  246. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/conversation-normalisers-source-agnosticism.test.js.map +1 -1
  247. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/conversation-normalisers-whatsapp-text.test.js +4 -4
  248. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/conversation-normalisers-whatsapp-text.test.js.map +1 -1
  249. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-archive-write.test.js +6 -6
  250. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-archive-write.test.js.map +1 -1
  251. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-ingest.test.js +7 -7
  252. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-ingest.test.js.map +1 -1
  253. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-update-not-applicable.test.js +2 -2
  254. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-update-not-applicable.test.js.map +1 -1
  255. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-update-personfields-open.test.js +3 -3
  256. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-update-personfields-open.test.js.map +1 -1
  257. package/payload/platform/plugins/memory/mcp/dist/tools/conversation-archive-derive-insights.d.ts +1 -1
  258. package/payload/platform/plugins/memory/mcp/dist/tools/conversation-archive-derive-insights.js +3 -3
  259. package/payload/platform/plugins/memory/mcp/dist/tools/conversation-archive-derive-insights.js.map +1 -1
  260. package/payload/platform/plugins/memory/mcp/dist/tools/conversation-archive-enrich-rejection.d.ts +1 -1
  261. package/payload/platform/plugins/memory/mcp/dist/tools/conversation-archive-enrich-rejection.js +1 -1
  262. package/payload/platform/plugins/memory/mcp/dist/tools/memory-archive-write.js +2 -2
  263. package/payload/platform/plugins/memory/mcp/dist/tools/memory-archive-write.js.map +1 -1
  264. package/payload/platform/plugins/memory/mcp/dist/tools/memory-classify.d.ts +1 -1
  265. package/payload/platform/plugins/memory/mcp/dist/tools/memory-classify.js +1 -1
  266. package/payload/platform/plugins/memory/mcp/dist/tools/memory-delete.d.ts +2 -2
  267. package/payload/platform/plugins/memory/mcp/dist/tools/memory-delete.js +1 -1
  268. package/payload/platform/plugins/memory/mcp/dist/tools/memory-delete.js.map +1 -1
  269. package/payload/platform/plugins/memory/mcp/dist/tools/memory-find-candidates.d.ts +3 -3
  270. package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest-extract.js +2 -2
  271. package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest-extract.js.map +1 -1
  272. package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest.d.ts +9 -9
  273. package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest.d.ts.map +1 -1
  274. package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest.js +10 -11
  275. package/payload/platform/plugins/memory/mcp/dist/tools/memory-ingest.js.map +1 -1
  276. package/payload/platform/plugins/memory/mcp/dist/tools/memory-list-attachments.js +1 -1
  277. package/payload/platform/plugins/memory/mcp/dist/tools/memory-list-attachments.js.map +1 -1
  278. package/payload/platform/plugins/memory/mcp/dist/tools/memory-search.js +1 -1
  279. package/payload/platform/plugins/memory/mcp/dist/tools/memory-search.js.map +1 -1
  280. package/payload/platform/plugins/memory/mcp/dist/tools/memory-update.js +1 -1
  281. package/payload/platform/plugins/memory/mcp/dist/tools/memory-update.js.map +1 -1
  282. package/payload/platform/plugins/memory/mcp/dist/tools/memory-write.d.ts +1 -1
  283. package/payload/platform/plugins/memory/mcp/dist/tools/memory-write.js +3 -3
  284. package/payload/platform/plugins/memory/mcp/dist/tools/memory-write.js.map +1 -1
  285. package/payload/platform/plugins/memory/mcp/dist/tools/profile-read.js +9 -9
  286. package/payload/platform/plugins/memory/mcp/dist/tools/profile-read.js.map +1 -1
  287. package/payload/platform/plugins/memory/mcp/dist/tools/profile-update.d.ts +5 -5
  288. package/payload/platform/plugins/memory/mcp/dist/tools/profile-update.js +9 -9
  289. package/payload/platform/plugins/memory/mcp/dist/tools/profile-update.js.map +1 -1
  290. package/payload/platform/plugins/memory/mcp/scripts/boot-smoke.sh +1 -1
  291. package/payload/platform/plugins/memory/mcp/scripts/graph/fixture.cypher +1 -1
  292. package/payload/platform/plugins/memory/mcp/vitest.config.ts +2 -2
  293. package/payload/platform/plugins/outlook/mcp/dist/lib/graph-client.js +1 -1
  294. package/payload/platform/plugins/outlook/mcp/dist/lib/graph-client.js.map +1 -1
  295. package/payload/platform/plugins/outlook/mcp/scripts/verify-doc-impl.sh +1 -1
  296. package/payload/platform/plugins/scheduling/PLUGIN.md +1 -1
  297. package/payload/platform/plugins/scheduling/mcp/dist/__tests__/time-resolve-description.test.js +1 -1
  298. package/payload/platform/plugins/scheduling/mcp/dist/__tests__/time-resolve-description.test.js.map +1 -1
  299. package/payload/platform/plugins/scheduling/mcp/dist/index.js +1 -1
  300. package/payload/platform/plugins/scheduling/mcp/dist/index.js.map +1 -1
  301. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/getUserTimezone.test.js +3 -3
  302. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/getUserTimezone.test.js.map +1 -1
  303. package/payload/platform/plugins/scheduling/mcp/dist/lib/neo4j.d.ts +2 -2
  304. package/payload/platform/plugins/scheduling/mcp/dist/lib/neo4j.js +5 -5
  305. package/payload/platform/plugins/scheduling/mcp/dist/lib/neo4j.js.map +1 -1
  306. package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.d.ts +1 -1
  307. package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.js +6 -6
  308. package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.js.map +1 -1
  309. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-event.js +1 -1
  310. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-event.js.map +1 -1
  311. package/payload/platform/plugins/tasks/mcp/dist/index.js +1 -1
  312. package/payload/platform/plugins/tasks/mcp/dist/index.js.map +1 -1
  313. package/payload/platform/plugins/tasks/mcp/dist/lib/neo4j.js +2 -2
  314. package/payload/platform/plugins/tasks/mcp/dist/lib/neo4j.js.map +1 -1
  315. package/payload/platform/plugins/tasks/mcp/dist/tools/project-create.js +2 -2
  316. package/payload/platform/plugins/tasks/mcp/dist/tools/project-create.js.map +1 -1
  317. package/payload/platform/plugins/tasks/mcp/dist/tools/session-name.d.ts +1 -1
  318. package/payload/platform/plugins/tasks/mcp/dist/tools/session-name.d.ts.map +1 -1
  319. package/payload/platform/plugins/tasks/mcp/dist/tools/task-create.d.ts +5 -5
  320. package/payload/platform/plugins/tasks/mcp/dist/tools/task-create.js +3 -3
  321. package/payload/platform/plugins/tasks/mcp/dist/tools/task-create.js.map +1 -1
  322. package/payload/platform/plugins/tasks/mcp/dist/tools/task-update.d.ts +4 -4
  323. package/payload/platform/plugins/tasks/mcp/dist/tools/task-update.js +2 -2
  324. package/payload/platform/plugins/tasks/mcp/dist/tools/task-update.js.map +1 -1
  325. package/payload/platform/plugins/telegram/mcp/dist/tools/message-history.js +2 -2
  326. package/payload/platform/plugins/telegram/mcp/dist/tools/message-history.js.map +1 -1
  327. package/payload/platform/plugins/waitlist/mcp/dist/lib/neo4j.js +2 -2
  328. package/payload/platform/plugins/waitlist/mcp/dist/lib/neo4j.js.map +1 -1
  329. package/payload/platform/plugins/waitlist/mcp/dist/tools/__tests__/waitlist-persist.test.js +3 -3
  330. package/payload/platform/plugins/waitlist/mcp/dist/tools/__tests__/waitlist-persist.test.js.map +1 -1
  331. package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-persist.d.ts +1 -1
  332. package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-persist.js +3 -3
  333. package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-persist.js.map +1 -1
  334. package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-setup.js +5 -5
  335. package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-setup.js.map +1 -1
  336. package/payload/platform/plugins/whatsapp/mcp/dist/call-api.d.ts +1 -1
  337. package/payload/platform/plugins/whatsapp/mcp/dist/call-api.js +1 -1
  338. package/payload/platform/plugins/workflows/mcp/dist/index.js +1 -1
  339. package/payload/platform/plugins/workflows/mcp/dist/index.js.map +1 -1
  340. package/payload/platform/plugins/workflows/mcp/dist/lib/active-runs.d.ts +1 -1
  341. package/payload/platform/plugins/workflows/mcp/dist/lib/active-runs.js +1 -1
  342. package/payload/platform/plugins/workflows/mcp/dist/lib/llm-call.d.ts +1 -1
  343. package/payload/platform/plugins/workflows/mcp/dist/lib/neo4j.js +2 -2
  344. package/payload/platform/plugins/workflows/mcp/dist/lib/neo4j.js.map +1 -1
  345. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-create.js +1 -1
  346. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-create.js.map +1 -1
  347. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-execute.js +4 -4
  348. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-execute.js.map +1 -1
  349. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-update.js +1 -1
  350. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-update.js.map +1 -1
  351. package/payload/platform/plugins/workflows/mcp/test-workflows.sh +2 -2
  352. package/payload/platform/scripts/__tests__/first-token-creates-stream-log.test.sh +1 -1
  353. package/payload/platform/scripts/__tests__/logs-read-prefix.sh +6 -6
  354. package/payload/platform/scripts/admin-conversation-recover.mjs +5 -5
  355. package/payload/platform/scripts/admin-persist-audit.ts +4 -4
  356. package/payload/platform/scripts/check-no-conversation-id-leaks.mjs +1 -1
  357. package/payload/platform/scripts/check-no-direct-clipboard.mjs +1 -1
  358. package/payload/platform/scripts/check-no-task-id-leaks.mjs +2 -2
  359. package/payload/platform/scripts/check-skill-load-coverage.mjs +1 -1
  360. package/payload/platform/scripts/component-knowledgedoc-backfill.ts +1 -1
  361. package/payload/platform/scripts/dedupe-userprofile-ghosts.sh +2 -2
  362. package/payload/platform/scripts/generate-entitlement-fixture.mjs +1 -1
  363. package/payload/platform/scripts/installer-device-verify.sh +6 -6
  364. package/payload/platform/scripts/lib/resolve-account-dir.sh +6 -6
  365. package/payload/platform/scripts/log-adherence-check.sh +3 -3
  366. package/payload/platform/scripts/logs-read.sh +13 -13
  367. package/payload/platform/scripts/logs-read.test.sh +1 -1
  368. package/payload/platform/scripts/migrate-import.sh +4 -4
  369. package/payload/platform/scripts/redact-install-logs.sh +1 -1
  370. package/payload/platform/scripts/seed-neo4j.sh +26 -32
  371. package/payload/platform/scripts/test-laptop-vnc-boot.sh +3 -3
  372. package/payload/platform/scripts/verify-skill-tool-surface.sh +17 -2
  373. package/payload/platform/scripts/vnc.sh +9 -9
  374. package/payload/platform/services/claude-session-manager/dist/config.d.ts +7 -2
  375. package/payload/platform/services/claude-session-manager/dist/config.d.ts.map +1 -1
  376. package/payload/platform/services/claude-session-manager/dist/config.js +3 -1
  377. package/payload/platform/services/claude-session-manager/dist/config.js.map +1 -1
  378. package/payload/platform/services/claude-session-manager/dist/http-server.d.ts +2 -2
  379. package/payload/platform/services/claude-session-manager/dist/http-server.d.ts.map +1 -1
  380. package/payload/platform/services/claude-session-manager/dist/http-server.js +133 -90
  381. package/payload/platform/services/claude-session-manager/dist/http-server.js.map +1 -1
  382. package/payload/platform/services/claude-session-manager/dist/index.js +17 -4
  383. package/payload/platform/services/claude-session-manager/dist/index.js.map +1 -1
  384. package/payload/platform/services/claude-session-manager/dist/jsonl-enumerator.d.ts +2 -2
  385. package/payload/platform/services/claude-session-manager/dist/jsonl-enumerator.d.ts.map +1 -1
  386. package/payload/platform/services/claude-session-manager/dist/jsonl-enumerator.js +4 -4
  387. package/payload/platform/services/claude-session-manager/dist/jsonl-enumerator.js.map +1 -1
  388. package/payload/platform/services/claude-session-manager/dist/jsonl-observer.js +1 -1
  389. package/payload/platform/services/claude-session-manager/dist/jsonl-observer.js.map +1 -1
  390. package/payload/platform/services/claude-session-manager/dist/jsonl-path.js +2 -2
  391. package/payload/platform/services/claude-session-manager/dist/jsonl-path.js.map +1 -1
  392. package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts +37 -18
  393. package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts.map +1 -1
  394. package/payload/platform/services/claude-session-manager/dist/pty-spawner.js +101 -44
  395. package/payload/platform/services/claude-session-manager/dist/pty-spawner.js.map +1 -1
  396. package/payload/platform/services/claude-session-manager/dist/public-tool-audit.js +1 -1
  397. package/payload/platform/services/claude-session-manager/dist/public-tool-audit.js.map +1 -1
  398. package/payload/platform/services/claude-session-manager/dist/session-store.d.ts +36 -11
  399. package/payload/platform/services/claude-session-manager/dist/session-store.d.ts.map +1 -1
  400. package/payload/platform/services/claude-session-manager/dist/session-store.js +53 -2
  401. package/payload/platform/services/claude-session-manager/dist/session-store.js.map +1 -1
  402. package/payload/platform/services/claude-session-manager/dist/spawn-rate-limiter.js +2 -2
  403. package/payload/platform/services/claude-session-manager/dist/spawn-rate-limiter.js.map +1 -1
  404. package/payload/platform/services/claude-session-manager/dist/system-prompt.d.ts +46 -1
  405. package/payload/platform/services/claude-session-manager/dist/system-prompt.d.ts.map +1 -1
  406. package/payload/platform/services/claude-session-manager/dist/system-prompt.js +131 -24
  407. package/payload/platform/services/claude-session-manager/dist/system-prompt.js.map +1 -1
  408. package/payload/platform/services/claude-session-manager/dist/tool-surface.js +1 -1
  409. package/payload/platform/services/claude-session-manager/dist/tool-surface.js.map +1 -1
  410. package/payload/platform/services/claude-session-manager/dist/types.d.ts +8 -1
  411. package/payload/platform/services/claude-session-manager/dist/types.d.ts.map +1 -1
  412. package/payload/platform/services/claude-session-manager/dist/url-capture.js +1 -1
  413. package/payload/platform/services/claude-session-manager/dist/url-capture.js.map +1 -1
  414. package/payload/platform/templates/agents/admin/IDENTITY.md +14 -0
  415. package/payload/platform/templates/agents/admin/SOUL.md +1 -3
  416. package/payload/platform/templates/specialists/agents/personal-assistant.md +1 -3
  417. package/payload/platform/templates/specialists/agents/project-manager.md +1 -1
  418. package/payload/platform/templates/systemd/edge.service.template +3 -3
  419. package/payload/premium-plugins/real-agent/BUNDLE.md +2 -4
  420. package/payload/premium-plugins/real-agent/plugins/.claude-plugin/marketplace.json +0 -5
  421. package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/lib/neo4j.js +3 -3
  422. package/payload/premium-plugins/real-agent/plugins/loop/mcp/dist/lib/neo4j.js.map +1 -1
  423. package/payload/premium-plugins/real-agent/plugins/loop/mcp/src/lib/neo4j.ts +3 -3
  424. package/payload/server/{chunk-ZGJ6CUU2.js → chunk-3G6JMV7N.js} +1 -1
  425. package/payload/server/{chunk-KVGTWNKQ.js → chunk-NNHHGQJL.js} +314 -5
  426. package/payload/server/{chunk-RZQMYJVY.js → chunk-QC5LHYPH.js} +3 -3
  427. package/payload/server/{cloudflare-task-tracker-4PKOLE4H.js → cloudflare-task-tracker-NEB3X6O2.js} +2 -2
  428. package/payload/server/maxy-edge.js +2 -2
  429. package/payload/server/public/assets/{admin-Cuu1QdAA.js → admin-CF2ZQvXu.js} +1 -1
  430. package/payload/server/public/index.html +1 -1
  431. package/payload/server/server.js +274 -396
  432. package/payload/platform/plugins/anthropic/.claude-plugin/plugin.json +0 -8
  433. package/payload/platform/plugins/anthropic/PLUGIN.md +0 -40
  434. package/payload/platform/plugins/anthropic/references/console-api.md +0 -186
  435. package/payload/platform/plugins/anthropic/references/setup-guide.md +0 -36
  436. package/payload/platform/plugins/anthropic/skills/get-api-key/SKILL.md +0 -136
  437. package/payload/platform/plugins/estate-onboarding/.claude-plugin/plugin.json +0 -8
  438. package/payload/platform/plugins/estate-onboarding/PLUGIN.md +0 -30
  439. package/payload/platform/plugins/estate-onboarding/skills/bootstrap/SKILL.md +0 -26
  440. package/payload/platform/plugins/estate-onboarding/skills/bootstrap/references/onboarding-flow.md +0 -63
  441. package/payload/premium-plugins/real-agent/plugins/estate-onboarding/.claude-plugin/plugin.json +0 -8
  442. package/payload/premium-plugins/real-agent/plugins/estate-onboarding/PLUGIN.md +0 -30
  443. package/payload/premium-plugins/real-agent/plugins/estate-onboarding/skills/bootstrap/SKILL.md +0 -26
  444. package/payload/premium-plugins/real-agent/plugins/estate-onboarding/skills/bootstrap/references/onboarding-flow.md +0 -63
package/dist/index.js CHANGED
@@ -38,7 +38,7 @@ const INSTALL_DIR = resolve(process.env.HOME ?? "/root", BRAND.installDir);
38
38
  const PERSIST_DIR = resolve(process.env.HOME ?? "/root", BRAND.configDir);
39
39
  const LOG_DIR = join(PERSIST_DIR, "logs");
40
40
  const LOG_FILE = join(LOG_DIR, `install-${new Date().toISOString().replace(/[:.]/g, "-")}.log`);
41
- // Task 048 — every `claude plugin` shellout must read/write the per-brand
41
+ // every `claude plugin` shellout must read/write the per-brand
42
42
  // CLAUDE_CONFIG_DIR that the systemd unit at port-resolution.ts:229,286 uses
43
43
  // at runtime. Without this override, the installer writes marketplaces and
44
44
  // enabledPlugins to $HOME/.claude/settings.json (user-default), and the
@@ -49,8 +49,9 @@ function claudePluginEnv() {
49
49
  return { ...process.env, CLAUDE_CONFIG_DIR };
50
50
  }
51
51
  /** Known brand hostnames in the Maxy ecosystem. Each brand ships a main unit
52
- * (`<hostname>.service`) and a per-brand edge unit (`<hostname>-edge.service`,
53
- * Task 662). Peer-brand detection matches only these filenames — stale units,
52
+ * (`<hostname>.service`) and a per-brand edge unit
53
+ * (`<hostname>-edge.service`). Peer-brand detection matches only these
54
+ * filenames — stale units,
54
55
  * gnome-keyring disable markers, and unrelated user services are not peer
55
56
  * evidence. When a third brand is added under `brands/`, append its hostname
56
57
  * here AND in the matching constant in `uninstall.ts` (intentional duplication
@@ -59,7 +60,7 @@ const KNOWN_BRAND_HOSTNAMES = ["maxy", "realagent", "maxy-2", "maxy-3", "maxy-4"
59
60
  // The device's actual hostname — may differ from BRAND.hostname if the user customized it.
60
61
  // Updated by installSystemDeps() after hostname setup; used for user-facing URLs.
61
62
  let DEVICE_HOSTNAME = BRAND.hostname;
62
- // Task 929 — absolute path to the non-snap Chromium binary chosen during
63
+ // absolute path to the non-snap Chromium binary chosen during
63
64
  // installSystemDeps(). Defaults to /usr/bin/chromium so non-Linux installs
64
65
  // (which never call ensureNonSnapChromium) and the systemd unit's
65
66
  // PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH still see a sensible value. On Linux,
@@ -162,7 +163,7 @@ function shell(command, args, options) {
162
163
  const cmd = options?.sudo ? "sudo" : command;
163
164
  const cmdArgs = options?.sudo ? [command, ...args] : args;
164
165
  const start = Date.now();
165
- // Redaction (Task 744): callers handling secrets pass redact: true so the
166
+ // Redaction: callers handling secrets pass redact: true so the
166
167
  // wrapper records the command name only, not the secret-bearing args. The
167
168
  // child process still receives the real args via spawnSync below; only the
168
169
  // install log line is sanitised. The grep-able audit shape stays:
@@ -178,7 +179,7 @@ function shell(command, args, options) {
178
179
  env: options?.env,
179
180
  });
180
181
  const dur = ((Date.now() - start) / 1000).toFixed(1);
181
- // bestEffort (Task 787): tear-down ops on units/state that may or may not
182
+ // bestEffort: tear-down ops on units/state that may or may not
182
183
  // exist (stop/disable a system service we may never have started, reset-failed
183
184
  // a freshly-created unit) log the non-zero exit but do not throw. Reserved
184
185
  // for the "may not exist" pattern only — never use for ops that must succeed.
@@ -269,12 +270,12 @@ function canSudo() {
269
270
  const result = spawnSync("sudo", ["-n", "true"], { stdio: "pipe", timeout: 5_000 });
270
271
  return result.status === 0;
271
272
  }
272
- // Task 634 — verified-not-asserted apt-dep reconciliation.
273
- // Task 637 — resolve package-name aliases before probing dpkg, so the
273
+ // verified-not-asserted apt-dep reconciliation.
274
+ // resolve package-name aliases before probing dpkg, so the
274
275
  // post-install check no longer false-negatives when apt resolves a virtual
275
276
  // name (e.g. Noble's `chromium` → `chromium-browser`).
276
277
  // UBUNTU_ALIASES, parseOsRelease, isUbuntuLike, and decideAptResolution moved
277
- // to ./apt-resolve.ts (Task 638). The pure logic lives there so a unit test
278
+ // to./apt-resolve.ts. The pure logic lives there so a unit test
278
279
  // can hit every branch without spawning real apt/dpkg or reading
279
280
  // /etc/os-release. The thin wrappers below feed real spawn + fs results into
280
281
  // that pure decision.
@@ -297,7 +298,7 @@ function aptCachePolicySummary(pkg) {
297
298
  return cand === "(none)" ? "candidate-none" : `candidate=${cand}`;
298
299
  }
299
300
  /**
300
- * Task 637 — map an apt-level package name to the concrete name dpkg will
301
+ * map an apt-level package name to the concrete name dpkg will
301
302
  * record after install. Resolution order:
302
303
  * 1. `dpkg -s pkg` exits 0 → name is concrete and installed; return pkg.
303
304
  * 2. `apt-cache policy pkg` reports a real Candidate → concrete-but-missing;
@@ -306,7 +307,7 @@ function aptCachePolicySummary(pkg) {
306
307
  * UBUNTU_ALIASES on an Ubuntu-like host → return the alias. Log the
307
308
  * resolution so the install log answers "what did apt resolve this to?".
308
309
  * 4. Otherwise return pkg unchanged — the post-check will throw loudly,
309
- * preserving Task 634's fail-loud contract for genuinely missing packages.
310
+ * preserving the fail-loud contract for genuinely missing packages.
310
311
  */
311
312
  function resolveAptName(pkg) {
312
313
  const dpkg = spawnSync("dpkg", ["-s", pkg], { stdio: "pipe", timeout: 5_000 });
@@ -371,7 +372,7 @@ function pkgsMissing(pkgs) {
371
372
  * surface at runtime when the binary is missing.
372
373
  *
373
374
  * Resolves each package through `resolveAptName` before both the install
374
- * command and the post-check, so alias packages (Task 637) pass through
375
+ * command and the post-check, so alias packages pass through
375
376
  * cleanly on distros where the apt-level name differs from the dpkg-recorded
376
377
  * name (e.g. Noble's chromium → chromium-browser). Resolution is computed
377
378
  * once per package and reused across install, post-check, and error
@@ -396,7 +397,7 @@ function installAptGroup(label, pkgs) {
396
397
  // ---------------------------------------------------------------------------
397
398
  const TOTAL = "11";
398
399
  /**
399
- * Task 840 — set macOS hostname via scutil. Three sequential `sudo scutil
400
+ * set macOS hostname via scutil. Three sequential `sudo scutil
400
401
  * --set` calls (HostName, LocalHostName, ComputerName) — `hostnamectl` is
401
402
  * Linux-only and `--hostname <h>` silently no-ops on darwin. All-or-nothing
402
403
  * rollback within the 3-call batch: if any call fails, we restore the
@@ -430,7 +431,7 @@ function setMacosHostnameViaScutil(hostname) {
430
431
  console.log(` [scutil] HostName=${hostname} LocalHostName=${hostname} ComputerName=${hostname} set ok`);
431
432
  }
432
433
  /**
433
- * Task 929 — detect snap-confined Chromium on Linux and install Google Chrome
434
+ * detect snap-confined Chromium on Linux and install Google Chrome
434
435
  * stable as the non-snap replacement. Runs after `installAptGroup("VNC stack")`
435
436
  * inside `installSystemDeps`. Resolution rules live in `snap-chromium.ts`
436
437
  * (pure decision); this wrapper does the spawnSync + apt-repo writes + post-
@@ -452,7 +453,7 @@ function setMacosHostnameViaScutil(hostname) {
452
453
  *
453
454
  * Post-install gate: spawn the resolved binary headless against a throwaway
454
455
  * profile dir under persistDir, assert exit 0. The AppArmor denial that
455
- * triggered Task 929 was on SingletonLock writes which `--headless=new` still
456
+ * triggered the original denial was on SingletonLock writes which `--headless=new` still
456
457
  * attempts, so the headless probe fires the same EACCES path that production
457
458
  * VNC headed launches do — closing the post-fix-sibling-audit-skipped gap.
458
459
  */
@@ -544,7 +545,7 @@ function ensureNonSnapChromium() {
544
545
  runChromiumPostInstallGate(RESOLVED_CHROMIUM_BIN);
545
546
  }
546
547
  /**
547
- * Task 929 post-install gate. Spawns the resolved Chromium binary headless
548
+ * post-install gate. Spawns the resolved Chromium binary headless
548
549
  * against a throwaway profile dir under persistDir (`~/.{brand}/chromium-
549
550
  * gate-profile/`). The AppArmor denial that triggered the task was on
550
551
  * SingletonLock writes which `--headless=new` still attempts, so this probe
@@ -556,7 +557,7 @@ function runChromiumPostInstallGate(chromiumBin) {
556
557
  const persistDir = resolve(process.env.HOME ?? "/root", BRAND.configDir);
557
558
  const gateProfileDir = join(persistDir, "chromium-gate-profile");
558
559
  mkdirSync(gateProfileDir, { recursive: true });
559
- console.log(` Verifying ${chromiumBin} can write to ${gateProfileDir} (Task 929 post-install gate)...`);
560
+ console.log(` Verifying ${chromiumBin} can write to ${gateProfileDir} (post-install gate)...`);
560
561
  const r = spawnSync(chromiumBin, [
561
562
  `--user-data-dir=${gateProfileDir}`,
562
563
  "--headless=new",
@@ -575,7 +576,7 @@ function runChromiumPostInstallGate(chromiumBin) {
575
576
  const stderr = (r.stderr ?? "").slice(-2000);
576
577
  const eaccesHit = /Permission denied/i.test(stderr) || /EACCES/i.test(stderr);
577
578
  const taskRef = eaccesHit
578
- ? "Task 929: chromium-profile not writable (likely AppArmor denial on snap-confined binary). "
579
+ ? "chromium-profile not writable (likely AppArmor denial on snap-confined binary). "
579
580
  : "";
580
581
  throw new Error(`${taskRef}Chromium post-install gate failed: ${chromiumBin} exited ${r.status} signal=${r.signal ?? "none"}. stderr:\n${stderr}`);
581
582
  }
@@ -583,7 +584,7 @@ function runChromiumPostInstallGate(chromiumBin) {
583
584
  logFile(` [snap-chromium] post-install gate ok: ${chromiumBin} exit=0`);
584
585
  }
585
586
  /**
586
- * Task 929 — write the resolved Chromium absolute path to
587
+ * write the resolved Chromium absolute path to
587
588
  * `<INSTALL_DIR>/platform/config/chromium-binary.path` so vnc.sh,
588
589
  * writeChromiumWrapper, and setup-tunnel.sh all read the same value. Called
589
590
  * after deployPayload so the platform/config/ directory exists. Idempotent:
@@ -606,7 +607,7 @@ function installSystemDeps() {
606
607
  log("1", TOTAL, "System dependencies and network...");
607
608
  const platform = requireSupportedPlatform(process.platform);
608
609
  if (platform === "darwin") {
609
- // Task 840 — darwin hostname via scutil when --hostname is supplied,
610
+ // darwin hostname via scutil when --hostname is supplied,
610
611
  // otherwise preserve the existing system hostname.
611
612
  if (HOSTNAME_FLAG) {
612
613
  console.log(` Hostname: ${HOSTNAME_FLAG} (from --hostname flag)`);
@@ -625,8 +626,8 @@ function installSystemDeps() {
625
626
  }
626
627
  catch { /* fallback to brand — set at declaration */ }
627
628
  }
628
- // Task 839 — macOS has no apt analogue for the VNC/WiFi-AP stacks
629
- // (kiosk display + hostapd/dnsmasq are Pi-specific per Task 836's
629
+ // macOS has no apt analogue for the VNC/WiFi-AP stacks
630
+ // (kiosk display + hostapd/dnsmasq are Pi-specific's
630
631
  // out-of-scope note). mDNS is provided by the OS, so avahi-* drop out.
631
632
  // Translate the remaining apt names through decideBrewResolution and
632
633
  // let installAllBrewPackages handle the install + verify pattern.
@@ -636,25 +637,25 @@ function installSystemDeps() {
636
637
  }
637
638
  const BASE_DEPS = ["curl", "git", "unzip", "jq", "avahi-daemon", "avahi-utils", "poppler-utils", "ffmpeg", "bind9-dnsutils"];
638
639
  // xterm is the *preferred* terminal-emulator binary for the VNC-rendered
639
- // Terminal surface (Task 632 — gnome-terminal is a D-Bus launcher that
640
+ // Terminal surface
640
641
  // delegates window creation to the session's gnome-terminal-server,
641
642
  // opening windows on the wrong display; xterm has no IPC layer and
642
643
  // honours DISPLAY directly). Kept in the apt list unconditionally so
643
644
  // vnc.sh's resolve_terminal_bin has a display-safe binary on every
644
645
  // supported distro (Ubuntu 24.04 noble/universe, Debian 12 bookworm/main
645
- // verified). xdotool (Task 632) backs the post-spawn display-membership
646
+ // verified). xdotool backs the post-spawn display-membership
646
647
  // assertion in vnc.sh check_window_on_display, closing the silent-fail
647
648
  // class where PID is alive but no window is mapped on the target display.
648
649
  const VNC_DEPS = ["tigervnc-standalone-server", "python3-websockify", "novnc", "xdg-utils", "chromium", "xterm", "xdotool"];
649
- // Task 664 retired the ttyd/tmux admin terminal stack — upgrades run via
650
+ // retired the ttyd/tmux admin terminal stack — upgrades run via
650
651
  // the action runner (systemd-run --user transient units) and no longer
651
652
  // need a shared tmux session. `tmux` was only required by the retired
652
653
  // byte-stream terminal; removing it shrinks the apt footprint.
653
654
  const WIFI_DEPS = ["hostapd", "dnsmasq"];
654
655
  const ALL_APT_DEPS = [...BASE_DEPS, ...VNC_DEPS, ...WIFI_DEPS];
655
- // Task 634 — verify the "deps are present" assumption with `dpkg -s` instead
656
+ // verify the "deps are present" assumption with `dpkg -s` instead
656
657
  // of asserting it (feedback_loud_failures.md). The previous silent-skip
657
- // branch was benign until Task 632 added xdotool (the first new apt dep
658
+ // branch was benign added xdotool (the first new apt dep
658
659
  // since the skip path became load-bearing on user-password-sudo devices).
659
660
  const missing = pkgsMissing(ALL_APT_DEPS);
660
661
  if (missing.length === 0) {
@@ -680,7 +681,7 @@ function installSystemDeps() {
680
681
  installAptGroup("VNC stack", VNC_DEPS);
681
682
  installAptGroup("WiFi AP", WIFI_DEPS);
682
683
  }
683
- // Task 929 — replace snap-confined Chromium with Google Chrome stable on
684
+ // replace snap-confined Chromium with Google Chrome stable on
684
685
  // Linux laptops (Ubuntu Noble) where `/usr/bin/chromium` realpaths to the
685
686
  // snap launcher. The snap AppArmor profile denies writes to hidden top-level
686
687
  // paths under $HOME, so any write to `~/.{brand}/chromium-profile/SingletonLock`
@@ -733,11 +734,11 @@ function installSystemDeps() {
733
734
  // set by the user or the first installer — subsequent brands must not overwrite it.
734
735
  const systemdUserDir = resolve(process.env.HOME ?? "/root", ".config/systemd/user");
735
736
  const serviceExists = existsSync(join(systemdUserDir, BRAND.serviceName));
736
- // Task 690: narrow peer detection to KNOWN_BRAND_HOSTNAMES. The previous
737
+ // narrow peer detection to KNOWN_BRAND_HOSTNAMES. The previous
737
738
  // predicate ("any *.service that isn't ours") matched stray user units
738
739
  // such as a `gnome-keyring-daemon.service -> /dev/null` disable marker,
739
740
  // silently flipping single-brand fresh installs into the "preserve hostname"
740
- // branch. Mirrors Task 683's `peerBrandPresent` allowlist in `uninstall.ts`.
741
+ // branch. Mirrors the `peerBrandPresent` allowlist in `uninstall.ts`.
741
742
  let otherBrandService = false;
742
743
  if (!serviceExists) {
743
744
  const peerUnits = KNOWN_BRAND_HOSTNAMES
@@ -876,7 +877,7 @@ function installNodejs() {
876
877
  if (platform === "darwin") {
877
878
  // Pass the apt-side `nodejs` name; decideBrewResolution maps it to
878
879
  // `node@22` per DARWIN_ALIASES so the cellar formula matches Maxy's
879
- // pinned-binaries floor (Task 836).
880
+ // pinned-binaries floor.
880
881
  installAllBrewPackages(["nodejs"], logFile);
881
882
  return;
882
883
  }
@@ -931,14 +932,14 @@ function installClaudeCode() {
931
932
  }
932
933
  }
933
934
  console.log(" Registering Claude plugin marketplaces...");
934
- // Task 048 — pre-create the per-brand CLAUDE_CONFIG_DIR so the first
935
+ // pre-create the per-brand CLAUDE_CONFIG_DIR so the first
935
936
  // `claude plugin marketplace add` has a directory to write into.
936
937
  mkdirSync(CLAUDE_CONFIG_DIR, { recursive: true });
937
938
  const marketplaceList = spawnSync("claude", ["plugin", "marketplace", "list"], { stdio: "pipe", encoding: "utf-8", env: claudePluginEnv() });
938
939
  if (marketplaceList.stderr)
939
940
  process.stderr.write(marketplaceList.stderr);
940
941
  const listed = marketplaceList.stdout ?? "";
941
- // Task 976: register three Anthropic marketplaces uniformly with
942
+ // register three Anthropic marketplaces uniformly with
942
943
  // [plugin-marketplace] observability. Each slug is grep-checked against
943
944
  // `marketplace list` for idempotence; failures log exit + first stderr
944
945
  // line but do not abort the installer (one marketplace's outage must not
@@ -1052,7 +1053,7 @@ function resetNeo4jAuth(port = DEFAULT_NEO4J_PORT, dataDir = "/var/lib/neo4j") {
1052
1053
  return password;
1053
1054
  }
1054
1055
  /**
1055
- * Task 744 — scrub plaintext neo4j passwords from pre-fix install-*.log files.
1056
+ * scrub plaintext neo4j passwords from pre-fix install-*.log files.
1056
1057
  * Calls platform/scripts/redact-install-logs.sh against the installer's LOG_DIR.
1057
1058
  * The script is idempotent; re-running on clean logs is a no-op. Failures here
1058
1059
  * are non-fatal — credential redaction is best-effort cleanup, not a blocker
@@ -1099,7 +1100,7 @@ function ensureNeo4jPassword() {
1099
1100
  }
1100
1101
  }
1101
1102
  // 2. Fresh install or recovery: no working same-brand password. Generate and set a new one.
1102
- // Brand isolation (Task 659): never read another brand's .neo4j-password.
1103
+ // Brand isolation: never read another brand's.neo4j-password.
1103
1104
  if (!existsSync(passwordFile)) {
1104
1105
  console.log(" No Neo4j password file found. Setting initial password...");
1105
1106
  }
@@ -1135,7 +1136,7 @@ function installNeo4j() {
1135
1136
  if (platform === "darwin") {
1136
1137
  // Homebrew's neo4j formula declares openjdk as a runtime dependency, so
1137
1138
  // Java is pulled in transitively — no separate openjdk install step.
1138
- // Process supervision (launchd LaunchAgent) is owned by Task 838; this
1139
+ // Process supervision (launchd LaunchAgent) is owned; this
1139
1140
  // step ends after `brew install neo4j` + initial-password seeding so the
1140
1141
  // payload deploy step finds the shared password file.
1141
1142
  installAllBrewPackages(["neo4j"], logFile);
@@ -1190,7 +1191,7 @@ function installNeo4j() {
1190
1191
  console.log(" Neo4j started. Password stored securely.");
1191
1192
  }
1192
1193
  /**
1193
- * Task 800 — does any peer brand on this host pin `NEO4J_URI=bolt://localhost:<default>`
1194
+ * does any peer brand on this host pin `NEO4J_URI=bolt://localhost:<default>`
1194
1195
  * in its `.env`? If yes, the apt-installed `neo4j.service` is its database and the
1195
1196
  * dedicated-unit installer must NOT stop+disable it. Returns the first matching
1196
1197
  * peer's hostname, or `null` when no peer pins the default port.
@@ -1200,7 +1201,7 @@ function installNeo4j() {
1200
1201
  * (permissions, transient I/O), the wrapper treats that peer as a *potential*
1201
1202
  * dependency and short-circuits to the kept-active path. Disabling the system
1202
1203
  * unit on faulty evidence would silently kill the peer's database (the exact
1203
- * failure Task 800 prevents); a conservatively-skipped disable is recoverable
1204
+ * failure mode the kept-active path prevents); a conservatively-skipped disable is recoverable
1204
1205
  * because the dedicated-unit bind check at the end of `setupDedicatedNeo4j`
1205
1206
  * fails loud if the system unit is actually free.
1206
1207
  */
@@ -1235,12 +1236,12 @@ function peerBrandUsingSystemUnit() {
1235
1236
  * Create a dedicated Neo4j instance for this brand when NEO4J_DEDICATED is true.
1236
1237
  * Produces: separate config dir, data dir, log dir, systemd service, and password.
1237
1238
  * On upgrade (config already exists), skips conf creation — but always runs the
1238
- * Task 787 state-remediation block (stop/disable system unit, reset-failed
1239
+ * state-remediation block (stop/disable system unit, reset-failed
1239
1240
  * dedicated, start, verify) so a half-installed Pi recovers in-place without
1240
1241
  * manual systemctl. ensureNeo4jPassword() handles password verification on the
1241
1242
  * recovery path.
1242
1243
  *
1243
- * Task 800: on multi-brand hosts where a peer brand still depends on the apt
1244
+ * on multi-brand hosts where a peer brand still depends on the apt
1244
1245
  * `neo4j.service` (port 7687), the stop+disable step is skipped — disabling
1245
1246
  * the system unit would kill the peer's database.
1246
1247
  */
@@ -1255,8 +1256,8 @@ function setupDedicatedNeo4j() {
1255
1256
  const httpPort = NEO4J_PORT - 213; // Preserve standard 7687/7474 offset
1256
1257
  // Per-brand state (sed, mkdir, chown, unit-write) is idempotent and runs on
1257
1258
  // every install. Only the base-config copy and initial-password rotation are
1258
- // gated to first install — Task 787 established that state remediation must
1259
- // run every install; Task 979 extended the same principle to the conf and
1259
+ // gated to first install established that state remediation must
1260
+ // run every install extended the same principle to the conf and
1260
1261
  // unit emission so a half-installed host (broken unit missing NEO4J_HOME)
1261
1262
  // recovers on retry without an out-of-band manual reset.
1262
1263
  const confExists = spawnSync("test", ["-f", `${confDir}/neo4j.conf`], { stdio: "pipe" }).status === 0;
@@ -1279,12 +1280,12 @@ function setupDedicatedNeo4j() {
1279
1280
  console.log(" [privileged] cp -r");
1280
1281
  shell("cp", ["-r", "/etc/neo4j", confDir], { sudo: true });
1281
1282
  }
1282
- // Idempotent per-brand state — runs on every install (Task 979).
1283
+ // Idempotent per-brand state — runs on every install.
1283
1284
  // sed `s|^#?key=.*|key=value|` no-ops when the file already has the target
1284
1285
  // value; mkdir -p, chown -R, and unit-write are idempotent by definition.
1285
1286
  // NEO4J_HOME=${dataDir} makes server.directories.run resolve per-brand to
1286
1287
  // ${dataDir}/run, so the launcher's pre-flight does not collide with the
1287
- // system unit's /var/lib/neo4j/run/neo4j.pid (Task 979 root cause). Plugins
1288
+ // system unit's /var/lib/neo4j/run/neo4j.pid (root cause). Plugins
1288
1289
  // and import are sed-overridden because the apt base conf pins them to
1289
1290
  // absolute /var/lib/neo4j/plugins and /var/lib/neo4j/import (shared).
1290
1291
  console.log(" [privileged] sed -i");
@@ -1347,7 +1348,7 @@ WantedBy=multi-user.target
1347
1348
  });
1348
1349
  }
1349
1350
  // ============================================================================
1350
- // Task 787 — unified state remediation + start + verify.
1351
+ // unified state remediation + start + verify.
1351
1352
  //
1352
1353
  // Runs on both fresh and recovery paths. The dedicated unit and the apt
1353
1354
  // package's system unit both exec /usr/bin/neo4j console without overriding
@@ -1360,9 +1361,9 @@ WantedBy=multi-user.target
1360
1361
  spawnSync("sudo", ["systemctl", "daemon-reload"], { stdio: "inherit" });
1361
1362
  console.log(" [privileged] systemctl enable");
1362
1363
  shell("systemctl", ["enable", serviceName], { sudo: true });
1363
- // Task 800: skip stop+disable when a peer brand on this host still depends
1364
+ // skip stop+disable when a peer brand on this host still depends
1364
1365
  // on the apt `neo4j.service` (port 7687). Disabling it would kill the peer's
1365
- // database — Task 797 reproducer on Neo's laptop. The kept-active path is
1366
+ // database reproducer on Neo's laptop. The kept-active path is
1366
1367
  // mutually exclusive with the disable path: exactly one log line per install.
1367
1368
  const peerOnSystemUnit = peerBrandUsingSystemUnit();
1368
1369
  if (peerOnSystemUnit !== null) {
@@ -1397,7 +1398,7 @@ WantedBy=multi-user.target
1397
1398
  spawnSync("sleep", ["2"]);
1398
1399
  }
1399
1400
  if (!listening) {
1400
- // Loud failure — no silent fallback to the system instance (Task 787).
1401
+ // Loud failure — no silent fallback to the system instance.
1401
1402
  const portCheck = spawnSync("ss", ["-tlnp"], { stdio: "pipe", timeout: 5000 });
1402
1403
  const portLines = (portCheck.stdout?.toString() ?? "").split("\n").filter((l) => l.includes(String(NEO4J_PORT)));
1403
1404
  const diagnostic = portLines.length > 0 ? portLines.join("; ") : "nothing listening on port";
@@ -1477,7 +1478,7 @@ function installOllama(embedModel) {
1477
1478
  logFile(` Pulling embedding model: ${embedModel}`);
1478
1479
  shellRetry("ollama", ["pull", embedModel], { timeout: 600_000 }, 3, 15);
1479
1480
  }
1480
- // Task 557 — uv/uvx bootstrap. Required by the `graph` MCP server which
1481
+ // uv/uvx bootstrap. Required by the `graph` MCP server which
1481
1482
  // spawns `uvx mcp-neo4j-cypher@0.6.0 --transport stdio`. Idempotent: when
1482
1483
  // uvx is already on PATH (or under $HOME/.local/bin) we skip. Non-fatal on
1483
1484
  // failure — the installer continues; the graph server will loudly fail
@@ -1524,7 +1525,7 @@ function installCloudflared() {
1524
1525
  // Homebrew's `cloudflared` formula tracks the Cloudflare release stream;
1525
1526
  // tunnel-login flow stays unchanged (`feedback_no_api_token_route.md`).
1526
1527
  // `cloudflared service install` is invoked by the launchd supervisor in
1527
- // Task 838 — out of scope here.
1528
+ // out of scope here.
1528
1529
  installAllBrewPackages(["cloudflared"], logFile);
1529
1530
  return;
1530
1531
  }
@@ -1573,7 +1574,7 @@ function installWhisperCpp() {
1573
1574
  }
1574
1575
  /**
1575
1576
  * Provision the shared HMAC secret used to sign remote-session cookies
1576
- * (Task 653). Both `maxy-edge` and `maxy-ui` read this file; without it
1577
+ *. Both `maxy-edge` and `maxy-ui` read this file; without it
1577
1578
  * they independently mint ephemeral secrets on first use and the
1578
1579
  * cross-process session namespace silently diverges again.
1579
1580
  *
@@ -1593,7 +1594,7 @@ function provisionRemoteSessionSecret() {
1593
1594
  writeFileSync(secretFile, randomBytes(32).toString("hex"), { mode: 0o600 });
1594
1595
  console.log(` [install] remote-session-secret provisioned path=${secretFile}`);
1595
1596
  }
1596
- // Task 904 — install-time admin-auth invariant. Walks every account.json
1597
+ // install-time admin-auth invariant. Walks every account.json
1597
1598
  // under accountsDir and compares its admins[] to the persistent users.json,
1598
1599
  // emitting one [install-invariant] line per divergence and one summary line.
1599
1600
  // Log-only (no install abort) so pre-Task-904 devices with already-divergent
@@ -1697,7 +1698,7 @@ function deployPayload() {
1697
1698
  mkdirSync(persistentDir, { recursive: true });
1698
1699
  cpSync(oldAccountsDir, persistentAccountsDir, { recursive: true });
1699
1700
  }
1700
- // Task 904 — users.json lives at <persistentDir>/users.json. Pre-Task-904
1701
+ // users.json lives at <persistentDir>/users.json. earlier
1701
1702
  // installs wrote to <INSTALL_DIR>/platform/config/users.json (the wipe zone)
1702
1703
  // and relied on a one-shot copy-up at first install plus a copy-back after
1703
1704
  // every wipe. The copy-back overwrote LIVE with the FROZEN-AT-FIRST-INSTALL
@@ -1707,7 +1708,7 @@ function deployPayload() {
1707
1708
  //
1708
1709
  // Legacy pickup: if a pre-Task-904 install left users.json inside the wipe
1709
1710
  // zone, copy it up once. Idempotent — guarded by !existsSync(persistentUsersFile).
1710
- // Safe to delete this block one release after Task 904 has been deployed
1711
+ // Safe to delete this block one release has been deployed
1711
1712
  // everywhere; until then it absorbs upgrades from any pre-Task-904 version.
1712
1713
  const persistentUsersFile = join(persistentDir, "users.json");
1713
1714
  const oldUsersFile = join(INSTALL_DIR, "platform/config/users.json");
@@ -1716,7 +1717,7 @@ function deployPayload() {
1716
1717
  cpSync(oldUsersFile, persistentUsersFile);
1717
1718
  console.log(" Migrated pre-Task-904 users.json to persistent storage.");
1718
1719
  }
1719
- // Task 923 — Claude Code OAuth credentials legacy pickup. Pre-Task-923
1720
+ // Claude Code OAuth credentials legacy pickup. earlier
1720
1721
  // installs shared `~/.claude/.credentials.json` across brands; the brand
1721
1722
  // main service's `claude` SDK subprocess and admin server now read from
1722
1723
  // `${persistDir}/.claude/.credentials.json` per the new
@@ -1750,7 +1751,7 @@ function deployPayload() {
1750
1751
  }
1751
1752
  writeFileSync(credsMigratedStamp, new Date().toISOString() + "\n");
1752
1753
  }
1753
- // Task 019 — pre-populate the brand `.claude.json` so the manager's
1754
+ // pre-populate the brand `.claude.json` so the manager's
1754
1755
  // PTY-spawned `claude --verbose --remote-control` boots straight into the
1755
1756
  // session URL without stopping at the first-run theme picker or the
1756
1757
  // workspace-trust dialog. Both prompts ate the manager's 30 s url-capture
@@ -1783,11 +1784,11 @@ function deployPayload() {
1783
1784
  console.log(` [install] claude-state primed: ${claudeStateFile} hasCompletedOnboarding=true trustedWorkspace=${homeWorkspace}`);
1784
1785
  // Brand isolation: installer does not read ~/.maxy/, ~/.cloudflared/, or
1785
1786
  // ~/.cloudflare/ on non-default brands. These are peer-brand or shared-singleton
1786
- // paths (Task 659). Pre-Task-659 installs that need to recover legacy state
1787
+ // paths. earlier installs that need to recover legacy state
1787
1788
  // follow the manual recovery paragraph in .docs/deployment.md.
1788
1789
  // Stop the running service before wiping directories (upgrade path).
1789
1790
  // The server holds open files in platform/ — rmSync fails with ENOTEMPTY if it's running.
1790
- // Task 838 — darwin uses `launchctl bootout` instead of systemctl; bootout
1791
+ // darwin uses `launchctl bootout` instead of systemctl; bootout
1791
1792
  // returns synchronously when the agent has exited.
1792
1793
  if (requireSupportedPlatform(process.platform) === "darwin") {
1793
1794
  spawnSync("launchctl", ["bootout", `${gui()}/${launchdLabel()}`], { stdio: "pipe", timeout: 15_000 });
@@ -1858,7 +1859,7 @@ function deployPayload() {
1858
1859
  cpSync(persistentPasswordFile, join(configDir, ".neo4j-password"));
1859
1860
  console.log(" Restored Neo4j password.");
1860
1861
  }
1861
- // Task 904 — users.json is read directly from persistentDir by both
1862
+ // users.json is read directly from persistentDir by both
1862
1863
  // platform/ui/app/lib/paths.ts (USERS_FILE = MAXY_DIR/users.json) and the
1863
1864
  // admin MCP plugin (USERS_FILE = CONFIG_DIR/users.json). No copy into the
1864
1865
  // wipe zone — the pre-Task-904 cpSync to platform/config/users.json was the
@@ -1883,7 +1884,7 @@ function deployPayload() {
1883
1884
  else {
1884
1885
  console.log(" [install] users.json: no persistent file (fresh install — set-pin will create it)");
1885
1886
  }
1886
- // Task 904 item 3 — install-time admin-auth invariant check. Walks every
1887
+ // install-time admin-auth invariant check. Walks every
1887
1888
  // data/accounts/*/account.json admins[] and compares to the persistent
1888
1889
  // users.json. Log-only (does NOT refuse install) so pre-Task-904 devices
1889
1890
  // with already-divergent state still upgrade; the [install-invariant]
@@ -1897,7 +1898,7 @@ function deployPayload() {
1897
1898
  writeFileSync(join(configDir, `.${BRAND.hostname}-version`), PKG_VERSION, "utf-8");
1898
1899
  console.log(` Deployed to ${INSTALL_DIR}`);
1899
1900
  }
1900
- // Task 030 — register the local + external Claude Code plugins after the
1901
+ // register the local + external Claude Code plugins after the
1901
1902
  // payload is on disk. The bundler stamps `.claude-plugin/marketplace.json`
1902
1903
  // at each plugin-tree root (platform/plugins/, premium-plugins/real-agent/
1903
1904
  // plugins/, premium-plugins/) so this function discovers them generically
@@ -1940,7 +1941,7 @@ function registerLocalAndExternalPlugins() {
1940
1941
  }
1941
1942
  }
1942
1943
  // Add each local marketplace. Idempotence via `marketplace list` grep.
1943
- // Task 048 — every `claude plugin …` call carries CLAUDE_CONFIG_DIR so
1944
+ // every `claude plugin …` call carries CLAUDE_CONFIG_DIR so
1944
1945
  // marketplaces register into the per-brand config dir that the runtime
1945
1946
  // session-manager unit reads from.
1946
1947
  const mkList = spawnSync("claude", ["plugin", "marketplace", "list"], { stdio: "pipe", encoding: "utf-8", env: claudePluginEnv() });
@@ -2030,7 +2031,7 @@ function registerLocalAndExternalPlugins() {
2030
2031
  logFile(`[plugin-configure] ERROR ${action.plugin.name} exit=${configure.status} stderr=${JSON.stringify(stderrShort)}`);
2031
2032
  }
2032
2033
  }
2033
- // Task 048 — post-install assertion. The per-brand CLAUDE_CONFIG_DIR is the
2034
+ // post-install assertion. The per-brand CLAUDE_CONFIG_DIR is the
2034
2035
  // only surface the runtime session-manager reads from; if any expected
2035
2036
  // marketplace is missing under .claude/plugins/marketplaces/, the operator
2036
2037
  // will hit "Unknown skill: onboarding" at step 6 of the bring-up. Fail the
@@ -2045,7 +2046,7 @@ function registerLocalAndExternalPlugins() {
2045
2046
  "claude-for-financial-services",
2046
2047
  ...localTrees.map(t => t.name),
2047
2048
  ]);
2048
- // Task 057: `claude plugin marketplace list` is the authoritative source.
2049
+ // `claude plugin marketplace list` is the authoritative source.
2049
2050
  // The `.claude/plugins/marketplaces/` directory only contains subdirs for
2050
2051
  // remote (git-cloned) marketplaces — local-source marketplaces registered
2051
2052
  // via `claude plugin marketplace add <directory-path>` live in user
@@ -2111,7 +2112,7 @@ function buildPlatform() {
2111
2112
  }
2112
2113
  console.log(` Installing server dependencies (${join(INSTALL_DIR, "server")})...`);
2113
2114
  shellRetry("npm", ["install", "--omit=dev", ...NPM_NET_FLAGS], { cwd: join(INSTALL_DIR, "server") }, 3, 15);
2114
- // Task 001 (maxy-code) — claude-session-manager has its own package.json
2115
+ // (maxy-code) — claude-session-manager has its own package.json
2115
2116
  // declaring hono + @hono/node-server + node-pty. node-pty is a native
2116
2117
  // binding; it MUST be installed on the Pi, not shipped pre-built (different
2117
2118
  // architecture between the build host and the Pi). Wipe + reinstall on
@@ -2231,7 +2232,7 @@ function setupVncViewer() {
2231
2232
  } catch (e) { /* swallow */ }
2232
2233
  }
2233
2234
 
2234
- // Layer-6 beacon (Task 958): emit event=rfb-connected and
2235
+ // Layer-6 beacon: emit event=rfb-connected and
2235
2236
  // event=rfb-error to the operator-grep lifecycle endpoint so
2236
2237
  // server.log shows the noVNC outcome alongside [setup-tunnel] /
2237
2238
  // [cloudflare-setup] / [device-url:click] / [http] / [websockify].
@@ -2351,7 +2352,7 @@ function setupVncViewer() {
2351
2352
  }
2352
2353
  function setupAccount() {
2353
2354
  log("10", TOTAL, "Setting up...");
2354
- // Task 787 — seed-neo4j.sh hard-exits without NEO4J_URI. The installer
2355
+ // seed-neo4j.sh hard-exits without NEO4J_URI. The installer
2355
2356
  // owns the brand-correct URI and password, so we derive them once.
2356
2357
  // Missing password file is a hard error: ensureNeo4jPassword() ran
2357
2358
  // upstream and would have thrown already if it couldn't reach the
@@ -2369,11 +2370,11 @@ function setupAccount() {
2369
2370
  logFile(` [neo4j] passing NEO4J_URI=${neo4jUri} to seed`);
2370
2371
  shell("bash", [seedScript], { cwd: INSTALL_DIR, env: neo4jEnv });
2371
2372
  }
2372
- // Task 068 — install-time defaults. Stamp `account.json` with the
2373
+ // install-time defaults. Stamp `account.json` with the
2373
2374
  // brand's default plugin set + default outputStyle / thinkingView, and
2374
2375
  // write a minimal admin SOUL.md. The agent boots into a working state
2375
2376
  // with no onboarding state machine; the operator builds personality up
2376
- // through use. The graph-write gate (Task 685) blocks user-domain writes
2377
+ // through use. The graph-write gate blocks user-domain writes
2377
2378
  // until AdminUser + LocalBusiness/personal-profile Person exist, so the
2378
2379
  // persona is elicited the first time the operator triggers a write.
2379
2380
  const accountId = resolveInstallAccountId();
@@ -2410,6 +2411,29 @@ function writeInstallDefaults(accountId) {
2410
2411
  writeFileSync(soulPath, `You are ${BRAND.productName}, an AI operations manager.\n`);
2411
2412
  console.log(` [install-defaults] soul-md path=${soulPath}`);
2412
2413
  logFile(` [install-defaults] soul-md path=${soulPath}`);
2414
+ // Public agent files — IDENTITY.md is always overwritten (Rubytech-controlled);
2415
+ // SOUL.md and config.json are created if missing (user-controlled). All three
2416
+ // are sourced from the payload templates under
2417
+ // <INSTALL_DIR>/platform/templates/agents/public/.
2418
+ const publicDir = join(accountDir, "agents/public");
2419
+ mkdirSync(publicDir, { recursive: true });
2420
+ const publicTemplatesDir = join(INSTALL_DIR, "platform/templates/agents/public");
2421
+ const publicIdentityDst = join(publicDir, "IDENTITY.md");
2422
+ cpSync(join(publicTemplatesDir, "IDENTITY.md"), publicIdentityDst);
2423
+ console.log(` [install-defaults] public-identity path=${publicIdentityDst}`);
2424
+ logFile(` [install-defaults] public-identity path=${publicIdentityDst}`);
2425
+ const publicSoulDst = join(publicDir, "SOUL.md");
2426
+ if (!existsSync(publicSoulDst)) {
2427
+ cpSync(join(publicTemplatesDir, "SOUL.md"), publicSoulDst);
2428
+ console.log(` [install-defaults] public-soul path=${publicSoulDst}`);
2429
+ logFile(` [install-defaults] public-soul path=${publicSoulDst}`);
2430
+ }
2431
+ const publicConfigDst = join(publicDir, "config.json");
2432
+ if (!existsSync(publicConfigDst)) {
2433
+ cpSync(join(publicTemplatesDir, "config.json"), publicConfigDst);
2434
+ console.log(` [install-defaults] public-config path=${publicConfigDst}`);
2435
+ logFile(` [install-defaults] public-config path=${publicConfigDst}`);
2436
+ }
2413
2437
  }
2414
2438
  // ---------------------------------------------------------------------------
2415
2439
  // Tunnel script shortcuts
@@ -2418,9 +2442,9 @@ function writeInstallDefaults(accountId) {
2418
2442
  // invocation `~/setup-tunnel.sh` (and `~/reset-tunnel.sh`). The filesystem
2419
2443
  // reality is <INSTALL_DIR>/platform/plugins/cloudflare/scripts/*.sh. Without
2420
2444
  // the symlink the agent's first SKILL-compliant invocation fails with exit
2421
- // 127 — the discipline-violation loop Task 555 exists to close.
2445
+ // 127 — the discipline-violation loop the symlink exists to close.
2422
2446
  //
2423
- // Collision discipline (Task 659 — last-writer-wins across brands):
2447
+ // Collision discipline (last-writer-wins across brands):
2424
2448
  // - absent path → create
2425
2449
  // - regular file → exit 1 (operator-owned file, do not clobber)
2426
2450
  // - symlink → same target → no-op
@@ -2458,7 +2482,7 @@ function createTunnelSymlink(linkPath, target) {
2458
2482
  console.error(` Remove the file and re-run: npx -y @rubytech/create-maxy`);
2459
2483
  process.exit(1);
2460
2484
  }
2461
- // Brand isolation (Task 659): a symlink at this path is either stale-same-brand,
2485
+ // Brand isolation: a symlink at this path is either stale-same-brand,
2462
2486
  // dangling, unreadable, or pointing at another brand. All four cases are resolved
2463
2487
  // by last-writer-wins overwrite — setup-tunnel.sh takes <brand> as argv, so
2464
2488
  // whichever brand's installer ran last owns the shortcut.
@@ -2505,13 +2529,13 @@ function installTunnelScripts() {
2505
2529
  // ---------------------------------------------------------------------------
2506
2530
  // Account discovery (shared by installService + the post-install summary)
2507
2531
  //
2508
- // Task 955 — `installService` stamps `Environment=ACCOUNT_ID=` into the brand
2532
+ // `installService` stamps `Environment=ACCOUNT_ID=` into the brand
2509
2533
  // systemd unit so the writeNodeWithEdges gate has a non-undefined identity to
2510
2534
  // compare against. Pulled from `INSTALL_DIR/data/accounts/<uuid>/account.json`
2511
2535
  // written by seed-neo4j.sh during setupAccount(). One reader, one shape, one
2512
2536
  // source of truth.
2513
2537
  //
2514
- // Task 039 retired the installer's cron registration — `resolveInstallAccountId`
2538
+ // retired the installer's cron registration — `resolveInstallAccountId`
2515
2539
  // kept its second consumer (installService) and is referenced again at print
2516
2540
  // time for the post-install banner.
2517
2541
  // ---------------------------------------------------------------------------
@@ -2528,26 +2552,26 @@ function resolveInstallAccountId() {
2528
2552
  catch { /* directory unreadable */ }
2529
2553
  return "";
2530
2554
  }
2531
- // Task 039 — `installCrons()` and the `# BEGIN/END <BRAND> CRONS` block lived
2555
+ // `installCrons()` and the `# BEGIN/END <BRAND> CRONS` block lived
2532
2556
  // here. All such events must be user-driven, not scheduled by the installer.
2533
2557
  // The legacy block recreated `data/accounts/<accountId>/logs/` every 60s via
2534
2558
  // `mkdir -p`, which tripped seed-neo4j.sh's stub-account-dirs guard on every
2535
2559
  // reinstall after `rm -rf ~/<installDir>`. Uninstall now strips the legacy
2536
2560
  // block (uninstall.ts `removeLegacyCronBlock`) so older installs migrate
2537
2561
  // cleanly. Consumer-side dispatcher replacement is tracked separately.
2538
- // Task 664 retired the ttyd/tmux/xterm admin terminal stack. Upgrades run
2562
+ // retired the ttyd/tmux/xterm admin terminal stack. Upgrades run
2539
2563
  // via the action runner — `systemd-run --user` transient units spawned by
2540
2564
  // POST /api/admin/actions/upgrade — whose lifetime is independent of
2541
- // maxy-ui, achieving the Task 647 invariant structurally rather than via
2565
+ // maxy-ui, achieving the invariant structurally rather than via
2542
2566
  // a peer edge service proxying a ttyd process. The installer no longer
2543
2567
  // provisions the ttyd binary, writes a tmux conf, or installs a ttyd
2544
2568
  // systemd unit. The corresponding admin UI (RemoteTerminal, TerminalOverlay,
2545
2569
  // xterm.js) was deleted in the same task.
2546
- // Task 838 — reverse-DNS LaunchAgent label. Becomes both the plist's
2570
+ // reverse-DNS LaunchAgent label. Becomes both the plist's
2547
2571
  // <key>Label</key> value and the file basename
2548
2572
  // (`~/Library/LaunchAgents/com.rubytech.<hostname>.plist`). Per-brand so
2549
2573
  // installing brand B never displaces brand A's agent (mirrors the per-brand
2550
- // systemd unit invariant from Task 662).
2574
+ // systemd unit invariant).
2551
2575
  function launchdLabel() {
2552
2576
  return `com.rubytech.${BRAND.hostname}`;
2553
2577
  }
@@ -2563,12 +2587,12 @@ function gui() {
2563
2587
  const uid = typeof process.getuid === "function" ? process.getuid() : 0;
2564
2588
  return `gui/${uid}`;
2565
2589
  }
2566
- // Task 838 — darwin LaunchAgent supervisor. Mirrors the systemd-user body
2590
+ // darwin LaunchAgent supervisor. Mirrors the systemd-user body
2567
2591
  // below at the success-criteria level: process registered with the user's
2568
2592
  // session manager, KeepAlive respawns on crash, RunAtLoad starts the agent
2569
- // on every login. Out-of-scope today (Task 839): brew-resolved node path,
2593
+ // on every login. Out-of-scope today: brew-resolved node path,
2570
2594
  // dedicated Neo4j on a non-default port. Falls back to /usr/local/bin/node
2571
- // (homebrew Intel + manual Apple-silicon installs) — Task 839 will replace
2595
+ // (homebrew Intel + manual Apple-silicon installs) will replace
2572
2596
  // this with the resolver.
2573
2597
  function installServiceDarwin() {
2574
2598
  const persistDir = resolve(process.env.HOME ?? "/", BRAND.configDir);
@@ -2617,7 +2641,7 @@ function installServiceDarwin() {
2617
2641
  const nodeBin = (nodeProbe.stdout ?? "").trim() || "/usr/local/bin/node";
2618
2642
  const wrapperBody = [
2619
2643
  "#!/bin/bash",
2620
- "# Task 838 — generated by create-maxy installService(). Reads .env then",
2644
+ "# generated by create-maxy installService(). Reads.env then",
2621
2645
  "# execs node so launchd's child inherits PORT, NEO4J_URI, etc. Replaces",
2622
2646
  "# the systemd EnvironmentFile= directive that has no launchd analogue.",
2623
2647
  `set -a; [ -f "${envPath}" ] && . "${envPath}"; set +a`,
@@ -2679,7 +2703,7 @@ function installServiceDarwin() {
2679
2703
  }
2680
2704
  function installService() {
2681
2705
  log("11", TOTAL, `Starting ${BRAND.productName}...`);
2682
- // Task 838 — branch on the Task 836 ternary instead of the legacy
2706
+ // branch ternary instead of the legacy
2683
2707
  // `isLinux()` boolean. Linux falls through to the systemd-user body
2684
2708
  // below; darwin renders + bootstraps a LaunchAgent and returns;
2685
2709
  // unsupported throws the literal refusal at requireSupportedPlatform.
@@ -2756,13 +2780,13 @@ function installService() {
2756
2780
  // Propagate to child processes — seed-neo4j.sh reads both variables.
2757
2781
  process.env.EMBED_DIMENSIONS = String(EMBED_DIMS);
2758
2782
  process.env.NEO4J_URI = `bolt://localhost:${NEO4J_PORT}`;
2759
- // Task 647: maxy-ui runs on an internal-only port so a restart does not
2783
+ // maxy-ui runs on an internal-only port so a restart does not
2760
2784
  // drop the public TCP socket. maxy-edge.service owns the public port and
2761
2785
  // the VNC stack; maxy-ui sits behind it on 127.0.0.1:MAXY_UI_INTERNAL_PORT.
2762
2786
  // PORT + 1 (derived) avoids a fixed-port collision if the operator chose a
2763
2787
  // non-default --port.
2764
2788
  //
2765
- // Task 666 — PORT in maxy.service's Environment block is the PUBLIC port,
2789
+ // PORT in maxy.service's Environment block is the PUBLIC port,
2766
2790
  // not the internal one. Previously we wrote `Environment=PORT=<internal>`,
2767
2791
  // which collided with the install-time reader further down, which
2768
2792
  // correctly treats Environment=PORT= as public. The overload caused +1
@@ -2772,10 +2796,10 @@ function installService() {
2772
2796
  const MAXY_UI_INTERNAL_PORT = PORT + 1;
2773
2797
  const edgeUnitShort = `${BRAND.hostname}-edge`;
2774
2798
  const edgeUnitName = `${edgeUnitShort}.service`;
2775
- // Per-brand X display (Task 553). Same value used for the edge unit's
2799
+ // Per-brand X display. Same value used for the edge unit's
2776
2800
  // DISPLAY env (stamped via __VNC_DISPLAY__ a few lines down) so the main
2777
2801
  // brand service and the edge service agree on which display Chromium runs.
2778
- // Task 924 + 959 — brand.json (BRAND) is the single source of truth for
2802
+ // brand.json (BRAND) is the single source of truth for
2779
2803
  // these fields at install time. The vncDisplay-derived offset rule lives
2780
2804
  // in the brand-creation tooling; at this point in the installer BRAND
2781
2805
  // already represents a parsed, validated brand manifest, and any missing
@@ -2796,13 +2820,13 @@ function installService() {
2796
2820
  const WEBSOCKIFY_PORT_BRAND = BRAND.websockifyPort;
2797
2821
  const CDP_PORT_BRAND = BRAND.cdpPort;
2798
2822
  const CLAUDE_SESSION_MANAGER_PORT_BRAND = BRAND.claudeSessionManagerPort;
2799
- // Task 924/938 pre-flight — refuse to write service files if any of the
2823
+ // pre-flight — refuse to write service files if any of the
2800
2824
  // three brand-scoped ports is already held by a process that is NOT this
2801
2825
  // brand's own on-demand browser nor a peer brand's edge stack.
2802
2826
  //
2803
- // Classification (Task 938 chromium, Task 939 Xtigervnc + websockify) reads
2804
- // `/proc/<pid>/cmdline` and applies a holder-specific argv anchor. Task 938
2805
- // covered chromium-only via `--user-data-dir=`; Task 939 closed the gap on
2827
+ // Classification (chromium Xtigervnc + websockify) reads
2828
+ // `/proc/<pid>/cmdline` and applies a holder-specific argv anchor.
2829
+ // covered chromium-only via `--user-data-dir=` closed the gap on
2806
2830
  // Xtigervnc (no such flag — anchor on the `:N` display literal) and
2807
2831
  // websockify (anchor on bind port). Brand identities (configDir,
2808
2832
  // vncDisplay, websockifyPort) come from brand-registry.json which the
@@ -2821,11 +2845,11 @@ function installService() {
2821
2845
  websockifyPort: WEBSOCKIFY_PORT_BRAND,
2822
2846
  };
2823
2847
  // Peer registry — load from payload/platform/config/brand-registry.json
2824
- // when present (Task 939+ bundles). Older bundles ship without the
2848
+ // when present. Older bundles ship without the
2825
2849
  // registry; in that case peerBrands stays empty. PEER_BRAND classification
2826
2850
  // for Xtigervnc/websockify is a defence-in-depth case anyway (port sets
2827
- // are disjoint by Task 924), so the empty-list fallback is safe — peer
2828
- // chromium will fall through to UNRELATED, matching pre-Task 938 behaviour
2851
+ // are disjoint), so the empty-list fallback is safe — peer
2852
+ // chromium will fall through to UNRELATED, matching earlier behaviour
2829
2853
  // for the only realistic scenario (a stale peer browser on the wrong CDP
2830
2854
  // port).
2831
2855
  const peerBrands = (() => {
@@ -2892,7 +2916,7 @@ function installService() {
2892
2916
  const classify = (ssOutput) => classifyPortHolder({
2893
2917
  ssOutput, ownBrand, peerBrands, getCmdline: readCmdline,
2894
2918
  });
2895
- // Task 939 — log line varies by detected holder so the operator can see
2919
+ // log line varies by detected holder so the operator can see
2896
2920
  // which OWN_BRAND stack is being killed. The kill loop is identical for
2897
2921
  // all three holders (SIGTERM → 300ms → recheck → SIGKILL → recheck), so
2898
2922
  // only the announce line differs.
@@ -2983,7 +3007,7 @@ function installService() {
2983
3007
  checkInstallPortFree("rfbPort", RFB_PORT);
2984
3008
  checkInstallPortFree("websockifyPort", WEBSOCKIFY_PORT_BRAND);
2985
3009
  checkInstallPortFree("cdpPort", CDP_PORT_BRAND);
2986
- // Task 955 — ACCOUNT_ID stamped into the brand unit so the writeNodeWithEdges
3010
+ // ACCOUNT_ID stamped into the brand unit so the writeNodeWithEdges
2987
3011
  // gate at platform/lib/graph-write/src/index.ts:170 has a real identity to
2988
3012
  // compare against (instead of process.env.ACCOUNT_ID === undefined). Resolved
2989
3013
  // here AFTER setupAccount() ran upstream — seed-neo4j.sh wrote account.json,
@@ -3007,12 +3031,12 @@ function installService() {
3007
3031
  rfbPort: RFB_PORT,
3008
3032
  websockifyPort: WEBSOCKIFY_PORT_BRAND,
3009
3033
  cdpPort: CDP_PORT_BRAND,
3010
- claudeSessionManagerPort: CLAUDE_SESSION_MANAGER_PORT_BRAND, // Task 001 (maxy-code)
3011
- chromiumBin: RESOLVED_CHROMIUM_BIN, // Task 929
3012
- accountId: installAccountId, // Task 955
3034
+ claudeSessionManagerPort: CLAUDE_SESSION_MANAGER_PORT_BRAND,
3035
+ chromiumBin: RESOLVED_CHROMIUM_BIN,
3036
+ accountId: installAccountId,
3013
3037
  });
3014
3038
  writeFileSync(join(serviceDir, BRAND.serviceName), serviceFile);
3015
- // Task 001 (maxy-code) — write the claude-session-manager unit. The main
3039
+ // (maxy-code) — write the claude-session-manager unit. The main
3016
3040
  // brand unit Requires= + After= this one, so systemd starts it first.
3017
3041
  const claudeSessionManagerUnitName = `${BRAND.hostname}-claude-session-manager.service`;
3018
3042
  const claudeSessionManagerUnit = buildClaudeSessionManagerUnitFile({
@@ -3026,13 +3050,13 @@ function installService() {
3026
3050
  });
3027
3051
  writeFileSync(join(serviceDir, claudeSessionManagerUnitName), claudeSessionManagerUnit);
3028
3052
  logFile(` ${claudeSessionManagerUnitName}: CLAUDE_SESSION_MANAGER_PORT=${CLAUDE_SESSION_MANAGER_PORT_BRAND}`);
3029
- // Task 647 — the edge service: always-on front door that owns the public
3053
+ // the edge service: always-on front door that owns the public
3030
3054
  // port (PORT) and the VNC stack (Xtigervnc + websockify). Its lifecycle is
3031
3055
  // independent of the main brand service, so an in-place upgrade triggered
3032
3056
  // from the admin terminal can restart the main brand service without
3033
3057
  // disconnecting the browser's remote terminal WebSocket.
3034
3058
  //
3035
- // Task 662: the unit is per-brand so two brands on the same device each
3059
+ // the unit is per-brand so two brands on the same device each
3036
3060
  // own their own edge listener on their own EDGE_PORT — installing brand B
3037
3061
  // never rewrites brand A's unit or steals brand A's public port. Upgrades
3038
3062
  // from pre-662 installs require the manual recovery paragraph in
@@ -3040,7 +3064,7 @@ function installService() {
3040
3064
  // intentionally scoped out.
3041
3065
  // VNC_DISPLAY (defined above for the main brand unit) is also stamped into
3042
3066
  // the edge unit so both services agree on the X display. Per-brand display
3043
- // closes the cross-brand cookie leak documented in Task 553.
3067
+ // closes the cross-brand cookie leak documented.
3044
3068
  const edgeTemplatePath = resolve(INSTALL_DIR, "platform/templates/systemd/edge.service.template");
3045
3069
  if (existsSync(edgeTemplatePath)) {
3046
3070
  const edgeServiceContent = readFileSync(edgeTemplatePath, "utf-8")
@@ -3058,7 +3082,7 @@ function installService() {
3058
3082
  else {
3059
3083
  console.error(` WARNING: edge.service.template missing at ${edgeTemplatePath} — VNC transport unavailable`);
3060
3084
  }
3061
- // Task 560: the unit declares Environment=PATH=%h/.local/bin:... so the graph
3085
+ // the unit declares Environment=PATH=%h/.local/bin:... so the graph
3062
3086
  // MCP shim's spawn("uvx", ...) resolves against uv's install location. Without
3063
3087
  // this line, the service inherits the default systemd-user PATH — which
3064
3088
  // excludes ~/.local/bin — and the shim exits ENOENT before any query lands.
@@ -3113,7 +3137,7 @@ WantedBy=multi-user.target
3113
3137
  catch { /* not critical */ }
3114
3138
  // Reload and (re)start.
3115
3139
  //
3116
- // Task 647 ordering: on upgrades, the old main brand service still holds
3140
+ // ordering: on upgrades, the old main brand service still holds
3117
3141
  // the public port (PORT). Stop it FIRST so the edge can bind that socket;
3118
3142
  // starting the edge first would race against the old main brand service
3119
3143
  // and fail with EADDRINUSE. Fresh installs: the stop is a no-op.
@@ -3184,7 +3208,7 @@ WantedBy=multi-user.target
3184
3208
  // Tunnel script smoke check — the cloudflare SKILL contract invokes
3185
3209
  // ~/setup-tunnel.sh directly. If the install-time symlink creation in
3186
3210
  // installTunnelScripts() didn't land, fail the install loudly here rather
3187
- // than shipping the exact Task 456 gap Task 555 exists to close.
3211
+ // than shipping a missing-symlink gap that would loop the agent on exit 127.
3188
3212
  for (const linkPath of [
3189
3213
  resolve(process.env.HOME ?? "/root", "setup-tunnel.sh"),
3190
3214
  resolve(process.env.HOME ?? "/root", "reset-tunnel.sh"),
@@ -3204,7 +3228,7 @@ WantedBy=multi-user.target
3204
3228
  }
3205
3229
  }
3206
3230
  // ---------------------------------------------------------------------------
3207
- // Task 034 — Samba provisioning. Runs after installService() so SMB never
3231
+ // Samba provisioning. Runs after installService() so SMB never
3208
3232
  // blocks the admin server starting; pure decisions live in samba-provision.ts.
3209
3233
  //
3210
3234
  // Four steps, each emitting one [install-invariant] samba-provision-<step>
@@ -3274,7 +3298,7 @@ function provisionSamba() {
3274
3298
  // the PIN. Scoped tight: only these two literal arg-vectors are
3275
3299
  // permitted; every other smbpasswd flavour still prompts.
3276
3300
  const SUDOERS = "/etc/sudoers.d/maxy-samba";
3277
- const sudoersBody = "# Task 034 — maxy-code Samba provisioning (smbpasswd sync from platform set-pin route).\n" +
3301
+ const sudoersBody = "# maxy-code Samba provisioning (smbpasswd sync from platform set-pin route).\n" +
3278
3302
  "admin ALL=(root) NOPASSWD: /usr/bin/smbpasswd -a -s admin, /usr/bin/smbpasswd -x admin\n";
3279
3303
  const sudoersTee = spawnSync("sudo", ["tee", SUDOERS], { input: sudoersBody, encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"], timeout: 5_000 });
3280
3304
  if (sudoersTee.status !== 0) {
@@ -3333,7 +3357,7 @@ if (_args.includes("--uninstall")) {
3333
3357
  // systemd applies EnvironmentFile=-~/.{brand}/.env AFTER Environment=PORT,
3334
3358
  // so .env is the final runtime truth and must be checked first on upgrade.
3335
3359
  //
3336
- // Task 666 — this block also performs one-shot port-drift recovery against
3360
+ // this block also performs one-shot port-drift recovery against
3337
3361
  // maxy-edge.service's Environment=EDGE_PORT=. See port-resolution.ts for the
3338
3362
  // pure logic; unit tests live at __tests__/port-canonicalisation.test.mjs.
3339
3363
  // ---------------------------------------------------------------------------
@@ -3514,7 +3538,7 @@ else {
3514
3538
  //
3515
3539
  // Default Maxy brand: 7687 (shared system Neo4j instance). Branded builds ship
3516
3540
  // a dedicated port in brand.json (e.g. Real Agent = 7688) so installing a
3517
- // second brand on the same device gets its own database by default — Task 659.
3541
+ // second brand on the same device gets its own database by default.
3518
3542
  //
3519
3543
  // Priority: --neo4j-port flag > .env NEO4J_URI (upgrade preserve) > BRAND.neo4jPort > 7687.
3520
3544
  // ---------------------------------------------------------------------------
@@ -3556,24 +3580,24 @@ else {
3556
3580
  // Dedicated = port differs from the default shared instance
3557
3581
  const NEO4J_DEDICATED = NEO4J_PORT !== DEFAULT_NEO4J_PORT;
3558
3582
  // ---------------------------------------------------------------------------
3559
- // Task 664 removed the per-brand ttyd port — the admin terminal stack
3583
+ // removed the per-brand ttyd port — the admin terminal stack
3560
3584
  // (ttyd, tmux, xterm.js) was retired in favour of the action runner that
3561
3585
  // spawns transient `systemd-run --user` units per upgrade or setup-tunnel
3562
3586
  // invocation. No TCP listener on the device needs to be reserved for an
3563
3587
  // interactive-shell surface any more.
3564
3588
  const PKG_VERSION = JSON.parse(readFileSync(resolve(import.meta.dirname, "../package.json"), "utf-8")).version;
3565
3589
  // ---------------------------------------------------------------------------
3566
- // Task 840 — pre-flight platform refusal.
3590
+ // pre-flight platform refusal.
3567
3591
  //
3568
3592
  // Runs BEFORE initLogging() (LOG_DIR creation), port resolution, and any
3569
- // brew/scutil/hostnamectl probe. Only Linux + darwin are supported (Task 836);
3593
+ // brew/scutil/hostnamectl probe. Only Linux + darwin are supported;
3570
3594
  // on darwin, macOS major must be ≥ 14 (the floor required by Tasks 838/839).
3571
3595
  // Older macOS partially succeeds, then breaks at the supervisor or brew-cellar
3572
3596
  // layer with cryptic errors — refusing loudly here is the contract.
3573
3597
  //
3574
3598
  // Platform-header line is emitted on every install start so operators can grep
3575
3599
  // `[create-maxy] platform=` to confirm pre-flight ran. On darwin the line also
3576
- // carries `macos=<v>` (Task 840 token) so the macOS-14 floor check is visible.
3600
+ // carries `macos=<v>` (token) so the macOS-14 floor check is visible.
3577
3601
  // ---------------------------------------------------------------------------
3578
3602
  const PLATFORM = requireSupportedPlatform(process.platform);
3579
3603
  let MACOS_VERSION = null;
@@ -3593,13 +3617,13 @@ if (PLATFORM === "darwin") {
3593
3617
  }
3594
3618
  }
3595
3619
  // Platform-header — first log line. Operators grep `[create-maxy] platform=`
3596
- // to confirm pre-flight ran. The /* macos=<v> */ token is the Task 840 marker;
3620
+ // to confirm pre-flight ran. The /* macos=<v> */ token is the marker;
3597
3621
  // keep it on this same line so 3-way merges with parallel installer edits stay
3598
3622
  // mechanical (no rewrap, no split into two log lines).
3599
3623
  const PLATFORM_HEADER = `[create-maxy] platform=${PLATFORM} arch=${process.arch}` +
3600
3624
  (MACOS_VERSION ? ` macos=${MACOS_VERSION}` : ``) +
3601
3625
  ` version=${PKG_VERSION}`;
3602
- // Task 062 — emit platform header and the resolved log/persist paths to
3626
+ // emit platform header and the resolved log/persist paths to
3603
3627
  // stdout BEFORE the log file is opened. If initLogging's mkdir or first
3604
3628
  // appendFileSync throws, the operator still sees brand/version/arch and the
3605
3629
  // exact path the log file SHOULD live at, instead of a silent exit between
@@ -3631,24 +3655,24 @@ try {
3631
3655
  installCloudflared();
3632
3656
  installWhisperCpp();
3633
3657
  deployPayload(); // Must happen before ensureNeo4jPassword — restores config backup
3634
- // Task 929: write the resolved Chromium absolute path into the deployed
3658
+ // write the resolved Chromium absolute path into the deployed
3635
3659
  // platform/config/ so vnc.sh, writeChromiumWrapper, and setup-tunnel.sh
3636
3660
  // all read the same value. Must run after deployPayload (config dir is
3637
3661
  // a payload subdirectory). Linux-only; no-op on darwin/non-linux.
3638
3662
  writeChromiumBinaryPathFile();
3639
- // Task 744: scrub plaintext neo4j passwords from any pre-fix install-*.log.
3663
+ // scrub plaintext neo4j passwords from any pre-fix install-*.log.
3640
3664
  // Idempotent — re-running on already-redacted logs is a no-op. Runs after
3641
3665
  // payload deploy so the bundled redact-install-logs.sh is on disk.
3642
3666
  redactInstallLogs();
3643
3667
  ensureNeo4jPassword(); // Now config/.neo4j-password is available if it existed before
3644
- provisionRemoteSessionSecret(); // Task 653: shared HMAC key readable by maxy-edge + maxy-ui
3668
+ provisionRemoteSessionSecret(); // shared HMAC key readable by maxy-edge + maxy-ui
3645
3669
  buildPlatform();
3646
- registerLocalAndExternalPlugins(); // Task 030: install-time plugin registration
3670
+ registerLocalAndExternalPlugins(); // install-time plugin registration
3647
3671
  setupVncViewer();
3648
3672
  setupAccount();
3649
3673
  installTunnelScripts(); // ~/setup-tunnel.sh, ~/reset-tunnel.sh — the SKILL contract
3650
3674
  installService();
3651
- // Task 034 — Samba on the LAN. Runs after the brand systemd unit is up so
3675
+ // Samba on the LAN. Runs after the brand systemd unit is up so
3652
3676
  // SMB provisioning never blocks the admin server starting; loud-fail per
3653
3677
  // step. The smbpasswd `user` step is deferred at install time and synced
3654
3678
  // by the platform's /set-pin route when the operator sets a PIN.