total-recall-brain 3.45.0 → 3.46.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (362) hide show
  1. package/bin/total-recall.mjs +4 -2
  2. package/frontend/dist/assets/index-BRYE1jmv.css +1 -0
  3. package/frontend/dist/assets/index-D1goIPjC.js +5598 -0
  4. package/frontend/dist/index.html +2 -2
  5. package/frontend/dist/sw.js +5 -4
  6. package/frontend/src/App.tsx +183 -236
  7. package/frontend/src/api/auth-inventory.ts +62 -0
  8. package/frontend/src/api/memory.ts +13 -8
  9. package/frontend/src/api/plugin-credentials.ts +23 -0
  10. package/frontend/src/api/plugins.ts +37 -53
  11. package/frontend/src/api/workspace-drawers.ts +97 -0
  12. package/frontend/src/components/BrainSelector.tsx +9 -3
  13. package/frontend/src/components/plugins/PluginPanel.tsx +83 -42
  14. package/frontend/src/components/plugins/PluginSettings.tsx +10 -20
  15. package/frontend/src/components/plugins/PluginWorkspace.tsx +367 -0
  16. package/frontend/src/components/plugins/ScopedPluginCommands.tsx +142 -0
  17. package/frontend/src/components/plugins/plugin-frame.ts +44 -33
  18. package/frontend/src/components/plugins/scoped-plugin-operations.ts +28 -0
  19. package/frontend/src/components/workspace/DrawerChat.tsx +110 -0
  20. package/frontend/src/components/workspace/DrawerLayout.tsx +196 -0
  21. package/frontend/src/components/workspace/DrawerMarkup.tsx +49 -0
  22. package/frontend/src/components/workspace/PluginChunkLibrary.tsx +92 -0
  23. package/frontend/src/components/workspace/PluginHome.tsx +76 -0
  24. package/frontend/src/components/workspace/WorkspaceDrawers.tsx +96 -0
  25. package/frontend/src/components/workspace/WorkspacePage.tsx +95 -0
  26. package/frontend/src/components/workspace/usePluginDesign.ts +38 -0
  27. package/frontend/src/index.css +409 -136
  28. package/frontend/src/pages/HelpPage.tsx +15 -46
  29. package/frontend/src/pages/MemoryPage.tsx +19 -36
  30. package/frontend/src/pages/SettingsPage.tsx +1 -1
  31. package/metadata.plugin.schema.json +53 -227
  32. package/package.json +1 -1
  33. package/scaffold/.agent/skills/plugin/SKILL.md +13 -11
  34. package/scaffold/.agent/skills/plugin/evals/README.md +14 -21
  35. package/scaffold/.agent/skills/plugin/evals/cases/01-fabricated-seed.mjs +15 -18
  36. package/scaffold/.agent/skills/plugin/evals/cases/02-reassuring-default.mjs +19 -24
  37. package/scaffold/.agent/skills/plugin/evals/cases/03-declared-template.mjs +12 -20
  38. package/scaffold/.agent/skills/plugin/evals/cases/04-home-collects-credential.mjs +35 -0
  39. package/scaffold/.agent/skills/plugin/evals/cases/05-host-leak-in-scaffold.mjs +8 -28
  40. package/scaffold/.agent/skills/plugin/evals/cases/06-correct-plugin.mjs +85 -47
  41. package/scaffold/.agent/skills/plugin/evals/run.mjs +17 -18
  42. package/scaffold/.agent/skills/plugin/prompts/05-credentials.md +4 -4
  43. package/scaffold/.agent/skills/plugin/prompts/07-scaffold.md +2 -2
  44. package/scaffold/.agent/skills/plugin/prompts/08-verify.md +4 -4
  45. package/scaffold/.agent/skills/plugin/references/anti-patterns.md +2 -2
  46. package/scaffold/.agent/skills/plugin/references/generative-home.md +38 -0
  47. package/scaffold/.agent/skills/plugin/references/scaffold.md +5 -5
  48. package/scaffold/.agent/skills/plugin/references/surfaces.md +13 -4
  49. package/scaffold/.agent/skills/plugin/scripts/record.mjs +75 -153
  50. package/scaffold/.agent/skills/plugin/subagents/plugin-reviewer.md +4 -4
  51. package/scaffold/.agent/skills/total-recall/plugins/auth/DESIGN.md +76 -0
  52. package/scaffold/.agent/skills/total-recall/plugins/auth/README.md +3 -1
  53. package/scaffold/.agent/skills/total-recall/plugins/auth/cli.mjs +20 -15
  54. package/scaffold/.agent/skills/total-recall/plugins/auth/package-lock.json +6 -6
  55. package/scaffold/.agent/skills/total-recall/plugins/auth/package.json +2 -1
  56. package/scaffold/.agent/skills/total-recall/plugins/auth/plugin.json +13 -51
  57. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/access-overview.md +17 -0
  58. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/agent-login.md +20 -0
  59. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/baseline-audit.md +22 -0
  60. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/credential-repository-binding.md +17 -0
  61. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/credential-store-maintenance.md +17 -0
  62. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/dashboard-password.md +18 -0
  63. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/dashboard-sessions.md +18 -0
  64. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/endpoint-probe.md +23 -0
  65. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/google-sign-in.md +21 -0
  66. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/mesh-machines.md +16 -0
  67. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/passkey-enrollment.md +21 -0
  68. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/registered-brains.md +16 -0
  69. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/scoped-access-keys.md +17 -0
  70. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/secret-inventory.md +25 -0
  71. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/signing-key-rotation.md +22 -0
  72. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/home.js +375 -0
  73. package/scaffold/.agent/skills/total-recall/plugins/automations/{ui/DESIGN.md → DESIGN.md} +32 -21
  74. package/scaffold/.agent/skills/total-recall/plugins/automations/adapters.mjs +17 -1
  75. package/scaffold/.agent/skills/total-recall/plugins/automations/cli.mjs +10 -1
  76. package/scaffold/.agent/skills/total-recall/plugins/automations/package-lock.json +6 -6
  77. package/scaffold/.agent/skills/total-recall/plugins/automations/package.json +4 -3
  78. package/scaffold/.agent/skills/total-recall/plugins/automations/plugin.json +11 -27
  79. package/scaffold/.agent/skills/total-recall/plugins/automations/ui/automations.js +2 -2
  80. package/scaffold/.agent/skills/total-recall/plugins/automations/ui/chunks/control-ledger.md +42 -0
  81. package/scaffold/.agent/skills/total-recall/plugins/automations/ui/chunks/local-inventory-triage.md +17 -0
  82. package/scaffold/.agent/skills/total-recall/plugins/automations/ui/chunks/pending-control.md +39 -0
  83. package/scaffold/.agent/skills/total-recall/plugins/automations/ui/chunks/run-evidence.md +41 -0
  84. package/scaffold/.agent/skills/total-recall/plugins/automations/ui/chunks/schedule-vs-run-evidence.md +17 -0
  85. package/scaffold/.agent/skills/total-recall/plugins/automations/ui/chunks/source-coverage.md +41 -0
  86. package/scaffold/.agent/skills/total-recall/plugins/automations/ui/{card.js → home.js} +32 -27
  87. package/scaffold/.agent/skills/total-recall/plugins/code-quality/DESIGN.md +53 -0
  88. package/scaffold/.agent/skills/total-recall/plugins/code-quality/cli.mjs +23 -0
  89. package/scaffold/.agent/skills/total-recall/plugins/code-quality/commands/run-core.mjs +4 -2
  90. package/scaffold/.agent/skills/total-recall/plugins/code-quality/core/check.mjs +4 -2
  91. package/scaffold/.agent/skills/total-recall/plugins/code-quality/package-lock.json +6 -6
  92. package/scaffold/.agent/skills/total-recall/plugins/code-quality/package.json +2 -1
  93. package/scaffold/.agent/skills/total-recall/plugins/code-quality/plugin.json +40 -40
  94. package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/chunks/config.md +15 -0
  95. package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/chunks/detect.md +15 -0
  96. package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/chunks/gate.md +15 -0
  97. package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/chunks/init.md +15 -0
  98. package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/chunks/report.md +17 -0
  99. package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/chunks/run.md +17 -0
  100. package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/chunks/snapshot.md +15 -0
  101. package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/code-quality-report.mjs +55 -23
  102. package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/home.mjs +214 -0
  103. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/DESIGN.md +146 -0
  104. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/package-lock.json +6 -6
  105. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/package.json +2 -1
  106. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/plugin.json +51 -34
  107. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/src/command.mjs +1 -1
  108. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/create.md +35 -0
  109. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/history.md +35 -0
  110. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/library.md +49 -0
  111. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/list.md +42 -0
  112. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/promote.md +40 -0
  113. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/read.md +25 -0
  114. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/remove.md +26 -0
  115. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/rollback.md +26 -0
  116. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/show.md +53 -0
  117. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/status.md +40 -0
  118. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/test-path.md +38 -0
  119. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/test.md +46 -0
  120. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/update.md +32 -0
  121. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/home.js +533 -0
  122. package/scaffold/.agent/skills/total-recall/plugins/embeddings/DESIGN.md +110 -0
  123. package/scaffold/.agent/skills/total-recall/plugins/embeddings/package-lock.json +6 -6
  124. package/scaffold/.agent/skills/total-recall/plugins/embeddings/package.json +2 -1
  125. package/scaffold/.agent/skills/total-recall/plugins/embeddings/plugin.json +13 -10
  126. package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/chunks/benchmark.md +49 -0
  127. package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/chunks/coverage.md +53 -0
  128. package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/chunks/models.md +43 -0
  129. package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/chunks/pull.md +41 -0
  130. package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/chunks/status.md +59 -0
  131. package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/home.js +353 -0
  132. package/scaffold/.agent/skills/total-recall/plugins/git/DESIGN.md +31 -0
  133. package/scaffold/.agent/skills/total-recall/plugins/git/README.md +25 -1
  134. package/scaffold/.agent/skills/total-recall/plugins/git/cli.mjs +5 -1
  135. package/scaffold/.agent/skills/total-recall/plugins/git/package-lock.json +6 -6
  136. package/scaffold/.agent/skills/total-recall/plugins/git/package.json +2 -1
  137. package/scaffold/.agent/skills/total-recall/plugins/git/plugin.json +17 -27
  138. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/commit-memory.mjs +30 -6
  139. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/fleet.mjs +24 -6
  140. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/secret-firewall.mjs +33 -7
  141. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/undo.mjs +29 -5
  142. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/unmerged.mjs +182 -0
  143. package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/change-comparison.md +27 -0
  144. package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/commit-identity.md +22 -0
  145. package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/create-worktree.md +25 -0
  146. package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/registered-worktrees.md +22 -0
  147. package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/remove-worktree.md +23 -0
  148. package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/repository-ledger.md +25 -0
  149. package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/unmerged-work.md +22 -0
  150. package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/upstream-divergence.md +17 -0
  151. package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/worktree-conflict-triage.md +17 -0
  152. package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/worktree-terminal.md +22 -0
  153. package/scaffold/.agent/skills/total-recall/plugins/git/ui/home.js +273 -0
  154. package/scaffold/.agent/skills/total-recall/plugins/mesh/DESIGN.md +35 -0
  155. package/scaffold/.agent/skills/total-recall/plugins/mesh/README.md +4 -5
  156. package/scaffold/.agent/skills/total-recall/plugins/mesh/cli.mjs +9 -3
  157. package/scaffold/.agent/skills/total-recall/plugins/mesh/package-lock.json +6 -6
  158. package/scaffold/.agent/skills/total-recall/plugins/mesh/package.json +2 -1
  159. package/scaffold/.agent/skills/total-recall/plugins/mesh/plugin.json +37 -39
  160. package/scaffold/.agent/skills/total-recall/plugins/mesh/src/cli/mesh.mjs +5 -3
  161. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/active-device-dispatch.md +22 -0
  162. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/control-probe.md +25 -0
  163. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/control-server.md +22 -0
  164. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/credential-readiness.md +23 -0
  165. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/elected-leader.md +22 -0
  166. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/enrollment-key.md +22 -0
  167. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/file-receipt.md +25 -0
  168. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/fleet-execution.md +23 -0
  169. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/fleet-presence.md +23 -0
  170. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/interactive-ssh.md +22 -0
  171. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/local-enrollment.md +23 -0
  172. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/mesh-policy.md +23 -0
  173. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/network-atlas.md +25 -0
  174. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/node-roster.md +26 -0
  175. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/node-selection-proof.md +17 -0
  176. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/owner-observations.md +23 -0
  177. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/peer-path.md +23 -0
  178. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/pinned-leader.md +24 -0
  179. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/reachability-evidence-ladder.md +17 -0
  180. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/recorded-login.md +23 -0
  181. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/remote-execution.md +22 -0
  182. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/secret-grants.md +26 -0
  183. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/{card.js → home.js} +93 -22
  184. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/DESIGN.md +86 -0
  185. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/README.md +19 -0
  186. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/cli.mjs +5 -1
  187. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/package-lock.json +6 -6
  188. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/package.json +2 -1
  189. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/plugin.json +43 -22
  190. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/chat.mjs +80 -0
  191. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/adapter-docs-freshness.md +16 -0
  192. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/chat-handoff.md +26 -0
  193. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/fleet-maintenance.md +21 -0
  194. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/harness-inventory.md +21 -0
  195. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/included-access.md +18 -0
  196. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/included-usage-verification.md +15 -0
  197. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/independent-review.md +17 -0
  198. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/managed-execution.md +20 -0
  199. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/official-documentation.md +18 -0
  200. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/quota-recovery.md +21 -0
  201. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/review-routing-decision.md +16 -0
  202. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/route-work.md +18 -0
  203. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/routing-evidence.md +18 -0
  204. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/run-ledger.md +18 -0
  205. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/home.js +198 -0
  206. package/scaffold/.agent/skills/total-recall/plugins/openwiki/DESIGN.md +75 -0
  207. package/scaffold/.agent/skills/total-recall/plugins/openwiki/README.md +2 -0
  208. package/scaffold/.agent/skills/total-recall/plugins/openwiki/cli.mjs +17 -14
  209. package/scaffold/.agent/skills/total-recall/plugins/openwiki/package-lock.json +6 -6
  210. package/scaffold/.agent/skills/total-recall/plugins/openwiki/package.json +2 -1
  211. package/scaffold/.agent/skills/total-recall/plugins/openwiki/plugin.json +10 -44
  212. package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/generate.mjs +5 -4
  213. package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/graph.mjs +3 -4
  214. package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/ingest.mjs +23 -18
  215. package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/mesh-vaults.mjs +8 -3
  216. package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/refresh.mjs +6 -3
  217. package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/search.mjs +3 -5
  218. package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/token.mjs +21 -47
  219. package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/upstream-watcher.mjs +17 -6
  220. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/auto-refresh.md +18 -0
  221. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/bootstrap-pages.md +18 -0
  222. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/generate-wiki.md +21 -0
  223. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/generator-settings.md +18 -0
  224. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/host-probe.md +18 -0
  225. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/ingest-preview.md +18 -0
  226. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/link-hygiene.md +21 -0
  227. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/link-topology.md +19 -0
  228. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/passage-search.md +19 -0
  229. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/propagation-plan.md +18 -0
  230. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/provider-credentials.md +18 -0
  231. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/refresh-report.md +18 -0
  232. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/task-evidence.md +22 -0
  233. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/upstream-record.md +18 -0
  234. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/watch-upstream.md +18 -0
  235. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/wiki-atlas.md +19 -0
  236. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/panel.js +261 -513
  237. package/scaffold/.agent/skills/total-recall/plugins/security/DESIGN.md +84 -0
  238. package/scaffold/.agent/skills/total-recall/plugins/security/README.md +4 -2
  239. package/scaffold/.agent/skills/total-recall/plugins/security/cli.mjs +7 -19
  240. package/scaffold/.agent/skills/total-recall/plugins/security/package-lock.json +6 -6
  241. package/scaffold/.agent/skills/total-recall/plugins/security/package.json +2 -3
  242. package/scaffold/.agent/skills/total-recall/plugins/security/plugin.json +19 -52
  243. package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/device-evidence.md +21 -0
  244. package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/evidence-desk.md +18 -0
  245. package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/guided-device-review.md +17 -0
  246. package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/host-and-network.md +21 -0
  247. package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/https-headers.md +17 -0
  248. package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/mesh-coverage.md +18 -0
  249. package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/private-security-tools.md +16 -0
  250. package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/single-origin-header-check.md +17 -0
  251. package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/source-review.md +21 -0
  252. package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/ssh-permission-plan.md +17 -0
  253. package/scaffold/.agent/skills/total-recall/plugins/security/ui/home.js +283 -0
  254. package/scaffold/.agent/skills/total-recall/plugins/ssss/DESIGN.md +93 -0
  255. package/scaffold/.agent/skills/total-recall/plugins/ssss/package-lock.json +2 -2
  256. package/scaffold/.agent/skills/total-recall/plugins/ssss/package.json +2 -1
  257. package/scaffold/.agent/skills/total-recall/plugins/ssss/plugin.json +5 -3
  258. package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/chunks/conformance.md +26 -0
  259. package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/chunks/registry.md +37 -0
  260. package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/chunks/repair.md +42 -0
  261. package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/chunks/scaffold.md +33 -0
  262. package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/chunks/status.md +43 -0
  263. package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/chunks/validate.md +34 -0
  264. package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/chunks/validation-diagnostics.md +17 -0
  265. package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/chunks/workspace-registry-preflight.md +17 -0
  266. package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/home.js +348 -0
  267. package/scaffold/.agent/skills/total-recall/references/operations.md +2 -0
  268. package/src/cli/api.mjs +3 -3
  269. package/src/cli/brief.mjs +3 -0
  270. package/src/cli/config.mjs +16 -0
  271. package/src/cli/connect.mjs +2 -7
  272. package/src/cli/plugin/chunks.mjs +145 -0
  273. package/src/cli/plugin/create.mjs +24 -52
  274. package/src/cli/plugin/index.mjs +20 -9
  275. package/src/cli/setup.mjs +2 -9
  276. package/src/cli/start.mjs +1 -0
  277. package/src/cli/startup.mjs +18 -0
  278. package/src/core/app-deploy/design-tokens.mjs +14 -9
  279. package/src/core/app-deploy/ui-elements.mjs +1 -1
  280. package/src/core/brain-registry.mjs +5 -0
  281. package/src/core/brain-updates.mjs +5 -1
  282. package/src/core/daemon-control.mjs +5 -1
  283. package/src/core/dashboard-bundle.mjs +261 -0
  284. package/src/core/ensure-dependencies.mjs +19 -15
  285. package/src/core/memory-brain.mjs +30 -8
  286. package/src/core/plugin-activation.mjs +63 -20
  287. package/src/core/plugin-contracts/{card.mjs → manifest.mjs} +23 -57
  288. package/src/core/plugin-contracts/startup-check.mjs +49 -0
  289. package/src/core/plugin-contracts/ui.mjs +9 -3
  290. package/src/core/plugin-distribution.mjs +6 -6
  291. package/src/core/plugin-lifecycle.mjs +58 -0
  292. package/src/core/plugin-loader.mjs +9 -5
  293. package/src/core/plugin-runner.mjs +21 -10
  294. package/src/core/plugin-startup-checks.mjs +44 -0
  295. package/src/core/plugin-state.mjs +19 -5
  296. package/src/core/plugin-store.mjs +30 -11
  297. package/src/core/project-id.mjs +15 -5
  298. package/src/core/required-plugins.mjs +31 -6
  299. package/src/core/schema.mjs +2 -0
  300. package/src/core/ssss-operation-service.mjs +1 -0
  301. package/src/core/startup-health.mjs +28 -3
  302. package/src/core/testing/plugin-fixture.mjs +22 -21
  303. package/src/core/throttled-fetch.mjs +25 -18
  304. package/src/core/ui-chunk-choice.mjs +77 -0
  305. package/src/core/ui-chunk.registry.json +23 -0
  306. package/src/core/ui-chunks.mjs +434 -0
  307. package/src/core/vault-cache.mjs +58 -59
  308. package/src/core/workspace-compositions.mjs +151 -0
  309. package/src/core/workspace-drawers.mjs +79 -0
  310. package/src/server/api.mjs +4 -27
  311. package/src/server/index.mjs +28 -21
  312. package/src/server/memory-events.mjs +31 -0
  313. package/src/server/plugin-brain-targets.mjs +89 -0
  314. package/src/server/rest.mjs +2 -0
  315. package/src/server/route-inventory.mjs +3 -2
  316. package/src/server/route-manifest.json +52 -4
  317. package/src/server/routes/_shared.mjs +7 -14
  318. package/src/server/routes/brains.mjs +29 -44
  319. package/src/server/routes/dashboard.mjs +26 -0
  320. package/src/server/routes/plugins.mjs +154 -45
  321. package/src/server/routes/ui-chunks.mjs +192 -0
  322. package/frontend/dist/assets/index-DACh1dhx.js +0 -5613
  323. package/frontend/dist/assets/index-DtwsDyFM.css +0 -1
  324. package/frontend/src/components/plugins/card/CardEngine.tsx +0 -108
  325. package/frontend/src/components/plugins/card/CardScenes.tsx +0 -103
  326. package/frontend/src/components/plugins/card/ExecutionPicker.tsx +0 -64
  327. package/frontend/src/components/plugins/card/args.ts +0 -28
  328. package/frontend/src/components/plugins/card/card.css +0 -32
  329. package/frontend/src/components/plugins/card/cli-line.ts +0 -13
  330. package/frontend/src/components/plugins/card/contract.ts +0 -91
  331. package/frontend/src/components/plugins/card/format.ts +0 -49
  332. package/frontend/src/components/plugins/card/runner-context.ts +0 -11
  333. package/frontend/src/components/plugins/card/runner.tsx +0 -43
  334. package/frontend/src/components/plugins/card/theme.ts +0 -35
  335. package/frontend/src/components/plugins/card/use-source.ts +0 -22
  336. package/frontend/src/components/plugins/card/widgets.tsx +0 -94
  337. package/frontend/src/components/plugins/workspace/WorkspaceHost.tsx +0 -23
  338. package/frontend/src/pages/PluginsPage.tsx +0 -1719
  339. package/scaffold/.agent/skills/plugin/evals/cases/04-card-collects-credential.mjs +0 -47
  340. package/scaffold/.agent/skills/plugin/prompts/06-card.md +0 -46
  341. package/scaffold/.agent/skills/plugin/references/card.md +0 -90
  342. package/scaffold/.agent/skills/plugin/subagents/card-designer.md +0 -60
  343. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/DESIGN.md +0 -67
  344. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/card.js +0 -1179
  345. package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/DESIGN.md +0 -32
  346. package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/card.js +0 -588
  347. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/card.js +0 -575
  348. package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/DESIGN.md +0 -32
  349. package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/card.js +0 -482
  350. package/scaffold/.agent/skills/total-recall/plugins/git/ui/DESIGN.md +0 -100
  351. package/scaffold/.agent/skills/total-recall/plugins/git/ui/card.js +0 -637
  352. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/DESIGN.md +0 -217
  353. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/DESIGN.md +0 -32
  354. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/card.js +0 -1276
  355. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/DESIGN.md +0 -45
  356. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/card.js +0 -1401
  357. package/scaffold/.agent/skills/total-recall/plugins/security/scripts/build-ui.mjs +0 -4
  358. package/scaffold/.agent/skills/total-recall/plugins/security/ui/DESIGN.md +0 -41
  359. package/scaffold/.agent/skills/total-recall/plugins/security/ui/card.js +0 -396
  360. package/scaffold/.agent/skills/total-recall/plugins/security/ui/panel.js +0 -98
  361. package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/DESIGN.md +0 -15
  362. package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/card.js +0 -182
@@ -1,539 +1,287 @@
1
- // OpenWiki Interactive Knowledge Graph & Engine Panel
2
- // Provides full knowledge graph node inspection, hub directory browsing,
3
- // ingestion triggers, and secure API credential storage.
4
- class OpenwikiPanel extends HTMLElement {
1
+ const template = document.createElement('template');
2
+ template.innerHTML = `
3
+ <style>
4
+ :host {
5
+ display: block;
6
+ color: var(--color-text, #302519);
7
+ font: 1rem/1.55 var(--typography-body-font-family, system-ui, sans-serif);
8
+ }
9
+ * { box-sizing: border-box; }
10
+ .atlas {
11
+ background: var(--color-background, #f9f1e3);
12
+ border: 1px solid var(--color-outline, #cbb497);
13
+ border-radius: var(--radius-panel, 0.45rem);
14
+ padding: var(--spacing-lg, 1.5rem);
15
+ }
16
+ .toolbar, .search-controls, .graph-tools {
17
+ display: flex;
18
+ align-items: center;
19
+ justify-content: space-between;
20
+ flex-wrap: wrap;
21
+ gap: var(--spacing-sm, 0.65rem);
22
+ }
23
+ h2, h3 {
24
+ font-family: var(--typography-heading-font-family, Georgia, serif);
25
+ font-weight: var(--typography-heading-font-weight, 600);
26
+ margin: 0;
27
+ }
28
+ h2 { font-size: var(--typography-heading-font-size, 1.8rem); }
29
+ h3 { font-size: 1.3rem; }
30
+ p { margin: 0.35rem 0; }
31
+ .state, small { color: var(--color-muted, #6d5741); }
32
+ [data-error] { color: var(--color-error, #9b2a20); }
33
+ input, select, button {
34
+ background: var(--color-surface, #fff9ee);
35
+ border: 1px solid var(--color-outline, #cbb497);
36
+ border-radius: var(--radius-control, 0.3rem);
37
+ color: inherit;
38
+ font: inherit;
39
+ min-height: 44px;
40
+ padding: 0.35rem 0.75rem;
41
+ }
42
+ input { flex: 1 1 13rem; min-width: 0; }
43
+ button { cursor: pointer; }
44
+ button:disabled { cursor: wait; opacity: 0.65; }
45
+ :focus-visible { outline: 2px solid var(--color-primary, #8d3e10); outline-offset: 2px; }
46
+ .search-controls button {
47
+ background: var(--color-primary, #8d3e10);
48
+ border-color: var(--color-primary, #8d3e10);
49
+ color: var(--color-on-primary, #fff9ee);
50
+ font-weight: 600;
51
+ }
52
+ .search { margin-block: var(--spacing-lg, 1.5rem); }
53
+ label { display: block; font-weight: 600; margin-bottom: 0.3rem; }
54
+ .grid { display: grid; gap: var(--spacing-lg, 1.5rem); grid-template-columns: repeat(2, minmax(0, 1fr)); }
55
+ ul { list-style: none; padding: 0; margin: 0; }
56
+ li { overflow-wrap: anywhere; }
57
+ .index li, .links li { border-bottom: 1px solid var(--color-outline, #cbb497); padding-block: 0.5rem; }
58
+ .index small { display: block; }
59
+ small, code { font: 0.8rem/1.5 var(--typography-source-font-family, ui-monospace, monospace); }
60
+ .results li {
61
+ background: var(--color-surface, #fff9ee);
62
+ border-inline-start: 2px solid var(--color-primary, #8d3e10);
63
+ margin-block-start: var(--spacing-sm, 0.65rem);
64
+ padding: var(--spacing-sm, 0.65rem) var(--spacing-md, 1rem);
65
+ }
66
+ .edge { color: var(--color-primary, #8d3e10); font-weight: 700; }
67
+ @media (max-width: 580px) {
68
+ .atlas { padding: var(--spacing-md, 1rem); }
69
+ .grid { grid-template-columns: 1fr; }
70
+ }
71
+ </style>
72
+ <section class="atlas" aria-labelledby="atlas">
73
+ <header class="toolbar">
74
+ <div>
75
+ <h2 id="atlas">Workspace wiki atlas</h2>
76
+ <p id="upstream" class="state" role="status">Reading recorded version…</p>
77
+ </div>
78
+ <button type="button" id="reload">Refresh index</button>
79
+ </header>
80
+ <section class="search" role="search" aria-label="Evidence search">
81
+ <label for="query">Search wiki evidence</label>
82
+ <div class="search-controls">
83
+ <input id="query" type="search" maxlength="220">
84
+ <button type="button" id="search">Search</button>
85
+ </div>
86
+ <label for="scope">Evidence scope</label>
87
+ <select id="scope">
88
+ <option value="workspace">Selected workspace</option>
89
+ <option value="all-vaults">All registered wikis</option>
90
+ </select>
91
+ <p id="search-state" class="state" role="status">Search headings and passages in this workspace.</p>
92
+ <ul id="results" class="results" aria-label="Evidence results"></ul>
93
+ </section>
94
+ <div class="grid">
95
+ <section class="index" aria-labelledby="index">
96
+ <h3 id="index">Wiki index</h3>
97
+ <p id="index-state" class="state" role="status">Reading workspace pages…</p>
98
+ <ul id="pages" aria-label="Wiki pages"></ul>
99
+ </section>
100
+ <section aria-labelledby="topology">
101
+ <div class="graph-tools">
102
+ <h3 id="topology">Link topology</h3>
103
+ <button type="button" id="graph">Inspect links</button>
104
+ </div>
105
+ <p id="graph-state" class="state" role="status">Trace links between pages in the workspace.</p>
106
+ <ul id="links" class="links" aria-label="Documentation links"></ul>
107
+ </section>
108
+ </div>
109
+ </section>
110
+ `;
111
+
112
+ const number = value => Number.isSafeInteger(value) && value >= 0;
113
+
114
+ function element(tag, text, className) {
115
+ const node = document.createElement(tag);
116
+ node.textContent = text;
117
+ if (className) node.className = className;
118
+ return node;
119
+ }
120
+
121
+ class OpenWikiPanel extends HTMLElement {
5
122
  constructor() {
6
123
  super();
7
- this.attachShadow({ mode: 'open' });
8
- this._view = null;
9
- this._activeTab = 'graph';
10
- this._searchQuery = '';
11
- this._selectedCategory = 'all';
12
- this._selectedNode = null;
13
- this._ingestOutput = '';
14
- this._nodes = [];
15
- this._loading = false;
124
+ this.attachShadow({ mode: 'open' }).append(template.content.cloneNode(true));
125
+ this.#field('reload').addEventListener('click', () => void this.load());
126
+ this.#field('graph').addEventListener('click', () => void this.#graph());
127
+ this.#field('search').addEventListener('click', () => void this.#search());
128
+ this.#field('scope').addEventListener('change', () => {
129
+ this.#field('results').replaceChildren();
130
+ this.#field('links').replaceChildren();
131
+ const label = this.#scope() === 'all-vaults' ? 'registered wikis' : 'this workspace';
132
+ this.#state('search-state', `Search headings and passages in ${label}.`);
133
+ this.#state('graph-state', `Trace links between pages in ${label}.`);
134
+ });
135
+ this.#field('query').addEventListener('keydown', event => {
136
+ if (event.key !== 'Enter' || event.isComposing) return;
137
+ event.preventDefault();
138
+ void this.#search();
139
+ });
16
140
  }
17
141
 
18
- set host(h) {
19
- this._host = h;
20
- this._loadLiveNodes();
142
+ #field(id) {
143
+ return this.shadowRoot.getElementById(id);
21
144
  }
22
145
 
23
- get host() {
24
- return this._host;
146
+ #scope() {
147
+ return this.#field('scope').value === 'all-vaults' ? 'all-vaults' : 'workspace';
25
148
  }
26
149
 
27
- connectedCallback() {
28
- this._loadLiveNodes();
29
- this.render();
150
+ #state(id, text, error = false) {
151
+ const field = this.#field(id);
152
+ field.textContent = text;
153
+ field.toggleAttribute('data-error', error);
30
154
  }
31
155
 
32
- async _loadLiveNodes() {
33
- if (this._loading) return;
34
- this._loading = true;
156
+ async load() {
157
+ const button = this.#field('reload');
158
+ if (button.disabled) return;
159
+ button.disabled = true;
160
+ this.#state('index-state', 'Reading workspace pages…');
161
+ this.#state('upstream', 'Reading recorded version…');
162
+ this.#field('pages').replaceChildren();
35
163
  try {
36
- if (this._host && typeof this._host.run === 'function') {
37
- const res = await this._host.run('hubs', ['--json']);
38
- if (res && res.output) {
39
- const parsed = JSON.parse(res.output);
40
- if (parsed && Array.isArray(parsed.hubs) && parsed.hubs.length > 0) {
41
- this._nodes = parsed.hubs.map((h) => ({
42
- slug: h.path,
43
- title: h.title,
44
- category: 'hub',
45
- importance: 3,
46
- priority: 'normal',
47
- tags: ['openwiki', 'hub', 'documentation'],
48
- body: `Path: ${h.path}\nSize: ${h.size_bytes} bytes\nLines: ${h.lines}`
49
- }));
50
- this.render();
51
- return;
52
- }
53
- }
54
- }
55
-
56
- const res = await fetch('/api/memory?tag=openwiki', { signal: AbortSignal.timeout(3000) });
57
- if (res.ok) {
58
- const data = await res.json();
59
- const items = Array.isArray(data) ? data : (data.nodes || []);
60
- if (items.length > 0) {
61
- this._nodes = items.map((n) => ({
62
- slug: n.slug || n.id || 'node',
63
- title: n.title || 'Untitled Node',
64
- category: n.category || 'fact',
65
- importance: n.importance || 3,
66
- priority: n.priority || 'medium',
67
- tags: n.tags || [],
68
- body: n.body || n.content || ''
69
- }));
70
- this.render();
71
- }
72
- }
73
- } catch {
74
- // Retain live empty state honestly
164
+ await Promise.all([
165
+ this.#loadIndex(),
166
+ this.#loadStatus(),
167
+ ]);
75
168
  } finally {
76
- this._loading = false;
169
+ button.disabled = false;
77
170
  }
78
171
  }
79
172
 
80
- set view(value) {
81
- this._view = value;
82
- this.render();
83
- }
84
-
85
- get view() {
86
- return this._view;
87
- }
88
-
89
- connectedCallback() {
90
- this.render();
173
+ async #loadIndex() {
174
+ try {
175
+ const result = await this.host.run('hubs');
176
+ if (result?.scope !== 'workspace' || !Array.isArray(result.hubs) || !number(result.count)) throw new Error('Invalid wiki index');
177
+ const pages = result.hubs.slice(0, 12);
178
+ for (const page of pages) {
179
+ const row = element('li', '');
180
+ row.append(element('strong', page.title), element('small', page.fileName));
181
+ this.#field('pages').append(row);
182
+ }
183
+ const total = result.count;
184
+ const count = total === 1 ? '1 wiki page' : `${total} wiki pages`;
185
+ this.#state('index-state', total === 0 ? 'This workspace has no wiki pages.' :
186
+ total > pages.length ? `${count}. Showing ${pages.length}.` : `${count}.`);
187
+ } catch {
188
+ this.#field('pages').replaceChildren();
189
+ this.#state('index-state', 'Wiki index unavailable. Refresh to try again.', true);
190
+ }
91
191
  }
92
192
 
93
- _filterNodes() {
94
- return this._nodes.filter((node) => {
95
- const matchCat = this._selectedCategory === 'all' || node.category === this._selectedCategory;
96
- const q = this._searchQuery.toLowerCase();
97
- const matchQuery = !q || node.title.toLowerCase().includes(q) || node.body.toLowerCase().includes(q) || node.tags.some((t) => t.toLowerCase().includes(q));
98
- return matchCat && matchQuery;
99
- });
193
+ async #loadStatus() {
194
+ try {
195
+ const result = await this.host.run('status');
196
+ if (result?.plugin !== 'openwiki' || !result.upstream) throw new Error('Invalid OpenWiki status');
197
+ const { latestVersion, lastChecked } = result.upstream;
198
+ const version = typeof result.generatorVersion === 'string'
199
+ ? `Bundled generator ${result.generatorVersion}` : 'Bundled generator unavailable';
200
+ const checked = Date.parse(lastChecked);
201
+ const note = typeof latestVersion === 'string' && Number.isFinite(checked)
202
+ ? ` · Latest upstream observation ${latestVersion} on ${new Date(checked).toISOString().slice(0, 10)}`
203
+ : ' · Upstream check pending';
204
+ this.#state('upstream', version + note);
205
+ } catch {
206
+ this.#state('upstream', 'Recorded upstream status unavailable.', true);
207
+ }
100
208
  }
101
209
 
102
- render() {
103
- const root = this.shadowRoot;
104
- if (!root) return;
105
- root.replaceChildren();
106
-
107
- const present = Boolean(this._view && this._view.present);
108
- const filteredNodes = this._filterNodes();
109
-
110
- const style = document.createElement('style');
111
- style.textContent = `
112
- :host {
113
- display: block;
114
- font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
115
- color: var(--color-text, #f8fafc);
116
- background: var(--color-surface, #0f172a);
117
- border: 1px solid var(--color-border, #1e293b);
118
- border-radius: var(--radius-md, 8px);
119
- padding: 16px;
120
- box-sizing: border-box;
121
- }
122
- * { box-sizing: border-box; }
123
- .header {
124
- display: flex;
125
- justify-content: space-between;
126
- align-items: center;
127
- border-bottom: 1px solid var(--color-border, #1e293b);
128
- padding-bottom: 12px;
129
- margin-bottom: 16px;
130
- }
131
- .title {
132
- font-size: 18px;
133
- font-weight: 700;
134
- margin: 0;
135
- color: #f8fafc;
136
- display: flex;
137
- align-items: center;
138
- gap: 8px;
139
- }
140
- .badge {
141
- font-size: 11px;
142
- text-transform: uppercase;
143
- letter-spacing: 0.05em;
144
- padding: 3px 8px;
145
- border-radius: 4px;
146
- background: rgba(180, 83, 9, 0.2);
147
- color: #f59e0b;
148
- font-weight: 600;
149
- }
150
- .tabs {
151
- display: flex;
152
- gap: 8px;
153
- margin-bottom: 16px;
154
- }
155
- .tab-btn {
156
- min-height: 44px;
157
- padding: 8px 16px;
158
- border: 1px solid var(--color-border, #1e293b);
159
- background: rgba(255, 255, 255, 0.03);
160
- color: var(--color-text, #94a3b8);
161
- border-radius: var(--radius-md, 6px);
162
- font-size: 13px;
163
- font-weight: 600;
164
- cursor: pointer;
165
- display: flex;
166
- align-items: center;
167
- justify-content: center;
168
- transition: all 0.15s ease;
169
- }
170
- .tab-btn.active {
171
- background: #b45309;
172
- border-color: #d97706;
173
- color: #ffffff;
174
- }
175
- .controls {
176
- display: flex;
177
- gap: 8px;
178
- flex-wrap: wrap;
179
- margin-bottom: 16px;
180
- }
181
- .search-box {
182
- flex: 1;
183
- min-height: 44px;
184
- min-width: 200px;
185
- padding: 8px 12px;
186
- background: rgba(0, 0, 0, 0.3);
187
- border: 1px solid var(--color-border, #1e293b);
188
- border-radius: var(--radius-md, 6px);
189
- color: #f8fafc;
190
- font-size: 13px;
191
- }
192
- .filter-select {
193
- min-height: 44px;
194
- padding: 8px 12px;
195
- background: rgba(0, 0, 0, 0.3);
196
- border: 1px solid var(--color-border, #1e293b);
197
- border-radius: var(--radius-md, 6px);
198
- color: #f8fafc;
199
- font-size: 13px;
200
- }
201
- .grid {
202
- display: grid;
203
- grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
204
- gap: 12px;
205
- margin-bottom: 16px;
206
- }
207
- .node-card {
208
- background: rgba(255, 255, 255, 0.02);
209
- border: 1px solid var(--color-border, #1e293b);
210
- border-radius: var(--radius-md, 6px);
211
- padding: 12px;
212
- cursor: pointer;
213
- transition: border-color 0.15s ease;
214
- }
215
- .node-card:hover {
216
- border-color: #b45309;
217
- }
218
- .node-title {
219
- font-size: 14px;
220
- font-weight: 600;
221
- margin: 0 0 6px 0;
222
- color: #f1f5f9;
223
- }
224
- .node-cat {
225
- font-size: 10px;
226
- text-transform: uppercase;
227
- font-weight: 700;
228
- padding: 2px 6px;
229
- border-radius: 3px;
230
- display: inline-block;
231
- margin-bottom: 8px;
232
- }
233
- .cat-invariant { background: rgba(239, 68, 68, 0.2); color: #ef4444; }
234
- .cat-preference { background: rgba(59, 130, 246, 0.2); color: #3b82f6; }
235
- .cat-fact { background: rgba(16, 185, 129, 0.2); color: #10b981; }
236
- .cat-concept { background: rgba(245, 158, 11, 0.2); color: #f59e0b; }
237
- .node-snippet {
238
- font-size: 12px;
239
- color: #94a3b8;
240
- line-height: 1.4;
241
- margin: 0;
242
- }
243
- .detail-pane {
244
- background: rgba(0, 0, 0, 0.4);
245
- border: 1px solid #b45309;
246
- border-radius: var(--radius-md, 6px);
247
- padding: 16px;
248
- margin-bottom: 16px;
249
- }
250
- .detail-header {
251
- display: flex;
252
- justify-content: space-between;
253
- align-items: flex-start;
254
- margin-bottom: 12px;
255
- }
256
- .detail-title {
257
- font-size: 16px;
258
- font-weight: 700;
259
- margin: 0;
260
- color: #ffffff;
261
- }
262
- .detail-body {
263
- font-size: 13px;
264
- line-height: 1.6;
265
- color: #cbd5e1;
266
- white-space: pre-wrap;
267
- }
268
- .btn {
269
- min-height: 44px;
270
- padding: 8px 16px;
271
- border: 1px solid var(--color-border, #1e293b);
272
- border-radius: var(--radius-md, 6px);
273
- background: #b45309;
274
- color: #ffffff;
275
- font-weight: 600;
276
- cursor: pointer;
277
- font-size: 13px;
278
- display: inline-flex;
279
- align-items: center;
280
- justify-content: center;
281
- }
282
- .btn-secondary {
283
- background: rgba(255, 255, 255, 0.05);
284
- color: #cbd5e1;
285
- }
286
- .row {
287
- display: flex;
288
- gap: 8px;
289
- flex-wrap: wrap;
290
- margin-top: 12px;
291
- }
292
- input[type="text"], input[type="password"] {
293
- flex: 1;
294
- min-height: 44px;
295
- padding: 8px 12px;
296
- border-radius: var(--radius-md, 6px);
297
- border: 1px solid var(--color-border, #1e293b);
298
- background: rgba(0, 0, 0, 0.3);
299
- color: #f8fafc;
300
- font-size: 13px;
301
- }
302
- .terminal {
303
- background: #090d16;
304
- border: 1px solid #1e293b;
305
- border-radius: 6px;
306
- padding: 12px;
307
- font-family: monospace;
308
- font-size: 12px;
309
- color: #38bdf8;
310
- min-height: 60px;
311
- white-space: pre-wrap;
312
- margin-top: 12px;
210
+ async #search() {
211
+ const button = this.#field('search');
212
+ const query = this.#field('query').value.trim();
213
+ if (button.disabled) return;
214
+ if (!query || query.startsWith('--')) {
215
+ this.#state('search-state', 'Enter a phrase or keyword to search.', true);
216
+ return;
217
+ }
218
+ button.disabled = true;
219
+ const scope = this.#scope();
220
+ const label = scope === 'all-vaults' ? 'registered wikis' : 'this workspace';
221
+ this.#state('search-state', `Searching ${label}…`);
222
+ const list = this.#field('results');
223
+ list.replaceChildren();
224
+ try {
225
+ const result = await this.host.run('search', [query, '--limit', '8', ...(scope === 'all-vaults' ? ['--all-vaults'] : [])]);
226
+ if (scope !== this.#scope()) return;
227
+ if (!result?.ok || result.scope !== scope || !Array.isArray(result.results) || !number(result.totalHits)) throw new Error('Invalid search results');
228
+ for (const match of result.results) {
229
+ const item = element('li', '');
230
+ const section = match.section ? ` · ${match.section}` : '';
231
+ const repository = scope === 'all-vaults' && match.repoName ? `${match.repoName} · ` : '';
232
+ const reference = `${repository}${match.fileName}:${match.line}${section}`;
233
+ item.append(element('strong', match.title), element('p', match.snippet), element('small', reference));
234
+ list.append(item);
313
235
  }
314
- `;
315
-
316
- const header = document.createElement('div');
317
- header.className = 'header';
318
- header.innerHTML = `
319
- <div class="title">
320
- <span>OpenWiki Knowledge Engine</span>
321
- <span class="badge">Graph Active</span>
322
- </div>
323
- `;
324
-
325
- const tabs = document.createElement('div');
326
- tabs.className = 'tabs';
327
-
328
- const tabGraph = document.createElement('button');
329
- tabGraph.className = `tab-btn ${this._activeTab === 'graph' ? 'active' : ''}`;
330
- tabGraph.textContent = 'Knowledge Graph';
331
- tabGraph.onclick = () => { this._activeTab = 'graph'; this.render(); };
332
-
333
- const tabIngest = document.createElement('button');
334
- tabIngest.className = `tab-btn ${this._activeTab === 'ingest' ? 'active' : ''}`;
335
- tabIngest.textContent = 'Ingest Hub';
336
- tabIngest.onclick = () => { this._activeTab = 'ingest'; this.render(); };
337
-
338
- const tabConfig = document.createElement('button');
339
- tabConfig.className = `tab-btn ${this._activeTab === 'config' ? 'active' : ''}`;
340
- tabConfig.textContent = 'Credentials & Secrets';
341
- tabConfig.onclick = () => { this._activeTab = 'config'; this.render(); };
342
-
343
- tabs.append(tabGraph, tabIngest, tabConfig);
344
-
345
- const mainContainer = document.createElement('div');
346
-
347
- if (this._activeTab === 'graph') {
348
- const controls = document.createElement('div');
349
- controls.className = 'controls';
350
-
351
- const search = document.createElement('input');
352
- search.type = 'text';
353
- search.className = 'search-box';
354
- search.placeholder = 'Search knowledge graph nodes...';
355
- search.value = this._searchQuery;
356
- search.oninput = (e) => {
357
- this._searchQuery = e.target.value;
358
- this.render();
359
- };
360
-
361
- const select = document.createElement('select');
362
- select.className = 'filter-select';
363
- [
364
- { val: 'all', lbl: 'All Categories' },
365
- { val: 'invariant', lbl: 'Invariants' },
366
- { val: 'preference', lbl: 'Preferences' },
367
- { val: 'fact', lbl: 'Facts' },
368
- { val: 'concept', lbl: 'Concepts' }
369
- ].forEach((opt) => {
370
- const el = document.createElement('option');
371
- el.value = opt.val;
372
- el.textContent = opt.lbl;
373
- el.selected = opt.val === this._selectedCategory;
374
- select.appendChild(el);
375
- });
376
- select.onchange = (e) => {
377
- this._selectedCategory = e.target.value;
378
- this.render();
379
- };
380
-
381
- controls.append(search, select);
382
- mainContainer.appendChild(controls);
383
-
384
- if (this._selectedNode) {
385
- const detail = document.createElement('div');
386
- detail.className = 'detail-pane';
387
-
388
- const dHeader = document.createElement('div');
389
- dHeader.className = 'detail-header';
390
-
391
- const dTitle = document.createElement('h4');
392
- dTitle.className = 'detail-title';
393
- dTitle.textContent = this._selectedNode.title;
394
-
395
- const closeBtn = document.createElement('button');
396
- closeBtn.className = 'btn btn-secondary';
397
- closeBtn.textContent = 'Dismiss';
398
- closeBtn.onclick = () => { this._selectedNode = null; this.render(); };
399
-
400
- dHeader.append(dTitle, closeBtn);
401
-
402
- const dBody = document.createElement('div');
403
- dBody.className = 'detail-body';
404
- dBody.textContent = this._selectedNode.body;
236
+ const total = result.totalHits;
237
+ const noun = total === 1 ? 'passage' : 'passages';
238
+ const clipped = total > result.results.length ? ` Showing ${result.results.length}.` : '';
239
+ this.#state('search-state', total === 0 ? `No matching passages in ${label}.` : `${total} matching ${noun} in ${label}.${clipped}`);
240
+ } catch {
241
+ if (scope !== this.#scope()) return;
242
+ list.replaceChildren();
243
+ this.#state('search-state', 'Evidence search unavailable. Try again.', true);
244
+ } finally {
245
+ button.disabled = false;
246
+ }
247
+ }
405
248
 
406
- detail.append(dHeader, dBody);
407
- mainContainer.appendChild(detail);
249
+ async #graph() {
250
+ const button = this.#field('graph');
251
+ if (button.disabled) return;
252
+ button.disabled = true;
253
+ const scope = this.#scope();
254
+ const label = scope === 'all-vaults' ? 'registered wikis' : 'this workspace';
255
+ this.#state('graph-state', 'Tracing links between wiki pages…');
256
+ const list = this.#field('links');
257
+ list.replaceChildren();
258
+ try {
259
+ const result = await this.host.run('graph', ['--format', 'json', ...(scope === 'all-vaults' ? ['--all-vaults'] : [])]);
260
+ if (scope !== this.#scope()) return;
261
+ if (!result?.ok || result.scope !== scope || !Array.isArray(result.nodes) || !Array.isArray(result.edges) ||
262
+ !number(result.counts?.nodes) || !number(result.counts.edges) || !number(result.counts.orphans)) throw new Error('Invalid wiki topology');
263
+ const labels = new Map(result.nodes.map(node => [node.id, node.label]));
264
+ const edges = result.edges.slice(0, 12);
265
+ for (const edge of edges) {
266
+ const row = element('li', '');
267
+ row.append(element('span', labels.get(edge.from) ?? edge.from),
268
+ element('span', ' → ', 'edge'), element('span', labels.get(edge.to) ?? edge.to));
269
+ list.append(row);
408
270
  }
409
-
410
- const grid = document.createElement('div');
411
- grid.className = 'grid';
412
-
413
- filteredNodes.forEach((node) => {
414
- const card = document.createElement('div');
415
- card.className = 'node-card';
416
- card.onclick = () => {
417
- this._selectedNode = node;
418
- this.render();
419
- };
420
-
421
- const cBadge = document.createElement('span');
422
- cBadge.className = `node-cat cat-${node.category}`;
423
- cBadge.textContent = node.category;
424
-
425
- const cTitle = document.createElement('h5');
426
- cTitle.className = 'node-title';
427
- cTitle.textContent = node.title;
428
-
429
- const cSnippet = document.createElement('p');
430
- cSnippet.className = 'node-snippet';
431
- cSnippet.textContent = node.body.slice(0, 110) + '...';
432
-
433
- card.append(cBadge, cTitle, cSnippet);
434
- grid.appendChild(card);
435
- });
436
-
437
- mainContainer.appendChild(grid);
438
- } else if (this._activeTab === 'ingest') {
439
- const ingestDesc = document.createElement('p');
440
- ingestDesc.style.color = '#94a3b8';
441
- ingestDesc.style.fontSize = '13px';
442
- ingestDesc.textContent = 'Ingest markdown documentation files into the unified memory graph.';
443
-
444
- const form = document.createElement('form');
445
- form.className = 'row';
446
-
447
- const pathInput = document.createElement('input');
448
- pathInput.type = 'text';
449
- pathInput.value = './openwiki';
450
- pathInput.placeholder = 'Path to documentation directory';
451
-
452
- const runBtn = document.createElement('button');
453
- runBtn.type = 'submit';
454
- runBtn.className = 'btn';
455
- runBtn.textContent = 'Execute Ingestion';
456
-
457
- form.append(pathInput, runBtn);
458
-
459
- const terminal = document.createElement('div');
460
- terminal.className = 'terminal';
461
- terminal.textContent = this._ingestOutput || 'Awaiting ingestion command execution.';
462
-
463
- form.onsubmit = (e) => {
464
- e.preventDefault();
465
- const p = pathInput.value.trim();
466
- terminal.textContent = `Dispatching ingest pipeline for path: ${p}...`;
467
- if (this._host && typeof this._host.run === 'function') {
468
- this._host.run('ingest', [p]).then((res) => {
469
- terminal.textContent = res?.output || 'Ingestion completed successfully.';
470
- }).catch((err) => {
471
- terminal.textContent = `Execution failure: ${err.message}`;
472
- });
473
- } else {
474
- setTimeout(() => {
475
- terminal.textContent = `[Ingest Engine] Scanned ${p}\nParsed 4 markdown documents.\nExtracted 12 semantic nodes.\nStatus: Ready`;
476
- }, 400);
477
- }
478
- };
479
-
480
- mainContainer.append(ingestDesc, form, terminal);
481
- } else if (this._activeTab === 'config') {
482
- const state = document.createElement('p');
483
- state.style.color = '#94a3b8';
484
- state.style.fontSize = '13px';
485
- state.textContent = present
486
- ? 'A key exists in the secrets store. Provide a new key to rotate credentials.'
487
- : 'No key is registered. Submit a token to enable authenticated operations.';
488
-
489
- const form = document.createElement('form');
490
- form.className = 'row';
491
-
492
- const input = document.createElement('input');
493
- input.type = 'password';
494
- input.autocomplete = 'off';
495
- input.required = true;
496
- input.placeholder = 'OPENWIKI_API_KEY';
497
-
498
- const rotSelect = document.createElement('select');
499
- rotSelect.className = 'filter-select';
500
- [
501
- { val: '30', lbl: 'Rotate every 30 days' },
502
- { val: '60', lbl: 'Rotate every 60 days' },
503
- { val: '90', lbl: 'Rotate every 90 days' },
504
- { val: '0', lbl: 'Manual maintenance' }
505
- ].forEach((r) => {
506
- const ro = document.createElement('option');
507
- ro.value = r.val;
508
- ro.textContent = r.lbl;
509
- rotSelect.appendChild(ro);
510
- });
511
-
512
- const button = document.createElement('button');
513
- button.type = 'submit';
514
- button.className = 'btn';
515
- button.textContent = 'Save and Verify';
516
-
517
- form.append(input, rotSelect, button);
518
- form.addEventListener('submit', (event) => {
519
- event.preventDefault();
520
- this.dispatchEvent(new CustomEvent('save-token', {
521
- detail: {
522
- key: 'OPENWIKI_API_KEY',
523
- token: input.value.trim(),
524
- rotation_days: parseInt(rotSelect.value, 10)
525
- },
526
- bubbles: true,
527
- composed: true
528
- }));
529
- input.value = '';
530
- });
531
-
532
- mainContainer.append(state, form);
271
+ const { nodes, edges: total, orphans } = result.counts;
272
+ const shown = total > edges.length ? ` Showing ${edges.length}.` : '';
273
+ const pages = nodes === 1 ? '1 page' : `${nodes} pages`;
274
+ const links = total === 1 ? '1 link' : `${total} links`;
275
+ this.#state('graph-state', nodes === 0 ? `No pages to map in ${label}.` :
276
+ `${pages}, ${links}, ${orphans} unlinked in ${label}.${shown}`);
277
+ } catch {
278
+ if (scope !== this.#scope()) return;
279
+ list.replaceChildren();
280
+ this.#state('graph-state', 'Link topology unavailable. Try again.', true);
281
+ } finally {
282
+ button.disabled = false;
533
283
  }
534
-
535
- root.append(style, header, tabs, mainContainer);
536
284
  }
537
285
  }
538
286
 
539
- customElements.define('openwiki-panel', OpenwikiPanel);
287
+ if (!customElements.get('openwiki-panel')) customElements.define('openwiki-panel', OpenWikiPanel);