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
@@ -3,7 +3,8 @@ import fs from "node:fs";
3
3
  import path from "node:path";
4
4
  import matter from "../../core/frontmatter.mjs";
5
5
  import { requireAuth, requireScope } from "../auth.mjs";
6
- import { getPluginById } from "../../core/plugin-loader.mjs";
6
+ import { resolvePluginBrainTargets } from '../plugin-brain-targets.mjs';
7
+ import { discoverPlugins, getPluginById } from "../../core/plugin-loader.mjs";
7
8
  import {
8
9
  listInstalledPlugins,
9
10
  listAvailableBundled,
@@ -18,20 +19,25 @@ import {
18
19
  import { listPeerPlugins } from "../../core/plugin-peers.mjs";
19
20
  import { runPluginCommand, validatePluginSecretInput } from "../../core/plugin-runner.mjs";
20
21
  import { readPluginRecord, patchPluginRecord, emit, vaultFor } from '../../core/plugin-store.mjs';
21
- import { setPluginActive } from '../../core/plugin-activation.mjs';
22
+ import { activatePluginOnUse, setPluginActive } from '../../core/plugin-activation.mjs';
22
23
  import { pluginActivation } from '../../core/plugin-state.mjs';
24
+ import { REQUIRED_INSTALLATION_PLUGIN_IDS } from '../../core/default-plugins.mjs';
23
25
  import { configurationValues } from '../../core/plugin-contracts/configuration.mjs';
24
26
  import { writeNodeValidatedAsync } from "../../core/validated-write.mjs";
25
27
  import { walkMd } from "../../core/vault.mjs";
26
28
  import { serverError, badRequest, VAULT_DIR, BRAIN_DIR, globalBrainDir, sanitizeNode } from "./_shared.mjs";
27
29
 
28
30
  const router = Router();
31
+ let activationTail = Promise.resolve();
29
32
 
30
- // Plugins always resolve against the server's own project. Routes used to take
31
- // a caller-supplied `root`, which let a request point discovery — and the
32
- // runner — at any directory on disk.
33
+ // Omitted selectors use the serving project. Explicit selectors resolve only
34
+ // through registered brains, without accepting host paths from a request.
33
35
  const projectRoot = () => process.cwd();
34
36
 
37
+ function surfaceTarget(req, id) {
38
+ return id === undefined ? { brainDir: BRAIN_DIR, projectRoot: projectRoot() } : resolvePluginBrainTargets([id], req.auth)[0];
39
+ }
40
+
35
41
  router.get('/api/plugins/execution-targets', requireAuth, requireScope('config:read'), async (req, res) => {
36
42
  try {
37
43
  const { loadPluginModule } = await import('../../core/plugin-runtime.mjs');
@@ -43,19 +49,81 @@ router.get('/api/plugins/execution-targets', requireAuth, requireScope('config:r
43
49
 
44
50
  router.put('/api/plugins/:id/activation', requireAuth, requireScope('config:write'), async (req, res) => {
45
51
  try {
46
- const result = await setPluginActive(req.params.id, req.body?.enabled, { projectRoot: projectRoot() });
47
- res.status(result.compilation.ok ? 200 : 500).json({ success: result.compilation.ok, ...result });
48
- } catch (err) { badRequest(res, err.message); }
52
+ const { enabled, brainIds, mode } = req.body || {};
53
+ if (req.query.brain !== undefined || req.body?.brainId !== undefined) {
54
+ return badRequest(res, 'Use the brainIds array to target plugin activation.');
55
+ }
56
+ if (mode === undefined && typeof enabled !== 'boolean') return badRequest(res, 'Plugin activation requires a boolean');
57
+ if (mode !== undefined && (enabled !== undefined || !['on-use', 'use'].includes(mode) ||
58
+ !Array.isArray(brainIds) || (mode === 'use' && brainIds.length !== 1))) {
59
+ return badRequest(res, 'On use requires project brain IDs. Opening a plugin requires one project brain ID.');
60
+ }
61
+ // Global changes rebuild project surfaces too, so serialize writes and rebuilds together.
62
+ const change = activationTail.then(async () => {
63
+ if (brainIds === undefined) {
64
+ const result = await setPluginActive(req.params.id, enabled, { projectRoot: projectRoot() });
65
+ const cleanup = reportedCleanup(result);
66
+ const success = result.compilation.ok && cleanup?.ok !== false;
67
+ return { status: success ? 200 : 500, body: { ...result, success, cleanup, ...(cleanup?.error ? { error: cleanup.error } : {}) } };
68
+ }
69
+ const targets = resolvePluginBrainTargets(brainIds, req.auth);
70
+ if (mode && targets.some(target => target.projectRoot === null)) {
71
+ return { status: 400, body: { error: 'On use is available for individual project brains.' } };
72
+ }
73
+ const results = [];
74
+ for (const target of targets) {
75
+ results.push(await updateSelectedPluginActivation(req.params.id, enabled, mode, target));
76
+ }
77
+ return { status: 200, body: { success: results.every(result => result.success), results } };
78
+ });
79
+ activationTail = change.catch(() => {});
80
+ const { status, body } = await change;
81
+ res.status(status).json(body);
82
+ } catch (err) { res.status(err.status || 400).json({ error: err.message }); }
49
83
  });
50
84
 
85
+ function reportedCleanup(result) {
86
+ if (!result.cleanup) return undefined;
87
+ const { ok, state } = result.cleanup;
88
+ return { ok, state, ...(ok ? {} : { error: 'The plugin is off, but cleanup did not finish. Retry cleanup.' }) };
89
+ }
90
+
91
+ async function updateSelectedPluginActivation(id, enabled, mode, { brainId, name, projectRoot }) {
92
+ const identity = { brainId, name };
93
+ const failure = error => ({ ...identity, success: false, error });
94
+ try {
95
+ const plugin = getPluginById(id, projectRoot);
96
+ if (!plugin?.valid) return failure('Plugin is unavailable in this brain.');
97
+ if ((enabled === false || mode === 'on-use') && REQUIRED_INSTALLATION_PLUGIN_IDS.includes(id)) {
98
+ return failure('Required plugins cannot be disabled.');
99
+ }
100
+ const result = mode === 'use'
101
+ ? await activatePluginOnUse(id, { projectRoot })
102
+ : await setPluginActive(id, mode ?? enabled, { projectRoot, scope: projectRoot === null ? 'shared' : 'project' });
103
+ if (!result) {
104
+ const activation = pluginActivation(plugin, { projectRoot });
105
+ return activation.enabled ? { ...identity, success: true, activation } : failure('This plugin is not set to open on use.');
106
+ }
107
+ if (mode === 'use' && !result.activation.enabled) return failure('The plugin was switched off before it could open.');
108
+ const cleanup = reportedCleanup(result);
109
+ const error = cleanup?.error || (result.compilation.ok ? undefined : 'Activation was saved, but the workspace could not be rebuilt.');
110
+ return { ...identity, success: !error, activation: result.activation, cleanup, error };
111
+ } catch {
112
+ return failure('Could not complete activation in this brain.');
113
+ }
114
+ }
115
+
51
116
  router.post('/api/plugins/:id/credentials', requireAuth, requireScope('config:write'), async (req, res) => {
117
+ let target;
118
+ try { target = surfaceTarget(req, req.query.brain); }
119
+ catch (error) { return res.status(error.status || 400).json({ error: 'Could not select the credential workspace.' }); }
52
120
  try {
53
- const plugin = getPluginById(req.params.id, projectRoot());
121
+ const plugin = getPluginById(req.params.id, target.projectRoot);
54
122
  if (!plugin) return res.status(404).json({ error: 'Plugin not installed' });
55
123
  const { key, value } = req.body || {};
56
124
  if (typeof key !== 'string' || typeof value !== 'string' || value.length > 16384 || !plugin.manifest.secrets?.some(secret => secret.key === key)) return badRequest(res, 'Invalid declared credential');
57
125
  const { loadPluginModule } = await import('../../core/plugin-runtime.mjs');
58
- const owner = await loadPluginModule(plugin.id, 'credentials');
126
+ const owner = await loadPluginModule(plugin.id, 'credentials', { projectRoot: target.projectRoot });
59
127
  const result = await owner.saveCredential({ key, value, configuration: readPluginRecord(plugin)?.configuration || {}, brainDir: process.env.TR_SECRETS_BRAIN || globalBrainDir || BRAIN_DIR });
60
128
  res.json(result);
61
129
  } catch (error) {
@@ -86,15 +154,21 @@ router.put('/api/plugins/:id/configuration', requireAuth, requireScope('config:w
86
154
  /** Serve only modules declared by an installed plugin's UI manifest. */
87
155
  router.get('/api/plugins/:id/ui/:element', requireAuth, requireScope('config:read'), (req, res) => {
88
156
  try {
89
- const plugin = getPluginById(req.params.id, projectRoot());
90
- if (!plugin?.valid) return res.status(404).json({ error: 'Plugin unavailable' });
157
+ const target = surfaceTarget(req, req.query.brain);
158
+ const plugin = getPluginById(req.params.id, target.projectRoot);
159
+ if (!plugin?.valid || (req.query.brain !== undefined && !pluginActivation(plugin, target).enabled)) {
160
+ return res.status(404).json({ error: 'Plugin unavailable' });
161
+ }
91
162
  const element = plugin.manifest?.ui?.elements?.find((item) => item.id === req.params.element);
92
163
  if (!element) return res.status(404).json({ error: 'UI element unavailable' });
93
164
  const root = fs.realpathSync(plugin.dir);
94
165
  const file = fs.realpathSync(path.resolve(root, element.module));
95
166
  if (!file.startsWith(root + path.sep)) return res.status(400).json({ error: 'Invalid UI module path' });
96
167
  res.type('text/javascript').set('X-Content-Type-Options', 'nosniff').send(fs.readFileSync(file, 'utf8'));
97
- } catch (err) { serverError(res, err); }
168
+ } catch (err) {
169
+ if ([400, 403, 404, 409, 503].includes(err.status)) return res.status(err.status).json({ error: err.message });
170
+ serverError(res, err);
171
+ }
98
172
  });
99
173
 
100
174
  /** Serve only the logo a plugin declares in branding.logo, never an arbitrary file. */
@@ -121,15 +195,45 @@ router.get('/api/plugins/:id/logo', requireAuth, requireScope('config:read'), (r
121
195
  * Installed plugins (project + global): manifest facts, provenance, content
122
196
  * hash, sharing state and scheduled-task history. Nothing else.
123
197
  */
124
- router.get("/api/plugins", requireAuth, requireScope("config:read"), (_req, res) => {
198
+ router.get("/api/plugins", requireAuth, requireScope("config:read"), (req, res) => {
125
199
  try {
126
- const plugins = listInstalledPlugins(projectRoot());
200
+ const selection = req.query.brain;
201
+ if (selection !== undefined && typeof selection !== 'string') return badRequest(res, 'Use one comma-separated brain selector.');
202
+ const plugins = selection === undefined
203
+ ? listInstalledPlugins(projectRoot())
204
+ : selectedPluginInventory(resolvePluginBrainTargets(selection.split(','), req.auth));
127
205
  res.json({ success: true, count: plugins.length, plugins });
128
206
  } catch (err) {
207
+ if (err.status) return res.status(err.status).json({ error: err.message });
129
208
  serverError(res, err);
130
209
  }
131
210
  });
132
211
 
212
+ function selectedPluginInventory(targets) {
213
+ const descriptions = new Map();
214
+ const serving = new Map(discoverPlugins(projectRoot()).map(plugin => [plugin.id, plugin]));
215
+ const catalogs = targets.map(target => new Map(
216
+ listInstalledPlugins(target.projectRoot, { descriptions }).map(plugin => [plugin.id, plugin]),
217
+ ));
218
+ const ids = new Set(catalogs.flatMap(catalog => [...catalog.keys()]));
219
+ return [...ids].map(id => {
220
+ const entries = catalogs.map(catalog => catalog.get(id));
221
+ const representative = entries.find(plugin => plugin?.valid) || entries.find(Boolean);
222
+ const activationByBrain = entries.map((plugin, index) => {
223
+ const { brainId, name } = targets[index];
224
+ const state = !plugin ? 'unavailable' : !plugin.valid ? 'error' : (plugin.activation?.state || 'error');
225
+ const mode = state === 'inactive' && plugin.activation?.mode;
226
+ return { brainId, name, state, enabled: state === 'active', required: !!plugin?.activation?.required, ...(mode ? { mode } : {}) };
227
+ });
228
+ const first = activationByBrain[0];
229
+ const state = activationByBrain.every(item => item.state === first.state && item.mode === first.mode) ? first.state : 'mixed';
230
+ const activation = { state, enabled: state === 'active', required: activationByBrain.some(item => item.required),
231
+ ...(state !== 'mixed' && first.mode ? { mode: first.mode } : {}) };
232
+ return { ...representative, activation, activationByBrain,
233
+ servingAvailable: Boolean(serving.get(id) && serving.get(id).dir === representative.dir) };
234
+ });
235
+ }
236
+
133
237
  /**
134
238
  * GET /api/plugins/available
135
239
  * Plugins bundled with this Total Recall package, installable on any node.
@@ -277,28 +381,7 @@ router.get("/api/plugins/:id", requireAuth, requireScope("config:read"), (req, r
277
381
  try {
278
382
  const plugin = getPluginById(req.params.id, projectRoot());
279
383
  if (!plugin) return res.status(404).json({ success: false, error: `Plugin ${req.params.id} not found` });
280
- res.json({ success: true, plugin: { ...describePlugin(plugin), manifest: plugin.manifest } });
281
- } catch (err) {
282
- serverError(res, err);
283
- }
284
- });
285
-
286
- /**
287
- * PATCH /api/plugins/:id/card-face
288
- * Customizes card face skin, theme, colors, headline, quick actions, and metrics.
289
- */
290
- router.patch("/api/plugins/:id/card-face", requireAuth, requireScope("config:write"), (req, res) => {
291
- try {
292
- const plugin = getPluginById(req.params.id, projectRoot());
293
- if (!plugin) return res.status(404).json({ success: false, error: `Plugin ${req.params.id} not found` });
294
- const manifestPath = path.join(plugin.dir, "plugin.json");
295
- if (!fs.existsSync(manifestPath)) return res.status(404).json({ success: false, error: "Manifest not found" });
296
- const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf8"));
297
- const { card_face = {}, branding = {} } = req.body || {};
298
- manifest.card_face = { ...(manifest.card_face || {}), ...card_face };
299
- manifest.branding = { ...(manifest.branding || {}), ...branding };
300
- fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2) + "\n", "utf8");
301
- res.json({ success: true, card_face: manifest.card_face, branding: manifest.branding });
384
+ res.json({ success: true, plugin: { ...describePlugin(plugin, projectRoot()), manifest: plugin.manifest } });
302
385
  } catch (err) {
303
386
  serverError(res, err);
304
387
  }
@@ -312,16 +395,37 @@ router.patch("/api/plugins/:id/card-face", requireAuth, requireScope("config:wri
312
395
  * write-level regardless of that declaration.
313
396
  */
314
397
  router.post("/api/plugins/:id/run", requireAuth, (req, res, next) => {
315
- const { subcommand, args = [], stdin, execution } = req.body || {};
398
+ const { subcommand, args = [], stdin, execution, brainId } = req.body || {};
316
399
  try {
317
- const plugin = getPluginById(req.params.id, projectRoot());
318
- const operation = plugin?.valid && plugin.manifest?.cli?.subcommands?.find(item => item.name === subcommand);
400
+ const target = surfaceTarget(req, brainId);
401
+ const plugin = getPluginById(req.params.id, target.projectRoot);
402
+ if (brainId !== undefined && execution) {
403
+ return res.status(400).json({ success: false, error: 'Use the selected brain with local plugin execution.' });
404
+ }
405
+ if (brainId !== undefined && ['on', 'off'].includes(subcommand || args?.[0])) {
406
+ return res.status(400).json({ success: false, error: 'Use the selected brain activation control.' });
407
+ }
408
+ const declared = plugin?.valid ? plugin.manifest?.cli?.subcommands || [] : [];
409
+ const operation = declared.find(item => item.name === subcommand);
410
+ const activation = ['on', 'off'].includes(subcommand) && Array.isArray(args) && !args.length && stdin === undefined && !execution;
411
+ const browserBlocked = item => item.sensitive_output === true || item.terminal_only === true;
412
+ if (operation ? browserBlocked(operation) : !activation && declared.some(browserBlocked)) {
413
+ return res.status(403).json({ success: false, error: 'Use the owning CLI or account controls for this operation.' });
414
+ }
415
+ const terminalFlags = new Set((operation ? [operation] : declared).flatMap(item => item.terminal_only_args ?? []));
416
+ if (Array.isArray(args) && args.some(arg => typeof arg === 'string' && terminalFlags.has(arg.split('=', 1)[0]))) {
417
+ return res.status(403).json({ success: false, error: 'Use the owning CLI for terminal-only arguments.' });
418
+ }
319
419
  res.locals.executionPlugin = plugin;
420
+ res.locals.executionTarget = target;
320
421
  const read = typeof subcommand === 'string' && Array.isArray(args) && args.every(arg => typeof arg === 'string') &&
321
422
  operation?.effect === 'read' && stdin === undefined && !execution &&
322
423
  !operation.args?.some(arg => arg.secret);
323
424
  return requireScope(read ? 'config:read' : 'config:write')(req, res, next);
324
- } catch (error) { badRequest(res, error.message); }
425
+ } catch (error) {
426
+ if ([400, 403, 404, 409, 503].includes(error.status)) return res.status(error.status).json({ error: error.message });
427
+ badRequest(res, error.message);
428
+ }
325
429
  }, async (req, res) => {
326
430
  try {
327
431
  const { subcommand = "", args = [], stdin, execution } = req.body || {};
@@ -329,21 +433,26 @@ router.post("/api/plugins/:id/run", requireAuth, (req, res, next) => {
329
433
  return badRequest(res, "subcommand must be a string and args an array of strings");
330
434
  }
331
435
  const plugin = res.locals.executionPlugin;
436
+ const target = res.locals.executionTarget;
437
+ const cwd = target.projectRoot ?? target.brainDir;
332
438
  if (!plugin) return res.status(404).json({ success: false, error: `Plugin ${req.params.id} not found` });
333
439
  if (!plugin.valid) return badRequest(res, `Plugin ${plugin.id} has an invalid manifest: ${plugin.errors.join("; ")}`);
334
440
  if (!plugin.manifest?.cli?.handler) return badRequest(res, `Plugin ${plugin.id} does not declare a CLI handler`);
441
+ if (req.body?.brainId !== undefined && !pluginActivation(plugin, target).enabled) {
442
+ return res.status(403).json({ success: false, error: 'Plugin is off in the selected brain.' });
443
+ }
335
444
  validatePluginSecretInput(plugin, subcommand, stdin);
336
445
 
337
446
  if (execution) {
338
447
  if (stdin !== undefined) return badRequest(res, 'Credential operations require direct local execution');
339
- if (!pluginActivation(plugin, { projectRoot: projectRoot() }).enabled && !['on', 'off', 'status', 'health', 'jobs', '--help', 'help'].includes(subcommand)) return badRequest(res, `Plugin ${plugin.id} is inactive`);
448
+ if (!pluginActivation(plugin, target).enabled && !['on', 'off', 'status', 'health', 'jobs', '--help', 'help'].includes(subcommand)) return badRequest(res, `Plugin ${plugin.id} is inactive`);
340
449
  const { loadPluginModule } = await import('../../core/plugin-runtime.mjs');
341
- const owner = await loadPluginModule('meta-harness', 'command-executor', { activeRequired: true });
342
- const result = await owner.executeCommand({ plugin, subcommand, args, execution, projectRoot: projectRoot() });
450
+ const owner = await loadPluginModule('meta-harness', 'command-executor', { activeRequired: true, projectRoot: target.projectRoot });
451
+ const result = await owner.executeCommand({ plugin, subcommand, args, execution, projectRoot: cwd });
343
452
  return res.json({ success: result.ok, pluginId: plugin.id, ...result });
344
453
  }
345
454
 
346
- const result = await runPluginCommand(plugin, { subcommand, args, ...(stdin !== undefined ? { stdinText: stdin } : {}), cwd: projectRoot(), secretsBrainDir: process.env.TR_SECRETS_BRAIN || globalBrainDir || BRAIN_DIR, maxOutputBytes: 4 * 1024 * 1024 });
455
+ const result = await runPluginCommand(plugin, { subcommand, args, ...(stdin !== undefined ? { stdinText: stdin } : {}), cwd, projectRoot: target.projectRoot, secretsBrainDir: process.env.TR_SECRETS_BRAIN || globalBrainDir || BRAIN_DIR, maxOutputBytes: 4 * 1024 * 1024 });
347
456
  res.json({ success: result.ok, pluginId: plugin.id, ...result });
348
457
  } catch (err) {
349
458
  badRequest(res, err.message);
@@ -3,184 +3,15 @@
3
3
  * Extracted from rest.mjs
4
4
  */
5
5
  import { Router } from 'express';
6
- import fs from 'node:fs';
7
- import path from 'node:path';
8
- import crypto from 'node:crypto';
9
6
  import { requireAuth, requireScope } from '../auth.mjs';
10
7
  import { processOperationAsync } from '../../core/operation-validator.mjs';
11
8
  import { invalidate } from '../../core/vault-cache.mjs';
12
9
  import {
13
- ROOT,
14
- INSTRUCTIONS,
15
- SKILLS_DIR,
16
10
  resolveVaultFromQuery,
17
11
  } from './_shared.mjs';
18
12
 
19
13
  const router = Router();
20
14
 
21
- // ─── SSSS Resources (sync and integration consumers) ─────────────────────────
22
-
23
- function sha256(content) {
24
- return crypto.createHash('sha256').update(content).digest('hex');
25
- }
26
-
27
- function readTextResource(filePath, name) {
28
- if (!fs.existsSync(filePath)) return null;
29
- const content = fs.readFileSync(filePath, 'utf8');
30
- const stat = fs.statSync(filePath);
31
- return {
32
- name,
33
- content,
34
- sha256: sha256(content),
35
- bytes: stat.size,
36
- modified: stat.mtime.toISOString()
37
- };
38
- }
39
-
40
- function sendTextResource(res, filePath, name) {
41
- const resource = readTextResource(filePath, name);
42
- if (!resource) {
43
- return res.status(404).json({ error: `${name} is not available` });
44
- }
45
- return res.json(resource);
46
- }
47
-
48
- function baseUrl(req) {
49
- return `${req.protocol}://${req.get('host')}`;
50
- }
51
-
52
- function absoluteUrl(req, routePath) {
53
- return new URL(routePath, baseUrl(req)).toString();
54
- }
55
-
56
- function ssssReferenceDir() {
57
- // Prefer compact TR references; fall back to legacy nested module paths.
58
- const candidates = [
59
- path.join(SKILLS_DIR, 'total-recall', 'references'),
60
- path.join(SKILLS_DIR, 'total-recall', 'modules', 'ssss', 'references'),
61
- path.join(SKILLS_DIR, 'okf', 'references'),
62
- ];
63
- return candidates.find((p) => fs.existsSync(p)) || candidates[0];
64
- }
65
-
66
- function ssssSkillDocPath() {
67
- const candidates = [
68
- path.join(SKILLS_DIR, 'total-recall', 'references', 'ssss-reference.md'),
69
- path.join(SKILLS_DIR, 'total-recall', 'SKILL.md'),
70
- path.join(SKILLS_DIR, 'total-recall', 'modules', 'ssss', 'MODULE.md'),
71
- path.join(SKILLS_DIR, 'okf', 'SKILL.md'),
72
- ];
73
- return candidates.find((p) => fs.existsSync(p)) || candidates[0];
74
- }
75
-
76
- function listSsssReferences(req) {
77
- const refsDir = ssssReferenceDir();
78
- if (!fs.existsSync(refsDir)) return [];
79
- return fs.readdirSync(refsDir)
80
- .filter(file => file.endsWith('.md'))
81
- .sort()
82
- .map((file) => {
83
- const name = file.replace(/\.md$/, '');
84
- const resource = readTextResource(path.join(refsDir, file), name);
85
- return {
86
- name,
87
- url: absoluteUrl(req, `/api/ssss/references/${name}`),
88
- sha256: resource?.sha256 || null,
89
- bytes: resource?.bytes || 0,
90
- modified: resource?.modified || null
91
- };
92
- });
93
- }
94
-
95
- function safeReferencePath(name) {
96
- if (!/^[a-zA-Z0-9_-]+$/.test(String(name || ''))) return null;
97
- return path.join(ssssReferenceDir(), `${name}.md`);
98
- }
99
-
100
- router.get('/api/ssss', requireAuth, requireScope('ssss:read'), (req, res) => {
101
- const resources = {
102
- instructions: {
103
- name: 'instructions',
104
- url: absoluteUrl(req, '/api/ssss/instructions'),
105
- ...(() => {
106
- const r = readTextResource(INSTRUCTIONS, 'instructions');
107
- return r ? { sha256: r.sha256, bytes: r.bytes, modified: r.modified } : { sha256: null, bytes: 0, modified: null };
108
- })()
109
- },
110
- skill: {
111
- name: 'ssss-skill',
112
- url: absoluteUrl(req, '/api/ssss/skill/ssss'),
113
- ...(() => {
114
- const r = readTextResource(ssssSkillDocPath(), 'ssss-skill');
115
- return r ? { sha256: r.sha256, bytes: r.bytes, modified: r.modified } : { sha256: null, bytes: 0, modified: null };
116
- })()
117
- },
118
- spec: {
119
- name: 'ssss-spec',
120
- url: absoluteUrl(req, '/api/ssss/spec'),
121
- ...(() => {
122
- const refs = ssssReferenceDir();
123
- const specPath = ['ssss-reference.md', 'ssss-spec.md']
124
- .map((n) => path.join(refs, n))
125
- .find((p) => fs.existsSync(p));
126
- const r = specPath ? readTextResource(specPath, 'ssss-spec') : null;
127
- return r ? { sha256: r.sha256, bytes: r.bytes, modified: r.modified } : { sha256: null, bytes: 0, modified: null };
128
- })()
129
- },
130
- references: listSsssReferences(req)
131
- };
132
-
133
- res.json({
134
- name: 'ssss',
135
- schema_version: 2,
136
- resources
137
- });
138
- });
139
-
140
- router.get('/api/ssss/instructions', requireAuth, requireScope('ssss:read', 'instructions:read'), (req, res) => {
141
- const surface = req.query.surface;
142
- // Prefer live INSTRUCTIONS constant (agent brain), then package ROOT fallback
143
- const instructionsPath = fs.existsSync(INSTRUCTIONS)
144
- ? INSTRUCTIONS
145
- : path.join(ROOT, 'INSTRUCTIONS.md');
146
- if (surface) {
147
- if (surface === 'INSTRUCTIONS.md') {
148
- return sendTextResource(res, instructionsPath, 'instructions');
149
- }
150
- const safeSurface = path.basename(surface);
151
- const candidates = [
152
- path.join(path.dirname(instructionsPath), safeSurface),
153
- path.join(ROOT, safeSurface),
154
- ];
155
- const surfacePath = candidates.find(p => fs.existsSync(p)) || candidates[0];
156
- return sendTextResource(res, surfacePath, safeSurface);
157
- }
158
- return sendTextResource(res, instructionsPath, 'instructions');
159
- });
160
-
161
- router.get('/api/ssss/skill/ssss', requireAuth, requireScope('ssss:read'), (_req, res) => {
162
- return sendTextResource(res, ssssSkillDocPath(), 'ssss-skill');
163
- });
164
-
165
- router.get('/api/ssss/spec', requireAuth, requireScope('ssss:read'), (_req, res) => {
166
- const refs = ssssReferenceDir();
167
- const specPath = ['ssss-reference.md', 'ssss-spec.md']
168
- .map((n) => path.join(refs, n))
169
- .find((p) => fs.existsSync(p));
170
- return sendTextResource(res, specPath || path.join(refs, 'ssss-reference.md'), 'ssss-spec');
171
- });
172
-
173
- router.get('/api/ssss/references', requireAuth, requireScope('ssss:read'), (req, res) => {
174
- res.json({ references: listSsssReferences(req) });
175
- });
176
-
177
- router.get('/api/ssss/references/:name', requireAuth, requireScope('ssss:read'), (req, res) => {
178
- const filePath = safeReferencePath(req.params.name);
179
- if (!filePath) return res.status(400).json({ error: 'Invalid reference name' });
180
- return sendTextResource(res, filePath, req.params.name);
181
- });
182
-
183
-
184
15
  export const ssssOperationHandler = async (req, res) => {
185
16
  try {
186
17
  const vaultRoot = resolveVaultFromQuery(req);
@@ -4,7 +4,6 @@
4
4
  * GET /api/logs/:type — Read last 200 lines of server or daemon log
5
5
  * POST /api/diagnostics/agents — Run upgrade --agents diagnostics
6
6
  * GET /api/pairing — Reachable URLs for the mobile pairing QR
7
- * GET /api/tasks/failed — List failed tasks from the DLQ
8
7
  * POST /api/tasks/:id/retry — Re-queue a failed task
9
8
  * GET /api/usage — Usage ledger + cost summary
10
9
  * GET /api/usage/providers — Spend as the providers report it
@@ -144,20 +143,6 @@ router.get('/api/pairing', requireAuth, requireScope('config:read'), async (_req
144
143
  }
145
144
  });
146
145
 
147
- /**
148
- * GET /api/tasks/failed
149
- * List failed tasks from the scheduler DLQ.
150
- */
151
- router.get('/api/tasks/failed', requireAuth, async (req, res) => {
152
- try {
153
- const { listTasks } = await import('../../core/task-envelope.mjs');
154
- const failed = listTasks(QUEUE_DIR, { status: 'failed' });
155
- res.json({ total: failed.length, tasks: failed });
156
- } catch (err) {
157
- serverError(res, err);
158
- }
159
- });
160
-
161
146
  /**
162
147
  * POST /api/tasks/:id/retry
163
148
  * Re-queue a failed task.
@@ -38,32 +38,6 @@ router.get('/api/tasks', requireAuth, requireScope('tasks:read'), (req, res) =>
38
38
  } catch (err) { serverError(res, err); }
39
39
  });
40
40
 
41
- router.delete('/api/tasks/cleanup', requireAuth, requireScope('tasks:write'), (req, res) => {
42
- try {
43
- if (!fs.existsSync(TASKS_DIR)) {
44
- return res.json({ deleted: 0 });
45
- }
46
- let deleted = 0;
47
- const files = fs.readdirSync(TASKS_DIR);
48
- for (const file of files) {
49
- if (!file.endsWith('.md')) continue;
50
- const filePath = path.join(TASKS_DIR, file);
51
- try {
52
- const raw = fs.readFileSync(filePath, 'utf8');
53
- const { data } = matter(raw);
54
- if (data.status === 'completed') {
55
- fs.unlinkSync(filePath);
56
- deleted++;
57
- }
58
- } catch (e) {
59
- // skip
60
- }
61
- }
62
- res.json({ deleted });
63
-
64
- } catch (err) { serverError(res, err); }
65
- });
66
-
67
41
  router.post('/api/tasks', requireAuth, requireScope('tasks:write'), (req, res) => {
68
42
  try {
69
43
  const { category, target, body, priority = 5 } = req.body || {};