total-recall-brain 3.44.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 (502) hide show
  1. package/bin/total-recall.mjs +10 -6
  2. package/docs/ARCHITECTURE.md +10 -7
  3. package/docs/reference/cli-reference.md +13 -8
  4. package/frontend/dist/assets/index-BRYE1jmv.css +1 -0
  5. package/frontend/dist/assets/index-D1goIPjC.js +5598 -0
  6. package/frontend/dist/index.html +2 -2
  7. package/frontend/dist/sw.js +5 -4
  8. package/frontend/src/App.tsx +185 -238
  9. package/frontend/src/api/auth-inventory.ts +62 -0
  10. package/frontend/src/api/memory.ts +13 -8
  11. package/frontend/src/api/plugin-credentials.ts +23 -0
  12. package/frontend/src/api/plugins.ts +37 -53
  13. package/frontend/src/api/workspace-drawers.ts +97 -0
  14. package/frontend/src/components/BrainSelector.tsx +9 -3
  15. package/frontend/src/components/plugins/PluginPanel.tsx +83 -42
  16. package/frontend/src/components/plugins/PluginSettings.tsx +10 -20
  17. package/frontend/src/components/plugins/PluginWorkspace.tsx +367 -0
  18. package/frontend/src/components/plugins/ScopedPluginCommands.tsx +142 -0
  19. package/frontend/src/components/plugins/plugin-frame.ts +44 -33
  20. package/frontend/src/components/plugins/scoped-plugin-operations.ts +28 -0
  21. package/frontend/src/components/workspace/DrawerChat.tsx +110 -0
  22. package/frontend/src/components/workspace/DrawerLayout.tsx +196 -0
  23. package/frontend/src/components/workspace/DrawerMarkup.tsx +49 -0
  24. package/frontend/src/components/workspace/PluginChunkLibrary.tsx +92 -0
  25. package/frontend/src/components/workspace/PluginHome.tsx +76 -0
  26. package/frontend/src/components/workspace/WorkspaceDrawers.tsx +96 -0
  27. package/frontend/src/components/workspace/WorkspacePage.tsx +95 -0
  28. package/frontend/src/components/workspace/usePluginDesign.ts +38 -0
  29. package/frontend/src/index.css +409 -136
  30. package/frontend/src/pages/HelpPage.tsx +15 -46
  31. package/frontend/src/pages/MemoryPage.tsx +19 -36
  32. package/frontend/src/pages/SettingsPage.tsx +1 -1
  33. package/metadata.plugin.schema.json +53 -227
  34. package/package.json +1 -1
  35. package/scaffold/.agent/skills/plugin/SKILL.md +13 -11
  36. package/scaffold/.agent/skills/plugin/evals/README.md +14 -21
  37. package/scaffold/.agent/skills/plugin/evals/cases/01-fabricated-seed.mjs +15 -18
  38. package/scaffold/.agent/skills/plugin/evals/cases/02-reassuring-default.mjs +19 -24
  39. package/scaffold/.agent/skills/plugin/evals/cases/03-declared-template.mjs +12 -20
  40. package/scaffold/.agent/skills/plugin/evals/cases/04-home-collects-credential.mjs +35 -0
  41. package/scaffold/.agent/skills/plugin/evals/cases/05-host-leak-in-scaffold.mjs +8 -28
  42. package/scaffold/.agent/skills/plugin/evals/cases/06-correct-plugin.mjs +85 -47
  43. package/scaffold/.agent/skills/plugin/evals/run.mjs +17 -18
  44. package/scaffold/.agent/skills/plugin/prompts/05-credentials.md +4 -4
  45. package/scaffold/.agent/skills/plugin/prompts/07-scaffold.md +2 -2
  46. package/scaffold/.agent/skills/plugin/prompts/08-verify.md +4 -4
  47. package/scaffold/.agent/skills/plugin/references/anti-patterns.md +2 -2
  48. package/scaffold/.agent/skills/plugin/references/generative-home.md +38 -0
  49. package/scaffold/.agent/skills/plugin/references/scaffold.md +5 -5
  50. package/scaffold/.agent/skills/plugin/references/surfaces.md +13 -4
  51. package/scaffold/.agent/skills/plugin/scripts/record.mjs +75 -153
  52. package/scaffold/.agent/skills/plugin/subagents/plugin-reviewer.md +4 -4
  53. package/scaffold/.agent/skills/total-recall/plugins/auth/DESIGN.md +76 -0
  54. package/scaffold/.agent/skills/total-recall/plugins/auth/README.md +3 -1
  55. package/scaffold/.agent/skills/total-recall/plugins/auth/cli.mjs +20 -15
  56. package/scaffold/.agent/skills/total-recall/plugins/auth/package-lock.json +7 -7
  57. package/scaffold/.agent/skills/total-recall/plugins/auth/package.json +2 -1
  58. package/scaffold/.agent/skills/total-recall/plugins/auth/plugin.json +13 -51
  59. package/scaffold/.agent/skills/total-recall/plugins/auth/src/cli-secret.mjs +20 -1
  60. package/scaffold/.agent/skills/total-recall/plugins/auth/src/secrets-store.mjs +12 -1
  61. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/access-overview.md +17 -0
  62. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/agent-login.md +20 -0
  63. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/baseline-audit.md +22 -0
  64. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/credential-repository-binding.md +17 -0
  65. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/credential-store-maintenance.md +17 -0
  66. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/dashboard-password.md +18 -0
  67. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/dashboard-sessions.md +18 -0
  68. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/endpoint-probe.md +23 -0
  69. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/google-sign-in.md +21 -0
  70. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/mesh-machines.md +16 -0
  71. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/passkey-enrollment.md +21 -0
  72. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/registered-brains.md +16 -0
  73. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/scoped-access-keys.md +17 -0
  74. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/secret-inventory.md +25 -0
  75. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/signing-key-rotation.md +22 -0
  76. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/home.js +375 -0
  77. package/scaffold/.agent/skills/total-recall/plugins/automations/BRICK.md +7 -0
  78. package/scaffold/.agent/skills/total-recall/plugins/automations/DESIGN.md +53 -0
  79. package/scaffold/.agent/skills/total-recall/plugins/automations/LICENSE +21 -0
  80. package/scaffold/.agent/skills/total-recall/plugins/automations/README.md +66 -0
  81. package/scaffold/.agent/skills/total-recall/plugins/automations/adapters.mjs +247 -0
  82. package/scaffold/.agent/skills/total-recall/plugins/automations/capability/index.mjs +16 -0
  83. package/scaffold/.agent/skills/total-recall/plugins/automations/cli.mjs +130 -0
  84. package/{src/core/plugin-cron.mjs → scaffold/.agent/skills/total-recall/plugins/automations/cron.mjs} +1 -3
  85. package/scaffold/.agent/skills/total-recall/plugins/automations/inventory.mjs +88 -0
  86. package/scaffold/.agent/skills/total-recall/plugins/automations/package-lock.json +7661 -0
  87. package/scaffold/.agent/skills/total-recall/plugins/automations/package.json +36 -0
  88. package/scaffold/.agent/skills/total-recall/plugins/automations/plugin.json +151 -0
  89. package/scaffold/.agent/skills/total-recall/plugins/automations/scheduler.mjs +246 -0
  90. package/scaffold/.agent/skills/total-recall/plugins/automations/ui/automations.js +2 -0
  91. package/scaffold/.agent/skills/total-recall/plugins/automations/ui/chunks/control-ledger.md +42 -0
  92. package/scaffold/.agent/skills/total-recall/plugins/automations/ui/chunks/local-inventory-triage.md +17 -0
  93. package/scaffold/.agent/skills/total-recall/plugins/automations/ui/chunks/pending-control.md +39 -0
  94. package/scaffold/.agent/skills/total-recall/plugins/automations/ui/chunks/run-evidence.md +41 -0
  95. package/scaffold/.agent/skills/total-recall/plugins/automations/ui/chunks/schedule-vs-run-evidence.md +17 -0
  96. package/scaffold/.agent/skills/total-recall/plugins/automations/ui/chunks/source-coverage.md +41 -0
  97. package/scaffold/.agent/skills/total-recall/plugins/automations/ui/home.js +278 -0
  98. package/scaffold/.agent/skills/total-recall/plugins/code-quality/DESIGN.md +53 -0
  99. package/scaffold/.agent/skills/total-recall/plugins/code-quality/cli.mjs +23 -0
  100. package/scaffold/.agent/skills/total-recall/plugins/code-quality/commands/run-core.mjs +5 -3
  101. package/scaffold/.agent/skills/total-recall/plugins/code-quality/core/check.mjs +61 -7
  102. package/scaffold/.agent/skills/total-recall/plugins/code-quality/core/report-data.mjs +40 -14
  103. package/scaffold/.agent/skills/total-recall/plugins/code-quality/core/report.mjs +15 -40
  104. package/scaffold/.agent/skills/total-recall/plugins/code-quality/package-lock.json +7 -7
  105. package/scaffold/.agent/skills/total-recall/plugins/code-quality/package.json +2 -1
  106. package/scaffold/.agent/skills/total-recall/plugins/code-quality/plugin.json +40 -40
  107. package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/chunks/config.md +15 -0
  108. package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/chunks/detect.md +15 -0
  109. package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/chunks/gate.md +15 -0
  110. package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/chunks/init.md +15 -0
  111. package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/chunks/report.md +17 -0
  112. package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/chunks/run.md +17 -0
  113. package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/chunks/snapshot.md +15 -0
  114. package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/code-quality-report.mjs +55 -23
  115. package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/home.mjs +214 -0
  116. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/DESIGN.md +146 -0
  117. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/package-lock.json +7 -7
  118. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/package.json +2 -1
  119. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/plugin.json +51 -34
  120. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/src/command.mjs +1 -1
  121. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/create.md +35 -0
  122. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/history.md +35 -0
  123. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/library.md +49 -0
  124. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/list.md +42 -0
  125. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/promote.md +40 -0
  126. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/read.md +25 -0
  127. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/remove.md +26 -0
  128. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/rollback.md +26 -0
  129. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/show.md +53 -0
  130. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/status.md +40 -0
  131. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/test-path.md +38 -0
  132. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/test.md +46 -0
  133. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/update.md +32 -0
  134. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/home.js +533 -0
  135. package/scaffold/.agent/skills/total-recall/plugins/embeddings/DESIGN.md +110 -0
  136. package/scaffold/.agent/skills/total-recall/plugins/embeddings/package-lock.json +7 -7
  137. package/scaffold/.agent/skills/total-recall/plugins/embeddings/package.json +2 -1
  138. package/scaffold/.agent/skills/total-recall/plugins/embeddings/plugin.json +13 -10
  139. package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/chunks/benchmark.md +49 -0
  140. package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/chunks/coverage.md +53 -0
  141. package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/chunks/models.md +43 -0
  142. package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/chunks/pull.md +41 -0
  143. package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/chunks/status.md +59 -0
  144. package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/home.js +353 -0
  145. package/scaffold/.agent/skills/total-recall/plugins/git/DESIGN.md +31 -0
  146. package/scaffold/.agent/skills/total-recall/plugins/git/README.md +136 -0
  147. package/scaffold/.agent/skills/total-recall/plugins/{git-sentinel → git}/cli.mjs +140 -24
  148. package/scaffold/.agent/skills/total-recall/plugins/{git-sentinel → git}/package-lock.json +9 -9
  149. package/scaffold/.agent/skills/total-recall/plugins/{git-sentinel → git}/package.json +4 -2
  150. package/scaffold/.agent/skills/total-recall/plugins/git/plugin.json +151 -0
  151. package/scaffold/.agent/skills/total-recall/plugins/git/src/lib/context.mjs +94 -0
  152. package/scaffold/.agent/skills/total-recall/plugins/git/src/lib/phase3-spec-support.mjs +50 -0
  153. package/scaffold/.agent/skills/total-recall/plugins/git/src/lib/runtime.mjs +40 -0
  154. package/scaffold/.agent/skills/total-recall/plugins/git/src/lib/spec-support.mjs +51 -0
  155. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/_support.mjs +195 -0
  156. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/auth.mjs +201 -0
  157. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/bisect.mjs +40 -0
  158. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/cli-meta.mjs +159 -0
  159. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/commit-memory.mjs +54 -0
  160. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/commit.mjs +46 -0
  161. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/fleet.mjs +174 -0
  162. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/force-push.mjs +58 -0
  163. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/group.mjs +119 -0
  164. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/handoff.mjs +59 -0
  165. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/message.mjs +22 -0
  166. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/resolve.mjs +60 -0
  167. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/rules.mjs +81 -0
  168. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/secret-firewall.mjs +92 -0
  169. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/undo.mjs +156 -0
  170. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/unmerged.mjs +182 -0
  171. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/why.mjs +16 -0
  172. package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/change-comparison.md +27 -0
  173. package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/commit-identity.md +22 -0
  174. package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/create-worktree.md +25 -0
  175. package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/registered-worktrees.md +22 -0
  176. package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/remove-worktree.md +23 -0
  177. package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/repository-ledger.md +25 -0
  178. package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/unmerged-work.md +22 -0
  179. package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/upstream-divergence.md +17 -0
  180. package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/worktree-conflict-triage.md +17 -0
  181. package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/worktree-terminal.md +22 -0
  182. package/scaffold/.agent/skills/total-recall/plugins/git/ui/home.js +273 -0
  183. package/scaffold/.agent/skills/total-recall/plugins/mesh/DESIGN.md +35 -0
  184. package/scaffold/.agent/skills/total-recall/plugins/mesh/README.md +4 -5
  185. package/scaffold/.agent/skills/total-recall/plugins/mesh/cli.mjs +9 -3
  186. package/scaffold/.agent/skills/total-recall/plugins/mesh/package-lock.json +7 -7
  187. package/scaffold/.agent/skills/total-recall/plugins/mesh/package.json +2 -1
  188. package/scaffold/.agent/skills/total-recall/plugins/mesh/plugin.json +37 -39
  189. package/scaffold/.agent/skills/total-recall/plugins/mesh/src/cli/mesh.mjs +5 -3
  190. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/active-device-dispatch.md +22 -0
  191. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/control-probe.md +25 -0
  192. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/control-server.md +22 -0
  193. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/credential-readiness.md +23 -0
  194. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/elected-leader.md +22 -0
  195. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/enrollment-key.md +22 -0
  196. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/file-receipt.md +25 -0
  197. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/fleet-execution.md +23 -0
  198. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/fleet-presence.md +23 -0
  199. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/interactive-ssh.md +22 -0
  200. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/local-enrollment.md +23 -0
  201. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/mesh-policy.md +23 -0
  202. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/network-atlas.md +25 -0
  203. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/node-roster.md +26 -0
  204. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/node-selection-proof.md +17 -0
  205. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/owner-observations.md +23 -0
  206. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/peer-path.md +23 -0
  207. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/pinned-leader.md +24 -0
  208. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/reachability-evidence-ladder.md +17 -0
  209. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/recorded-login.md +23 -0
  210. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/remote-execution.md +22 -0
  211. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/secret-grants.md +26 -0
  212. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/{card.js → home.js} +93 -22
  213. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/DESIGN.md +86 -0
  214. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/README.md +44 -9
  215. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/capability/BRICK.md +1 -1
  216. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/capability/index.mjs +18 -6
  217. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/cli.mjs +128 -24
  218. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/package-lock.json +7 -7
  219. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/package.json +3 -2
  220. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/plugin.json +188 -34
  221. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/skills/meta-harness/SKILL.md +17 -3
  222. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/adoption.mjs +2 -2
  223. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/alerts.mjs +3 -3
  224. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/cascade.mjs +92 -18
  225. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/chat.mjs +80 -0
  226. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/control.mjs +145 -0
  227. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/coordinator.mjs +42 -21
  228. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/dispatch-request.mjs +4 -2
  229. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/dispatch.mjs +33 -9
  230. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/documentation.mjs +55 -11
  231. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/executor.mjs +26 -4
  232. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/gate-adapters/hermes.mjs +29 -1
  233. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/gate-adapters/index.mjs +1 -1
  234. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/included-usage.mjs +1 -1
  235. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/jobs.mjs +84 -0
  236. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/learner.mjs +3 -12
  237. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/maintenance.mjs +17 -0
  238. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/mcp-server.mjs +228 -0
  239. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/process-manager.mjs +25 -2
  240. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/reasoning.mjs +1 -1
  241. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/remote-operation.mjs +5 -1
  242. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/review.mjs +34 -3
  243. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/reviews.mjs +25 -0
  244. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/router.mjs +1 -1
  245. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/session/claude.mjs +319 -0
  246. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/session/codex.mjs +387 -0
  247. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/session/result.mjs +67 -0
  248. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/session/resume.mjs +373 -0
  249. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/session/run.mjs +223 -0
  250. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/session-jobs.mjs +72 -0
  251. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/setup.mjs +6 -3
  252. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/termination.mjs +16 -12
  253. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/threads.mjs +32 -1
  254. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/usage-queue.mjs +1 -1
  255. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/verify-ssss.mjs +3 -3
  256. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/worker.mjs +285 -40
  257. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/worktree.mjs +76 -9
  258. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/adapter-docs-freshness.md +16 -0
  259. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/chat-handoff.md +26 -0
  260. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/fleet-maintenance.md +21 -0
  261. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/harness-inventory.md +21 -0
  262. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/included-access.md +18 -0
  263. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/included-usage-verification.md +15 -0
  264. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/independent-review.md +17 -0
  265. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/managed-execution.md +20 -0
  266. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/official-documentation.md +18 -0
  267. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/quota-recovery.md +21 -0
  268. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/review-routing-decision.md +16 -0
  269. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/route-work.md +18 -0
  270. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/routing-evidence.md +18 -0
  271. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/run-ledger.md +18 -0
  272. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/home.js +198 -0
  273. package/scaffold/.agent/skills/total-recall/plugins/openwiki/DESIGN.md +75 -0
  274. package/scaffold/.agent/skills/total-recall/plugins/openwiki/README.md +2 -0
  275. package/scaffold/.agent/skills/total-recall/plugins/openwiki/cli.mjs +64 -32
  276. package/scaffold/.agent/skills/total-recall/plugins/openwiki/package-lock.json +7 -7
  277. package/scaffold/.agent/skills/total-recall/plugins/openwiki/package.json +2 -1
  278. package/scaffold/.agent/skills/total-recall/plugins/openwiki/plugin.json +10 -44
  279. package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/generate.mjs +5 -4
  280. package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/graph.mjs +3 -4
  281. package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/ingest.mjs +23 -18
  282. package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/mesh-vaults.mjs +8 -3
  283. package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/refresh-diagnostics.mjs +44 -0
  284. package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/refresh.mjs +123 -113
  285. package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/search.mjs +3 -5
  286. package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/token.mjs +21 -47
  287. package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/upstream-watcher.mjs +17 -6
  288. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/auto-refresh.md +18 -0
  289. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/bootstrap-pages.md +18 -0
  290. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/generate-wiki.md +21 -0
  291. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/generator-settings.md +18 -0
  292. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/host-probe.md +18 -0
  293. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/ingest-preview.md +18 -0
  294. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/link-hygiene.md +21 -0
  295. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/link-topology.md +19 -0
  296. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/passage-search.md +19 -0
  297. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/propagation-plan.md +18 -0
  298. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/provider-credentials.md +18 -0
  299. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/refresh-report.md +18 -0
  300. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/task-evidence.md +22 -0
  301. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/upstream-record.md +18 -0
  302. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/watch-upstream.md +18 -0
  303. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/wiki-atlas.md +19 -0
  304. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/panel.js +261 -513
  305. package/scaffold/.agent/skills/total-recall/plugins/security/DESIGN.md +84 -0
  306. package/scaffold/.agent/skills/total-recall/plugins/security/README.md +4 -2
  307. package/scaffold/.agent/skills/total-recall/plugins/security/cli.mjs +7 -19
  308. package/scaffold/.agent/skills/total-recall/plugins/security/package-lock.json +7 -7
  309. package/scaffold/.agent/skills/total-recall/plugins/security/package.json +2 -3
  310. package/scaffold/.agent/skills/total-recall/plugins/security/plugin.json +19 -52
  311. package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/device-evidence.md +21 -0
  312. package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/evidence-desk.md +18 -0
  313. package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/guided-device-review.md +17 -0
  314. package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/host-and-network.md +21 -0
  315. package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/https-headers.md +17 -0
  316. package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/mesh-coverage.md +18 -0
  317. package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/private-security-tools.md +16 -0
  318. package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/single-origin-header-check.md +17 -0
  319. package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/source-review.md +21 -0
  320. package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/ssh-permission-plan.md +17 -0
  321. package/scaffold/.agent/skills/total-recall/plugins/security/ui/home.js +283 -0
  322. package/scaffold/.agent/skills/total-recall/plugins/ssss/DESIGN.md +93 -0
  323. package/scaffold/.agent/skills/total-recall/plugins/ssss/package-lock.json +2 -2
  324. package/scaffold/.agent/skills/total-recall/plugins/ssss/package.json +2 -1
  325. package/scaffold/.agent/skills/total-recall/plugins/ssss/plugin.json +5 -3
  326. package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/chunks/conformance.md +26 -0
  327. package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/chunks/registry.md +37 -0
  328. package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/chunks/repair.md +42 -0
  329. package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/chunks/scaffold.md +33 -0
  330. package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/chunks/status.md +43 -0
  331. package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/chunks/validate.md +34 -0
  332. package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/chunks/validation-diagnostics.md +17 -0
  333. package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/chunks/workspace-registry-preflight.md +17 -0
  334. package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/home.js +348 -0
  335. package/scaffold/.agent/skills/total-recall/references/operations.md +3 -1
  336. package/src/cli/agent.mjs +1 -1
  337. package/src/cli/api.mjs +3 -3
  338. package/src/cli/brief.mjs +3 -0
  339. package/src/cli/command.mjs +41 -2
  340. package/src/cli/config.mjs +16 -0
  341. package/src/cli/connect.mjs +2 -7
  342. package/src/cli/dream.mjs +93 -69
  343. package/src/cli/harness.mjs +4 -4
  344. package/src/cli/help.mjs +1 -1
  345. package/src/cli/init.mjs +0 -25
  346. package/src/cli/lessons.mjs +51 -0
  347. package/src/cli/memory-plugin.mjs +1 -1
  348. package/src/cli/plugin/chunks.mjs +145 -0
  349. package/src/cli/plugin/copies.mjs +64 -14
  350. package/src/cli/plugin/create.mjs +30 -59
  351. package/src/cli/plugin/index.mjs +31 -16
  352. package/src/cli/plugin/install.mjs +10 -15
  353. package/src/cli/plugin/remove.mjs +1 -1
  354. package/src/cli/plugin/search.mjs +2 -2
  355. package/src/cli/preflight.mjs +19 -6
  356. package/src/cli/proposals.mjs +1 -1
  357. package/src/cli/recall.mjs +66 -23
  358. package/src/cli/remember.mjs +3 -14
  359. package/src/cli/server.mjs +18 -0
  360. package/src/cli/setup.mjs +2 -9
  361. package/src/cli/start.mjs +1 -0
  362. package/src/cli/startup.mjs +19 -0
  363. package/src/cli/task.mjs +9 -2
  364. package/src/cli/update.mjs +6 -2
  365. package/src/core/access-ledger.mjs +78 -0
  366. package/src/core/agent-manager.mjs +2 -2
  367. package/src/core/app-deploy/design-tokens.mjs +14 -9
  368. package/src/core/app-deploy/ui-elements.mjs +1 -1
  369. package/src/core/brain-locate.mjs +15 -0
  370. package/src/core/brain-registry.mjs +5 -0
  371. package/src/core/brain-updates.mjs +35 -11
  372. package/src/core/claude-hooks.mjs +3 -1
  373. package/src/core/cleanup-task.mjs +15 -0
  374. package/src/core/cli-commands.mjs +2 -0
  375. package/src/core/cli-maintenance.mjs +4 -1
  376. package/src/core/cli-semantic-index.mjs +23 -3
  377. package/src/core/context-compiler.mjs +20 -0
  378. package/src/core/daemon-control.mjs +5 -1
  379. package/src/core/daemon-loop.mjs +39 -62
  380. package/src/core/dashboard-bundle.mjs +261 -0
  381. package/src/core/default-plugins.mjs +1 -1
  382. package/src/core/dream.mjs +33 -105
  383. package/src/core/ensure-dependencies.mjs +152 -0
  384. package/src/core/fast-recall.mjs +2 -2
  385. package/src/core/field-evaluation.mjs +23 -0
  386. package/src/core/gate-mode.mjs +1 -1
  387. package/src/core/harness-hooks.mjs +14 -2
  388. package/src/core/lesson-hooks.mjs +74 -0
  389. package/src/core/lesson-memory.mjs +24 -0
  390. package/src/core/lesson-sessions.mjs +52 -0
  391. package/src/core/lessons.mjs +96 -0
  392. package/src/core/memory-brain.mjs +30 -8
  393. package/src/core/meta-harness.mjs +2 -2
  394. package/src/core/optimizer.mjs +66 -165
  395. package/src/core/plugin-activation.mjs +63 -20
  396. package/src/core/plugin-contracts/{card.mjs → manifest.mjs} +26 -57
  397. package/src/core/plugin-contracts/startup-check.mjs +49 -0
  398. package/src/core/plugin-contracts/ui.mjs +9 -3
  399. package/src/core/plugin-distribution.mjs +6 -6
  400. package/src/core/plugin-lifecycle.mjs +58 -0
  401. package/src/core/plugin-loader.mjs +21 -8
  402. package/src/core/plugin-runner.mjs +21 -10
  403. package/src/core/plugin-runtime.mjs +40 -1
  404. package/src/core/plugin-startup-checks.mjs +44 -0
  405. package/src/core/plugin-state.mjs +19 -5
  406. package/src/core/plugin-store.mjs +64 -33
  407. package/src/core/post-mortem.mjs +52 -36
  408. package/src/core/preflight-gate.mjs +23 -2
  409. package/src/core/project-id.mjs +15 -5
  410. package/src/core/proposal-applier.mjs +31 -2
  411. package/src/core/repo-sync.mjs +4 -6
  412. package/src/core/required-plugins.mjs +57 -10
  413. package/src/core/rule-length.mjs +23 -0
  414. package/src/core/runtime.mjs +1 -1
  415. package/src/core/scheduler.mjs +35 -43
  416. package/src/core/schema.mjs +3 -2
  417. package/src/core/search.mjs +4 -3
  418. package/src/core/server-service.mjs +148 -0
  419. package/src/core/session-watcher.mjs +19 -1
  420. package/src/core/skill-gap.mjs +16 -0
  421. package/src/core/ssss-kernel-bridge.mjs +32 -4
  422. package/src/core/ssss-operation-service.mjs +1 -0
  423. package/src/core/startup-health.mjs +34 -4
  424. package/src/core/surface.mjs +65 -54
  425. package/src/core/task-executors.mjs +54 -106
  426. package/src/core/testing/plugin-fixture.mjs +22 -21
  427. package/src/core/throttled-fetch.mjs +25 -18
  428. package/src/core/ui-chunk-choice.mjs +77 -0
  429. package/src/core/ui-chunk.registry.json +23 -0
  430. package/src/core/ui-chunks.mjs +434 -0
  431. package/src/core/validated-write.mjs +1 -0
  432. package/src/core/vault-cache.mjs +58 -59
  433. package/src/core/vector-field.mjs +134 -192
  434. package/src/core/workspace-compositions.mjs +151 -0
  435. package/src/core/workspace-drawers.mjs +79 -0
  436. package/src/server/api.mjs +4 -27
  437. package/src/server/index.mjs +28 -21
  438. package/src/server/invoke-core-child.mjs +24 -0
  439. package/src/server/invoke-core-operations.mjs +102 -0
  440. package/src/server/memory-events.mjs +31 -0
  441. package/src/server/plugin-brain-targets.mjs +89 -0
  442. package/src/server/rest.mjs +2 -0
  443. package/src/server/route-inventory.mjs +3 -2
  444. package/src/server/route-manifest.json +47 -55
  445. package/src/server/routes/_shared.mjs +7 -14
  446. package/src/server/routes/brains.mjs +29 -62
  447. package/src/server/routes/context.mjs +0 -41
  448. package/src/server/routes/dashboard.mjs +26 -0
  449. package/src/server/routes/invoke.mjs +26 -1
  450. package/src/server/routes/plugins.mjs +154 -45
  451. package/src/server/routes/ssss.mjs +0 -169
  452. package/src/server/routes/system.mjs +0 -15
  453. package/src/server/routes/tasks.mjs +0 -26
  454. package/src/server/routes/ui-chunks.mjs +192 -0
  455. package/src/server/routes/vault.mjs +2 -23
  456. package/frontend/dist/assets/index-DD4qONvH.js +0 -5607
  457. package/frontend/dist/assets/index-DtwsDyFM.css +0 -1
  458. package/frontend/src/components/plugins/card/CardEngine.tsx +0 -108
  459. package/frontend/src/components/plugins/card/CardScenes.tsx +0 -103
  460. package/frontend/src/components/plugins/card/ExecutionPicker.tsx +0 -64
  461. package/frontend/src/components/plugins/card/args.ts +0 -28
  462. package/frontend/src/components/plugins/card/card.css +0 -32
  463. package/frontend/src/components/plugins/card/cli-line.ts +0 -13
  464. package/frontend/src/components/plugins/card/contract.ts +0 -91
  465. package/frontend/src/components/plugins/card/format.ts +0 -49
  466. package/frontend/src/components/plugins/card/runner-context.ts +0 -11
  467. package/frontend/src/components/plugins/card/runner.tsx +0 -43
  468. package/frontend/src/components/plugins/card/theme.ts +0 -35
  469. package/frontend/src/components/plugins/card/use-source.ts +0 -22
  470. package/frontend/src/components/plugins/card/widgets.tsx +0 -94
  471. package/frontend/src/components/plugins/workspace/WorkspaceHost.tsx +0 -23
  472. package/frontend/src/pages/PluginsPage.tsx +0 -1719
  473. package/scaffold/.agent/skills/plugin/evals/cases/04-card-collects-credential.mjs +0 -47
  474. package/scaffold/.agent/skills/plugin/prompts/06-card.md +0 -46
  475. package/scaffold/.agent/skills/plugin/references/card.md +0 -90
  476. package/scaffold/.agent/skills/plugin/subagents/card-designer.md +0 -60
  477. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/DESIGN.md +0 -67
  478. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/card.js +0 -1179
  479. package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/DESIGN.md +0 -32
  480. package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/card.js +0 -588
  481. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/card.js +0 -575
  482. package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/DESIGN.md +0 -32
  483. package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/card.js +0 -482
  484. package/scaffold/.agent/skills/total-recall/plugins/git-sentinel/README.md +0 -53
  485. package/scaffold/.agent/skills/total-recall/plugins/git-sentinel/plugin.json +0 -129
  486. package/scaffold/.agent/skills/total-recall/plugins/git-sentinel/ui/DESIGN.md +0 -100
  487. package/scaffold/.agent/skills/total-recall/plugins/git-sentinel/ui/card.js +0 -637
  488. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/DESIGN.md +0 -217
  489. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/DESIGN.md +0 -32
  490. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/card.js +0 -1276
  491. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/DESIGN.md +0 -45
  492. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/card.js +0 -1401
  493. package/scaffold/.agent/skills/total-recall/plugins/security/scripts/build-ui.mjs +0 -4
  494. package/scaffold/.agent/skills/total-recall/plugins/security/ui/DESIGN.md +0 -41
  495. package/scaffold/.agent/skills/total-recall/plugins/security/ui/card.js +0 -396
  496. package/scaffold/.agent/skills/total-recall/plugins/security/ui/panel.js +0 -98
  497. package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/DESIGN.md +0 -15
  498. package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/card.js +0 -182
  499. package/src/core/append-log.mjs +0 -131
  500. package/src/core/plugin-tasks.mjs +0 -173
  501. package/templates/onboarding-interview.md +0 -82
  502. /package/scaffold/.agent/skills/total-recall/plugins/{git-sentinel → git}/LICENSE +0 -0
@@ -1,9 +1,8 @@
1
1
  import fs from "node:fs";
2
2
  import path from "node:path";
3
3
  import { spawnSync } from "node:child_process";
4
- import { validatePluginManifest } from "../../core/plugin-loader.mjs";
4
+ import { validatePluginManifest, isCronExpression } from "../../core/plugin-loader.mjs";
5
5
  import { installPlugin } from "../../core/plugin-store.mjs";
6
- import { parseCron } from "../../core/plugin-cron.mjs";
7
6
 
8
7
  function toTitleCase(kebab) {
9
8
  return kebab
@@ -111,13 +110,10 @@ customElements.define('${id}-panel', ${panelClass});
111
110
  }
112
111
 
113
112
  export async function createPlugin(args = []) {
114
- const isGlobal = args.includes("--global") || args.includes("-g");
113
+ // Every plugin is installed in the shared folder; --global is accepted and changes nothing.
115
114
  let withCli = args.includes("--with-cli");
116
115
  const withGenerator = args.includes("--with-generator");
117
- // A card face is bespoke owner code, authored by hand once the plugin's
118
- // function is understood. The scaffold deliberately ships without one, so
119
- // there is nothing to generate here; `--with-ui` is accepted only to explain
120
- // that to anyone who asks for it.
116
+ // The owner authors the native Home after defining the plugin's workflows.
121
117
  const asksForUi = args.includes("--with-ui");
122
118
  const withTask = args.includes("--with-task");
123
119
  const createGithub = args.includes("--github");
@@ -212,7 +208,7 @@ export async function createPlugin(args = []) {
212
208
 
213
209
  if (!id) {
214
210
  console.error("❌ Error: Missing plugin id.");
215
- console.error(" Usage: total-recall plugin create <id> [--from-skill <path>] [--capability] [--name <name>] [--description <desc>] [--category <cat>] [--global]\n");
211
+ console.error(" Usage: total-recall plugin create <id> [--from-skill <path>] [--capability] [--name <name>] [--description <desc>] [--category <cat>]\n");
216
212
  process.exit(1);
217
213
  }
218
214
 
@@ -226,7 +222,7 @@ export async function createPlugin(args = []) {
226
222
  if (!taskCommand || !/^[a-z][a-z0-9-]*$/.test(taskCommand) || !taskSchedule || !taskIntent) {
227
223
  throw new Error('--with-task requires --task-command <subcommand>, --task-schedule "<five-field cron>", and --task-intent <description>');
228
224
  }
229
- parseCron(taskSchedule);
225
+ if (!isCronExpression(taskSchedule)) throw new Error(`--task-schedule must be a five-field cron expression, got "${taskSchedule}"`);
230
226
  } else if (taskCommand || taskSchedule || taskIntent) {
231
227
  throw new Error('--task-* options require --with-task');
232
228
  }
@@ -252,17 +248,15 @@ export async function createPlugin(args = []) {
252
248
  version: "0.1.0",
253
249
  description: pluginDesc,
254
250
  license: "MIT",
255
- // Declares this plugin as a fresh scaffold so it can install before its
256
- // bespoke card face exists. Remove the flag when the face is authored.
251
+ auth: { plugin: "auth", methods: ["passkey", "google-oauth2"], session_verification: true },
252
+ // An unfinished scaffold can install while the owner writes its Home.
257
253
  scaffold: true,
258
254
  // How work reaches this plugin. `preflight coverage` reports it until tasks are written.
259
255
  gate: { tasks: [], owned_commands: [] }
260
256
  };
261
257
  if (useCases.length > 0) manifest.use_cases = useCases;
262
258
 
263
- // House rule: a plugin for a service that needs an API key ships a CLI to save
264
- // it, so it works the moment the key is pasted. Its card face is authored by
265
- // hand later, like every other face.
259
+ // A plugin with a provider credential can save it through the shared Auth CLI.
266
260
  if (apiKeys.length) {
267
261
  withCli = true;
268
262
  manifest.secrets = apiKeys.map((key) => ({ key, description: `${pluginName} service API key (paste it in the plugin UI)`, required: true }));
@@ -302,8 +296,7 @@ export async function createPlugin(args = []) {
302
296
  ]
303
297
  });
304
298
  }
305
- // The card contract reads the plugin's real state through a declared read
306
- // command; a scaffold without this shows no live status.
299
+ // Give the Home a declared read operation for live status.
307
300
  manifest.status = { command: "status", refresh_seconds: 60 };
308
301
 
309
302
  const cliContent = `#!/usr/bin/env node
@@ -359,12 +352,6 @@ export default run;
359
352
  manifest.tasks = [{ intent: taskIntent, schedule: taskSchedule, command: taskCommand, placement: 'selected-node' }];
360
353
  }
361
354
 
362
- // No UI is generated. Every plugin must have a card face, but a face is
363
- // bespoke owner code authored by hand once the plugin's function is known:
364
- // a generated stub is what produced a ecosystem of identical cards. The
365
- // scaffold therefore reports the face as outstanding rather than faking one.
366
- const cardOutstanding = true;
367
-
368
355
  if (isCapability) {
369
356
  manifest.deploy = {
370
357
  targets: ["ssss-app", "nextjs", "react", "flask"],
@@ -446,19 +433,12 @@ export default generateContext;
446
433
  fs.writeFileSync(path.join(pluginDir, "generator.mjs"), generatorContent, "utf8");
447
434
  }
448
435
 
449
- manifest.capability = {
450
- entry: "capability/index.mjs",
451
- exports: ["getCapabilityStatus"]
452
- };
453
-
454
436
  const validation = validatePluginManifest(manifest);
455
437
  if (!validation.valid) {
456
438
  console.error("❌ Validation failed for generated manifest:", validation.errors);
457
439
  fs.rmSync(pluginDir, { recursive: true, force: true });
458
440
  process.exit(1);
459
441
  }
460
- // The scaffold installs without a card face, and says so. Its face is
461
- // authored by hand next; the warning is the reminder, not a failure.
462
442
  if (validation.warnings?.length) {
463
443
  for (const warning of validation.warnings) console.log(`⚠️ ${warning}`);
464
444
  }
@@ -493,7 +473,7 @@ export default generateContext;
493
473
  if (category) lines.push(`- **SSSS Category**: \`${category}\``);
494
474
  if (withCli) lines.push(`- **CLI Command**: \`npx total-recall ${id}\``);
495
475
  if (withTask) lines.push(`- **Scheduled task**: \`${taskCommand}\` at \`${taskSchedule}\` (selected node; implement the command and choose a node before use)`);
496
- if (asksForUi) lines.push('- **UI**: no card face is generated. Author `ui/card.js` and `ui/DESIGN.md` by hand for this plugin\'s own function, then declare the face in `ui.elements[]`');
476
+ if (asksForUi) lines.push('- **UI**: author the plugin workspace and its native panels for this plugin’s own function. Declare the panels in `ui.elements[]`.');
497
477
  if (apiKeys.length) lines.push('- **API key**: paste it in the plugin UI (`save-token` event) or pipe it to `npx total-recall ' + id + ' token set --stdin`; stored as `' + apiKeys[0] + '` in the secrets store');
498
478
  lines.push(
499
479
  "",
@@ -507,6 +487,24 @@ export default generateContext;
507
487
  ""
508
488
  );
509
489
 
490
+ lines.push(
491
+ "## Authoring generative UI",
492
+ "",
493
+ "Keep a bespoke `DESIGN.md` at the plugin root. Describe the palette, typography, layout, interaction and accessibility. Work with the user on the design and assets. Package this file and the authored blocks with the plugin.",
494
+ "",
495
+ "Author one SSSS Markdown document per reusable block at `ui/chunks/<id>.md`. Use `type: ui-chunk:chunk`, the manifest ID as `plugin`, the filename stem as `id`, a `title`, `description`, ISO `timestamp`, meaningful `intents` and supported `surfaces` from `page`, `left`, `right` and `bottom`. Use raw HTML for the body.",
496
+ "",
497
+ "Declare the native workspace entry in `ui.home` and its design in `ui.design_tokens`. Bind each block to exact manifest operation names in `operations` and verified fields in `data` using `operation:/json/pointer`. Declare browser-safe inputs so users can run the operation in place. Use a native `panel` for specialized editable controls. Keep credentials and private data out of routing metadata.",
498
+ "",
499
+ "Find the extension with `total-recall plugin chunks registry` and verify each block with `total-recall plugin chunks validate <file>`. Compare `total-recall plugin chunks coverage --plugin <id>` with the owner inventory. Use `total-recall plugin chunks <intent> --surface <surface>` to find blocks. Add `--decision` to request an explicit typed choice. The result identifies a block by its stable `plugin:id`.",
500
+ "",
501
+ "Keep packaged defaults in the owner repository. Users can choose and arrange installed blocks, provide their own HTML and edit the design with their agent. Submit broadly useful owner changes to the plugin repository.",
502
+ "",
503
+ "An agent can author any additional SSSS block for an enabled plugin. For a task-specific block, use `total-recall plugin chunks add <id.md> --plugin <owner> --brain <brain> --json` to validate and publish it. Read the result back by its stable `owner:id` key.",
504
+ "",
505
+ "For contextual selection, use `total-recall decision compose --plugin <owner> --intent <intent> --page <id> --title <title> --brain <brain>`. For exact placement, use `total-recall plugin chunks page <id> <owner:block>... --title <title> --brain <brain>`. To edit an existing page, read it with the same command without block keys, then pass its complete ordered keys and `--revision <version>` instead of `--title`. Reopen the saved page and verify each workflow against real data.",
506
+ ""
507
+ );
510
508
  fs.writeFileSync(path.join(pluginDir, "README.md"), lines.join("\n"), "utf8");
511
509
 
512
510
  // ── Standalone repository files ──────────────────────────────────────────
@@ -534,34 +532,7 @@ export default generateContext;
534
532
  fs.writeFileSync(path.join(pluginDir, '.gitignore'), 'node_modules/\n.env*\n.agent/skills/total-recall/\ndist/\nreports/\n.DS_Store\nINSTRUCTIONS.md\nAGENTS.md\n', 'utf8');
535
533
  fs.writeFileSync(path.join(pluginDir, 'LICENSE'), mitLicense(holder), 'utf8');
536
534
 
537
- // Capability brick
538
- fs.mkdirSync(path.join(pluginDir, 'capability'), { recursive: true });
539
- fs.writeFileSync(path.join(pluginDir, 'capability', 'index.mjs'), `/**
540
- * Portable capability brick for ${pluginName}.
541
- * Zero host dependencies; pure portable JavaScript.
542
- */
543
- export async function getCapabilityStatus() {
544
- return { ready: true, initialized: true };
545
- }
546
- `, 'utf8');
547
- fs.writeFileSync(path.join(pluginDir, 'capability', 'BRICK.md'), `# ${pluginName} — Capability Brick
548
-
549
- Portable core capability for ${pluginName}.
550
-
551
- ## Exported Functions
552
- - \`getCapabilityStatus()\`: Returns capability readiness and initialization status.
553
- `, 'utf8');
554
-
555
535
  fs.mkdirSync(path.join(pluginDir, 'test'), { recursive: true });
556
- fs.writeFileSync(path.join(pluginDir, 'test', 'capability.test.mjs'), `import test from 'node:test';
557
- import assert from 'node:assert/strict';
558
- import { getCapabilityStatus } from '../capability/index.mjs';
559
-
560
- test('capability brick loads and exports status', async () => {
561
- const status = await getCapabilityStatus();
562
- assert.equal(status.ready, true);
563
- });
564
- `, 'utf8');
565
536
  fs.writeFileSync(path.join(pluginDir, 'test', 'manifest.test.mjs'), `import test from 'node:test';
566
537
  import assert from 'node:assert/strict';
567
538
  import fs from 'node:fs';
@@ -589,7 +560,7 @@ test('every file the manifest references exists', () => {
589
560
  // ── Install: a link to the repo, so the repo is what runs ───────────────
590
561
  let installed = false;
591
562
  if (!skipInstall) {
592
- await installPlugin(pluginDir, { link: true, global: isGlobal, projectRoot: process.cwd() });
563
+ await installPlugin(pluginDir, { link: true, projectRoot: process.cwd() });
593
564
  installed = true;
594
565
  }
595
566
 
@@ -613,7 +584,7 @@ test('every file the manifest references exists', () => {
613
584
  if (withCli) {
614
585
  console.log(` CLI Handler: \x1b[32m${path.join(pluginDir, "cli.mjs")}\x1b[0m`);
615
586
  }
616
- console.log(` Installed: ${installed ? `linked into ${isGlobal ? 'the global' : 'this project\'s'} plugins` : 'no (--no-install)'}`);
587
+ console.log(` Installed: ${installed ? `linked into the shared plugin folder` : 'no (--no-install)'}`);
617
588
  console.log(` GitHub: ${githubUrl || (createGithub ? 'creation failed' : 'not created (re-run with --github, or: gh repo create tr-plugin-' + id + ' --private --source ' + pluginDir + ')')}`);
618
589
  console.log(`\nNext steps:`);
619
590
  console.log(` Test: \x1b[32mcd ${pluginDir} && npm test\x1b[0m`);
@@ -10,6 +10,7 @@ import { getPlugin, getPluginMonetization, globalPluginsDir, projectPluginsDir }
10
10
  import { describePlugin, pruneReplacementArchives, replacementArchiveDir } from '../../core/plugin-store.mjs';
11
11
  import { buildPluginCatalog } from '../../core/plugin-catalog.mjs';
12
12
  import { setPluginActive } from '../../core/plugin-activation.mjs';
13
+ import { detectProjectBrain } from '../../core/brain-locate.mjs';
13
14
 
14
15
  function printHelp() {
15
16
  console.log(`
@@ -26,9 +27,13 @@ Usage:
26
27
  Commands:
27
28
  list Installed plugins (project & global) with source and sharing
28
29
  library [--plugin ID] Installed CLI operation library (--json for agents)
30
+ chunks [query] Search installed SSSS UI chunks and validate owner files
29
31
  refresh Rebuild installed command inventories and instruction surfaces
30
- copies [dir] [--apply] Audit repository copies of shared defaults. --apply deletes only
31
- bundled matches. Add --archive-stale to preserve older differing copies.
32
+ copies [dir] [--apply] Audit repository copies of shared defaults and shadow links. --apply
33
+ deletes bundled matches, unlinks shadows (on/off records are kept)
34
+ and removes install records of plugins installed nowhere.
35
+ Add --archive-stale to preserve older differing copies, and
36
+ --drop-repo-only to delete plugins that exist only in the repository.
32
37
  replacements [--prune] [--keep N] [--project] [--json]
33
38
  Copies kept by install --replace (default: shared folder). Reports
34
39
  the space; --prune keeps the newest N per plugin (default 1) and
@@ -36,6 +41,7 @@ Commands:
36
41
  on <id> / off <id> Enable/disable host execution for this repository alone
37
42
  --all-repos Change the shared setting for every repository
38
43
  --clear Drop this repository's override; follow the shared setting
44
+ on-use <id> Activate when deliberately opened or used in this repository
39
45
  available [query] Plugins bundled with this Total Recall package
40
46
  peers [query] Plugins your mesh peers share (queried live)
41
47
  search <query> Search bundled plugins and mesh peers
@@ -49,7 +55,8 @@ Commands:
49
55
  <path> a local directory
50
56
  --link, -l Symlink a local directory instead of copying
51
57
  --replace Replace an install, retain previous source and restore on failure
52
- --global, -g Install for every project on this machine
58
+ Every plugin installs into the shared folder for all repositories;
59
+ a repository switches it with 'plugin on|off <id>'.
53
60
  update [--check] [--json] Reinstall every plugin whose git repo, mesh peer or source
54
61
  directory moved ahead (--check only reports; also runs hourly
55
62
  in 'update --automatic')
@@ -57,7 +64,7 @@ Commands:
57
64
  unshare <id> Stop offering it
58
65
  publish <id> Publish plugin to the Store and lock release (--no-lock)
59
66
  monetize <id> Configure plugin pricing, period, and payout recipient
60
- remove <id> Uninstall (--global for the machine-wide copy)
67
+ remove <id> Uninstall from the shared folder
61
68
  license <id> [cmd] Check or activate plugin license (status, activate, checkout, verify)
62
69
  info <id> Manifest, provenance, hash and task history
63
70
  vendor <source> [dir] Add a plugin to this project as a brick (default bricks/<id>); the
@@ -71,7 +78,7 @@ Commands:
71
78
  --category <cat> Declare an SSSS memory category
72
79
  --with-cli Generate CLI command handler
73
80
  --with-generator Generate context generator
74
- --with-ui Generate token-driven panel element
81
+ --with-ui Include owner UI authoring instructions
75
82
  --with-task Declare a selected-node scheduled task
76
83
  --task-command <cmd> Task CLI subcommand (requires --with-task)
77
84
  --task-schedule <cron> Five-field local-time schedule
@@ -80,10 +87,10 @@ Commands:
80
87
 
81
88
  Examples:
82
89
  npx total-recall plugin available --use-case software-development
83
- npx total-recall plugin install git-sentinel
84
- npx total-recall plugin share git-sentinel
90
+ npx total-recall plugin install git
91
+ npx total-recall plugin share git
85
92
  npx total-recall plugin peers
86
- npx total-recall plugin install peer:mac-mini/git-sentinel
93
+ npx total-recall plugin install peer:mac-mini/git
87
94
  npx total-recall plugin create reading-list --use-case research --with-cli
88
95
  `);
89
96
  }
@@ -112,33 +119,41 @@ export async function run(argv = []) {
112
119
  if (!result.ok || !setup.ok) process.exitCode = 1;
113
120
  return;
114
121
  }
115
- if (command === 'on' || command === 'off') {
122
+ if (['on', 'off', 'on-use'].includes(command)) {
123
+ const projectRoot = detectProjectBrain(process.cwd())?.projectRoot ?? process.cwd();
116
124
  const id = rest.find(argument => !argument.startsWith('-'));
117
125
  if (!id) throw new Error(`Usage: total-recall plugin ${command} <id> [--all-repos|--clear]`);
118
126
  const flags = rest.filter(argument => argument.startsWith('-'));
127
+ if (command === 'on-use' && flags.some(flag => flag !== '--json')) throw new Error('Use on-use for one repository without --all-repos or --clear.');
119
128
  const unknown = flags.find(flag => !['--all-repos', '--clear', '--json'].includes(flag));
120
129
  if (unknown) throw new Error(`Unsupported plugin ${command} option: ${unknown}`);
121
130
  if (flags.includes('--all-repos') && flags.includes('--clear')) throw new Error('Choose --all-repos or --clear, not both');
122
131
  if (flags.includes('--clear')) {
123
132
  if (command === 'off') throw new Error('--clear removes a repository override; use it with on, not off');
124
- const cleared = await setPluginActive(id, true, { clear: true });
133
+ const cleared = await setPluginActive(id, true, { clear: true, projectRoot });
125
134
  const activation = cleared.activation || {};
126
135
  console.log(flags.includes('--json') ? JSON.stringify(cleared)
127
136
  : `♻️ ${id} follows the shared setting again in this repository (${activation.state || 'unknown'})`);
128
137
  if (!cleared.compilation.ok) process.exitCode = 1;
129
138
  return;
130
139
  }
131
- const result = await setPluginActive(id, command === 'on', { scope: flags.includes('--all-repos') ? 'shared' : 'project' });
140
+ const result = await setPluginActive(id, command === 'on-use' ? command : command === 'on', { projectRoot, scope: flags.includes('--all-repos') ? 'shared' : 'project' });
132
141
  const activation = result.activation || {};
133
142
  if (flags.includes('--json')) console.log(JSON.stringify(result));
134
- else console.log(`${command === 'on' ? '✅' : '⛔'} ${id} ${command === 'on' ? 'enabled' : 'disabled'} for ${result.scope === 'shared' ? 'every repository' : 'this repository'} (${activation.state || 'unknown'})`);
135
- if (!result.compilation.ok) process.exitCode = 1;
143
+ else if (command === 'on-use') console.log(`${id} will activate on use in this repository.`);
144
+ else {
145
+ console.log(`${command === 'on' ? '✅' : '⛔'} ${id} ${command === 'on' ? 'enabled' : 'disabled'} for ${result.scope === 'shared' ? 'every repository' : 'this repository'} (${activation.state || 'unknown'})`);
146
+ if (result.cleanup?.state === 'archived') console.log('Repository plugin state archived.');
147
+ if (result.cleanup?.state === 'restored') console.log('Repository plugin state restored.');
148
+ if (result.cleanup?.ok === false) console.error(`Cleanup pending. ${result.cleanup.error}`);
149
+ }
150
+ if (!result.compilation.ok || result.cleanup?.ok === false) process.exitCode = 1;
136
151
  return;
137
152
  }
138
153
 
139
- if (command === 'card' || command === 'card-face' || command === 'skin') {
140
- await managePluginCard(rest);
141
- return;
154
+ if (command === 'chunks') {
155
+ const { runPluginChunks } = await import('./chunks.mjs');
156
+ return runPluginChunks(rest);
142
157
  }
143
158
 
144
159
  if (rest.includes('--help') || rest.includes('-h')) {
@@ -2,18 +2,22 @@ import { installPlugin as install } from '../../core/plugin-distribution.mjs';
2
2
  import { syncPluginCommands } from '../command.mjs';
3
3
 
4
4
  export async function installPlugin(args = []) {
5
- const isGlobal = args.includes('--global') || args.includes('-g');
5
+ // Every plugin installs into the shared folder; `--global` is accepted and changes nothing.
6
6
  const isLink = args.includes('--link') || args.includes('-l');
7
7
  const source = args.find(a => !a.startsWith('-'));
8
8
 
9
+ if (args.includes('--project')) {
10
+ console.error("❌ Plugins are installed only in the shared folder. In a repository, switch one with 'total-recall plugin on|off <id>'.");
11
+ process.exit(1);
12
+ }
9
13
  if (!source) {
10
14
  console.error('❌ Error: Missing plugin source.');
11
- console.error(' Usage: total-recall plugin install <bundled-id | share-link | peer:<host>/<id> | git-url | path> [--link] [--global]\n');
15
+ console.error(' Usage: total-recall plugin install <bundled-id | share-link | peer:<host>/<id> | git-url | path> [--link]\n');
12
16
  process.exit(1);
13
17
  }
14
18
 
15
19
  try {
16
- const result = await install(source, { projectRoot: process.cwd(), global: isGlobal, link: isLink, replace:args.includes('--replace') });
20
+ const result = await install(source, { projectRoot: process.cwd(), link: isLink, replace:args.includes('--replace') });
17
21
  const from = result.source.kind === 'peer' ? `peer ${result.source.peer_hostname}` : result.source.kind;
18
22
  console.log(`\n✅ Installed '${result.plugin.name}' (id: ${result.plugin.id}, v${result.plugin.version}) from ${from}`);
19
23
  console.log(` Location: ${result.plugin.dir}`);
@@ -24,7 +28,7 @@ export async function installPlugin(args = []) {
24
28
  } else if (result.dependencies?.reason && !['no package.json', 'no dependencies declared'].includes(result.dependencies.reason)) {
25
29
  console.log(` Dependencies: NOT installed (${result.dependencies.reason})`);
26
30
  }
27
- const cmds = syncPluginCommands(result.plugin.dir, { global: isGlobal });
31
+ const cmds = syncPluginCommands(result.plugin.dir, { global: true });
28
32
  if (cmds.created.length) console.log(` Commands: ${cmds.created.map((c) => `total-recall ${c}`).join(', ')}`);
29
33
  for (const c of cmds.skipped) console.log(` Skipped command '${c.name}': ${c.reason}`);
30
34
  console.log('');
@@ -34,17 +38,8 @@ export async function installPlugin(args = []) {
34
38
  return;
35
39
  }
36
40
  const { autoCompileSurfaces } = await import('../../core/auto-compile.mjs');
37
- // Compile the layer the plugin actually landed in. `scope` is not enough on
38
- // its own: from a directory with no project brain, projectPluginsDir(cwd)
39
- // resolves to the global plugins dir, so a plugin installed into the global
40
- // brain still reports scope 'project'. Ask the resolver whether a project
41
- // brain exists at all, and otherwise fall back to the global layer — the one
42
- // that was really written. Assuming 'project' compiled nothing and printed
43
- // "Auto-compile failed: No project brain found" after a successful install.
44
- const { resolveBrainDir } = await import('../agent-dir.mjs');
45
- let targetLayer = 'global';
46
- try { resolveBrainDir('project'); targetLayer = 'project'; } catch { targetLayer = 'global'; }
47
- if (!await autoCompileSurfaces({ layer: targetLayer, semantic: false, force: true })) process.exitCode = 1;
41
+ // The plugin landed in the shared folder, so the global layer is the one to compile.
42
+ if (!await autoCompileSurfaces({ layer: 'global', semantic: false, force: true })) process.exitCode = 1;
48
43
  } catch (err) {
49
44
  console.error(`❌ ${err.message}`);
50
45
  process.exit(1);
@@ -8,7 +8,7 @@ export async function removePlugin(args = []) {
8
8
 
9
9
  if (!id) {
10
10
  console.error('❌ Error: Missing plugin ID to remove.');
11
- console.error(' Usage: total-recall plugin remove <id> [--global]\n');
11
+ console.error(' Usage: total-recall plugin remove <id>\n');
12
12
  process.exit(1);
13
13
  }
14
14
 
@@ -22,7 +22,7 @@ function parseArgs(args) {
22
22
  * `includes` makes a short query match inside unrelated words: searching "git"
23
23
  * returned the signing plugin, whose description begins "Digital agreement…".
24
24
  * A hit inside a word is only accepted at a word start so that real substrings
25
- * still work ("sent" finds "git-sentinel") without matching "digital".
25
+ * still work ("qual" finds "code-quality") without matching "digital".
26
26
  */
27
27
  function matches(p, query, useCase) {
28
28
  if (useCase && !(p.use_cases || []).includes(useCase)) return false;
@@ -32,7 +32,7 @@ function matches(p, query, useCase) {
32
32
  const words = query.split(/\s+/).filter(Boolean);
33
33
  return words.every((word) => {
34
34
  const escaped = word.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
35
- // Anchor at a word start so "sent" matches "git-sentinel" but "git" does
35
+ // Anchor at a word start so "qual" matches "code-quality" but "git" does
36
36
  // not match "digital".
37
37
  const bounded = new RegExp(`(^|[^a-z0-9])${escaped}`, 'i');
38
38
  return haystacks.some((h) => bounded.test(h) || h.startsWith(word));
@@ -1,16 +1,18 @@
1
1
  import { spawnSync } from 'node:child_process';
2
2
  import fs from 'node:fs';
3
3
  import path from 'node:path';
4
+ import { ensureDependencies } from '../core/ensure-dependencies.mjs';
4
5
  import { detectProjectBrain } from '../core/brain-locate.mjs';
5
6
  import { globalBrainDirFor, isBrainEnabled } from '../core/brain-registry.mjs';
6
7
  import { GATE_MODES, gateConfigPath, projectBrainDir, readGateLayers, resolveGateMode, writeGateMode } from '../core/gate-mode.mjs';
7
8
  import { installHarnessHooks, loadGateAdapters } from '../core/harness-hooks.mjs';
8
- import { ackDirectory, capsuleVerb, decide, isAckCommand, isCheckCommand, isRouteCommand, isSubagentPayload, nativeToolOf, sessionOf, SWEEP_CONSULT_MS, whenGateFails } from '../core/preflight-gate.mjs';
9
+ import { ackDirectory, capsuleVerb, decide, gatePackageBroken, isAckCommand, isCheckCommand, isRouteCommand, isSubagentPayload, nativeToolOf, sessionOf, SWEEP_CONSULT_MS, whenGateFails } from '../core/preflight-gate.mjs';
9
10
  import { ACK_COMMAND, acknowledge, checkAgentReceipt, checkAnyReceipt, findRoot, forgetCapsuleDeliveries, lastArrivalMs, lastCapsuleDelivery, lastConsultMs, lastRoutedMs, lastRouteWarnedMs, lastSessionAck, markArrival, markDelegated, markRouted, markRouteWarned, markSessionAck, noteCaller, recordDecision, sessionHasStanding, sessionKey, readDecisions, takeCaller } from '../core/preflight-receipt.mjs';
10
11
 
11
12
  const USAGE = `Usage: total-recall preflight <command>
12
13
  ack --task "<task>" [--action read,edit,test] [--json] Record a receipt after context ready:true and rules verify, and print the capsule.
13
14
  Prints one line instead when this session received the same rules and skills within 2 hours
15
+ Restores missing or stale locked dependencies for edit/test actions
14
16
  check [--json] Exit 1 unless a fresh receipt covers this agent, wherever it acknowledged.
15
17
  Run by hand, it reports this directory's receipt
16
18
  gate [--harness <id>] Hook entry: read a call on stdin, answer allow or deny (exit 2 on deny)
@@ -81,12 +83,23 @@ async function ack(args) {
81
83
  const task = flag(args, '--task') || '';
82
84
  const actions = flag(args, '--action') || 'read,edit,test';
83
85
  const result = acknowledge({ root, task, actions, maxAgeMs: await configuredMaxAgeMs(), session: takeCaller(root, 'ack', { task }) });
86
+ const needsDependencies = actions.split(',').some(action => ['edit', 'test'].includes(action.trim()));
87
+ const dependencies = result.ok && needsDependencies ? await ensureDependencies(root, { reason: `preflight:${actions}` }) : null;
88
+ const ok = result.ok && dependencies?.ok !== false;
84
89
  if (args.includes('--json')) {
85
- console.log(JSON.stringify({ ok: result.ok, problems: result.problems, receipt: result.file || null, capsule: result.capsule ?? null, unchanged: Boolean(result.unchanged) }));
86
- if (!result.ok) process.exitCode = 1;
90
+ console.log(JSON.stringify({ ok, problems: [...result.problems, ...(dependencies?.ok === false ? [`dependencies: ${dependencies.error}`] : [])], receipt: result.file || null, capsule: result.capsule ?? null, unchanged: Boolean(result.unchanged), dependencies }));
91
+ if (!ok) process.exitCode = 1;
87
92
  return;
88
93
  }
89
94
  if (!result.ok) return printFailure(result.problems);
95
+ if (dependencies) {
96
+ const detail = dependencies.ok ? (dependencies.command?.join(' ') || dependencies.trigger) : dependencies.error;
97
+ console.log(` dependencies: ${dependencies.status} — ${detail}`);
98
+ if (!dependencies.ok) {
99
+ console.error('✖ Dependency install failed. Repair dependencies before edit or test work. The instruction receipt is recorded.');
100
+ process.exitCode = 1;
101
+ }
102
+ }
90
103
  if (result.unchanged) {
91
104
  const age = result.unchanged.ageMs < 60000 ? 'less than a minute ago' : `${Math.round(result.unchanged.ageMs / 60000)} minutes ago`;
92
105
  console.log(`✔ tr-preflight recorded: rules and skills are unchanged since this session received the capsule ${age}, so there is nothing new to read. If your task is new, or you no longer have the capsule, run: total-recall context "<task>" --action ${actions}`);
@@ -398,6 +411,8 @@ function evaluate(call, options = {}) {
398
411
  }
399
412
 
400
413
  function judge(call, { harness, readablePaths, session = null, subagent = false, nativeTool = null } = {}) {
414
+ const broken = gatePackageBroken();
415
+ if (broken) return whenGateFails(call, new Error(broken));
401
416
  const root = findRoot(call.cwd || process.cwd());
402
417
  const limit = envMaxAgeMs();
403
418
  const declared = readGateDeclarations();
@@ -584,12 +599,10 @@ async function mode(args) {
584
599
 
585
600
  export default async function preflight(args = []) {
586
601
  const [first = '--help'] = args;
587
- if (first === '--help' || first === '-h' || first === 'help') return console.log(USAGE);
602
+ if (first === '--help' || first === '-h' || first === 'help' || args.includes('--help') || args.includes('-h')) return console.log(USAGE);
588
603
  // Original `tr-preflight` forms.
589
604
  if (first === '--ack' || first === 'ack') return ack(args);
590
605
  if (first === '--check' || first === 'check') return check(args);
591
- // Help never performs the subcommand: `install --help` once rewrote the harness settings (C-019).
592
- if (args.includes('--help') || args.includes('-h')) return console.log(USAGE);
593
606
  if (first === 'gate') return gate(args.slice(1));
594
607
  if (first === 'remind') return remind(args);
595
608
  if (first === 'session-start') return sessionStart();
@@ -208,7 +208,7 @@ export default async function proposals(args) {
208
208
  console.log(` ${String(days).padStart(4)}d [i${n.importance}] ${n.slug}`);
209
209
  }
210
210
  if (stale.length > 40) console.log(`\n … and ${stale.length - 40} more.`);
211
- console.log('\n The dream cycle queues these for research automatically.\n');
211
+ console.log('\n This query is read-only. Request research explicitly for a node that needs verification.\n');
212
212
  return;
213
213
  }
214
214
 
@@ -1,5 +1,22 @@
1
1
  import { resolveAgentDir, resolveBrainDir, parseLayerFlag, getBothBrains } from './agent-dir.mjs';
2
2
  import path from 'node:path';
3
+ import fs from 'node:fs';
4
+
5
+ /** One brain search shared by recall and paired evaluation. Does not record access. */
6
+ export async function searchRecallBrain(query, { semantic = false, forceFast = false, field = false, ...options } = {}) {
7
+ let rankResults = null;
8
+ if (field) {
9
+ const { loadField, rankWithField } = await import('../core/vector-field.mjs');
10
+ const compiled = loadField(options.derivedDir);
11
+ if (!compiled) throw new Error('Vector field missing or corrupt. Run total-recall recall --compile-field first.');
12
+ rankResults = results => rankWithField(results, { field: compiled, derivedDir: options.derivedDir });
13
+ }
14
+ const { fastSearch } = await import('../core/fast-recall.mjs');
15
+ const fastResults = fastSearch(query, { ...options, fullText: !forceFast, rankResults });
16
+ if (!semantic || fastResults.some(result => (result.base_score ?? result.score) === 1) || forceFast) return fastResults;
17
+ const { semanticSearch } = await import('../core/search.mjs');
18
+ return semanticSearch(query, { ...options, rankResults });
19
+ }
3
20
 
4
21
  function printHelp() {
5
22
  console.log(`
@@ -20,8 +37,18 @@ function printHelp() {
20
37
  --fast Force frontmatter-only search without semantic fallback
21
38
  --local Search indexed body text without a provider (default)
22
39
  --semantic Opt into semantic enrichment
40
+ --field Re-rank candidates with the compiled field (opt-in, local)
41
+ --compile-field Compile existing embeddings into the selected brain's field
42
+ --evaluate-field <file> Compare local recall with/without field on fixed JSON queries
23
43
  --timings Print local stage timings on stderr
24
44
 
45
+ Field operations (support --project/--global, --top-k, --format):
46
+ total-recall recall --compile-field --project
47
+ total-recall recall --evaluate-field queries.json --project --format json
48
+ Query file: [{ "query": "search terms", "relevant": ["expected-slug"] }]
49
+ Overlap@k = shared slugs / k. Hit rate@k = queries with a relevant slug / queries.
50
+ Evaluation does not record access. It uses local recall and requires a compiled field.
51
+
25
52
  Examples:
26
53
  npx total-recall recall "Never run tsc directly"
27
54
  npx total-recall recall "Express server port" --top-k 3
@@ -55,6 +82,7 @@ export default async function recall(args) {
55
82
  let forceFast = false;
56
83
  let semantic = false;
57
84
  let timings = false;
85
+ let field = false;
58
86
 
59
87
  for (let i = 1; i < remainingArgs.length; i++) {
60
88
  const arg = remainingArgs[i];
@@ -111,8 +139,11 @@ export default async function recall(args) {
111
139
  semantic = false;
112
140
  } else if (arg === '--timings') {
113
141
  timings = true;
142
+ } else if (arg === '--field') {
143
+ field = true;
114
144
  }
115
145
  }
146
+ top_k = Math.max(1, Math.min(20, top_k));
116
147
 
117
148
  // Determine which brains to search
118
149
  const brains = getBothBrains();
@@ -152,6 +183,26 @@ export default async function recall(args) {
152
183
  }
153
184
 
154
185
  try {
186
+ if (query === '--compile-field' || query === '--evaluate-field') {
187
+ const reports = [];
188
+ const cases = query === '--evaluate-field'
189
+ ? JSON.parse(fs.readFileSync(remainingArgs[1], 'utf8')) : null;
190
+ for (const target of searchTargets) {
191
+ const options = { vaultDir: path.join(target.brainDir, 'memory-vault'),
192
+ derivedDir: path.join(target.brainDir, 'memory-derived'), top_k, includeSessions: false };
193
+ if (query === '--evaluate-field') {
194
+ const { evaluateField } = await import('../core/field-evaluation.mjs');
195
+ reports.push({ brain: target.label, ...await evaluateField(cases, {
196
+ topK: top_k, search: (q, enabled) => searchRecallBrain(q, { ...options, field: enabled }),
197
+ }) });
198
+ } else {
199
+ const { compileField } = await import('../core/vector-field.mjs');
200
+ reports.push({ brain: target.label, ...(await compileField(options)).meta });
201
+ }
202
+ }
203
+ console.log(JSON.stringify(reports, null, 2));
204
+ return;
205
+ }
155
206
  // Search all target brains and merge results
156
207
  let allResults = [];
157
208
  let isDegraded = false;
@@ -164,8 +215,7 @@ export default async function recall(args) {
164
215
 
165
216
  try {
166
217
  let results = [];
167
- const { fastSearch } = await import('../core/fast-recall.mjs');
168
- const fastResults = fastSearch(query, {
218
+ results = await searchRecallBrain(query, {
169
219
  derivedDir,
170
220
  vaultDir,
171
221
  top_k,
@@ -174,28 +224,12 @@ export default async function recall(args) {
174
224
  modality,
175
225
  importance,
176
226
  priority,
177
- fullText: !forceFast,
227
+ forceFast, semantic, field,
228
+ includeSessions: includeSessions && target.label !== 'global',
178
229
  });
179
- if (timings) console.error(JSON.stringify({ brain: target.label, ...fastResults.stats }));
180
- if (['missing', 'corrupt', 'metadata-only'].includes(fastResults.stats.index) && !forceFast) {
181
- console.error(`Local full-text index for ${target.label}: ${fastResults.stats.index}. Run total-recall compile to rebuild; available metadata results may be incomplete.`);
182
- }
183
-
184
- if (!semantic || fastResults.some(result => result.score === 1) || forceFast) {
185
- results = fastResults;
186
- } else {
187
- const { semanticSearch } = await import('../core/search.mjs');
188
- results = await semanticSearch(query, {
189
- vaultDir,
190
- derivedDir,
191
- top_k,
192
- includeSessions: includeSessions && target.label !== 'global', // sessions only in project/local
193
- category,
194
- tags,
195
- modality,
196
- importance,
197
- priority
198
- });
230
+ if (timings) console.error(JSON.stringify({ brain: target.label, ...results.stats }));
231
+ if (['missing', 'corrupt', 'metadata-only'].includes(results.stats?.index) && !forceFast) {
232
+ console.error(`Local full-text index for ${target.label}: ${results.stats.index}. Run total-recall compile to rebuild; available metadata results may be incomplete.`);
199
233
  }
200
234
  if (results.degradedTextSearch) {
201
235
  isDegraded = true;
@@ -226,6 +260,15 @@ export default async function recall(args) {
226
260
  allResults.sort((a, b) => (b.score || 0) - (a.score || 0));
227
261
  allResults = allResults.slice(0, top_k);
228
262
 
263
+ // DECAY-01: a recalled memory is a used memory; record it in the brain it came from.
264
+ try {
265
+ const { recordAccess } = await import('../core/access-ledger.mjs');
266
+ for (const target of searchTargets) {
267
+ const slugs = allResults.filter(r => r._layer === target.label).map(r => r.slug || r.id).filter(Boolean);
268
+ recordAccess(path.join(target.brainDir, 'memory-derived'), slugs);
269
+ }
270
+ } catch { /* access accounting never breaks recall */ }
271
+
229
272
  if (format === 'json') {
230
273
  for (const error of searchErrors) console.error(`Search failed for ${error.label}: ${error.message.split('\n')[0]}`);
231
274
  if (searchErrors.length && !allResults.length) process.exitCode = 1;