total-recall-brain 3.45.0 → 3.46.0

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 (362) hide show
  1. package/bin/total-recall.mjs +4 -2
  2. package/frontend/dist/assets/index-BRYE1jmv.css +1 -0
  3. package/frontend/dist/assets/index-D1goIPjC.js +5598 -0
  4. package/frontend/dist/index.html +2 -2
  5. package/frontend/dist/sw.js +5 -4
  6. package/frontend/src/App.tsx +183 -236
  7. package/frontend/src/api/auth-inventory.ts +62 -0
  8. package/frontend/src/api/memory.ts +13 -8
  9. package/frontend/src/api/plugin-credentials.ts +23 -0
  10. package/frontend/src/api/plugins.ts +37 -53
  11. package/frontend/src/api/workspace-drawers.ts +97 -0
  12. package/frontend/src/components/BrainSelector.tsx +9 -3
  13. package/frontend/src/components/plugins/PluginPanel.tsx +83 -42
  14. package/frontend/src/components/plugins/PluginSettings.tsx +10 -20
  15. package/frontend/src/components/plugins/PluginWorkspace.tsx +367 -0
  16. package/frontend/src/components/plugins/ScopedPluginCommands.tsx +142 -0
  17. package/frontend/src/components/plugins/plugin-frame.ts +44 -33
  18. package/frontend/src/components/plugins/scoped-plugin-operations.ts +28 -0
  19. package/frontend/src/components/workspace/DrawerChat.tsx +110 -0
  20. package/frontend/src/components/workspace/DrawerLayout.tsx +196 -0
  21. package/frontend/src/components/workspace/DrawerMarkup.tsx +49 -0
  22. package/frontend/src/components/workspace/PluginChunkLibrary.tsx +92 -0
  23. package/frontend/src/components/workspace/PluginHome.tsx +76 -0
  24. package/frontend/src/components/workspace/WorkspaceDrawers.tsx +96 -0
  25. package/frontend/src/components/workspace/WorkspacePage.tsx +95 -0
  26. package/frontend/src/components/workspace/usePluginDesign.ts +38 -0
  27. package/frontend/src/index.css +409 -136
  28. package/frontend/src/pages/HelpPage.tsx +15 -46
  29. package/frontend/src/pages/MemoryPage.tsx +19 -36
  30. package/frontend/src/pages/SettingsPage.tsx +1 -1
  31. package/metadata.plugin.schema.json +53 -227
  32. package/package.json +1 -1
  33. package/scaffold/.agent/skills/plugin/SKILL.md +13 -11
  34. package/scaffold/.agent/skills/plugin/evals/README.md +14 -21
  35. package/scaffold/.agent/skills/plugin/evals/cases/01-fabricated-seed.mjs +15 -18
  36. package/scaffold/.agent/skills/plugin/evals/cases/02-reassuring-default.mjs +19 -24
  37. package/scaffold/.agent/skills/plugin/evals/cases/03-declared-template.mjs +12 -20
  38. package/scaffold/.agent/skills/plugin/evals/cases/04-home-collects-credential.mjs +35 -0
  39. package/scaffold/.agent/skills/plugin/evals/cases/05-host-leak-in-scaffold.mjs +8 -28
  40. package/scaffold/.agent/skills/plugin/evals/cases/06-correct-plugin.mjs +85 -47
  41. package/scaffold/.agent/skills/plugin/evals/run.mjs +17 -18
  42. package/scaffold/.agent/skills/plugin/prompts/05-credentials.md +4 -4
  43. package/scaffold/.agent/skills/plugin/prompts/07-scaffold.md +2 -2
  44. package/scaffold/.agent/skills/plugin/prompts/08-verify.md +4 -4
  45. package/scaffold/.agent/skills/plugin/references/anti-patterns.md +2 -2
  46. package/scaffold/.agent/skills/plugin/references/generative-home.md +38 -0
  47. package/scaffold/.agent/skills/plugin/references/scaffold.md +5 -5
  48. package/scaffold/.agent/skills/plugin/references/surfaces.md +13 -4
  49. package/scaffold/.agent/skills/plugin/scripts/record.mjs +75 -153
  50. package/scaffold/.agent/skills/plugin/subagents/plugin-reviewer.md +4 -4
  51. package/scaffold/.agent/skills/total-recall/plugins/auth/DESIGN.md +76 -0
  52. package/scaffold/.agent/skills/total-recall/plugins/auth/README.md +3 -1
  53. package/scaffold/.agent/skills/total-recall/plugins/auth/cli.mjs +20 -15
  54. package/scaffold/.agent/skills/total-recall/plugins/auth/package-lock.json +6 -6
  55. package/scaffold/.agent/skills/total-recall/plugins/auth/package.json +2 -1
  56. package/scaffold/.agent/skills/total-recall/plugins/auth/plugin.json +13 -51
  57. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/access-overview.md +17 -0
  58. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/agent-login.md +20 -0
  59. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/baseline-audit.md +22 -0
  60. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/credential-repository-binding.md +17 -0
  61. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/credential-store-maintenance.md +17 -0
  62. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/dashboard-password.md +18 -0
  63. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/dashboard-sessions.md +18 -0
  64. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/endpoint-probe.md +23 -0
  65. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/google-sign-in.md +21 -0
  66. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/mesh-machines.md +16 -0
  67. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/passkey-enrollment.md +21 -0
  68. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/registered-brains.md +16 -0
  69. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/scoped-access-keys.md +17 -0
  70. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/secret-inventory.md +25 -0
  71. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/signing-key-rotation.md +22 -0
  72. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/home.js +375 -0
  73. package/scaffold/.agent/skills/total-recall/plugins/automations/{ui/DESIGN.md → DESIGN.md} +32 -21
  74. package/scaffold/.agent/skills/total-recall/plugins/automations/adapters.mjs +17 -1
  75. package/scaffold/.agent/skills/total-recall/plugins/automations/cli.mjs +10 -1
  76. package/scaffold/.agent/skills/total-recall/plugins/automations/package-lock.json +6 -6
  77. package/scaffold/.agent/skills/total-recall/plugins/automations/package.json +4 -3
  78. package/scaffold/.agent/skills/total-recall/plugins/automations/plugin.json +11 -27
  79. package/scaffold/.agent/skills/total-recall/plugins/automations/ui/automations.js +2 -2
  80. package/scaffold/.agent/skills/total-recall/plugins/automations/ui/chunks/control-ledger.md +42 -0
  81. package/scaffold/.agent/skills/total-recall/plugins/automations/ui/chunks/local-inventory-triage.md +17 -0
  82. package/scaffold/.agent/skills/total-recall/plugins/automations/ui/chunks/pending-control.md +39 -0
  83. package/scaffold/.agent/skills/total-recall/plugins/automations/ui/chunks/run-evidence.md +41 -0
  84. package/scaffold/.agent/skills/total-recall/plugins/automations/ui/chunks/schedule-vs-run-evidence.md +17 -0
  85. package/scaffold/.agent/skills/total-recall/plugins/automations/ui/chunks/source-coverage.md +41 -0
  86. package/scaffold/.agent/skills/total-recall/plugins/automations/ui/{card.js → home.js} +32 -27
  87. package/scaffold/.agent/skills/total-recall/plugins/code-quality/DESIGN.md +53 -0
  88. package/scaffold/.agent/skills/total-recall/plugins/code-quality/cli.mjs +23 -0
  89. package/scaffold/.agent/skills/total-recall/plugins/code-quality/commands/run-core.mjs +4 -2
  90. package/scaffold/.agent/skills/total-recall/plugins/code-quality/core/check.mjs +4 -2
  91. package/scaffold/.agent/skills/total-recall/plugins/code-quality/package-lock.json +6 -6
  92. package/scaffold/.agent/skills/total-recall/plugins/code-quality/package.json +2 -1
  93. package/scaffold/.agent/skills/total-recall/plugins/code-quality/plugin.json +40 -40
  94. package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/chunks/config.md +15 -0
  95. package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/chunks/detect.md +15 -0
  96. package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/chunks/gate.md +15 -0
  97. package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/chunks/init.md +15 -0
  98. package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/chunks/report.md +17 -0
  99. package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/chunks/run.md +17 -0
  100. package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/chunks/snapshot.md +15 -0
  101. package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/code-quality-report.mjs +55 -23
  102. package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/home.mjs +214 -0
  103. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/DESIGN.md +146 -0
  104. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/package-lock.json +6 -6
  105. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/package.json +2 -1
  106. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/plugin.json +51 -34
  107. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/src/command.mjs +1 -1
  108. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/create.md +35 -0
  109. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/history.md +35 -0
  110. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/library.md +49 -0
  111. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/list.md +42 -0
  112. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/promote.md +40 -0
  113. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/read.md +25 -0
  114. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/remove.md +26 -0
  115. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/rollback.md +26 -0
  116. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/show.md +53 -0
  117. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/status.md +40 -0
  118. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/test-path.md +38 -0
  119. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/test.md +46 -0
  120. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/update.md +32 -0
  121. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/home.js +533 -0
  122. package/scaffold/.agent/skills/total-recall/plugins/embeddings/DESIGN.md +110 -0
  123. package/scaffold/.agent/skills/total-recall/plugins/embeddings/package-lock.json +6 -6
  124. package/scaffold/.agent/skills/total-recall/plugins/embeddings/package.json +2 -1
  125. package/scaffold/.agent/skills/total-recall/plugins/embeddings/plugin.json +13 -10
  126. package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/chunks/benchmark.md +49 -0
  127. package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/chunks/coverage.md +53 -0
  128. package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/chunks/models.md +43 -0
  129. package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/chunks/pull.md +41 -0
  130. package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/chunks/status.md +59 -0
  131. package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/home.js +353 -0
  132. package/scaffold/.agent/skills/total-recall/plugins/git/DESIGN.md +31 -0
  133. package/scaffold/.agent/skills/total-recall/plugins/git/README.md +25 -1
  134. package/scaffold/.agent/skills/total-recall/plugins/git/cli.mjs +5 -1
  135. package/scaffold/.agent/skills/total-recall/plugins/git/package-lock.json +6 -6
  136. package/scaffold/.agent/skills/total-recall/plugins/git/package.json +2 -1
  137. package/scaffold/.agent/skills/total-recall/plugins/git/plugin.json +17 -27
  138. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/commit-memory.mjs +30 -6
  139. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/fleet.mjs +24 -6
  140. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/secret-firewall.mjs +33 -7
  141. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/undo.mjs +29 -5
  142. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/unmerged.mjs +182 -0
  143. package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/change-comparison.md +27 -0
  144. package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/commit-identity.md +22 -0
  145. package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/create-worktree.md +25 -0
  146. package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/registered-worktrees.md +22 -0
  147. package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/remove-worktree.md +23 -0
  148. package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/repository-ledger.md +25 -0
  149. package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/unmerged-work.md +22 -0
  150. package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/upstream-divergence.md +17 -0
  151. package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/worktree-conflict-triage.md +17 -0
  152. package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/worktree-terminal.md +22 -0
  153. package/scaffold/.agent/skills/total-recall/plugins/git/ui/home.js +273 -0
  154. package/scaffold/.agent/skills/total-recall/plugins/mesh/DESIGN.md +35 -0
  155. package/scaffold/.agent/skills/total-recall/plugins/mesh/README.md +4 -5
  156. package/scaffold/.agent/skills/total-recall/plugins/mesh/cli.mjs +9 -3
  157. package/scaffold/.agent/skills/total-recall/plugins/mesh/package-lock.json +6 -6
  158. package/scaffold/.agent/skills/total-recall/plugins/mesh/package.json +2 -1
  159. package/scaffold/.agent/skills/total-recall/plugins/mesh/plugin.json +37 -39
  160. package/scaffold/.agent/skills/total-recall/plugins/mesh/src/cli/mesh.mjs +5 -3
  161. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/active-device-dispatch.md +22 -0
  162. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/control-probe.md +25 -0
  163. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/control-server.md +22 -0
  164. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/credential-readiness.md +23 -0
  165. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/elected-leader.md +22 -0
  166. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/enrollment-key.md +22 -0
  167. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/file-receipt.md +25 -0
  168. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/fleet-execution.md +23 -0
  169. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/fleet-presence.md +23 -0
  170. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/interactive-ssh.md +22 -0
  171. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/local-enrollment.md +23 -0
  172. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/mesh-policy.md +23 -0
  173. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/network-atlas.md +25 -0
  174. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/node-roster.md +26 -0
  175. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/node-selection-proof.md +17 -0
  176. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/owner-observations.md +23 -0
  177. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/peer-path.md +23 -0
  178. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/pinned-leader.md +24 -0
  179. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/reachability-evidence-ladder.md +17 -0
  180. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/recorded-login.md +23 -0
  181. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/remote-execution.md +22 -0
  182. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/secret-grants.md +26 -0
  183. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/{card.js → home.js} +93 -22
  184. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/DESIGN.md +86 -0
  185. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/README.md +19 -0
  186. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/cli.mjs +5 -1
  187. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/package-lock.json +6 -6
  188. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/package.json +2 -1
  189. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/plugin.json +43 -22
  190. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/chat.mjs +80 -0
  191. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/adapter-docs-freshness.md +16 -0
  192. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/chat-handoff.md +26 -0
  193. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/fleet-maintenance.md +21 -0
  194. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/harness-inventory.md +21 -0
  195. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/included-access.md +18 -0
  196. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/included-usage-verification.md +15 -0
  197. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/independent-review.md +17 -0
  198. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/managed-execution.md +20 -0
  199. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/official-documentation.md +18 -0
  200. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/quota-recovery.md +21 -0
  201. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/review-routing-decision.md +16 -0
  202. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/route-work.md +18 -0
  203. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/routing-evidence.md +18 -0
  204. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/run-ledger.md +18 -0
  205. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/home.js +198 -0
  206. package/scaffold/.agent/skills/total-recall/plugins/openwiki/DESIGN.md +75 -0
  207. package/scaffold/.agent/skills/total-recall/plugins/openwiki/README.md +2 -0
  208. package/scaffold/.agent/skills/total-recall/plugins/openwiki/cli.mjs +17 -14
  209. package/scaffold/.agent/skills/total-recall/plugins/openwiki/package-lock.json +6 -6
  210. package/scaffold/.agent/skills/total-recall/plugins/openwiki/package.json +2 -1
  211. package/scaffold/.agent/skills/total-recall/plugins/openwiki/plugin.json +10 -44
  212. package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/generate.mjs +5 -4
  213. package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/graph.mjs +3 -4
  214. package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/ingest.mjs +23 -18
  215. package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/mesh-vaults.mjs +8 -3
  216. package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/refresh.mjs +6 -3
  217. package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/search.mjs +3 -5
  218. package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/token.mjs +21 -47
  219. package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/upstream-watcher.mjs +17 -6
  220. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/auto-refresh.md +18 -0
  221. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/bootstrap-pages.md +18 -0
  222. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/generate-wiki.md +21 -0
  223. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/generator-settings.md +18 -0
  224. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/host-probe.md +18 -0
  225. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/ingest-preview.md +18 -0
  226. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/link-hygiene.md +21 -0
  227. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/link-topology.md +19 -0
  228. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/passage-search.md +19 -0
  229. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/propagation-plan.md +18 -0
  230. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/provider-credentials.md +18 -0
  231. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/refresh-report.md +18 -0
  232. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/task-evidence.md +22 -0
  233. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/upstream-record.md +18 -0
  234. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/watch-upstream.md +18 -0
  235. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/wiki-atlas.md +19 -0
  236. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/panel.js +261 -513
  237. package/scaffold/.agent/skills/total-recall/plugins/security/DESIGN.md +84 -0
  238. package/scaffold/.agent/skills/total-recall/plugins/security/README.md +4 -2
  239. package/scaffold/.agent/skills/total-recall/plugins/security/cli.mjs +7 -19
  240. package/scaffold/.agent/skills/total-recall/plugins/security/package-lock.json +6 -6
  241. package/scaffold/.agent/skills/total-recall/plugins/security/package.json +2 -3
  242. package/scaffold/.agent/skills/total-recall/plugins/security/plugin.json +19 -52
  243. package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/device-evidence.md +21 -0
  244. package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/evidence-desk.md +18 -0
  245. package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/guided-device-review.md +17 -0
  246. package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/host-and-network.md +21 -0
  247. package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/https-headers.md +17 -0
  248. package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/mesh-coverage.md +18 -0
  249. package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/private-security-tools.md +16 -0
  250. package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/single-origin-header-check.md +17 -0
  251. package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/source-review.md +21 -0
  252. package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/ssh-permission-plan.md +17 -0
  253. package/scaffold/.agent/skills/total-recall/plugins/security/ui/home.js +283 -0
  254. package/scaffold/.agent/skills/total-recall/plugins/ssss/DESIGN.md +93 -0
  255. package/scaffold/.agent/skills/total-recall/plugins/ssss/package-lock.json +2 -2
  256. package/scaffold/.agent/skills/total-recall/plugins/ssss/package.json +2 -1
  257. package/scaffold/.agent/skills/total-recall/plugins/ssss/plugin.json +5 -3
  258. package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/chunks/conformance.md +26 -0
  259. package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/chunks/registry.md +37 -0
  260. package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/chunks/repair.md +42 -0
  261. package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/chunks/scaffold.md +33 -0
  262. package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/chunks/status.md +43 -0
  263. package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/chunks/validate.md +34 -0
  264. package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/chunks/validation-diagnostics.md +17 -0
  265. package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/chunks/workspace-registry-preflight.md +17 -0
  266. package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/home.js +348 -0
  267. package/scaffold/.agent/skills/total-recall/references/operations.md +2 -0
  268. package/src/cli/api.mjs +3 -3
  269. package/src/cli/brief.mjs +3 -0
  270. package/src/cli/config.mjs +16 -0
  271. package/src/cli/connect.mjs +2 -7
  272. package/src/cli/plugin/chunks.mjs +145 -0
  273. package/src/cli/plugin/create.mjs +24 -52
  274. package/src/cli/plugin/index.mjs +20 -9
  275. package/src/cli/setup.mjs +2 -9
  276. package/src/cli/start.mjs +1 -0
  277. package/src/cli/startup.mjs +18 -0
  278. package/src/core/app-deploy/design-tokens.mjs +14 -9
  279. package/src/core/app-deploy/ui-elements.mjs +1 -1
  280. package/src/core/brain-registry.mjs +5 -0
  281. package/src/core/brain-updates.mjs +5 -1
  282. package/src/core/daemon-control.mjs +5 -1
  283. package/src/core/dashboard-bundle.mjs +261 -0
  284. package/src/core/ensure-dependencies.mjs +19 -15
  285. package/src/core/memory-brain.mjs +30 -8
  286. package/src/core/plugin-activation.mjs +63 -20
  287. package/src/core/plugin-contracts/{card.mjs → manifest.mjs} +23 -57
  288. package/src/core/plugin-contracts/startup-check.mjs +49 -0
  289. package/src/core/plugin-contracts/ui.mjs +9 -3
  290. package/src/core/plugin-distribution.mjs +6 -6
  291. package/src/core/plugin-lifecycle.mjs +58 -0
  292. package/src/core/plugin-loader.mjs +9 -5
  293. package/src/core/plugin-runner.mjs +21 -10
  294. package/src/core/plugin-startup-checks.mjs +44 -0
  295. package/src/core/plugin-state.mjs +19 -5
  296. package/src/core/plugin-store.mjs +30 -11
  297. package/src/core/project-id.mjs +15 -5
  298. package/src/core/required-plugins.mjs +31 -6
  299. package/src/core/schema.mjs +2 -0
  300. package/src/core/ssss-operation-service.mjs +1 -0
  301. package/src/core/startup-health.mjs +28 -3
  302. package/src/core/testing/plugin-fixture.mjs +22 -21
  303. package/src/core/throttled-fetch.mjs +25 -18
  304. package/src/core/ui-chunk-choice.mjs +77 -0
  305. package/src/core/ui-chunk.registry.json +23 -0
  306. package/src/core/ui-chunks.mjs +434 -0
  307. package/src/core/vault-cache.mjs +58 -59
  308. package/src/core/workspace-compositions.mjs +151 -0
  309. package/src/core/workspace-drawers.mjs +79 -0
  310. package/src/server/api.mjs +4 -27
  311. package/src/server/index.mjs +28 -21
  312. package/src/server/memory-events.mjs +31 -0
  313. package/src/server/plugin-brain-targets.mjs +89 -0
  314. package/src/server/rest.mjs +2 -0
  315. package/src/server/route-inventory.mjs +3 -2
  316. package/src/server/route-manifest.json +52 -4
  317. package/src/server/routes/_shared.mjs +7 -14
  318. package/src/server/routes/brains.mjs +29 -44
  319. package/src/server/routes/dashboard.mjs +26 -0
  320. package/src/server/routes/plugins.mjs +154 -45
  321. package/src/server/routes/ui-chunks.mjs +192 -0
  322. package/frontend/dist/assets/index-DACh1dhx.js +0 -5613
  323. package/frontend/dist/assets/index-DtwsDyFM.css +0 -1
  324. package/frontend/src/components/plugins/card/CardEngine.tsx +0 -108
  325. package/frontend/src/components/plugins/card/CardScenes.tsx +0 -103
  326. package/frontend/src/components/plugins/card/ExecutionPicker.tsx +0 -64
  327. package/frontend/src/components/plugins/card/args.ts +0 -28
  328. package/frontend/src/components/plugins/card/card.css +0 -32
  329. package/frontend/src/components/plugins/card/cli-line.ts +0 -13
  330. package/frontend/src/components/plugins/card/contract.ts +0 -91
  331. package/frontend/src/components/plugins/card/format.ts +0 -49
  332. package/frontend/src/components/plugins/card/runner-context.ts +0 -11
  333. package/frontend/src/components/plugins/card/runner.tsx +0 -43
  334. package/frontend/src/components/plugins/card/theme.ts +0 -35
  335. package/frontend/src/components/plugins/card/use-source.ts +0 -22
  336. package/frontend/src/components/plugins/card/widgets.tsx +0 -94
  337. package/frontend/src/components/plugins/workspace/WorkspaceHost.tsx +0 -23
  338. package/frontend/src/pages/PluginsPage.tsx +0 -1719
  339. package/scaffold/.agent/skills/plugin/evals/cases/04-card-collects-credential.mjs +0 -47
  340. package/scaffold/.agent/skills/plugin/prompts/06-card.md +0 -46
  341. package/scaffold/.agent/skills/plugin/references/card.md +0 -90
  342. package/scaffold/.agent/skills/plugin/subagents/card-designer.md +0 -60
  343. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/DESIGN.md +0 -67
  344. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/card.js +0 -1179
  345. package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/DESIGN.md +0 -32
  346. package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/card.js +0 -588
  347. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/card.js +0 -575
  348. package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/DESIGN.md +0 -32
  349. package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/card.js +0 -482
  350. package/scaffold/.agent/skills/total-recall/plugins/git/ui/DESIGN.md +0 -100
  351. package/scaffold/.agent/skills/total-recall/plugins/git/ui/card.js +0 -637
  352. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/DESIGN.md +0 -217
  353. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/DESIGN.md +0 -32
  354. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/card.js +0 -1276
  355. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/DESIGN.md +0 -45
  356. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/card.js +0 -1401
  357. package/scaffold/.agent/skills/total-recall/plugins/security/scripts/build-ui.mjs +0 -4
  358. package/scaffold/.agent/skills/total-recall/plugins/security/ui/DESIGN.md +0 -41
  359. package/scaffold/.agent/skills/total-recall/plugins/security/ui/card.js +0 -396
  360. package/scaffold/.agent/skills/total-recall/plugins/security/ui/panel.js +0 -98
  361. package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/DESIGN.md +0 -15
  362. package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/card.js +0 -182
@@ -12,7 +12,7 @@ Measured against the current ecosystem, vendoring a plugin copies its whole tree
12
12
 
13
13
  | What a builder receives | Why it fails |
14
14
  | --- | --- |
15
- | the card face | its only data channel is `host.run`, a Total Recall host the app does not have |
15
+ | the native Home | its only data channel is `host.run`, a Total Recall host the app does not have |
16
16
  | an auth client that shells out to `total-recall` | the app breaks the moment Total Recall is absent — `Auth credential read failed` |
17
17
  | request logic inlined in `argv`-parsing handlers | there is nothing to import; 19 of 34 plugins export only `run` |
18
18
  | `https://example.com/checkout/success`, a default amount of `2000` | a real app would send paying customers to a placeholder domain |
@@ -44,7 +44,7 @@ The rules the shape enforces:
44
44
  - **Returned data, not printed text.** Printing is the CLI's job.
45
45
  - **Thrown errors, never `process.exitCode`.** The application decides how to fail.
46
46
  - **No Total Recall.** The capability does not know it exists.
47
- - **No card, no design tokens, no logo.** There is no dashboard to render them.
47
+ - **Keep dashboard presentation assets in the plugin.** There is no dashboard to render them.
48
48
 
49
49
  **Plus a builder entry point** — `BRICK.md`, short and concrete:
50
50
 
@@ -68,8 +68,8 @@ It states what to import, what to pass, where credentials come from, and what co
68
68
 
69
69
  ## What a scaffold never contains
70
70
 
71
- - the card face, `ui/DESIGN.md`, a logo
72
- - the plugin manifest — a manifest of Total Recall commands, secrets and a card means nothing in an app
71
+ - the native Home, `DESIGN.md`, a logo
72
+ - the plugin manifest — a manifest of Total Recall commands, secrets and dashboard UI means nothing in an app
73
73
  - any call to `total-recall`, `TOTAL_RECALL_BIN`, or an auth store
74
74
  - `argv` parsing or `console.log` as its output
75
75
  - a placeholder URL, an example default, or the author's own values
@@ -103,7 +103,7 @@ The CLI becomes a **thin adapter**: parse arguments, resolve credentials through
103
103
  - [ ] Every exported function is callable with caller-supplied arguments and an injected transport.
104
104
  - [ ] No `total-recall` string is reachable from the payload.
105
105
  - [ ] No `example.com`, no author default, no placeholder value.
106
- - [ ] No `ui/`, no `card.js`, no manifest.
106
+ - [ ] Keep `ui/` and the manifest in the plugin package.
107
107
  - [ ] The suite fails if the capability spawns a process — proving standalone operation rather than assuming it.
108
108
  - [ ] Vendored into a clean app, its suite passes there.
109
109
 
@@ -109,19 +109,20 @@ Five-field cron. `command` must be a declared subcommand.
109
109
 
110
110
  Live behaviour rather than a command. Module keys are lowercase kebab-case.
111
111
 
112
- ## UI — the card face
112
+ ## UI — native Home
113
113
 
114
114
  ```json
115
115
  "ui": {
116
- "design_tokens": "ui/DESIGN.md",
116
+ "home": "fleet",
117
+ "design_tokens": "DESIGN.md",
117
118
  "elements": [
118
- { "id": "card", "kind": "card", "tag": "tr-host-telemetry-card", "module": "ui/card.js",
119
+ { "id": "fleet", "kind": "panel", "tag": "tr-host-telemetry-home", "module": "ui/home.js",
119
120
  "description": "Fleet telemetry board" }
120
121
  ]
121
122
  }
122
123
  ```
123
124
 
124
- **Every plugin has a card**: exactly one element of kind `card`, and **no `card_layout`** — a declared template is an error, not a fallback. `description` says what the element is. See [card](card.md).
125
+ Package the owner design and [SSSS page blocks](generative-home.md) alongside the native Home. Additional panels are available by their declared IDs.
125
126
 
126
127
  ## Deploy
127
128
 
@@ -184,6 +185,14 @@ Keys are camelCase and may not contain `password`, `secret`, `apiKey` or `token`
184
185
 
185
186
  `command` must be a declared `read` subcommand. `refresh_seconds` is 5–86400.
186
187
 
188
+ ## Startup check — what a session should see when it starts
189
+
190
+ ```json
191
+ "startup_check": { "command": "unmerged", "args": ["--json"], "timeout_ms": 20000 }
192
+ ```
193
+
194
+ Optional. `command` must be a declared `read` subcommand; `args` are at most 8 plain arguments; `timeout_ms` is 1000–30000 (default 15000). `total-recall startup check` and `brief` run it in the session's directory and show its `summary` when `outstanding` is above zero. The command prints one JSON object `{ "ok": true, "outstanding": 0, "summary": "one line: what and where" }`. A failure, a timeout or any other shape is shown as unavailable, never as clean. Declare it only for something that needs attention at the start of work, and keep it fast.
195
+
187
196
  ## Gate — how work reaches your plugin
188
197
 
189
198
  Every plugin declares this, even one with nothing to claim. Write it by hand from what your plugin actually does.
@@ -6,7 +6,7 @@
6
6
  * non-zero on any failure and prints the real reason. Nothing here trusts a
7
7
  * declaration: every check reads the actual files or runs the actual command.
8
8
  *
9
- * node record.mjs <pluginDir> [--manifest|--card|--secrets|--scaffold|--reuse|--json]
9
+ * node record.mjs <pluginDir> [--manifest|--home|--secrets|--scaffold|--reuse|--json]
10
10
  *
11
11
  * Checks are marked PASS, FAIL or WARN. A WARN is a judgement call the agent
12
12
  * must resolve; a FAIL is a rejection.
@@ -17,8 +17,12 @@ import { execFileSync } from 'node:child_process';
17
17
  import { pathToFileURL } from 'node:url';
18
18
 
19
19
  const args = process.argv.slice(2);
20
+ if (args.includes('--card')) {
21
+ console.error('Legacy plugin cards are retired. Verify the native Home with --home.');
22
+ process.exit(2);
23
+ }
20
24
  const json = args.includes('--json');
21
- const only = ['--manifest', '--card', '--secrets', '--scaffold', '--reuse'].filter((f) => args.includes(f));
25
+ const only = ['--manifest', '--home', '--secrets', '--scaffold', '--reuse'].filter((f) => args.includes(f));
22
26
  const root = path.resolve(args.find((a) => !a.startsWith('-')) || '.');
23
27
  const want = (section) => only.length === 0 || only.includes(section);
24
28
 
@@ -30,7 +34,6 @@ const record = (section, level, check, detail) => results.push({ section, level,
30
34
  const read = (rel) => {
31
35
  try { return fs.readFileSync(path.join(root, rel), 'utf8'); } catch { return ''; }
32
36
  };
33
- const exists = (rel) => fs.existsSync(path.join(root, rel));
34
37
 
35
38
  /** Files the plugin owns, excluding dependencies and the brain. */
36
39
  function walk(dir, out = [], base = root) {
@@ -63,10 +66,18 @@ let manifest = null;
63
66
  }
64
67
  }
65
68
 
66
- // Validate with the real contract when this skill is inside a Total Recall checkout.
67
- if (manifest && want('--manifest')) {
68
- const loaderPath = path.resolve(import.meta.dirname, '../../../../src/core/plugin-loader.mjs');
69
- if (fs.existsSync(loaderPath)) {
69
+ // Use the host that runs block validation when it is given by path.
70
+ if (manifest && (want('--manifest') || want('--home'))) {
71
+ const binary = process.env.TOTAL_RECALL_BIN;
72
+ const explicit = binary && path.isAbsolute(binary) && fs.existsSync(binary)
73
+ ? path.resolve(path.dirname(fs.realpathSync(binary)), '../src/core/plugin-loader.mjs')
74
+ : null;
75
+ const loaderPath = [
76
+ explicit,
77
+ path.resolve(import.meta.dirname, '../../../../src/core/plugin-loader.mjs'),
78
+ path.resolve(import.meta.dirname, '../../../../../src/core/plugin-loader.mjs'),
79
+ ].find(file => file && fs.existsSync(file));
80
+ if (loaderPath) {
70
81
  try {
71
82
  const { validatePluginManifest } = await import(pathToFileURL(loaderPath).href);
72
83
  const v = validatePluginManifest(manifest);
@@ -81,27 +92,21 @@ if (manifest && want('--manifest')) {
81
92
  } else {
82
93
  record('manifest', 'WARN', 'contract', 'validator not found; structural checks only');
83
94
  }
95
+ }
84
96
 
85
- // Card declaration
86
- const elements = manifest.ui?.elements || [];
87
- // One face (kind 'card') plus any number of screens (kind 'panel'); a panel is never the face.
88
- const faces = elements.filter((e) => e && e.kind === 'card');
89
- if (manifest.card_layout !== undefined) {
90
- record('manifest', 'FAIL', 'no template', "'card_layout' is declared; a face is bespoke owner code");
91
- } else {
92
- record('manifest', 'PASS', 'no template', 'no card_layout');
93
- }
94
- if (faces.length === 0) {
95
- record('manifest', 'FAIL', 'card declared', 'every plugin has a card; ui.elements declares none');
96
- } else if (faces.length > 1) {
97
- record('manifest', 'FAIL', 'card declared', `${faces.length} faces declared; exactly one is allowed`);
98
- } else {
99
- const face = faces[0];
100
- record('manifest', 'PASS', 'card declared', `<${face.tag}> → ${face.module}`);
101
- if (!exists(face.module)) record('manifest', 'FAIL', 'card module resolves', `${face.module} does not exist`);
102
- else record('manifest', 'PASS', 'card module resolves', face.module);
97
+ if (manifest && (want('--manifest') || want('--home'))) {
98
+ const elements = Array.isArray(manifest.ui?.elements) ? manifest.ui.elements : [];
99
+ const obsolete = ['card', 'card_face', 'card_layout'].filter(field => Object.hasOwn(manifest, field));
100
+ if (elements.some(element => ['card', 'card-face'].includes(element?.kind))) obsolete.push('ui.elements');
101
+ for (const file of walk(root).filter(file => /^ui\/(card|card-face)\.(m?js|css)$/.test(file))) obsolete.push(file);
102
+ record('manifest', obsolete.length ? 'FAIL' : 'PASS', 'native presentation only',
103
+ obsolete.length ? `Remove legacy declarations or assets: ${obsolete.join(', ')}` : 'No legacy declarations or assets');
104
+ if (!manifest.ui?.home && manifest.brick !== true && manifest.scaffold !== true) {
105
+ record('manifest', 'FAIL', 'UI declared', 'Declare a native ui.home.');
103
106
  }
107
+ }
104
108
 
109
+ if (manifest && want('--manifest')) {
105
110
  // Declared effects and typed arguments on the CLI surface.
106
111
  for (const sub of manifest.cli?.subcommands || []) {
107
112
  if (!['read', 'write', 'destructive', 'send'].includes(sub.effect)) {
@@ -124,6 +129,51 @@ if (manifest && want('--manifest')) {
124
129
  }
125
130
  }
126
131
 
132
+ if (want('--home') && manifest && (manifest.ui?.home || only.includes('--home'))) {
133
+ const hasAuth = manifest.auth?.plugin === 'auth' && manifest.auth.session_verification === true;
134
+ record('home', hasAuth ? 'PASS' : 'FAIL', 'Bundled Auth', hasAuth ? 'Host session verification' : 'Declare auth.plugin and auth.session_verification.');
135
+ const home = manifest.ui?.elements?.find(element => element.id === manifest.ui.home);
136
+ const files = walk(root);
137
+ const validHome = home && ['panel', 'form', 'list', 'detail', 'widget'].includes(home.kind) && files.includes(home.module);
138
+ record('home', validHome ? 'PASS' : 'FAIL', 'Home element', validHome ? home.id : 'Declare a valid native ui.home.');
139
+ if (validHome) {
140
+ const source = read(home.module);
141
+ const seeded = /\b(?:hostname|loadAvg|usedPercent|uptimeSeconds)\s*:\s*(?:["'][^"']+["']|\[\s*\d|\d)/;
142
+ if (seeded.test(source)) record('home', 'FAIL', 'no seeded values', 'A live reading is initialized with a literal.');
143
+ const reassurance = /(?:\|\||\?\?)\s*['"](?:Up to date|Synced|Repository Active|ONLINE|Healthy|Connected|All good|OK)['"]/;
144
+ if (reassurance.test(source)) record('home', 'FAIL', 'no reassuring default', 'An unverified reading defaults to a successful state.');
145
+ const credentialPanel = home.events?.includes('save-token') && home.props?.view && manifest.secrets?.length === 1;
146
+ const ownsCredentialStore = manifest.id === 'auth' && hasAuth &&
147
+ home.events?.includes('auth-inventory') && home.events?.includes('auth-credential-mutate');
148
+ if (!credentialPanel && !ownsCredentialStore && /type\s*=\s*["']password["']|input\.type\s*=\s*["']password["']/.test(source)) {
149
+ record('home', 'FAIL', 'credential interface', 'Use shared Auth or a declared host credential panel.');
150
+ }
151
+ }
152
+ const hasDesign = manifest.ui?.design_tokens === 'DESIGN.md' && !!read('DESIGN.md').trim();
153
+ record('home', hasDesign ? 'PASS' : 'FAIL', 'Owner design', hasDesign ? 'DESIGN.md' : 'Package and declare root DESIGN.md.');
154
+ const covered = new Set();
155
+ let pageBlocks = 0;
156
+ for (const file of files.filter(file => /^ui\/chunks\/[^/]+\.md$/.test(file))) {
157
+ try {
158
+ const output = execFileSync(process.env.TOTAL_RECALL_BIN || 'total-recall',
159
+ ['plugin', 'chunks', 'validate', path.join(root, file), '--plugin-dir', root, '--json'],
160
+ { cwd: root, encoding: 'utf8', timeout: 15000, stdio: ['ignore', 'pipe', 'pipe'] });
161
+ const { chunk } = JSON.parse(output);
162
+ if (chunk.surfaces.includes('page')) {
163
+ pageBlocks++;
164
+ for (const operation of chunk.operations || []) covered.add(operation);
165
+ }
166
+ record('home', 'PASS', 'SSSS block', chunk.key);
167
+ } catch (error) {
168
+ record('home', 'FAIL', 'SSSS block', `${file}: ${String(error.stdout || error.message).trim().slice(0, 500)}`);
169
+ }
170
+ }
171
+ if (!pageBlocks) record('home', 'FAIL', 'Page blocks', 'Home has no validated page blocks.');
172
+ const missing = (manifest.cli?.subcommands || []).map(operation => operation.name).filter(name => !covered.has(name));
173
+ if (missing.length) record('home', 'FAIL', 'Operation coverage', missing.join(', '));
174
+ else if (pageBlocks) record('home', 'PASS', 'Operation coverage', 'All declared operations have page blocks.');
175
+ }
176
+
127
177
  /* ── reuse ───────────────────────────────────────────────────────────────── */
128
178
 
129
179
  function pluginInventory(command) {
@@ -181,119 +231,6 @@ if (want('--reuse') && manifest) {
181
231
  }
182
232
  }
183
233
 
184
- /* ── card ────────────────────────────────────────────────────────────────── */
185
-
186
- if (want('--card') && manifest) {
187
- const face = (manifest.ui?.elements || []).find((e) => e && e.kind === 'card');
188
- const src = face ? read(face.module) : '';
189
- if (!src) {
190
- record('card', 'FAIL', 'card source readable', 'no card module to read');
191
- } else {
192
- const lines = src.split('\n');
193
-
194
- // A credential must never be collectable from the face.
195
- if (/type\s*=\s*["']password["']/.test(src) || /input\.type\s*=\s*["']password["']/.test(src)) {
196
- record('card', 'FAIL', 'never collects a credential', 'a password input exists in the card');
197
- } else {
198
- record('card', 'PASS', 'never collects a credential', 'no password input');
199
- }
200
- if (/save-token|dispatchEvent\(\s*new CustomEvent\(\s*["']save-/.test(src)) {
201
- record('card', 'FAIL', 'never transmits a credential', 'the card dispatches a credential event');
202
- } else {
203
- record('card', 'PASS', 'never transmits a credential', 'no credential event');
204
- }
205
-
206
- // Seeded values: a literal that looks like a reading, not a read of one.
207
- // Each pattern requires an actual literal (a digit or a quoted string), so
208
- // a ternary such as `? h.loadAvg : []` is not mistaken for a seed.
209
- const seedPatterns = [
210
- [/\bthis\.(sample|reading|status|telemetry|gateway|data)\s*=\s*\{[^}]*\b(hostname|loadAvg|usedPercent|uptimeSeconds)\b/s, 'a seeded reading object'],
211
- [/hostname\s*:\s*["'][^"']+["']/, 'a literal hostname'],
212
- [/usedPercent\s*:\s*\d/, 'a literal usedPercent'],
213
- [/loadAvg\s*:\s*\[\s*\d/, 'a literal load average'],
214
- [/\bvalue\s*=\s*["']\d+(\.\d+)?["']/, 'a seeded input value'],
215
- ];
216
- let seeded = [];
217
- for (const [re, what] of seedPatterns) if (re.test(src)) seeded.push(what);
218
- if (seeded.length) record('card', 'FAIL', 'no seeded values', seeded.join('; '));
219
- else record('card', 'PASS', 'no seeded values', 'no literal reading found');
220
-
221
- // A reassuring default is a *fallback* for an unknown — `x || 'Up to date'`
222
- // or `x ?? 'Synced'`. The same word chosen by a ternary between two honest
223
- // labels (`ok ? 'Connected' : 'Unconfigured'`) is not a default, so only a
224
- // fallback position is flagged.
225
- const reassuringWords = ['Up to date', 'Synced', 'Repository Active', 'ONLINE', 'Healthy', 'Connected', 'All good', 'OK'];
226
- const reassuranceFallbacks = [];
227
- for (const word of reassuringWords) {
228
- for (const quote of ["'", '"']) {
229
- const literal = `${quote}${word}${quote}`;
230
- const index = src.indexOf(literal);
231
- if (index === -1) continue;
232
- // Look back for the operator that makes it a default.
233
- const before = src.slice(Math.max(0, index - 40), index);
234
- if (/\|\||\?\?\s*$/.test(before) || /\?\?\s*$/.test(src.slice(Math.max(0, index - 6), index))) {
235
- reassuranceFallbacks.push(word);
236
- break;
237
- }
238
- // A default inside a catch branch is a fallback too.
239
- const sinceCatch = src.slice(src.lastIndexOf('catch', index) === -1 ? 0 : src.lastIndexOf('catch', index), index);
240
- if (src.lastIndexOf('catch', index) !== -1 && sinceCatch.length < 200 && !/}\s*(else|finally)/.test(sinceCatch)) {
241
- reassuranceFallbacks.push(`${word} (in a catch)`);
242
- break;
243
- }
244
- }
245
- }
246
- if (reassuranceFallbacks.length) record('card', 'FAIL', 'no reassuring default', reassuranceFallbacks.join(', '));
247
- else record('card', 'PASS', 'no reassuring default', 'none found');
248
-
249
- // Randomness is how fabricated ids appear.
250
- if (/Math\.random\(/.test(src)) record('card', 'FAIL', 'no invented identifiers', 'Math.random in the card');
251
- else record('card', 'PASS', 'no invented identifiers', 'no Math.random');
252
-
253
- // Every read must go through the host, and failures must be states.
254
- if (!/host\.run|this\.host/.test(src)) {
255
- record('card', 'WARN', 'reads through the host', 'no host.run reference; does it render real data?');
256
- } else {
257
- record('card', 'PASS', 'reads through the host', 'host.run is used');
258
- }
259
- if (!/catch/.test(src)) record('card', 'WARN', 'failures are states', 'no catch; can the card show a failed read?');
260
- else record('card', 'PASS', 'failures are states', 'a catch exists');
261
-
262
- // A timer left running after disconnect.
263
- if (/setInterval/.test(src) && !/disconnectedCallback/.test(src)) {
264
- record('card', 'FAIL', 'timers cleared', 'setInterval without disconnectedCallback');
265
- } else {
266
- record('card', 'PASS', 'timers cleared', 'no leaked interval');
267
- }
268
-
269
- // Raw hex outside a token block suggests a hard-coded palette.
270
- const hex = [...src.matchAll(/#[0-9a-fA-F]{6}\b/g)];
271
- const tokenBlockHex = (src.match(/--face-[a-z-]+:\s*#[0-9a-fA-F]{3,8}/g) || []).length;
272
- if (hex.length - tokenBlockHex > 6) {
273
- record('card', 'WARN', 'tokens only', `${hex.length - tokenBlockHex} raw hex values outside token declarations`);
274
- } else {
275
- record('card', 'PASS', 'tokens only', 'colour is declared as tokens');
276
- }
277
-
278
- // The host's tokens must actually be used.
279
- for (const token of ['--text-primary', '--border']) {
280
- if (!src.includes(token)) record('card', 'WARN', 'host tokens used', `${token} is not referenced; the face may not adapt to the dashboard`);
281
- }
282
-
283
- // Accessibility floor.
284
- if (!/min-height:\s*(4[4-9]|[5-9]\d)px/.test(src)) {
285
- record('card', 'WARN', 'touch targets', 'no control declares a >=44px minimum height');
286
- } else {
287
- record('card', 'PASS', 'touch targets', 'controls reach 44px');
288
- }
289
- if (!/prefers-reduced-motion/.test(src)) {
290
- record('card', 'WARN', 'reduced motion', 'prefers-reduced-motion is not respected');
291
- } else {
292
- record('card', 'PASS', 'reduced motion', 'respected');
293
- }
294
- }
295
- }
296
-
297
234
  /* ── secrets ─────────────────────────────────────────────────────────────── */
298
235
 
299
236
  if (want('--secrets') && manifest) {
@@ -312,21 +249,6 @@ if (want('--secrets') && manifest) {
312
249
  else record('secrets', 'PASS', 'declared secret is not ambient', key);
313
250
  }
314
251
 
315
- // The card may name a credential's identifier — it must, so the operator
316
- // knows which key to set. What it must never do is receive or render the
317
- // value. The only channel a value could travel on is stdin, so that is the
318
- // thing to forbid.
319
- const faceSrc = read(manifest.ui?.elements?.find?.((e) => e.kind === 'card')?.module || '');
320
- if (/stdin\s*:/.test(faceSrc)) {
321
- record('secrets', 'FAIL', 'card never receives a credential', 'the card passes stdin to host.run');
322
- } else {
323
- record('secrets', 'PASS', 'card never receives a credential', 'no stdin channel from the face');
324
- }
325
- const names = (manifest.secrets || []).filter((s) => faceSrc.includes(s.key));
326
- if (names.length) {
327
- record('secrets', 'PASS', 'card names the identifier only', `${names.map((s) => s.key).join(', ')} — so the operator can fix it`);
328
- }
329
-
330
252
  // Credential access must go through auth.
331
253
  const authUse = files.some((f) => /auth['"],\s*['"]secret|auth secret/.test(read(f)));
332
254
  if ((manifest.secrets || []).length && !authUse) {
@@ -14,13 +14,13 @@ Do not fix anything. Report only. A report with no violations must say why it is
14
14
 
15
15
  Work from the [anti-patterns](../references/anti-patterns.md) catalogue. It is the record of every failure actually found in this ecosystem, so it is the highest-yield place to look.
16
16
 
17
- **Fabrication.** Seeded readings, invented API results, hard-coded status claims, fixed text where a command belongs. Grep the card and the CLI for literals that could be a fabricated value: a hostname, a percentage, a latency, a status word, a session id.
17
+ **Fabrication.** Seeded readings, invented API results, hard-coded status claims, fixed text where a command belongs. Grep the Home and the CLI for literals that could be a fabricated value: a hostname, a percentage, a latency, a status word, a session id.
18
18
 
19
- **Reassuring defaults.** A default that reports success, health or cleanliness the plugin has not verified. This is the most damaging pattern found: a card read three fields the command never returns and defaulted to `"Up to date"`, so a repository with three unpushed commits rendered as clean. For every value on the card, trace it to the command field it came from — and prove the field exists in the command's real output.
19
+ **Reassuring defaults.** A default that reports success, health or cleanliness the plugin has not verified. This is the most damaging pattern found: a card read three fields the command never returns and defaulted to `"Up to date"`, so a repository with three unpushed commits rendered as clean. For every value on the Home, trace it to the command field it came from — and prove the field exists in the command's real output.
20
20
 
21
21
  **Credential violations.** A second store; a secret in `argv`; a secret in a log or stdout; an input that accepts a key; error text telling the user to install another product.
22
22
 
23
- **Templates.** A `card_layout`; a region or widget list; a face that would suit a different plugin; screens derived from the command list rather than the plugin's tasks.
23
+ **Templates.** A shared template or a Home that would suit a different plugin; screens derived from the command list rather than the plugin's tasks.
24
24
 
25
25
  **Host leaks in a scaffold.** Any `total-recall` reference, `TOTAL_RECALL_BIN`, or auth-store read reachable from `capability/`. Any `ui/` file in the scaffold payload.
26
26
 
@@ -34,7 +34,7 @@ Work from the [anti-patterns](../references/anti-patterns.md) catalogue. It is t
34
34
 
35
35
  1. Run `node ../scripts/record.mjs <path> --json` and read every failure.
36
36
  2. `total-recall plugin info <id>` — read the errors and warnings.
37
- 3. For each value the card shows, find the command field behind it. If you cannot, that is a violation.
37
+ 3. For each value the Home shows, find the command field behind it. If you cannot, that is a violation.
38
38
  4. Read the CLI for `--help` without credentials, `--json` on every subcommand, non-zero exit on failure.
39
39
  5. Render the face and look at it. Do not review a face you have not seen.
40
40
  6. Read the tests. A test that injects a fake credential path proves logic, not the contract.
@@ -0,0 +1,76 @@
1
+ ---
2
+ version: "1.0"
3
+ name: Auth & Secrets
4
+ description: A pine-green operator console for credentials, registered brains, and Mesh machines.
5
+ colors:
6
+ primary: "#64e3a4"
7
+ background: "#101e19"
8
+ surface: "#192d24"
9
+ text: "#f2f8f3"
10
+ muted: "#b1c9ba"
11
+ outline: "#3f6350"
12
+ warning: "#f4d18c"
13
+ danger: "#ffbbb1"
14
+ typography:
15
+ body:
16
+ fontFamily: "Outfit, system-ui, sans-serif"
17
+ fontSize: 1rem
18
+ lineHeight: 1.5
19
+ heading:
20
+ fontFamily: "Outfit, system-ui, sans-serif"
21
+ fontSize: 1.4rem
22
+ fontWeight: 700
23
+ label:
24
+ fontFamily: "JetBrains Mono, ui-monospace, monospace"
25
+ fontSize: 0.75rem
26
+ letterSpacing: 0.05em
27
+ spacing:
28
+ sm: 0.65rem
29
+ md: 1rem
30
+ lg: 1.5rem
31
+ rounded:
32
+ panel: 0.65rem
33
+ control: 0.4rem
34
+ components:
35
+ access-overview:
36
+ backgroundColor: "{colors.surface}"
37
+ borderColor: "{colors.outline}"
38
+ borderWidth: 1px
39
+ borderStyle: solid
40
+ rounded: "{rounded.panel}"
41
+ padding: "{spacing.md}"
42
+ ---
43
+
44
+ # Auth & Secrets
45
+
46
+ ## Overview
47
+
48
+ Auth Home is an operator inventory. Start with credential names, providers, repository bindings, storage and rotation. Give registered brains, Mesh machines, and sign-in checks their own views.
49
+
50
+ ## Colors
51
+
52
+ Use deep pine for the workspace and a lighter pine for inset surfaces. Mint identifies a present configuration or a completed audit. Amber flags setup or a finding. Coral marks unavailable checks and failed requests. Accompany every status color with readable text.
53
+
54
+ ## Typography
55
+
56
+ Use Outfit for headings and body text. Use JetBrains Mono for workflow labels and command syntax. Fall back to the system families on a device without either font.
57
+
58
+ ## Layout
59
+
60
+ Use a compact heading and section navigation above a searchable table. Keep table headings visible during scrolling. Let the table scroll horizontally at narrow widths. Keep credential values inside the owner’s secure workflows.
61
+
62
+ ## Elevation & Depth
63
+
64
+ Separate the console with a single outline and inset dividers. Use flat color so a warning keeps its prominence.
65
+
66
+ ## Shapes
67
+
68
+ Use modestly rounded corners for the console and controls. Keep state labels as plain text.
69
+
70
+ ## Components
71
+
72
+ Access overview introduces the local configuration and links its block to the native panel. The panel uses the authenticated bridge to refresh state and run a baseline audit. Workflow blocks use headings, short steps and exact local command names. Named component tokens apply to the access overview.
73
+
74
+ ## Do's and Don'ts
75
+
76
+ Use visible focus, status announcements and touch targets of at least 44 pixels. Keep the interface still. Report a failed or unavailable check in text. Keep sign-in ceremonies and credential entry in the owner workflows.
@@ -18,7 +18,9 @@ Dashboard/step-up/collaboration tokens use HS256 with issuer, purpose-specific a
18
18
 
19
19
  Before uninstall, auth verifies and preserves encrypted ciphertext outside the brain. Locked, corrupt, plaintext, conflicting or unmigrated legacy credentials abort teardown. No live credential migration is performed by source changes.
20
20
 
21
- The card displays requested results only. The panel performs browser credential creation plus server verification before reporting registration success. Hardware attestation, provider availability and rotation schedules are never fabricated.
21
+ ## Auth Home
22
+
23
+ Open **Auth & Secrets** from the dashboard's Plugins folder to check sign-in setup and run the host baseline. Customize its colors, typography and layout in `DESIGN.md`. The independent SSSS blocks in `ui/chunks/` bind to the owner CLI and can be composed into pages and drawers. Credential entry and one-time outputs stay in the native Auth flows. The account panel uses browser credential creation and server verification to enroll a passkey.
22
24
 
23
25
  Integration and whole-ecosystem migration remain in progress. Fixture tests do not prove a physical passkey, OAuth provider login or fleet deployment.
24
26
 
@@ -294,24 +294,29 @@ async function handleAudit(subArgs, json) {
294
294
  return;
295
295
  }
296
296
  const brain = resolveBrainDir();
297
- const webauthnPath = path.join(brain, 'config', 'webauthn.json');
298
297
  const findings = [];
299
298
 
300
- // Check 1: WebAuthn file permissions
301
- if (fs.existsSync(webauthnPath)) {
302
- try {
303
- const stats = fs.statSync(webauthnPath);
304
- const mode = (stats.mode & 0o777).toString(8);
305
- if (mode !== '600' && mode !== '400') {
306
- findings.push({
307
- target: 'webauthn.json',
308
- severity: 'HIGH',
309
- message: `Permissions mode is ${mode}, expected 0600 (owner read/write only)`,
310
- });
311
- }
312
- } catch {
313
- // stat check fallback
299
+ // Check 1: The same canonical passkey state the owner reads and writes.
300
+ try {
301
+ const { resolveWebAuthnPath } = await import('./src/webauthn-store.mjs');
302
+ const { authState } = await import('./src/metadata-state.mjs');
303
+ await listStoredPasskeys();
304
+ const { documentPath } = authState(resolveWebAuthnPath(brain));
305
+ const stats = fs.lstatSync(documentPath, { throwIfNoEntry: false });
306
+ const mode = stats && (stats.mode & 0o777);
307
+ if (stats && mode !== 0o600 && mode !== 0o400) {
308
+ findings.push({
309
+ target: 'webauthn.json',
310
+ severity: 'HIGH',
311
+ message: `Passkey state permissions are ${mode.toString(8)}, expected 0600 or 0400`,
312
+ });
314
313
  }
314
+ } catch {
315
+ findings.push({
316
+ target: 'webauthn.json',
317
+ severity: 'HIGH',
318
+ message: 'Could not read or validate the Auth passkey state',
319
+ });
315
320
  }
316
321
 
317
322
  // Check 2: Session secret entropy
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "tr-plugin-auth",
3
- "version": "1.2.10",
3
+ "version": "1.3.0",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "tr-plugin-auth",
9
- "version": "1.2.10",
9
+ "version": "1.3.0",
10
10
  "license": "MIT",
11
11
  "dependencies": {
12
12
  "@gregiteen/ssss-cli": "0.14.5",
@@ -19,7 +19,7 @@
19
19
  },
20
20
  "devDependencies": {
21
21
  "supertest": "^7.3.1",
22
- "total-recall-brain": "3.44.0",
22
+ "total-recall-brain": "3.45.0",
23
23
  "vitest": "^4.1.12"
24
24
  }
25
25
  },
@@ -6704,9 +6704,9 @@
6704
6704
  }
6705
6705
  },
6706
6706
  "node_modules/total-recall-brain": {
6707
- "version": "3.44.0",
6708
- "resolved": "https://registry.npmjs.org/total-recall-brain/-/total-recall-brain-3.44.0.tgz",
6709
- "integrity": "sha512-VNPaIO9zsSwoxAsJ5ByIQBP9zPpLq4RiQO7Vrex4rBOHFQJT50P7utcZiLMSZTyZJU4C/m5uB8qTCSBMp6+l6Q==",
6707
+ "version": "3.45.0",
6708
+ "resolved": "https://registry.npmjs.org/total-recall-brain/-/total-recall-brain-3.45.0.tgz",
6709
+ "integrity": "sha512-HDYfROazZbsLHQsFPnlBcSpe1HL1QEi7JG8x/eNRUI06RxVQsZWl8LwBo2lTWjWRDrKmCy7BUmSXQDuWF3lrEw==",
6710
6710
  "dev": true,
6711
6711
  "license": "MIT",
6712
6712
  "workspaces": [
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tr-plugin-auth",
3
- "version": "1.2.10",
3
+ "version": "1.3.0",
4
4
  "description": "White-label Total Recall auth plugin: Passkey biometric FIDO2 and Google OAuth2 authentication.",
5
5
  "type": "module",
6
6
  "main": "cli.mjs",
@@ -29,6 +29,7 @@
29
29
  "cli.mjs",
30
30
  "plugin.json",
31
31
  "README.md",
32
+ "DESIGN.md",
32
33
  "src/",
33
34
  "scripts/",
34
35
  "!src/**/*.spec.mjs",