total-recall-brain 3.45.0 → 3.46.1

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 (363) hide show
  1. package/bin/total-recall.mjs +7 -2
  2. package/frontend/dist/assets/index-BRYE1jmv.css +1 -0
  3. package/frontend/dist/assets/index-D1goIPjC.js +5598 -0
  4. package/frontend/dist/index.html +2 -2
  5. package/frontend/dist/sw.js +5 -4
  6. package/frontend/src/App.tsx +183 -236
  7. package/frontend/src/api/auth-inventory.ts +62 -0
  8. package/frontend/src/api/memory.ts +13 -8
  9. package/frontend/src/api/plugin-credentials.ts +23 -0
  10. package/frontend/src/api/plugins.ts +37 -53
  11. package/frontend/src/api/workspace-drawers.ts +97 -0
  12. package/frontend/src/components/BrainSelector.tsx +9 -3
  13. package/frontend/src/components/plugins/PluginPanel.tsx +83 -42
  14. package/frontend/src/components/plugins/PluginSettings.tsx +10 -20
  15. package/frontend/src/components/plugins/PluginWorkspace.tsx +367 -0
  16. package/frontend/src/components/plugins/ScopedPluginCommands.tsx +142 -0
  17. package/frontend/src/components/plugins/plugin-frame.ts +44 -33
  18. package/frontend/src/components/plugins/scoped-plugin-operations.ts +28 -0
  19. package/frontend/src/components/workspace/DrawerChat.tsx +110 -0
  20. package/frontend/src/components/workspace/DrawerLayout.tsx +196 -0
  21. package/frontend/src/components/workspace/DrawerMarkup.tsx +49 -0
  22. package/frontend/src/components/workspace/PluginChunkLibrary.tsx +92 -0
  23. package/frontend/src/components/workspace/PluginHome.tsx +76 -0
  24. package/frontend/src/components/workspace/WorkspaceDrawers.tsx +96 -0
  25. package/frontend/src/components/workspace/WorkspacePage.tsx +95 -0
  26. package/frontend/src/components/workspace/usePluginDesign.ts +38 -0
  27. package/frontend/src/index.css +409 -136
  28. package/frontend/src/pages/HelpPage.tsx +15 -46
  29. package/frontend/src/pages/MemoryPage.tsx +19 -36
  30. package/frontend/src/pages/SettingsPage.tsx +1 -1
  31. package/metadata.plugin.schema.json +53 -227
  32. package/package.json +1 -1
  33. package/scaffold/.agent/skills/plugin/SKILL.md +13 -11
  34. package/scaffold/.agent/skills/plugin/evals/README.md +14 -21
  35. package/scaffold/.agent/skills/plugin/evals/cases/01-fabricated-seed.mjs +15 -18
  36. package/scaffold/.agent/skills/plugin/evals/cases/02-reassuring-default.mjs +19 -24
  37. package/scaffold/.agent/skills/plugin/evals/cases/03-declared-template.mjs +12 -20
  38. package/scaffold/.agent/skills/plugin/evals/cases/04-home-collects-credential.mjs +35 -0
  39. package/scaffold/.agent/skills/plugin/evals/cases/05-host-leak-in-scaffold.mjs +8 -28
  40. package/scaffold/.agent/skills/plugin/evals/cases/06-correct-plugin.mjs +85 -47
  41. package/scaffold/.agent/skills/plugin/evals/run.mjs +17 -18
  42. package/scaffold/.agent/skills/plugin/prompts/05-credentials.md +4 -4
  43. package/scaffold/.agent/skills/plugin/prompts/07-scaffold.md +2 -2
  44. package/scaffold/.agent/skills/plugin/prompts/08-verify.md +4 -4
  45. package/scaffold/.agent/skills/plugin/references/anti-patterns.md +2 -2
  46. package/scaffold/.agent/skills/plugin/references/generative-home.md +38 -0
  47. package/scaffold/.agent/skills/plugin/references/scaffold.md +5 -5
  48. package/scaffold/.agent/skills/plugin/references/surfaces.md +13 -4
  49. package/scaffold/.agent/skills/plugin/scripts/record.mjs +75 -153
  50. package/scaffold/.agent/skills/plugin/subagents/plugin-reviewer.md +4 -4
  51. package/scaffold/.agent/skills/total-recall/plugins/auth/DESIGN.md +76 -0
  52. package/scaffold/.agent/skills/total-recall/plugins/auth/README.md +3 -1
  53. package/scaffold/.agent/skills/total-recall/plugins/auth/cli.mjs +20 -15
  54. package/scaffold/.agent/skills/total-recall/plugins/auth/package-lock.json +6 -6
  55. package/scaffold/.agent/skills/total-recall/plugins/auth/package.json +2 -1
  56. package/scaffold/.agent/skills/total-recall/plugins/auth/plugin.json +13 -51
  57. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/access-overview.md +17 -0
  58. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/agent-login.md +20 -0
  59. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/baseline-audit.md +22 -0
  60. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/credential-repository-binding.md +17 -0
  61. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/credential-store-maintenance.md +17 -0
  62. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/dashboard-password.md +18 -0
  63. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/dashboard-sessions.md +18 -0
  64. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/endpoint-probe.md +23 -0
  65. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/google-sign-in.md +21 -0
  66. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/mesh-machines.md +16 -0
  67. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/passkey-enrollment.md +21 -0
  68. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/registered-brains.md +16 -0
  69. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/scoped-access-keys.md +17 -0
  70. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/secret-inventory.md +25 -0
  71. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/signing-key-rotation.md +22 -0
  72. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/home.js +375 -0
  73. package/scaffold/.agent/skills/total-recall/plugins/automations/{ui/DESIGN.md → DESIGN.md} +32 -21
  74. package/scaffold/.agent/skills/total-recall/plugins/automations/adapters.mjs +17 -1
  75. package/scaffold/.agent/skills/total-recall/plugins/automations/cli.mjs +10 -1
  76. package/scaffold/.agent/skills/total-recall/plugins/automations/package-lock.json +6 -6
  77. package/scaffold/.agent/skills/total-recall/plugins/automations/package.json +4 -3
  78. package/scaffold/.agent/skills/total-recall/plugins/automations/plugin.json +11 -27
  79. package/scaffold/.agent/skills/total-recall/plugins/automations/ui/automations.js +2 -2
  80. package/scaffold/.agent/skills/total-recall/plugins/automations/ui/chunks/control-ledger.md +42 -0
  81. package/scaffold/.agent/skills/total-recall/plugins/automations/ui/chunks/local-inventory-triage.md +17 -0
  82. package/scaffold/.agent/skills/total-recall/plugins/automations/ui/chunks/pending-control.md +39 -0
  83. package/scaffold/.agent/skills/total-recall/plugins/automations/ui/chunks/run-evidence.md +41 -0
  84. package/scaffold/.agent/skills/total-recall/plugins/automations/ui/chunks/schedule-vs-run-evidence.md +17 -0
  85. package/scaffold/.agent/skills/total-recall/plugins/automations/ui/chunks/source-coverage.md +41 -0
  86. package/scaffold/.agent/skills/total-recall/plugins/automations/ui/{card.js → home.js} +32 -27
  87. package/scaffold/.agent/skills/total-recall/plugins/code-quality/DESIGN.md +53 -0
  88. package/scaffold/.agent/skills/total-recall/plugins/code-quality/cli.mjs +23 -0
  89. package/scaffold/.agent/skills/total-recall/plugins/code-quality/commands/run-core.mjs +4 -2
  90. package/scaffold/.agent/skills/total-recall/plugins/code-quality/core/check.mjs +4 -2
  91. package/scaffold/.agent/skills/total-recall/plugins/code-quality/package-lock.json +6 -6
  92. package/scaffold/.agent/skills/total-recall/plugins/code-quality/package.json +2 -1
  93. package/scaffold/.agent/skills/total-recall/plugins/code-quality/plugin.json +40 -40
  94. package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/chunks/config.md +15 -0
  95. package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/chunks/detect.md +15 -0
  96. package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/chunks/gate.md +15 -0
  97. package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/chunks/init.md +15 -0
  98. package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/chunks/report.md +17 -0
  99. package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/chunks/run.md +17 -0
  100. package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/chunks/snapshot.md +15 -0
  101. package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/code-quality-report.mjs +55 -23
  102. package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/home.mjs +214 -0
  103. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/DESIGN.md +146 -0
  104. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/package-lock.json +6 -6
  105. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/package.json +2 -1
  106. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/plugin.json +51 -34
  107. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/src/command.mjs +1 -1
  108. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/create.md +35 -0
  109. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/history.md +35 -0
  110. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/library.md +49 -0
  111. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/list.md +42 -0
  112. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/promote.md +40 -0
  113. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/read.md +25 -0
  114. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/remove.md +26 -0
  115. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/rollback.md +26 -0
  116. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/show.md +53 -0
  117. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/status.md +40 -0
  118. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/test-path.md +38 -0
  119. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/test.md +46 -0
  120. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/update.md +32 -0
  121. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/home.js +533 -0
  122. package/scaffold/.agent/skills/total-recall/plugins/embeddings/DESIGN.md +110 -0
  123. package/scaffold/.agent/skills/total-recall/plugins/embeddings/package-lock.json +6 -6
  124. package/scaffold/.agent/skills/total-recall/plugins/embeddings/package.json +2 -1
  125. package/scaffold/.agent/skills/total-recall/plugins/embeddings/plugin.json +13 -10
  126. package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/chunks/benchmark.md +49 -0
  127. package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/chunks/coverage.md +53 -0
  128. package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/chunks/models.md +43 -0
  129. package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/chunks/pull.md +41 -0
  130. package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/chunks/status.md +59 -0
  131. package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/home.js +353 -0
  132. package/scaffold/.agent/skills/total-recall/plugins/git/DESIGN.md +31 -0
  133. package/scaffold/.agent/skills/total-recall/plugins/git/README.md +25 -1
  134. package/scaffold/.agent/skills/total-recall/plugins/git/cli.mjs +5 -1
  135. package/scaffold/.agent/skills/total-recall/plugins/git/package-lock.json +6 -6
  136. package/scaffold/.agent/skills/total-recall/plugins/git/package.json +2 -1
  137. package/scaffold/.agent/skills/total-recall/plugins/git/plugin.json +17 -27
  138. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/commit-memory.mjs +30 -6
  139. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/fleet.mjs +24 -6
  140. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/secret-firewall.mjs +33 -7
  141. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/undo.mjs +29 -5
  142. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/unmerged.mjs +182 -0
  143. package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/change-comparison.md +27 -0
  144. package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/commit-identity.md +22 -0
  145. package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/create-worktree.md +25 -0
  146. package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/registered-worktrees.md +22 -0
  147. package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/remove-worktree.md +23 -0
  148. package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/repository-ledger.md +25 -0
  149. package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/unmerged-work.md +22 -0
  150. package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/upstream-divergence.md +17 -0
  151. package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/worktree-conflict-triage.md +17 -0
  152. package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/worktree-terminal.md +22 -0
  153. package/scaffold/.agent/skills/total-recall/plugins/git/ui/home.js +273 -0
  154. package/scaffold/.agent/skills/total-recall/plugins/mesh/DESIGN.md +35 -0
  155. package/scaffold/.agent/skills/total-recall/plugins/mesh/README.md +4 -5
  156. package/scaffold/.agent/skills/total-recall/plugins/mesh/cli.mjs +9 -3
  157. package/scaffold/.agent/skills/total-recall/plugins/mesh/package-lock.json +6 -6
  158. package/scaffold/.agent/skills/total-recall/plugins/mesh/package.json +2 -1
  159. package/scaffold/.agent/skills/total-recall/plugins/mesh/plugin.json +37 -39
  160. package/scaffold/.agent/skills/total-recall/plugins/mesh/src/cli/mesh.mjs +5 -3
  161. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/active-device-dispatch.md +22 -0
  162. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/control-probe.md +25 -0
  163. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/control-server.md +22 -0
  164. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/credential-readiness.md +23 -0
  165. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/elected-leader.md +22 -0
  166. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/enrollment-key.md +22 -0
  167. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/file-receipt.md +25 -0
  168. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/fleet-execution.md +23 -0
  169. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/fleet-presence.md +23 -0
  170. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/interactive-ssh.md +22 -0
  171. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/local-enrollment.md +23 -0
  172. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/mesh-policy.md +23 -0
  173. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/network-atlas.md +25 -0
  174. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/node-roster.md +26 -0
  175. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/node-selection-proof.md +17 -0
  176. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/owner-observations.md +23 -0
  177. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/peer-path.md +23 -0
  178. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/pinned-leader.md +24 -0
  179. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/reachability-evidence-ladder.md +17 -0
  180. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/recorded-login.md +23 -0
  181. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/remote-execution.md +22 -0
  182. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/secret-grants.md +26 -0
  183. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/{card.js → home.js} +93 -22
  184. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/DESIGN.md +86 -0
  185. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/README.md +19 -0
  186. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/cli.mjs +5 -1
  187. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/package-lock.json +6 -6
  188. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/package.json +2 -1
  189. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/plugin.json +43 -22
  190. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/chat.mjs +80 -0
  191. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/adapter-docs-freshness.md +16 -0
  192. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/chat-handoff.md +26 -0
  193. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/fleet-maintenance.md +21 -0
  194. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/harness-inventory.md +21 -0
  195. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/included-access.md +18 -0
  196. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/included-usage-verification.md +15 -0
  197. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/independent-review.md +17 -0
  198. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/managed-execution.md +20 -0
  199. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/official-documentation.md +18 -0
  200. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/quota-recovery.md +21 -0
  201. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/review-routing-decision.md +16 -0
  202. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/route-work.md +18 -0
  203. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/routing-evidence.md +18 -0
  204. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/run-ledger.md +18 -0
  205. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/home.js +198 -0
  206. package/scaffold/.agent/skills/total-recall/plugins/openwiki/DESIGN.md +75 -0
  207. package/scaffold/.agent/skills/total-recall/plugins/openwiki/README.md +2 -0
  208. package/scaffold/.agent/skills/total-recall/plugins/openwiki/cli.mjs +17 -14
  209. package/scaffold/.agent/skills/total-recall/plugins/openwiki/package-lock.json +6 -6
  210. package/scaffold/.agent/skills/total-recall/plugins/openwiki/package.json +2 -1
  211. package/scaffold/.agent/skills/total-recall/plugins/openwiki/plugin.json +10 -44
  212. package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/generate.mjs +5 -4
  213. package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/graph.mjs +3 -4
  214. package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/ingest.mjs +23 -18
  215. package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/mesh-vaults.mjs +8 -3
  216. package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/refresh.mjs +6 -3
  217. package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/search.mjs +3 -5
  218. package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/token.mjs +21 -47
  219. package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/upstream-watcher.mjs +17 -6
  220. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/auto-refresh.md +18 -0
  221. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/bootstrap-pages.md +18 -0
  222. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/generate-wiki.md +21 -0
  223. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/generator-settings.md +18 -0
  224. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/host-probe.md +18 -0
  225. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/ingest-preview.md +18 -0
  226. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/link-hygiene.md +21 -0
  227. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/link-topology.md +19 -0
  228. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/passage-search.md +19 -0
  229. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/propagation-plan.md +18 -0
  230. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/provider-credentials.md +18 -0
  231. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/refresh-report.md +18 -0
  232. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/task-evidence.md +22 -0
  233. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/upstream-record.md +18 -0
  234. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/watch-upstream.md +18 -0
  235. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/wiki-atlas.md +19 -0
  236. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/panel.js +261 -513
  237. package/scaffold/.agent/skills/total-recall/plugins/security/DESIGN.md +84 -0
  238. package/scaffold/.agent/skills/total-recall/plugins/security/README.md +4 -2
  239. package/scaffold/.agent/skills/total-recall/plugins/security/cli.mjs +7 -19
  240. package/scaffold/.agent/skills/total-recall/plugins/security/package-lock.json +6 -6
  241. package/scaffold/.agent/skills/total-recall/plugins/security/package.json +2 -3
  242. package/scaffold/.agent/skills/total-recall/plugins/security/plugin.json +19 -52
  243. package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/device-evidence.md +21 -0
  244. package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/evidence-desk.md +18 -0
  245. package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/guided-device-review.md +17 -0
  246. package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/host-and-network.md +21 -0
  247. package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/https-headers.md +17 -0
  248. package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/mesh-coverage.md +18 -0
  249. package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/private-security-tools.md +16 -0
  250. package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/single-origin-header-check.md +17 -0
  251. package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/source-review.md +21 -0
  252. package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/ssh-permission-plan.md +17 -0
  253. package/scaffold/.agent/skills/total-recall/plugins/security/ui/home.js +283 -0
  254. package/scaffold/.agent/skills/total-recall/plugins/ssss/DESIGN.md +93 -0
  255. package/scaffold/.agent/skills/total-recall/plugins/ssss/package-lock.json +2 -2
  256. package/scaffold/.agent/skills/total-recall/plugins/ssss/package.json +2 -1
  257. package/scaffold/.agent/skills/total-recall/plugins/ssss/plugin.json +5 -3
  258. package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/chunks/conformance.md +26 -0
  259. package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/chunks/registry.md +37 -0
  260. package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/chunks/repair.md +42 -0
  261. package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/chunks/scaffold.md +33 -0
  262. package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/chunks/status.md +43 -0
  263. package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/chunks/validate.md +34 -0
  264. package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/chunks/validation-diagnostics.md +17 -0
  265. package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/chunks/workspace-registry-preflight.md +17 -0
  266. package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/home.js +348 -0
  267. package/scaffold/.agent/skills/total-recall/references/operations.md +2 -0
  268. package/src/cli/api.mjs +3 -3
  269. package/src/cli/brief.mjs +3 -0
  270. package/src/cli/config.mjs +16 -0
  271. package/src/cli/connect.mjs +2 -7
  272. package/src/cli/plugin/chunks.mjs +145 -0
  273. package/src/cli/plugin/create.mjs +24 -52
  274. package/src/cli/plugin/index.mjs +20 -9
  275. package/src/cli/setup.mjs +2 -9
  276. package/src/cli/start.mjs +1 -0
  277. package/src/cli/startup.mjs +18 -0
  278. package/src/core/app-deploy/design-tokens.mjs +14 -9
  279. package/src/core/app-deploy/ui-elements.mjs +1 -1
  280. package/src/core/brain-registry.mjs +5 -0
  281. package/src/core/brain-updates.mjs +5 -1
  282. package/src/core/daemon-control.mjs +5 -1
  283. package/src/core/dashboard-bundle.mjs +261 -0
  284. package/src/core/default-plugin-refresh.mjs +39 -0
  285. package/src/core/ensure-dependencies.mjs +19 -15
  286. package/src/core/memory-brain.mjs +30 -8
  287. package/src/core/plugin-activation.mjs +63 -20
  288. package/src/core/plugin-contracts/{card.mjs → manifest.mjs} +23 -57
  289. package/src/core/plugin-contracts/startup-check.mjs +49 -0
  290. package/src/core/plugin-contracts/ui.mjs +9 -3
  291. package/src/core/plugin-distribution.mjs +6 -6
  292. package/src/core/plugin-lifecycle.mjs +58 -0
  293. package/src/core/plugin-loader.mjs +9 -5
  294. package/src/core/plugin-runner.mjs +21 -10
  295. package/src/core/plugin-startup-checks.mjs +44 -0
  296. package/src/core/plugin-state.mjs +19 -5
  297. package/src/core/plugin-store.mjs +30 -11
  298. package/src/core/project-id.mjs +15 -5
  299. package/src/core/required-plugins.mjs +31 -6
  300. package/src/core/schema.mjs +2 -0
  301. package/src/core/ssss-operation-service.mjs +1 -0
  302. package/src/core/startup-health.mjs +28 -3
  303. package/src/core/testing/plugin-fixture.mjs +22 -21
  304. package/src/core/throttled-fetch.mjs +25 -18
  305. package/src/core/ui-chunk-choice.mjs +77 -0
  306. package/src/core/ui-chunk.registry.json +23 -0
  307. package/src/core/ui-chunks.mjs +434 -0
  308. package/src/core/vault-cache.mjs +58 -59
  309. package/src/core/workspace-compositions.mjs +151 -0
  310. package/src/core/workspace-drawers.mjs +79 -0
  311. package/src/server/api.mjs +4 -27
  312. package/src/server/index.mjs +28 -21
  313. package/src/server/memory-events.mjs +31 -0
  314. package/src/server/plugin-brain-targets.mjs +89 -0
  315. package/src/server/rest.mjs +2 -0
  316. package/src/server/route-inventory.mjs +3 -2
  317. package/src/server/route-manifest.json +52 -4
  318. package/src/server/routes/_shared.mjs +7 -14
  319. package/src/server/routes/brains.mjs +29 -44
  320. package/src/server/routes/dashboard.mjs +26 -0
  321. package/src/server/routes/plugins.mjs +154 -45
  322. package/src/server/routes/ui-chunks.mjs +192 -0
  323. package/frontend/dist/assets/index-DACh1dhx.js +0 -5613
  324. package/frontend/dist/assets/index-DtwsDyFM.css +0 -1
  325. package/frontend/src/components/plugins/card/CardEngine.tsx +0 -108
  326. package/frontend/src/components/plugins/card/CardScenes.tsx +0 -103
  327. package/frontend/src/components/plugins/card/ExecutionPicker.tsx +0 -64
  328. package/frontend/src/components/plugins/card/args.ts +0 -28
  329. package/frontend/src/components/plugins/card/card.css +0 -32
  330. package/frontend/src/components/plugins/card/cli-line.ts +0 -13
  331. package/frontend/src/components/plugins/card/contract.ts +0 -91
  332. package/frontend/src/components/plugins/card/format.ts +0 -49
  333. package/frontend/src/components/plugins/card/runner-context.ts +0 -11
  334. package/frontend/src/components/plugins/card/runner.tsx +0 -43
  335. package/frontend/src/components/plugins/card/theme.ts +0 -35
  336. package/frontend/src/components/plugins/card/use-source.ts +0 -22
  337. package/frontend/src/components/plugins/card/widgets.tsx +0 -94
  338. package/frontend/src/components/plugins/workspace/WorkspaceHost.tsx +0 -23
  339. package/frontend/src/pages/PluginsPage.tsx +0 -1719
  340. package/scaffold/.agent/skills/plugin/evals/cases/04-card-collects-credential.mjs +0 -47
  341. package/scaffold/.agent/skills/plugin/prompts/06-card.md +0 -46
  342. package/scaffold/.agent/skills/plugin/references/card.md +0 -90
  343. package/scaffold/.agent/skills/plugin/subagents/card-designer.md +0 -60
  344. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/DESIGN.md +0 -67
  345. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/card.js +0 -1179
  346. package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/DESIGN.md +0 -32
  347. package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/card.js +0 -588
  348. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/card.js +0 -575
  349. package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/DESIGN.md +0 -32
  350. package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/card.js +0 -482
  351. package/scaffold/.agent/skills/total-recall/plugins/git/ui/DESIGN.md +0 -100
  352. package/scaffold/.agent/skills/total-recall/plugins/git/ui/card.js +0 -637
  353. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/DESIGN.md +0 -217
  354. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/DESIGN.md +0 -32
  355. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/card.js +0 -1276
  356. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/DESIGN.md +0 -45
  357. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/card.js +0 -1401
  358. package/scaffold/.agent/skills/total-recall/plugins/security/scripts/build-ui.mjs +0 -4
  359. package/scaffold/.agent/skills/total-recall/plugins/security/ui/DESIGN.md +0 -41
  360. package/scaffold/.agent/skills/total-recall/plugins/security/ui/card.js +0 -396
  361. package/scaffold/.agent/skills/total-recall/plugins/security/ui/panel.js +0 -98
  362. package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/DESIGN.md +0 -15
  363. package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/card.js +0 -182
@@ -1,1276 +0,0 @@
1
- /**
2
- * Metaharness — Multi-Agent Coordination & Inspection Console
3
- *
4
- * Bespoke operator interface for terminal coding agent fleet management.
5
- * Displays real-time agent discovery matrix, mesh node targets, authentication
6
- * postures, quotas and memory, sourced model figures, routing, threads and review.
7
- */
8
-
9
- const DASH = '\u2014';
10
-
11
- function escapeHtml(str) {
12
- if (str === null || str === undefined) return '';
13
- return String(str).replace(/[&<>"']/g, c => ({
14
- '&': '&amp;',
15
- '<': '&lt;',
16
- '>': '&gt;',
17
- '"': '&quot;',
18
- "'": '&#39;'
19
- }[c]));
20
- }
21
-
22
- export class CommandFleetCard extends HTMLElement {
23
- constructor() {
24
- super();
25
- this.agents = [];
26
- this.selectedAgent = null;
27
- this.selectedNode = 'local';
28
- this.nodes = [];
29
- this.executing = false;
30
- this.screen = 'fleet'; // 'fleet' | 'router' | 'quotas' | 'benchmarks' | 'threads'
31
- this.quotas = null;
32
- this.benchmarks = null;
33
- this.routeResult = null;
34
- this.routeInput = '';
35
- this.threads = [];
36
- this.selectedThreadId = null;
37
- this.reviewVerdict = null;
38
- this.reviewing = false;
39
- this.reviewBase = 'main';
40
- this.reviewAuthor = '';
41
- this.coordinationInput = '';
42
- this.coordinationMode = 'pipeline';
43
- this.coordinationResult = null;
44
- this.documentation = null;
45
- this.changelog = null;
46
- }
47
-
48
- connectedCallback() {
49
- if (!this.shadowRoot) {
50
- this.attachShadow({ mode: 'open' });
51
- }
52
- this.render();
53
- this.refreshFleet();
54
- }
55
-
56
- async setScreen(screen) {
57
- this.screen = screen;
58
- this.render();
59
- if (screen === 'quotas' && !this.quotas) {
60
- await this.refreshQuotas();
61
- } else if (screen === 'benchmarks' && !this.benchmarks) {
62
- await this.refreshBenchmarks();
63
- } else if (screen === 'threads' && this.threads.length === 0) {
64
- await this.refreshThreads();
65
- } else if (screen === 'docs') {
66
- await this.refreshDocsPanel();
67
- }
68
- }
69
-
70
- async refreshFleet() {
71
- if (!this.host) return;
72
- try {
73
- const res = await this.host.run('status', ['--node', this.selectedNode, '--json']);
74
- let parsed = [];
75
- if (Array.isArray(res)) {
76
- parsed = res;
77
- } else if (res && typeof res === 'object') {
78
- if (Array.isArray(res.agents)) parsed = res.agents;
79
- if (res.documentation) this.docsFresh = Boolean(res.documentation.ok);
80
- } else if (typeof res === 'string' && res.trim().startsWith('{')) {
81
- try {
82
- const obj = JSON.parse(res);
83
- if (Array.isArray(obj.agents)) parsed = obj.agents;
84
- if (obj.documentation) this.docsFresh = Boolean(obj.documentation.ok);
85
- } catch {}
86
- } else if (typeof res === 'string' && res.trim().startsWith('[')) {
87
- try { parsed = JSON.parse(res); } catch {}
88
- }
89
- this.agents = parsed;
90
-
91
- if (this.agents.length > 0 && !this.selectedAgent) {
92
- this.selectedAgent = this.agents[0].id || this.agents[0].name;
93
- }
94
-
95
- // Query mesh nodes
96
- try {
97
- const nodeRes = await this.host.run('nodes', ['--json']);
98
- if (Array.isArray(nodeRes)) this.nodes = nodeRes;
99
- else if (nodeRes && Array.isArray(nodeRes.nodes)) this.nodes = nodeRes.nodes;
100
- else if (nodeRes && Array.isArray(nodeRes.targets)) this.nodes = nodeRes.targets;
101
- } catch {
102
- this.nodes = [{ id: 'local', name: 'This Node' }];
103
- }
104
-
105
- this.loadError = null;
106
- this.render();
107
- } catch (error) {
108
- this.agents = [];
109
- this.loadError = error?.message || 'The fleet could not be read';
110
- this.render();
111
- }
112
- }
113
-
114
- /** Re-read whatever the visible screen shows, after a failure or a node change. */
115
- retry() {
116
- this.loadError = null;
117
- this.render();
118
- if (this.screen === 'quotas') return this.refreshQuotas();
119
- if (this.screen === 'benchmarks') return this.refreshBenchmarks();
120
- if (this.screen === 'threads') return this.refreshThreads();
121
- if (this.screen === 'docs') return this.refreshDocsPanel();
122
- return this.refreshFleet();
123
- }
124
-
125
- async refreshQuotas() {
126
- if (!this.host) return;
127
- try {
128
- const res = await this.host.run('quota', ['--node', this.selectedNode, '--json']);
129
- const parsed = typeof res === 'string' ? JSON.parse(res) : res;
130
- this.quotas = parsed?.quotas || null;
131
- this.fleet = parsed?.fleet || null;
132
- this.loadError = null;
133
- this.render();
134
- } catch (error) {
135
- this.quotas = null;
136
- this.loadError = error?.message || 'Quotas could not be read';
137
- this.render();
138
- }
139
- }
140
-
141
- async refreshBenchmarks() {
142
- if (!this.host) return;
143
- try {
144
- const res = await this.host.run('benchmarks', ['--json']);
145
- const parsed = typeof res === 'string' ? JSON.parse(res) : res;
146
- this.benchmarks = parsed || null;
147
- this.loadError = null;
148
- this.render();
149
- } catch (error) {
150
- this.benchmarks = null;
151
- this.loadError = error?.message || 'The catalog could not be read';
152
- this.render();
153
- }
154
- }
155
-
156
- async executeRoute(task, execute = false) {
157
- if (!this.host || !task) return;
158
- this.executing = true;
159
- this.render();
160
- try {
161
- const res = await this.host.run('route', [task, '--node', this.selectedNode, ...(execute ? ['--execute', '--gate', '--background'] : []), '--json']);
162
- this.routeResult = typeof res === 'string' ? JSON.parse(res) : res;
163
- } catch (err) {
164
- this.routeResult = { ok: false, error: err.message };
165
- } finally {
166
- this.executing = false;
167
- this.render();
168
- }
169
- }
170
-
171
- async refreshThreads() {
172
- if (!this.host) return;
173
- try {
174
- const res = await this.host.run('threads', ['list', '--json']);
175
- const parsed = typeof res === 'string' ? JSON.parse(res) : res;
176
- this.threads = Array.isArray(parsed) ? parsed : (parsed?.threads || []);
177
- if (this.threads.length > 0 && !this.selectedThreadId) {
178
- this.selectedThreadId = this.threads[0].id;
179
- }
180
- this.loadError = null;
181
- this.render();
182
- } catch (error) {
183
- this.threads = [];
184
- this.loadError = error?.message || 'Threads could not be read';
185
- this.render();
186
- }
187
- }
188
-
189
- async executeReview(base = 'main') {
190
- if (!this.host || this.reviewing) return;
191
- this.reviewing = true;
192
- this.render();
193
- try {
194
- const thread = this.threads.find(item => item.id === this.selectedThreadId);
195
- const implementer = thread?.turns?.findLast(turn => /implementer/i.test(turn.role || ''))?.agent;
196
- const author = this.reviewAuthor || implementer || (thread?.platform !== 'universal' ? thread?.platform : null);
197
- if (!author) throw new Error('Select the author before requesting independent review');
198
- const res = await this.host.run('review', [`${base}...HEAD`, '--author', author, '--node', this.selectedNode, ...(thread ? ['--thread', thread.id] : []), '--json']);
199
- this.reviewVerdict = typeof res === 'string' ? JSON.parse(res) : res;
200
- } catch (err) {
201
- this.reviewVerdict = { ok: false, error: err.message };
202
- } finally {
203
- this.reviewing = false;
204
- this.render();
205
- }
206
- }
207
-
208
- selectThread(id) {
209
- this.selectedThreadId = id;
210
- this.render();
211
- }
212
-
213
- async selectAgent(id) {
214
- this.selectedAgent = id;
215
- this.render();
216
- }
217
-
218
- async switchNode(nodeId) {
219
- this.selectedNode = nodeId;
220
- this.render();
221
- await this.refreshFleet();
222
- if (this.screen === 'quotas') {
223
- await this.refreshQuotas();
224
- }
225
- }
226
-
227
- async refreshDocs() {
228
- if (!this.host || this.executing) return;
229
- this.executing = true;
230
- this.render();
231
- try {
232
- await this.host.run('docs-ensure', [...(this.selectedAgent ? ['--agent', this.selectedAgent] : []), '--json']);
233
- if (this.screen === 'docs') await this.refreshDocsPanel();
234
- await this.refreshFleet();
235
- } catch {
236
- await this.refreshFleet();
237
- } finally {
238
- this.executing = false;
239
- this.render();
240
- }
241
- }
242
-
243
- async executeCoordination(execute = false) {
244
- if (!this.host || !this.coordinationInput.trim() || this.executing) return;
245
- this.executing = true;
246
- this.render();
247
- try {
248
- const value = await this.host.run('coordinate', [this.coordinationInput, '--mode', this.coordinationMode, '--node', this.selectedNode, ...(execute ? ['--execute', '--gate', '--background'] : []), '--json']);
249
- this.coordinationResult = typeof value === 'string' ? JSON.parse(value) : value;
250
- } catch (error) { this.coordinationResult = { ok: false, error: error.message }; }
251
- finally { this.executing = false; this.render(); }
252
- }
253
-
254
- async refreshDocsPanel() {
255
- if (!this.host) return;
256
- this.loadError = null;
257
- // docs-status exits 1 while any source is stale. That is a real status to show, not a failure to read it.
258
- const asStatus = text => { try { const parsed = JSON.parse(String(text).trim()); return Array.isArray(parsed?.agents) ? parsed : null; } catch { return null; } };
259
- try {
260
- const value = await this.host.run('docs-status', ['--json']);
261
- this.documentation = typeof value === 'string' ? JSON.parse(value) : value;
262
- } catch (error) {
263
- this.documentation = asStatus(error?.message);
264
- if (!this.documentation) this.loadError = error?.message || 'Documentation status could not be read';
265
- }
266
- try {
267
- const changelog = this.selectedAgent ? await this.host.run('changelog', [this.selectedAgent, '--json']) : null;
268
- this.changelog = typeof changelog === 'string' ? JSON.parse(changelog) : changelog;
269
- } catch (error) { this.changelog = null; this.loadError = this.loadError || error?.message || 'Changelog could not be read'; }
270
- this.render();
271
- }
272
-
273
- render() {
274
- const root = this.shadowRoot;
275
- if (!root) return;
276
-
277
- const installedAgents = this.agents.filter(a => a.installed !== false);
278
- const active = this.agents.find(a => (a.id || a.name) === this.selectedAgent) || this.agents[0];
279
-
280
- root.innerHTML = `
281
- <style>
282
- :host {
283
- --face-bg: #0c1427;
284
- --face-surface: #1e293b;
285
- --face-line: #1e293b;
286
- --face-text: #f1f5f9;
287
- --face-muted: #94a3b8;
288
- --face-brand: #3b82f6;
289
- --face-brand-hover: #60a5fa;
290
- --face-accent: #38bdf8;
291
- --face-ok: #10b981;
292
- --face-warn: #f59e0b;
293
- --face-danger: #ef4444;
294
- --face-dark: #0c1427;
295
-
296
- display: block;
297
- font-family: var(--font-sans, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif);
298
- color: var(--text-primary, var(--face-text));
299
- background: var(--bg-secondary, var(--face-bg));
300
- border: 1px solid var(--border, var(--face-line));
301
- border-radius: 8px;
302
- padding: 16px;
303
- box-sizing: border-box;
304
- overflow: hidden;
305
- }
306
-
307
- @media (prefers-reduced-motion: reduce) {
308
- *, ::before, ::after {
309
- animation-duration: 0.01ms !important;
310
- animation-iteration-count: 1 !important;
311
- transition-duration: 0.01ms !important;
312
- }
313
- }
314
-
315
- /* Header Bar */
316
- .header {
317
- display: flex;
318
- align-items: center;
319
- justify-content: space-between;
320
- flex-wrap: wrap;
321
- gap: 12px;
322
- padding-bottom: 14px;
323
- border-bottom: 1px solid var(--border, var(--face-line));
324
- margin-bottom: 14px;
325
- }
326
-
327
- .brand-group {
328
- display: flex;
329
- align-items: center;
330
- gap: 10px;
331
- }
332
-
333
- .wordmark-badge {
334
- font-family: var(--font-mono, 'JetBrains Mono', monospace);
335
- font-size: 13px;
336
- font-weight: 800;
337
- letter-spacing: 0.05em;
338
- color: var(--card-accent, var(--face-accent));
339
- background: rgba(59, 130, 246, 0.12);
340
- padding: 6px 10px;
341
- border-radius: 6px;
342
- border: 1px solid rgba(59, 130, 246, 0.3);
343
- }
344
-
345
- .title-meta {
346
- display: flex;
347
- flex-direction: column;
348
- }
349
-
350
- .plugin-title {
351
- font-size: 14px;
352
- font-weight: 700;
353
- color: var(--text-primary, var(--face-text));
354
- margin: 0;
355
- }
356
-
357
- .plugin-subtitle {
358
- font-size: 11px;
359
- color: var(--text-secondary, var(--face-muted));
360
- margin: 0;
361
- }
362
-
363
- .status-chip {
364
- display: flex;
365
- align-items: center;
366
- gap: 6px;
367
- font-size: 11px;
368
- font-weight: 600;
369
- color: var(--face-ok);
370
- background: rgba(16, 185, 129, 0.1);
371
- border: 1px solid rgba(16, 185, 129, 0.25);
372
- border-radius: 20px;
373
- padding: 4px 10px;
374
- }
375
-
376
- /* Screen Navigation Tabs */
377
- .tabs-bar {
378
- display: flex;
379
- flex-wrap: wrap;
380
- gap: 8px;
381
- margin-bottom: 14px;
382
- border-bottom: 1px solid var(--border, var(--face-line));
383
- padding-bottom: 8px;
384
- }
385
-
386
- .tab-btn {
387
- font-size: 12px;
388
- font-weight: 600;
389
- padding: 6px 12px;
390
- border-radius: 6px;
391
- border: 1px solid transparent;
392
- background: transparent;
393
- color: var(--text-secondary, var(--face-muted));
394
- cursor: pointer;
395
- min-height: 44px;
396
- display: flex;
397
- align-items: center;
398
- }
399
-
400
- .tab-btn[data-active="true"] {
401
- background: rgba(59, 130, 246, 0.15);
402
- color: var(--face-accent);
403
- border-color: rgba(59, 130, 246, 0.4);
404
- }
405
-
406
- /* Node Selector & Action Controls */
407
- .node-bar {
408
- display: flex;
409
- align-items: center;
410
- justify-content: space-between;
411
- flex-wrap: wrap;
412
- gap: 10px;
413
- margin-bottom: 14px;
414
- }
415
-
416
- .node-toggles {
417
- display: flex;
418
- gap: 6px;
419
- flex-wrap: wrap;
420
- }
421
-
422
- .btn-node {
423
- font-size: 11px;
424
- font-weight: 600;
425
- padding: 6px 12px;
426
- border-radius: 5px;
427
- border: 1px solid var(--border, var(--face-line));
428
- background: rgba(30, 41, 59, 0.5);
429
- color: var(--text-secondary, var(--face-muted));
430
- cursor: pointer;
431
- min-height: 44px;
432
- display: flex;
433
- align-items: center;
434
- }
435
-
436
- .btn-node[data-active="true"] {
437
- background: rgba(59, 130, 246, 0.2);
438
- border-color: rgba(59, 130, 246, 0.5);
439
- color: var(--text-primary, var(--face-text));
440
- }
441
-
442
- .btn-action {
443
- font-size: 11px;
444
- font-weight: 600;
445
- padding: 6px 12px;
446
- border-radius: 5px;
447
- background: rgba(59, 130, 246, 0.15);
448
- border: 1px solid rgba(59, 130, 246, 0.4);
449
- color: var(--face-accent);
450
- cursor: pointer;
451
- min-height: 44px;
452
- display: flex;
453
- align-items: center;
454
- }
455
-
456
- /* Workspace Grid (Fleet View) */
457
- .workspace-grid {
458
- display: grid;
459
- grid-template-columns: 240px 1fr;
460
- gap: 14px;
461
- }
462
-
463
- @media (max-width: 768px) {
464
- .workspace-grid {
465
- grid-template-columns: 1fr;
466
- }
467
- }
468
-
469
- .roster-card {
470
- background: rgba(15, 23, 42, 0.6);
471
- border: 1px solid var(--border, var(--face-line));
472
- border-radius: 6px;
473
- padding: 8px;
474
- max-height: 380px;
475
- overflow-y: auto;
476
- display: flex;
477
- flex-direction: column;
478
- gap: 4px;
479
- }
480
-
481
- .agent-item {
482
- display: flex;
483
- align-items: center;
484
- justify-content: space-between;
485
- padding: 8px 10px;
486
- border-radius: 4px;
487
- border: 1px solid transparent;
488
- background: transparent;
489
- cursor: pointer;
490
- text-align: left;
491
- width: 100%;
492
- min-height: 44px;
493
- box-sizing: border-box;
494
- }
495
-
496
- .agent-item:hover {
497
- background: rgba(30, 41, 59, 0.4);
498
- }
499
-
500
- .agent-item[data-selected="true"] {
501
- background: rgba(59, 130, 246, 0.15);
502
- border-color: rgba(59, 130, 246, 0.4);
503
- }
504
-
505
- .agent-meta-left {
506
- display: flex;
507
- flex-direction: column;
508
- gap: 2px;
509
- }
510
-
511
- .agent-name {
512
- font-size: 12px;
513
- font-weight: 700;
514
- color: var(--text-primary, var(--face-text));
515
- }
516
-
517
- .agent-version {
518
- font-family: var(--font-mono, 'JetBrains Mono', monospace);
519
- font-size: 10px;
520
- color: var(--text-secondary, var(--face-muted));
521
- }
522
-
523
- .agent-badges {
524
- display: flex;
525
- flex-direction: column;
526
- align-items: flex-end;
527
- gap: 3px;
528
- }
529
-
530
- .badge-status {
531
- font-size: 9px;
532
- font-weight: 700;
533
- padding: 2px 6px;
534
- border-radius: 10px;
535
- letter-spacing: 0.02em;
536
- }
537
-
538
- .badge-online {
539
- background: rgba(16, 185, 129, 0.15);
540
- color: var(--face-ok);
541
- }
542
-
543
- .badge-offline {
544
- background: rgba(239, 68, 68, 0.15);
545
- color: var(--face-danger);
546
- }
547
-
548
- .badge-auth-ok {
549
- background: rgba(56, 189, 248, 0.15);
550
- color: var(--face-accent);
551
- }
552
-
553
- .badge-auth-needed {
554
- background: rgba(245, 158, 11, 0.15);
555
- color: var(--face-warn);
556
- }
557
-
558
- .inspector-panel {
559
- background: rgba(15, 23, 42, 0.6);
560
- border: 1px solid var(--border, var(--face-line));
561
- border-radius: 6px;
562
- padding: 14px;
563
- display: flex;
564
- flex-direction: column;
565
- gap: 14px;
566
- }
567
-
568
- .inspector-title {
569
- font-size: 14px;
570
- font-weight: 700;
571
- margin: 0;
572
- color: var(--text-primary, var(--face-text));
573
- padding-bottom: 8px;
574
- border-bottom: 1px solid var(--border, var(--face-line));
575
- }
576
-
577
- .property-grid {
578
- display: grid;
579
- grid-template-columns: repeat(2, 1fr);
580
- gap: 10px;
581
- }
582
-
583
- .property-box {
584
- background: rgba(30, 41, 59, 0.4);
585
- border: 1px solid var(--border, var(--face-line));
586
- border-radius: 5px;
587
- padding: 8px 10px;
588
- display: flex;
589
- flex-direction: column;
590
- gap: 3px;
591
- }
592
-
593
- .property-label {
594
- font-size: 10px;
595
- color: var(--text-secondary, var(--face-muted));
596
- text-transform: uppercase;
597
- letter-spacing: 0.05em;
598
- }
599
-
600
- .property-val {
601
- font-family: var(--font-mono, 'JetBrains Mono', monospace);
602
- font-size: 12px;
603
- font-weight: 700;
604
- color: var(--text-primary, var(--face-text));
605
- }
606
-
607
- .permission-pills {
608
- display: flex;
609
- flex-wrap: wrap;
610
- gap: 6px;
611
- margin-top: 6px;
612
- }
613
-
614
- .pill-permission {
615
- font-family: var(--font-mono, 'JetBrains Mono', monospace);
616
- font-size: 10px;
617
- padding: 4px 8px;
618
- border-radius: 4px;
619
- background: rgba(15, 23, 42, 0.8);
620
- border: 1px solid var(--border, var(--face-line));
621
- color: var(--text-secondary, var(--face-muted));
622
- }
623
-
624
- .pill-active {
625
- color: var(--face-ok);
626
- border-color: rgba(16, 185, 129, 0.4);
627
- background: rgba(16, 185, 129, 0.1);
628
- }
629
-
630
- /* Quotas & Benchmarks Tables */
631
- .table-panel {
632
- background: rgba(15, 23, 42, 0.6);
633
- border: 1px solid var(--border, var(--face-line));
634
- border-radius: 6px;
635
- padding: 12px;
636
- overflow-x: auto;
637
- }
638
-
639
- .data-table {
640
- width: 100%;
641
- border-collapse: collapse;
642
- font-size: 11px;
643
- }
644
-
645
- .data-table th {
646
- text-align: left;
647
- padding: 8px 10px;
648
- border-bottom: 1px solid var(--border, var(--face-line));
649
- color: var(--text-secondary, var(--face-muted));
650
- font-weight: 600;
651
- text-transform: uppercase;
652
- }
653
-
654
- .data-table td {
655
- padding: 8px 10px;
656
- border-bottom: 1px solid rgba(30, 41, 59, 0.4);
657
- color: var(--text-primary, var(--face-text));
658
- }
659
-
660
- /* Router Interactive Form */
661
- .router-panel {
662
- background: rgba(15, 23, 42, 0.6);
663
- border: 1px solid var(--border, var(--face-line));
664
- border-radius: 6px;
665
- padding: 14px;
666
- display: flex;
667
- flex-direction: column;
668
- gap: 12px;
669
- }
670
-
671
- .input-row {
672
- display: flex;
673
- flex-wrap: wrap;
674
- align-items: center;
675
- gap: 8px;
676
- }
677
- .input-row .task-input { min-width: 0; }
678
-
679
- .task-input {
680
- flex: 1;
681
- background: rgba(30, 41, 59, 0.6);
682
- border: 1px solid var(--border, var(--face-line));
683
- border-radius: 5px;
684
- color: var(--text-primary, var(--face-text));
685
- padding: 8px 12px;
686
- font-size: 12px;
687
- min-height: 44px;
688
- box-sizing: border-box;
689
- }
690
-
691
- .empty-agents-box {
692
- padding: 36px 16px;
693
- text-align: center;
694
- font-size: 12px;
695
- color: var(--text-secondary, var(--face-muted));
696
- }
697
-
698
- /* Threads & Review Layout */
699
- .threads-grid {
700
- display: grid;
701
- grid-template-columns: 280px 1fr;
702
- gap: 14px;
703
- }
704
-
705
- @media (max-width: 768px) {
706
- .threads-grid {
707
- grid-template-columns: 1fr;
708
- }
709
- }
710
-
711
- .threads-list {
712
- background: rgba(15, 23, 42, 0.6);
713
- border: 1px solid var(--border, var(--face-line));
714
- border-radius: 6px;
715
- padding: 8px;
716
- max-height: 440px;
717
- overflow-y: auto;
718
- display: flex;
719
- flex-direction: column;
720
- gap: 6px;
721
- }
722
-
723
- .thread-card-btn {
724
- display: flex;
725
- flex-direction: column;
726
- gap: 4px;
727
- padding: 10px;
728
- border-radius: 5px;
729
- border: 1px solid transparent;
730
- background: rgba(30, 41, 59, 0.4);
731
- cursor: pointer;
732
- text-align: left;
733
- width: 100%;
734
- min-height: 44px;
735
- box-sizing: border-box;
736
- }
737
-
738
- .thread-card-btn:hover {
739
- background: rgba(30, 41, 59, 0.7);
740
- }
741
-
742
- .thread-card-btn[data-selected="true"] {
743
- background: rgba(59, 130, 246, 0.15);
744
- border-color: rgba(59, 130, 246, 0.4);
745
- }
746
-
747
- .thread-title-text {
748
- font-size: 12px;
749
- font-weight: 700;
750
- color: var(--text-primary, var(--face-text));
751
- }
752
-
753
- .thread-meta-row {
754
- display: flex;
755
- align-items: center;
756
- justify-content: space-between;
757
- font-size: 10px;
758
- color: var(--text-secondary, var(--face-muted));
759
- }
760
-
761
- .thread-detail-panel {
762
- background: rgba(15, 23, 42, 0.6);
763
- border: 1px solid var(--border, var(--face-line));
764
- border-radius: 6px;
765
- padding: 14px;
766
- display: flex;
767
- flex-direction: column;
768
- gap: 14px;
769
- max-height: 440px;
770
- overflow-y: auto;
771
- }
772
-
773
- .review-box {
774
- background: rgba(30, 41, 59, 0.4);
775
- border: 1px solid var(--border, var(--face-line));
776
- border-radius: 6px;
777
- padding: 12px;
778
- display: flex;
779
- flex-direction: column;
780
- gap: 10px;
781
- }
782
-
783
- .verdict-badge {
784
- display: inline-flex;
785
- align-items: center;
786
- padding: 4px 10px;
787
- border-radius: 4px;
788
- font-weight: 700;
789
- font-size: 11px;
790
- text-transform: uppercase;
791
- }
792
-
793
- .verdict-pass {
794
- background: rgba(16, 185, 129, 0.2);
795
- color: var(--face-ok);
796
- border: 1px solid rgba(16, 185, 129, 0.4);
797
- }
798
-
799
- .verdict-fail {
800
- background: rgba(239, 68, 68, 0.2);
801
- color: var(--face-danger);
802
- border: 1px solid rgba(239, 68, 68, 0.4);
803
- }
804
-
805
- .verdict-caution {
806
- background: rgba(245, 158, 11, 0.2);
807
- color: var(--face-warn);
808
- border: 1px solid rgba(245, 158, 11, 0.4);
809
- }
810
-
811
- .turns-log {
812
- display: flex;
813
- flex-direction: column;
814
- gap: 8px;
815
- }
816
-
817
- .turn-box {
818
- background: rgba(15, 23, 42, 0.7);
819
- border: 1px solid var(--border, var(--face-line));
820
- border-radius: 5px;
821
- padding: 8px 10px;
822
- font-size: 11px;
823
- }
824
-
825
- .turn-header {
826
- display: flex;
827
- justify-content: space-between;
828
- font-weight: 700;
829
- color: var(--face-accent);
830
- margin-bottom: 4px;
831
- font-size: 10px;
832
- text-transform: uppercase;
833
- }
834
-
835
- .turn-content {
836
- font-family: var(--font-mono, 'JetBrains Mono', monospace);
837
- font-size: 10px;
838
- color: var(--text-primary, var(--face-text));
839
- white-space: pre-wrap;
840
- word-break: break-word;
841
- }
842
-
843
- /* Footer Telemetry */
844
- .footer-bar {
845
- display: flex;
846
- justify-content: space-between;
847
- align-items: center;
848
- padding-top: 12px;
849
- margin-top: 14px;
850
- border-top: 1px solid var(--border, var(--face-line));
851
- font-size: 10px;
852
- color: var(--text-secondary, var(--face-muted));
853
- }
854
- </style>
855
-
856
- <div class="header">
857
- <div class="brand-group">
858
- <div class="wordmark-badge">METAHARNESS</div>
859
- <div class="title-meta">
860
- <h3 class="plugin-title">Metaharness Fleet</h3>
861
- <p class="plugin-subtitle">Multi-agent runtime coordination, quotas & benchmarks</p>
862
- </div>
863
- </div>
864
- <div class="status-chip">
865
- ${installedAgents.length > 0 ? `${installedAgents.length} Agents Installed` : this.loadError ? 'Not Loaded' : 'Scanning Fleet'}
866
- </div>
867
- </div>
868
-
869
- ${this.loadError ? `
870
- <div class="inspector-panel" role="alert" style="flex-direction: row; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap;">
871
- <span style="font-size: 12px; color: var(--face-danger);">${escapeHtml(String(this.loadError).slice(0, 240))}</span>
872
- <button class="btn-action" id="btn-retry" type="button">Retry</button>
873
- </div>
874
- ` : ''}
875
-
876
- <div class="tabs-bar">
877
- <button class="tab-btn" data-active="${this.screen === 'fleet'}" data-screen="fleet" type="button">Fleet Roster</button>
878
- <button class="tab-btn" data-active="${this.screen === 'quotas'}" data-screen="quotas" type="button">Quotas & RAM</button>
879
- <button class="tab-btn" data-active="${this.screen === 'benchmarks'}" data-screen="benchmarks" type="button">Benchmarks</button>
880
- <button class="tab-btn" data-active="${this.screen === 'router'}" data-screen="router" type="button">Smart Router</button>
881
- <button class="tab-btn" data-active="${this.screen === 'threads'}" data-screen="threads" type="button">Threads & Review</button>
882
- <button class="tab-btn" data-active="${this.screen === 'coordination'}" data-screen="coordination" type="button">Coordination</button>
883
- <button class="tab-btn" data-active="${this.screen === 'docs'}" data-screen="docs" type="button">Docs & Changes</button>
884
- </div>
885
-
886
- <div class="node-bar">
887
- <div class="node-toggles">
888
- ${(this.nodes.length > 0 ? this.nodes : [{ id: 'local', name: 'This Node' }]).map(node => `
889
- <button class="btn-node" data-active="${this.selectedNode === (node.id || node)}" type="button" data-node-id="${escapeHtml(node.id || node)}">
890
- ${escapeHtml(node.name || node.id || node)}
891
- </button>
892
- `).join('')}
893
- </div>
894
- <button class="btn-action" type="button" id="btn-docs" ${this.executing ? 'disabled' : ''}>
895
- ${this.executing ? 'Working...' : 'Sync Documentation'}
896
- </button>
897
- </div>
898
-
899
- ${this.screen === 'fleet' ? `
900
- <div class="workspace-grid">
901
- <div class="roster-card">
902
- ${this.agents.length > 0 ? this.agents.map(a => `
903
- <button class="agent-item" data-selected="${(a.id || a.name) === this.selectedAgent}" type="button" data-agent-id="${escapeHtml(a.id || a.name)}">
904
- <div class="agent-meta-left">
905
- <span class="agent-name">${escapeHtml(a.name || a.id)}</span>
906
- <span class="agent-version">${escapeHtml(a.version || DASH)}</span>
907
- </div>
908
- <div class="agent-badges">
909
- <span class="badge-status ${a.installed !== false ? 'badge-online' : 'badge-offline'}">
910
- ${a.installed !== false ? 'Installed' : 'Missing'}
911
- </span>
912
- ${a.installed !== false ? `
913
- <span class="badge-status ${a.authenticated === true ? 'badge-auth-ok' : 'badge-auth-needed'}">
914
- ${a.blockedBy === 'no-chat-model' ? 'No chat model' : a.authenticated === true ? 'Signed in' : a.authenticated === false ? 'Sign-in needed' : 'Not probed'}
915
- </span>
916
- ` : ''}
917
- </div>
918
- </button>
919
- `).join('') : `
920
- <div class="empty-agents-box">${this.loadError ? 'The fleet could not be read.' : 'Scanning for terminal coding agents...'}</div>
921
- `}
922
- </div>
923
-
924
- <div class="inspector-panel">
925
- ${active ? `
926
- <h4 class="inspector-title">${escapeHtml(active.name || active.id)} Details</h4>
927
- <div class="property-grid">
928
- <div class="property-box">
929
- <span class="property-label">Installed Version</span>
930
- <span class="property-val">${escapeHtml(active.version || DASH)}</span>
931
- </div>
932
- <div class="property-box">
933
- <span class="property-label">Account</span>
934
- <span class="property-val">${active.authenticated === true ? 'Signed in' : active.authenticated === false ? 'Not signed in' : 'No login probe; a run proves it'}</span>
935
- </div>
936
- ${active.chatModels ? `
937
- <div class="property-box">
938
- <span class="property-label">Chat Models</span>
939
- <span class="property-val">${escapeHtml(active.chatModels.join(', ') || 'None installed')}</span>
940
- </div>
941
- ` : ''}
942
- <div class="property-box">
943
- <span class="property-label">Fleet Documentation</span>
944
- <span class="property-val" style="color: ${this.docsFresh ? 'var(--face-ok)' : 'var(--face-muted)'};">
945
- ${this.docsFresh ? 'All sources current' : 'Some sources stale'}
946
- </span>
947
- </div>
948
- </div>
949
- ${active.docs ? `<a class="property-label" href="${escapeHtml(active.docs)}" target="_blank" rel="noreferrer">Official documentation</a>` : ''}
950
- ` : `
951
- <div class="empty-agents-box">Select an agent from the fleet roster to inspect configuration.</div>
952
- `}
953
- </div>
954
- </div>
955
- ` : ''}
956
-
957
- ${this.screen === 'quotas' ? `
958
- <div class="table-panel">
959
- <table class="data-table">
960
- <thead>
961
- <tr>
962
- <th>Harness / System</th>
963
- <th>Type</th>
964
- <th>Usage %</th>
965
- <th>5h Used</th>
966
- <th>Weekly Used</th>
967
- <th>Status</th>
968
- </tr>
969
- </thead>
970
- <tbody>
971
- ${this.quotas?.system ? `
972
- <tr>
973
- <td><strong>System Host Memory</strong></td>
974
- <td>Hardware RAM</td>
975
- <td>${this.quotas.system.memoryUtilizationPercent}%</td>
976
- <td colspan="2">${this.quotas.system.freeMemGB} GB free / ${this.quotas.system.totalMemGB} GB total</td>
977
- <td><span class="badge-status badge-online">Operational</span></td>
978
- </tr>
979
- ` : ''}
980
- ${this.quotas ? Object.entries(this.quotas).filter(([k]) => k !== 'system').map(([k, q]) => `
981
- <tr>
982
- <td><strong>${escapeHtml(k.toUpperCase())}</strong></td>
983
- <td>${escapeHtml(q.billingModel || (q.metered ? 'Metered Credits' : 'Subscription'))}</td>
984
- <td>${typeof q.usagePercent === 'number' ? `${q.usagePercent}%` : DASH}</td>
985
- <td>${typeof q.rolling5hUsedPercent === 'number' ? `${q.rolling5hUsedPercent}%` : DASH}</td>
986
- <td>${typeof q.weeklyUsedPercent === 'number' ? `${q.weeklyUsedPercent}%` : DASH}</td>
987
- <td title="${escapeHtml(q.quotaNote || '')}">
988
- <span class="badge-status ${q.status === 'ready' ? 'badge-online' : (q.status === 'not_installed' ? 'badge-offline' : 'badge-auth-needed')}">
989
- ${escapeHtml(q.status === 'exhausted' && q.resetsAt ? `exhausted until ${new Date(q.resetsAt).toLocaleString()}` : q.status)}
990
- </span>
991
- </td>
992
- </tr>
993
- `).join('') : `
994
- <tr><td colspan="6" style="text-align:center;">${this.loadError ? 'Not loaded.' : 'Loading quota telemetry...'}</td></tr>
995
- `}
996
- </tbody>
997
- </table>
998
- </div>
999
- ` : ''}
1000
-
1001
- ${this.screen === 'benchmarks' ? `
1002
- <div class="table-panel">
1003
- <table class="data-table">
1004
- <thead>
1005
- <tr>
1006
- <th>Model</th>
1007
- <th>Harness</th>
1008
- <th>Per 1M In / Out</th>
1009
- <th>Intelligence</th>
1010
- <th>Engineering</th>
1011
- <th>SWE-bench Pro</th>
1012
- <th>Terminal-Bench${this.benchmarks?.sources?.terminalBench?.benchmark ? ` ${escapeHtml(this.benchmarks.sources.terminalBench.benchmark)}` : ''}</th>
1013
- <th>Harness Pass Rate</th>
1014
- </tr>
1015
- </thead>
1016
- <tbody>
1017
- ${this.benchmarks ? (this.benchmarks.models || []).filter(m => !/-(low|medium)$/.test(m.id)).map(m => {
1018
- const local = this.benchmarks.local?.[m.harness];
1019
- return `
1020
- <tr>
1021
- <td><strong>${escapeHtml(m.name || m.id)}</strong></td>
1022
- <td>${escapeHtml(m.harness)}</td>
1023
- <td>${m.pricing ? `$${m.pricing.promptPer1M} / $${m.pricing.completionPer1M}` : DASH}</td>
1024
- <td>${m.intelligenceIndex ?? DASH}</td>
1025
- <td>${m.engineeringIndex ?? DASH}</td>
1026
- <td>${typeof m.sweBenchPro === 'number' ? `${m.sweBenchPro}%` : DASH}</td>
1027
- <td>${typeof m.terminalBench === 'number' ? `${m.terminalBench}%` : DASH}</td>
1028
- <td>${local ? `${local.passRate}% (${local.total} runs)` : DASH}</td>
1029
- </tr>
1030
- `;
1031
- }).join('') : `
1032
- <tr><td colspan="7" style="text-align:center;">${this.loadError ? 'Not loaded.' : 'Loading catalog...'}</td></tr>
1033
- `}
1034
- ${this.benchmarks && !this.benchmarks.synced ? `
1035
- <tr><td colspan="7" style="text-align:center;">${escapeHtml(this.benchmarks.note || 'Catalog not synced')}</td></tr>
1036
- ` : ''}
1037
- </tbody>
1038
- </table>
1039
- ${this.benchmarks?.sources ? `
1040
- <div style="display:flex; flex-direction:column; gap:4px; padding:10px; font-size:11px; color:var(--face-muted);">
1041
- ${Object.entries(this.benchmarks.sources).map(([name, s]) => `
1042
- <span>${escapeHtml(name)}: ${s.ok ? `${s.count} rows, ${escapeHtml(new Date(s.fetchedAt).toLocaleString())}` : `unavailable (${escapeHtml(s.error || 'unknown error')})`}${s.attribution ? `. ${escapeHtml(s.attribution)}` : ''}</span>
1043
- `).join('')}
1044
- </div>
1045
- ` : ''}
1046
- </div>
1047
- ` : ''}
1048
-
1049
- ${this.screen === 'router' ? `
1050
- <div class="router-panel">
1051
- <div class="input-row">
1052
- <input class="task-input" id="task-input" type="text" placeholder="Enter task to evaluate complexity and optimal harness..." value="${escapeHtml(this.routeInput)}" />
1053
- <button class="btn-action" id="btn-route" type="button" ${this.executing ? 'disabled' : ''}>Evaluate Route</button>
1054
- <button class="btn-action" id="btn-route-run" type="button" ${this.executing ? 'disabled' : ''}>Run with gates</button>
1055
- </div>
1056
-
1057
- ${this.routeResult ? `
1058
- <div class="inspector-panel" style="background: rgba(30, 41, 59, 0.3);">
1059
- <h4 class="inspector-title">${this.routeResult.selected ? `Route Recommendation: ${escapeHtml(this.routeResult.selected.toUpperCase())} (${escapeHtml(this.routeResult.tier?.toUpperCase())} TIER)` : escapeHtml(this.routeResult.error || 'No harness can take this task right now')}</h4>
1060
- <div class="property-grid">
1061
- <div class="property-box">
1062
- <span class="property-label">Complexity Score</span>
1063
- <span class="property-val">${this.routeResult.complexity?.score ?? DASH}/100</span>
1064
- </div>
1065
- <div class="property-box">
1066
- <span class="property-label">Active Factors</span>
1067
- <span class="property-val">${escapeHtml((this.routeResult.complexity?.factors || []).join(', ') || 'Standard task')}</span>
1068
- </div>
1069
- <div class="property-box">
1070
- <span class="property-label">Unavailable Now</span>
1071
- <span class="property-val">${escapeHtml((this.routeResult.excluded || []).map(e => `${e.harness}: ${e.reason}`).join('; ') || 'None')}</span>
1072
- </div>
1073
- <div class="property-box">
1074
- <span class="property-label">Warnings</span>
1075
- <span class="property-val">${escapeHtml((this.routeResult.warnings || []).join(' ') || 'None')}</span>
1076
- </div>
1077
- </div>
1078
- </div>
1079
- ` : ''}
1080
- </div>
1081
- ` : ''}
1082
-
1083
- ${this.screen === 'coordination' ? `
1084
- <div class="router-panel">
1085
- <label for="coordination-task">Task</label>
1086
- <textarea class="task-input" id="coordination-task" rows="3">${escapeHtml(this.coordinationInput)}</textarea>
1087
- <div class="input-row">
1088
- <label for="coordination-mode">Workflow</label>
1089
- <select class="task-input" id="coordination-mode">${['pipeline', 'council', 'race'].map(mode => `<option value="${mode}" ${this.coordinationMode === mode ? 'selected' : ''}>${mode === 'pipeline' ? 'Plan, implement and verify' : mode === 'council' ? 'Parallel independent assessment' : 'Parallel verified candidates'}</option>`).join('')}</select>
1090
- <button class="btn-action" id="btn-coordinate-plan" ${this.executing ? 'disabled' : ''}>Preview plan</button>
1091
- <button class="btn-action" id="btn-coordinate-run" ${this.executing ? 'disabled' : ''}>Run with gates</button>
1092
- </div>
1093
- ${this.coordinationResult ? `<div class="inspector-panel">
1094
- <h4>${escapeHtml(this.coordinationResult.error || (this.coordinationResult.background ? 'Run started' : this.coordinationResult.ok ? 'Workflow ready' : 'Workflow failed'))}</h4>
1095
- ${this.coordinationResult.pid ? `<p>Process ${escapeHtml(this.coordinationResult.pid)}. Follow its progress in Threads.</p>` : ''}
1096
- ${(this.coordinationResult.stages || []).map(stage => `<div class="property-box"><strong>${escapeHtml(stage.role || stage.name || stage.agent)}</strong><span>${escapeHtml(stage.agent || DASH)} · ${stage.passed === true ? 'Passed' : stage.passed === false ? 'Failed' : 'Planned'}</span></div>`).join('')}
1097
- ${this.coordinationResult.branch ? `<p>Branch: ${escapeHtml(this.coordinationResult.branch)}</p>` : ''}
1098
- </div>` : '<p>Preview the assigned agents, then start isolated work with verification.</p>'}
1099
- </div>
1100
- ` : ''}
1101
-
1102
- ${this.screen === 'docs' ? `
1103
- <div class="router-panel">
1104
- <h4>Documentation coverage</h4>
1105
- <div class="property-grid">${(this.documentation?.agents || []).map(agent => `<div class="property-box"><strong>${escapeHtml(agent.id)}</strong><span>${agent.fresh ? 'Current' : agent.complete ? 'Stale' : 'Unavailable'} · ${escapeHtml(agent.pages)} pages</span><span>${escapeHtml(agent.error || agent.checkedAt || DASH)}</span></div>`).join('') || '<p>No documentation report loaded.</p>'}</div>
1106
- <label for="docs-agent">Harness</label>
1107
- <select class="task-input" id="docs-agent">${this.agents.map(agent => `<option value="${escapeHtml(agent.id)}" ${this.selectedAgent === agent.id ? 'selected' : ''}>${escapeHtml(agent.name || agent.id)}</option>`).join('')}</select>
1108
- <button class="btn-action" id="btn-changelog">Read changes</button>
1109
- ${this.changelog ? `<div class="inspector-panel"><h4>Upstream changes</h4><pre style="white-space:pre-wrap;overflow-wrap:anywhere;max-height:260px;overflow:auto">${escapeHtml(this.changelog.error || this.changelog.changelog || this.changelog.content || this.changelog.output || this.changelog.note || 'No changelog content returned')}</pre></div>` : ''}
1110
- </div>
1111
- ` : ''}
1112
-
1113
- ${this.screen === 'threads' ? `
1114
- <div class="threads-grid">
1115
- <div class="threads-list">
1116
- ${this.threads.length > 0 ? this.threads.map(t => `
1117
- <button class="thread-card-btn" data-selected="${t.id === (this.selectedThreadId || this.threads[0]?.id)}" type="button" data-thread-id="${escapeHtml(t.id)}">
1118
- <div class="thread-title-text">${escapeHtml(t.title || t.id)}</div>
1119
- <div class="thread-meta-row">
1120
- <span>${escapeHtml(t.branch || 'No branch')}</span>
1121
- <span class="badge-status ${t.status === 'closed' ? 'badge-offline' : 'badge-online'}">${escapeHtml(t.status || 'active')}</span>
1122
- </div>
1123
- <div class="thread-meta-row">
1124
- <span>Lead: ${escapeHtml(t.platform || DASH)}</span>
1125
- <span>${(t.turns || []).length} turns</span>
1126
- </div>
1127
- </button>
1128
- `).join('') : `
1129
- <div class="empty-agents-box">No persistent threads found. Create one with: total-recall meta-harness threads create</div>
1130
- `}
1131
- </div>
1132
-
1133
- <div class="thread-detail-panel">
1134
- <div class="review-box">
1135
- <h4 class="inspector-title" style="margin:0 0 6px 0;">Cross-Model Adversarial Code Review</h4>
1136
- <p class="plugin-subtitle" style="margin:0 0 10px 0;">Audits branch diff against base using a strictly distinct model family to eliminate confirmation bias.</p>
1137
- <div class="input-row">
1138
- <input class="task-input" id="review-base-input" type="text" placeholder="Base branch (default: main)" value="${escapeHtml(this.reviewBase)}" />
1139
- <select class="task-input" id="review-author" aria-label="Code author"><option value="">Author from selected thread</option>${this.agents.map(agent => `<option value="${escapeHtml(agent.id)}" ${this.reviewAuthor === agent.id ? 'selected' : ''}>${escapeHtml(agent.name || agent.id)}</option>`).join('')}</select>
1140
- <button class="btn-action" id="btn-run-review" type="button" ${this.reviewing ? 'disabled' : ''}>
1141
- ${this.reviewing ? 'Auditing...' : 'Run Review'}
1142
- </button>
1143
- </div>
1144
-
1145
- ${this.reviewVerdict ? (() => {
1146
- const result = this.reviewVerdict;
1147
- const review = result.review;
1148
- const verdict = review?.verdict || result.verdict || null;
1149
- if (!verdict) return `<div style="margin-top: 10px; font-size: 11px; color: var(--face-danger);">${escapeHtml(result.error || 'The review did not complete.')}</div>`;
1150
- const tone = verdict === 'APPROVE' ? 'pass' : verdict === 'REQUEST_CHANGES' ? 'fail' : 'caution';
1151
- return `
1152
- <div style="margin-top: 10px; display: flex; flex-direction: column; gap: 8px;">
1153
- <div style="display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 6px;">
1154
- <span class="verdict-badge verdict-${tone}">VERDICT: ${escapeHtml(verdict)}</span>
1155
- ${review ? `<span class="pill-permission pill-active">Reviewer: ${escapeHtml(review.reviewerName || review.reviewer)}</span>` : ''}
1156
- </div>
1157
- <div style="font-size: 11px;">${escapeHtml(review?.summary || result.summary || '')}</div>
1158
- ${review?.truncated ? `<div style="font-size: 11px; color: var(--face-danger);">The diff was too large to send whole; the reviewer was told to read the rest.</div>` : ''}
1159
- ${review?.findings?.length ? `
1160
- <div style="font-size: 11px; color: var(--face-danger);">
1161
- <strong>Findings:</strong>
1162
- <ul style="margin: 4px 0; padding-left: 18px;">
1163
- ${review.findings.map(f => `<li>${escapeHtml(f.severity || '')} ${escapeHtml(f.file || '')}: ${escapeHtml(f.issue || '')}</li>`).join('')}
1164
- </ul>
1165
- </div>
1166
- ` : ''}
1167
- </div>
1168
- `;
1169
- })() : ''}
1170
- </div>
1171
-
1172
- ${(() => {
1173
- const active = this.threads.find(t => t.id === this.selectedThreadId) || this.threads[0];
1174
- if (!active) return '';
1175
- return `
1176
- <div class="inspector-panel" style="background: rgba(30, 41, 59, 0.3);">
1177
- <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px;">
1178
- <h4 class="inspector-title" style="margin: 0;">${escapeHtml(active.title)}</h4>
1179
- <span class="agent-version">Thread ID: ${escapeHtml(active.id)}</span>
1180
- </div>
1181
- <div class="turns-log">
1182
- ${(active.turns && active.turns.length > 0) ? active.turns.map(turn => `
1183
- <div class="turn-box">
1184
- <div class="turn-header">
1185
- <span>${escapeHtml(turn.role || 'Agent')} &bull; ${escapeHtml(turn.agent || '')}</span>
1186
- <span>${new Date(turn.timestamp || Date.now()).toLocaleTimeString()}</span>
1187
- </div>
1188
- <div class="turn-content">${escapeHtml(turn.content)}</div>
1189
- </div>
1190
- `).join('') : `
1191
- <div style="font-size: 11px; color: var(--face-muted);">No turns recorded in this thread yet.</div>
1192
- `}
1193
- </div>
1194
- </div>
1195
- `;
1196
- })()}
1197
- </div>
1198
- </div>
1199
- ` : ''}
1200
-
1201
- <div class="footer-bar">
1202
- <span>Target: ${this.selectedNode.toUpperCase()} MESH NODE</span>
1203
- <span>${this.agents.filter(a => a.authenticated === true).length} signed in, ${this.agents.filter(a => a.authenticated === 'unknown').length} not probed</span>
1204
- </div>
1205
- `;
1206
-
1207
- // Event listeners
1208
- root.querySelectorAll('.tab-btn').forEach(btn => {
1209
- btn.addEventListener('click', () => {
1210
- const screen = btn.getAttribute('data-screen');
1211
- if (screen) this.setScreen(screen);
1212
- });
1213
- });
1214
-
1215
- root.querySelectorAll('.btn-node').forEach(btn => {
1216
- btn.addEventListener('click', () => {
1217
- const id = btn.getAttribute('data-node-id');
1218
- if (id) this.switchNode(id);
1219
- });
1220
- });
1221
-
1222
- root.querySelectorAll('.agent-item').forEach(btn => {
1223
- btn.addEventListener('click', () => {
1224
- const id = btn.getAttribute('data-agent-id');
1225
- if (id) this.selectAgent(id);
1226
- });
1227
- });
1228
-
1229
- root.querySelector('#btn-docs')?.addEventListener('click', () => this.refreshDocs());
1230
- root.querySelector('#btn-retry')?.addEventListener('click', () => this.retry());
1231
-
1232
- const taskInput = root.querySelector('#task-input');
1233
- if (taskInput) {
1234
- taskInput.addEventListener('input', (e) => {
1235
- this.routeInput = e.target.value;
1236
- });
1237
- }
1238
-
1239
- root.querySelector('#btn-route')?.addEventListener('click', () => {
1240
- if (this.routeInput) this.executeRoute(this.routeInput);
1241
- });
1242
- root.querySelector('#btn-route-run')?.addEventListener('click', () => this.executeRoute(this.routeInput, true));
1243
- root.querySelector('#coordination-task')?.addEventListener('input', event => { this.coordinationInput = event.target.value; });
1244
- root.querySelector('#coordination-mode')?.addEventListener('change', event => { this.coordinationMode = event.target.value; });
1245
- root.querySelector('#btn-coordinate-plan')?.addEventListener('click', () => this.executeCoordination());
1246
- root.querySelector('#btn-coordinate-run')?.addEventListener('click', () => this.executeCoordination(true));
1247
- root.querySelector('#docs-agent')?.addEventListener('change', event => { this.selectedAgent = event.target.value; });
1248
- root.querySelector('#btn-changelog')?.addEventListener('click', () => this.refreshDocsPanel());
1249
-
1250
- root.querySelectorAll('.thread-card-btn').forEach(btn => {
1251
- btn.addEventListener('click', () => {
1252
- const id = btn.getAttribute('data-thread-id');
1253
- if (id) this.selectThread(id);
1254
- });
1255
- });
1256
-
1257
- const reviewBaseInput = root.querySelector('#review-base-input');
1258
- if (reviewBaseInput) {
1259
- reviewBaseInput.addEventListener('input', (e) => {
1260
- this.reviewBase = e.target.value;
1261
- });
1262
- }
1263
-
1264
- root.querySelector('#btn-run-review')?.addEventListener('click', () => {
1265
- this.executeReview(this.reviewBase);
1266
- });
1267
- root.querySelector('#review-author')?.addEventListener('change', event => { this.reviewAuthor = event.target.value; });
1268
- }
1269
- }
1270
-
1271
- if (!customElements.get('meta-harness-card')) {
1272
- customElements.define('meta-harness-card', CommandFleetCard);
1273
- }
1274
- if (!customElements.get('command-fleet-card')) {
1275
- customElements.define('command-fleet-card', class extends CommandFleetCard {});
1276
- }