total-recall-brain 3.44.0 → 3.46.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (502) hide show
  1. package/bin/total-recall.mjs +10 -6
  2. package/docs/ARCHITECTURE.md +10 -7
  3. package/docs/reference/cli-reference.md +13 -8
  4. package/frontend/dist/assets/index-BRYE1jmv.css +1 -0
  5. package/frontend/dist/assets/index-D1goIPjC.js +5598 -0
  6. package/frontend/dist/index.html +2 -2
  7. package/frontend/dist/sw.js +5 -4
  8. package/frontend/src/App.tsx +185 -238
  9. package/frontend/src/api/auth-inventory.ts +62 -0
  10. package/frontend/src/api/memory.ts +13 -8
  11. package/frontend/src/api/plugin-credentials.ts +23 -0
  12. package/frontend/src/api/plugins.ts +37 -53
  13. package/frontend/src/api/workspace-drawers.ts +97 -0
  14. package/frontend/src/components/BrainSelector.tsx +9 -3
  15. package/frontend/src/components/plugins/PluginPanel.tsx +83 -42
  16. package/frontend/src/components/plugins/PluginSettings.tsx +10 -20
  17. package/frontend/src/components/plugins/PluginWorkspace.tsx +367 -0
  18. package/frontend/src/components/plugins/ScopedPluginCommands.tsx +142 -0
  19. package/frontend/src/components/plugins/plugin-frame.ts +44 -33
  20. package/frontend/src/components/plugins/scoped-plugin-operations.ts +28 -0
  21. package/frontend/src/components/workspace/DrawerChat.tsx +110 -0
  22. package/frontend/src/components/workspace/DrawerLayout.tsx +196 -0
  23. package/frontend/src/components/workspace/DrawerMarkup.tsx +49 -0
  24. package/frontend/src/components/workspace/PluginChunkLibrary.tsx +92 -0
  25. package/frontend/src/components/workspace/PluginHome.tsx +76 -0
  26. package/frontend/src/components/workspace/WorkspaceDrawers.tsx +96 -0
  27. package/frontend/src/components/workspace/WorkspacePage.tsx +95 -0
  28. package/frontend/src/components/workspace/usePluginDesign.ts +38 -0
  29. package/frontend/src/index.css +409 -136
  30. package/frontend/src/pages/HelpPage.tsx +15 -46
  31. package/frontend/src/pages/MemoryPage.tsx +19 -36
  32. package/frontend/src/pages/SettingsPage.tsx +1 -1
  33. package/metadata.plugin.schema.json +53 -227
  34. package/package.json +1 -1
  35. package/scaffold/.agent/skills/plugin/SKILL.md +13 -11
  36. package/scaffold/.agent/skills/plugin/evals/README.md +14 -21
  37. package/scaffold/.agent/skills/plugin/evals/cases/01-fabricated-seed.mjs +15 -18
  38. package/scaffold/.agent/skills/plugin/evals/cases/02-reassuring-default.mjs +19 -24
  39. package/scaffold/.agent/skills/plugin/evals/cases/03-declared-template.mjs +12 -20
  40. package/scaffold/.agent/skills/plugin/evals/cases/04-home-collects-credential.mjs +35 -0
  41. package/scaffold/.agent/skills/plugin/evals/cases/05-host-leak-in-scaffold.mjs +8 -28
  42. package/scaffold/.agent/skills/plugin/evals/cases/06-correct-plugin.mjs +85 -47
  43. package/scaffold/.agent/skills/plugin/evals/run.mjs +17 -18
  44. package/scaffold/.agent/skills/plugin/prompts/05-credentials.md +4 -4
  45. package/scaffold/.agent/skills/plugin/prompts/07-scaffold.md +2 -2
  46. package/scaffold/.agent/skills/plugin/prompts/08-verify.md +4 -4
  47. package/scaffold/.agent/skills/plugin/references/anti-patterns.md +2 -2
  48. package/scaffold/.agent/skills/plugin/references/generative-home.md +38 -0
  49. package/scaffold/.agent/skills/plugin/references/scaffold.md +5 -5
  50. package/scaffold/.agent/skills/plugin/references/surfaces.md +13 -4
  51. package/scaffold/.agent/skills/plugin/scripts/record.mjs +75 -153
  52. package/scaffold/.agent/skills/plugin/subagents/plugin-reviewer.md +4 -4
  53. package/scaffold/.agent/skills/total-recall/plugins/auth/DESIGN.md +76 -0
  54. package/scaffold/.agent/skills/total-recall/plugins/auth/README.md +3 -1
  55. package/scaffold/.agent/skills/total-recall/plugins/auth/cli.mjs +20 -15
  56. package/scaffold/.agent/skills/total-recall/plugins/auth/package-lock.json +7 -7
  57. package/scaffold/.agent/skills/total-recall/plugins/auth/package.json +2 -1
  58. package/scaffold/.agent/skills/total-recall/plugins/auth/plugin.json +13 -51
  59. package/scaffold/.agent/skills/total-recall/plugins/auth/src/cli-secret.mjs +20 -1
  60. package/scaffold/.agent/skills/total-recall/plugins/auth/src/secrets-store.mjs +12 -1
  61. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/access-overview.md +17 -0
  62. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/agent-login.md +20 -0
  63. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/baseline-audit.md +22 -0
  64. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/credential-repository-binding.md +17 -0
  65. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/credential-store-maintenance.md +17 -0
  66. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/dashboard-password.md +18 -0
  67. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/dashboard-sessions.md +18 -0
  68. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/endpoint-probe.md +23 -0
  69. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/google-sign-in.md +21 -0
  70. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/mesh-machines.md +16 -0
  71. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/passkey-enrollment.md +21 -0
  72. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/registered-brains.md +16 -0
  73. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/scoped-access-keys.md +17 -0
  74. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/secret-inventory.md +25 -0
  75. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/signing-key-rotation.md +22 -0
  76. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/home.js +375 -0
  77. package/scaffold/.agent/skills/total-recall/plugins/automations/BRICK.md +7 -0
  78. package/scaffold/.agent/skills/total-recall/plugins/automations/DESIGN.md +53 -0
  79. package/scaffold/.agent/skills/total-recall/plugins/automations/LICENSE +21 -0
  80. package/scaffold/.agent/skills/total-recall/plugins/automations/README.md +66 -0
  81. package/scaffold/.agent/skills/total-recall/plugins/automations/adapters.mjs +247 -0
  82. package/scaffold/.agent/skills/total-recall/plugins/automations/capability/index.mjs +16 -0
  83. package/scaffold/.agent/skills/total-recall/plugins/automations/cli.mjs +130 -0
  84. package/{src/core/plugin-cron.mjs → scaffold/.agent/skills/total-recall/plugins/automations/cron.mjs} +1 -3
  85. package/scaffold/.agent/skills/total-recall/plugins/automations/inventory.mjs +88 -0
  86. package/scaffold/.agent/skills/total-recall/plugins/automations/package-lock.json +7661 -0
  87. package/scaffold/.agent/skills/total-recall/plugins/automations/package.json +36 -0
  88. package/scaffold/.agent/skills/total-recall/plugins/automations/plugin.json +151 -0
  89. package/scaffold/.agent/skills/total-recall/plugins/automations/scheduler.mjs +246 -0
  90. package/scaffold/.agent/skills/total-recall/plugins/automations/ui/automations.js +2 -0
  91. package/scaffold/.agent/skills/total-recall/plugins/automations/ui/chunks/control-ledger.md +42 -0
  92. package/scaffold/.agent/skills/total-recall/plugins/automations/ui/chunks/local-inventory-triage.md +17 -0
  93. package/scaffold/.agent/skills/total-recall/plugins/automations/ui/chunks/pending-control.md +39 -0
  94. package/scaffold/.agent/skills/total-recall/plugins/automations/ui/chunks/run-evidence.md +41 -0
  95. package/scaffold/.agent/skills/total-recall/plugins/automations/ui/chunks/schedule-vs-run-evidence.md +17 -0
  96. package/scaffold/.agent/skills/total-recall/plugins/automations/ui/chunks/source-coverage.md +41 -0
  97. package/scaffold/.agent/skills/total-recall/plugins/automations/ui/home.js +278 -0
  98. package/scaffold/.agent/skills/total-recall/plugins/code-quality/DESIGN.md +53 -0
  99. package/scaffold/.agent/skills/total-recall/plugins/code-quality/cli.mjs +23 -0
  100. package/scaffold/.agent/skills/total-recall/plugins/code-quality/commands/run-core.mjs +5 -3
  101. package/scaffold/.agent/skills/total-recall/plugins/code-quality/core/check.mjs +61 -7
  102. package/scaffold/.agent/skills/total-recall/plugins/code-quality/core/report-data.mjs +40 -14
  103. package/scaffold/.agent/skills/total-recall/plugins/code-quality/core/report.mjs +15 -40
  104. package/scaffold/.agent/skills/total-recall/plugins/code-quality/package-lock.json +7 -7
  105. package/scaffold/.agent/skills/total-recall/plugins/code-quality/package.json +2 -1
  106. package/scaffold/.agent/skills/total-recall/plugins/code-quality/plugin.json +40 -40
  107. package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/chunks/config.md +15 -0
  108. package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/chunks/detect.md +15 -0
  109. package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/chunks/gate.md +15 -0
  110. package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/chunks/init.md +15 -0
  111. package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/chunks/report.md +17 -0
  112. package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/chunks/run.md +17 -0
  113. package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/chunks/snapshot.md +15 -0
  114. package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/code-quality-report.mjs +55 -23
  115. package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/home.mjs +214 -0
  116. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/DESIGN.md +146 -0
  117. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/package-lock.json +7 -7
  118. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/package.json +2 -1
  119. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/plugin.json +51 -34
  120. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/src/command.mjs +1 -1
  121. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/create.md +35 -0
  122. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/history.md +35 -0
  123. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/library.md +49 -0
  124. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/list.md +42 -0
  125. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/promote.md +40 -0
  126. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/read.md +25 -0
  127. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/remove.md +26 -0
  128. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/rollback.md +26 -0
  129. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/show.md +53 -0
  130. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/status.md +40 -0
  131. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/test-path.md +38 -0
  132. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/test.md +46 -0
  133. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/update.md +32 -0
  134. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/home.js +533 -0
  135. package/scaffold/.agent/skills/total-recall/plugins/embeddings/DESIGN.md +110 -0
  136. package/scaffold/.agent/skills/total-recall/plugins/embeddings/package-lock.json +7 -7
  137. package/scaffold/.agent/skills/total-recall/plugins/embeddings/package.json +2 -1
  138. package/scaffold/.agent/skills/total-recall/plugins/embeddings/plugin.json +13 -10
  139. package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/chunks/benchmark.md +49 -0
  140. package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/chunks/coverage.md +53 -0
  141. package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/chunks/models.md +43 -0
  142. package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/chunks/pull.md +41 -0
  143. package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/chunks/status.md +59 -0
  144. package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/home.js +353 -0
  145. package/scaffold/.agent/skills/total-recall/plugins/git/DESIGN.md +31 -0
  146. package/scaffold/.agent/skills/total-recall/plugins/git/README.md +136 -0
  147. package/scaffold/.agent/skills/total-recall/plugins/{git-sentinel → git}/cli.mjs +140 -24
  148. package/scaffold/.agent/skills/total-recall/plugins/{git-sentinel → git}/package-lock.json +9 -9
  149. package/scaffold/.agent/skills/total-recall/plugins/{git-sentinel → git}/package.json +4 -2
  150. package/scaffold/.agent/skills/total-recall/plugins/git/plugin.json +151 -0
  151. package/scaffold/.agent/skills/total-recall/plugins/git/src/lib/context.mjs +94 -0
  152. package/scaffold/.agent/skills/total-recall/plugins/git/src/lib/phase3-spec-support.mjs +50 -0
  153. package/scaffold/.agent/skills/total-recall/plugins/git/src/lib/runtime.mjs +40 -0
  154. package/scaffold/.agent/skills/total-recall/plugins/git/src/lib/spec-support.mjs +51 -0
  155. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/_support.mjs +195 -0
  156. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/auth.mjs +201 -0
  157. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/bisect.mjs +40 -0
  158. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/cli-meta.mjs +159 -0
  159. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/commit-memory.mjs +54 -0
  160. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/commit.mjs +46 -0
  161. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/fleet.mjs +174 -0
  162. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/force-push.mjs +58 -0
  163. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/group.mjs +119 -0
  164. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/handoff.mjs +59 -0
  165. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/message.mjs +22 -0
  166. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/resolve.mjs +60 -0
  167. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/rules.mjs +81 -0
  168. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/secret-firewall.mjs +92 -0
  169. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/undo.mjs +156 -0
  170. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/unmerged.mjs +182 -0
  171. package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/why.mjs +16 -0
  172. package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/change-comparison.md +27 -0
  173. package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/commit-identity.md +22 -0
  174. package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/create-worktree.md +25 -0
  175. package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/registered-worktrees.md +22 -0
  176. package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/remove-worktree.md +23 -0
  177. package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/repository-ledger.md +25 -0
  178. package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/unmerged-work.md +22 -0
  179. package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/upstream-divergence.md +17 -0
  180. package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/worktree-conflict-triage.md +17 -0
  181. package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/worktree-terminal.md +22 -0
  182. package/scaffold/.agent/skills/total-recall/plugins/git/ui/home.js +273 -0
  183. package/scaffold/.agent/skills/total-recall/plugins/mesh/DESIGN.md +35 -0
  184. package/scaffold/.agent/skills/total-recall/plugins/mesh/README.md +4 -5
  185. package/scaffold/.agent/skills/total-recall/plugins/mesh/cli.mjs +9 -3
  186. package/scaffold/.agent/skills/total-recall/plugins/mesh/package-lock.json +7 -7
  187. package/scaffold/.agent/skills/total-recall/plugins/mesh/package.json +2 -1
  188. package/scaffold/.agent/skills/total-recall/plugins/mesh/plugin.json +37 -39
  189. package/scaffold/.agent/skills/total-recall/plugins/mesh/src/cli/mesh.mjs +5 -3
  190. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/active-device-dispatch.md +22 -0
  191. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/control-probe.md +25 -0
  192. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/control-server.md +22 -0
  193. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/credential-readiness.md +23 -0
  194. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/elected-leader.md +22 -0
  195. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/enrollment-key.md +22 -0
  196. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/file-receipt.md +25 -0
  197. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/fleet-execution.md +23 -0
  198. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/fleet-presence.md +23 -0
  199. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/interactive-ssh.md +22 -0
  200. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/local-enrollment.md +23 -0
  201. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/mesh-policy.md +23 -0
  202. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/network-atlas.md +25 -0
  203. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/node-roster.md +26 -0
  204. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/node-selection-proof.md +17 -0
  205. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/owner-observations.md +23 -0
  206. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/peer-path.md +23 -0
  207. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/pinned-leader.md +24 -0
  208. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/reachability-evidence-ladder.md +17 -0
  209. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/recorded-login.md +23 -0
  210. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/remote-execution.md +22 -0
  211. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/secret-grants.md +26 -0
  212. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/{card.js → home.js} +93 -22
  213. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/DESIGN.md +86 -0
  214. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/README.md +44 -9
  215. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/capability/BRICK.md +1 -1
  216. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/capability/index.mjs +18 -6
  217. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/cli.mjs +128 -24
  218. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/package-lock.json +7 -7
  219. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/package.json +3 -2
  220. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/plugin.json +188 -34
  221. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/skills/meta-harness/SKILL.md +17 -3
  222. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/adoption.mjs +2 -2
  223. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/alerts.mjs +3 -3
  224. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/cascade.mjs +92 -18
  225. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/chat.mjs +80 -0
  226. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/control.mjs +145 -0
  227. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/coordinator.mjs +42 -21
  228. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/dispatch-request.mjs +4 -2
  229. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/dispatch.mjs +33 -9
  230. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/documentation.mjs +55 -11
  231. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/executor.mjs +26 -4
  232. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/gate-adapters/hermes.mjs +29 -1
  233. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/gate-adapters/index.mjs +1 -1
  234. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/included-usage.mjs +1 -1
  235. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/jobs.mjs +84 -0
  236. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/learner.mjs +3 -12
  237. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/maintenance.mjs +17 -0
  238. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/mcp-server.mjs +228 -0
  239. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/process-manager.mjs +25 -2
  240. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/reasoning.mjs +1 -1
  241. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/remote-operation.mjs +5 -1
  242. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/review.mjs +34 -3
  243. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/reviews.mjs +25 -0
  244. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/router.mjs +1 -1
  245. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/session/claude.mjs +319 -0
  246. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/session/codex.mjs +387 -0
  247. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/session/result.mjs +67 -0
  248. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/session/resume.mjs +373 -0
  249. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/session/run.mjs +223 -0
  250. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/session-jobs.mjs +72 -0
  251. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/setup.mjs +6 -3
  252. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/termination.mjs +16 -12
  253. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/threads.mjs +32 -1
  254. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/usage-queue.mjs +1 -1
  255. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/verify-ssss.mjs +3 -3
  256. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/worker.mjs +285 -40
  257. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/worktree.mjs +76 -9
  258. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/adapter-docs-freshness.md +16 -0
  259. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/chat-handoff.md +26 -0
  260. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/fleet-maintenance.md +21 -0
  261. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/harness-inventory.md +21 -0
  262. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/included-access.md +18 -0
  263. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/included-usage-verification.md +15 -0
  264. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/independent-review.md +17 -0
  265. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/managed-execution.md +20 -0
  266. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/official-documentation.md +18 -0
  267. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/quota-recovery.md +21 -0
  268. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/review-routing-decision.md +16 -0
  269. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/route-work.md +18 -0
  270. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/routing-evidence.md +18 -0
  271. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/run-ledger.md +18 -0
  272. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/home.js +198 -0
  273. package/scaffold/.agent/skills/total-recall/plugins/openwiki/DESIGN.md +75 -0
  274. package/scaffold/.agent/skills/total-recall/plugins/openwiki/README.md +2 -0
  275. package/scaffold/.agent/skills/total-recall/plugins/openwiki/cli.mjs +64 -32
  276. package/scaffold/.agent/skills/total-recall/plugins/openwiki/package-lock.json +7 -7
  277. package/scaffold/.agent/skills/total-recall/plugins/openwiki/package.json +2 -1
  278. package/scaffold/.agent/skills/total-recall/plugins/openwiki/plugin.json +10 -44
  279. package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/generate.mjs +5 -4
  280. package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/graph.mjs +3 -4
  281. package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/ingest.mjs +23 -18
  282. package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/mesh-vaults.mjs +8 -3
  283. package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/refresh-diagnostics.mjs +44 -0
  284. package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/refresh.mjs +123 -113
  285. package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/search.mjs +3 -5
  286. package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/token.mjs +21 -47
  287. package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/upstream-watcher.mjs +17 -6
  288. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/auto-refresh.md +18 -0
  289. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/bootstrap-pages.md +18 -0
  290. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/generate-wiki.md +21 -0
  291. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/generator-settings.md +18 -0
  292. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/host-probe.md +18 -0
  293. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/ingest-preview.md +18 -0
  294. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/link-hygiene.md +21 -0
  295. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/link-topology.md +19 -0
  296. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/passage-search.md +19 -0
  297. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/propagation-plan.md +18 -0
  298. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/provider-credentials.md +18 -0
  299. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/refresh-report.md +18 -0
  300. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/task-evidence.md +22 -0
  301. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/upstream-record.md +18 -0
  302. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/watch-upstream.md +18 -0
  303. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/wiki-atlas.md +19 -0
  304. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/panel.js +261 -513
  305. package/scaffold/.agent/skills/total-recall/plugins/security/DESIGN.md +84 -0
  306. package/scaffold/.agent/skills/total-recall/plugins/security/README.md +4 -2
  307. package/scaffold/.agent/skills/total-recall/plugins/security/cli.mjs +7 -19
  308. package/scaffold/.agent/skills/total-recall/plugins/security/package-lock.json +7 -7
  309. package/scaffold/.agent/skills/total-recall/plugins/security/package.json +2 -3
  310. package/scaffold/.agent/skills/total-recall/plugins/security/plugin.json +19 -52
  311. package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/device-evidence.md +21 -0
  312. package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/evidence-desk.md +18 -0
  313. package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/guided-device-review.md +17 -0
  314. package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/host-and-network.md +21 -0
  315. package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/https-headers.md +17 -0
  316. package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/mesh-coverage.md +18 -0
  317. package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/private-security-tools.md +16 -0
  318. package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/single-origin-header-check.md +17 -0
  319. package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/source-review.md +21 -0
  320. package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/ssh-permission-plan.md +17 -0
  321. package/scaffold/.agent/skills/total-recall/plugins/security/ui/home.js +283 -0
  322. package/scaffold/.agent/skills/total-recall/plugins/ssss/DESIGN.md +93 -0
  323. package/scaffold/.agent/skills/total-recall/plugins/ssss/package-lock.json +2 -2
  324. package/scaffold/.agent/skills/total-recall/plugins/ssss/package.json +2 -1
  325. package/scaffold/.agent/skills/total-recall/plugins/ssss/plugin.json +5 -3
  326. package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/chunks/conformance.md +26 -0
  327. package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/chunks/registry.md +37 -0
  328. package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/chunks/repair.md +42 -0
  329. package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/chunks/scaffold.md +33 -0
  330. package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/chunks/status.md +43 -0
  331. package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/chunks/validate.md +34 -0
  332. package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/chunks/validation-diagnostics.md +17 -0
  333. package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/chunks/workspace-registry-preflight.md +17 -0
  334. package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/home.js +348 -0
  335. package/scaffold/.agent/skills/total-recall/references/operations.md +3 -1
  336. package/src/cli/agent.mjs +1 -1
  337. package/src/cli/api.mjs +3 -3
  338. package/src/cli/brief.mjs +3 -0
  339. package/src/cli/command.mjs +41 -2
  340. package/src/cli/config.mjs +16 -0
  341. package/src/cli/connect.mjs +2 -7
  342. package/src/cli/dream.mjs +93 -69
  343. package/src/cli/harness.mjs +4 -4
  344. package/src/cli/help.mjs +1 -1
  345. package/src/cli/init.mjs +0 -25
  346. package/src/cli/lessons.mjs +51 -0
  347. package/src/cli/memory-plugin.mjs +1 -1
  348. package/src/cli/plugin/chunks.mjs +145 -0
  349. package/src/cli/plugin/copies.mjs +64 -14
  350. package/src/cli/plugin/create.mjs +30 -59
  351. package/src/cli/plugin/index.mjs +31 -16
  352. package/src/cli/plugin/install.mjs +10 -15
  353. package/src/cli/plugin/remove.mjs +1 -1
  354. package/src/cli/plugin/search.mjs +2 -2
  355. package/src/cli/preflight.mjs +19 -6
  356. package/src/cli/proposals.mjs +1 -1
  357. package/src/cli/recall.mjs +66 -23
  358. package/src/cli/remember.mjs +3 -14
  359. package/src/cli/server.mjs +18 -0
  360. package/src/cli/setup.mjs +2 -9
  361. package/src/cli/start.mjs +1 -0
  362. package/src/cli/startup.mjs +19 -0
  363. package/src/cli/task.mjs +9 -2
  364. package/src/cli/update.mjs +6 -2
  365. package/src/core/access-ledger.mjs +78 -0
  366. package/src/core/agent-manager.mjs +2 -2
  367. package/src/core/app-deploy/design-tokens.mjs +14 -9
  368. package/src/core/app-deploy/ui-elements.mjs +1 -1
  369. package/src/core/brain-locate.mjs +15 -0
  370. package/src/core/brain-registry.mjs +5 -0
  371. package/src/core/brain-updates.mjs +35 -11
  372. package/src/core/claude-hooks.mjs +3 -1
  373. package/src/core/cleanup-task.mjs +15 -0
  374. package/src/core/cli-commands.mjs +2 -0
  375. package/src/core/cli-maintenance.mjs +4 -1
  376. package/src/core/cli-semantic-index.mjs +23 -3
  377. package/src/core/context-compiler.mjs +20 -0
  378. package/src/core/daemon-control.mjs +5 -1
  379. package/src/core/daemon-loop.mjs +39 -62
  380. package/src/core/dashboard-bundle.mjs +261 -0
  381. package/src/core/default-plugins.mjs +1 -1
  382. package/src/core/dream.mjs +33 -105
  383. package/src/core/ensure-dependencies.mjs +152 -0
  384. package/src/core/fast-recall.mjs +2 -2
  385. package/src/core/field-evaluation.mjs +23 -0
  386. package/src/core/gate-mode.mjs +1 -1
  387. package/src/core/harness-hooks.mjs +14 -2
  388. package/src/core/lesson-hooks.mjs +74 -0
  389. package/src/core/lesson-memory.mjs +24 -0
  390. package/src/core/lesson-sessions.mjs +52 -0
  391. package/src/core/lessons.mjs +96 -0
  392. package/src/core/memory-brain.mjs +30 -8
  393. package/src/core/meta-harness.mjs +2 -2
  394. package/src/core/optimizer.mjs +66 -165
  395. package/src/core/plugin-activation.mjs +63 -20
  396. package/src/core/plugin-contracts/{card.mjs → manifest.mjs} +26 -57
  397. package/src/core/plugin-contracts/startup-check.mjs +49 -0
  398. package/src/core/plugin-contracts/ui.mjs +9 -3
  399. package/src/core/plugin-distribution.mjs +6 -6
  400. package/src/core/plugin-lifecycle.mjs +58 -0
  401. package/src/core/plugin-loader.mjs +21 -8
  402. package/src/core/plugin-runner.mjs +21 -10
  403. package/src/core/plugin-runtime.mjs +40 -1
  404. package/src/core/plugin-startup-checks.mjs +44 -0
  405. package/src/core/plugin-state.mjs +19 -5
  406. package/src/core/plugin-store.mjs +64 -33
  407. package/src/core/post-mortem.mjs +52 -36
  408. package/src/core/preflight-gate.mjs +23 -2
  409. package/src/core/project-id.mjs +15 -5
  410. package/src/core/proposal-applier.mjs +31 -2
  411. package/src/core/repo-sync.mjs +4 -6
  412. package/src/core/required-plugins.mjs +57 -10
  413. package/src/core/rule-length.mjs +23 -0
  414. package/src/core/runtime.mjs +1 -1
  415. package/src/core/scheduler.mjs +35 -43
  416. package/src/core/schema.mjs +3 -2
  417. package/src/core/search.mjs +4 -3
  418. package/src/core/server-service.mjs +148 -0
  419. package/src/core/session-watcher.mjs +19 -1
  420. package/src/core/skill-gap.mjs +16 -0
  421. package/src/core/ssss-kernel-bridge.mjs +32 -4
  422. package/src/core/ssss-operation-service.mjs +1 -0
  423. package/src/core/startup-health.mjs +34 -4
  424. package/src/core/surface.mjs +65 -54
  425. package/src/core/task-executors.mjs +54 -106
  426. package/src/core/testing/plugin-fixture.mjs +22 -21
  427. package/src/core/throttled-fetch.mjs +25 -18
  428. package/src/core/ui-chunk-choice.mjs +77 -0
  429. package/src/core/ui-chunk.registry.json +23 -0
  430. package/src/core/ui-chunks.mjs +434 -0
  431. package/src/core/validated-write.mjs +1 -0
  432. package/src/core/vault-cache.mjs +58 -59
  433. package/src/core/vector-field.mjs +134 -192
  434. package/src/core/workspace-compositions.mjs +151 -0
  435. package/src/core/workspace-drawers.mjs +79 -0
  436. package/src/server/api.mjs +4 -27
  437. package/src/server/index.mjs +28 -21
  438. package/src/server/invoke-core-child.mjs +24 -0
  439. package/src/server/invoke-core-operations.mjs +102 -0
  440. package/src/server/memory-events.mjs +31 -0
  441. package/src/server/plugin-brain-targets.mjs +89 -0
  442. package/src/server/rest.mjs +2 -0
  443. package/src/server/route-inventory.mjs +3 -2
  444. package/src/server/route-manifest.json +47 -55
  445. package/src/server/routes/_shared.mjs +7 -14
  446. package/src/server/routes/brains.mjs +29 -62
  447. package/src/server/routes/context.mjs +0 -41
  448. package/src/server/routes/dashboard.mjs +26 -0
  449. package/src/server/routes/invoke.mjs +26 -1
  450. package/src/server/routes/plugins.mjs +154 -45
  451. package/src/server/routes/ssss.mjs +0 -169
  452. package/src/server/routes/system.mjs +0 -15
  453. package/src/server/routes/tasks.mjs +0 -26
  454. package/src/server/routes/ui-chunks.mjs +192 -0
  455. package/src/server/routes/vault.mjs +2 -23
  456. package/frontend/dist/assets/index-DD4qONvH.js +0 -5607
  457. package/frontend/dist/assets/index-DtwsDyFM.css +0 -1
  458. package/frontend/src/components/plugins/card/CardEngine.tsx +0 -108
  459. package/frontend/src/components/plugins/card/CardScenes.tsx +0 -103
  460. package/frontend/src/components/plugins/card/ExecutionPicker.tsx +0 -64
  461. package/frontend/src/components/plugins/card/args.ts +0 -28
  462. package/frontend/src/components/plugins/card/card.css +0 -32
  463. package/frontend/src/components/plugins/card/cli-line.ts +0 -13
  464. package/frontend/src/components/plugins/card/contract.ts +0 -91
  465. package/frontend/src/components/plugins/card/format.ts +0 -49
  466. package/frontend/src/components/plugins/card/runner-context.ts +0 -11
  467. package/frontend/src/components/plugins/card/runner.tsx +0 -43
  468. package/frontend/src/components/plugins/card/theme.ts +0 -35
  469. package/frontend/src/components/plugins/card/use-source.ts +0 -22
  470. package/frontend/src/components/plugins/card/widgets.tsx +0 -94
  471. package/frontend/src/components/plugins/workspace/WorkspaceHost.tsx +0 -23
  472. package/frontend/src/pages/PluginsPage.tsx +0 -1719
  473. package/scaffold/.agent/skills/plugin/evals/cases/04-card-collects-credential.mjs +0 -47
  474. package/scaffold/.agent/skills/plugin/prompts/06-card.md +0 -46
  475. package/scaffold/.agent/skills/plugin/references/card.md +0 -90
  476. package/scaffold/.agent/skills/plugin/subagents/card-designer.md +0 -60
  477. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/DESIGN.md +0 -67
  478. package/scaffold/.agent/skills/total-recall/plugins/auth/ui/card.js +0 -1179
  479. package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/DESIGN.md +0 -32
  480. package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/card.js +0 -588
  481. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/card.js +0 -575
  482. package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/DESIGN.md +0 -32
  483. package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/card.js +0 -482
  484. package/scaffold/.agent/skills/total-recall/plugins/git-sentinel/README.md +0 -53
  485. package/scaffold/.agent/skills/total-recall/plugins/git-sentinel/plugin.json +0 -129
  486. package/scaffold/.agent/skills/total-recall/plugins/git-sentinel/ui/DESIGN.md +0 -100
  487. package/scaffold/.agent/skills/total-recall/plugins/git-sentinel/ui/card.js +0 -637
  488. package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/DESIGN.md +0 -217
  489. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/DESIGN.md +0 -32
  490. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/card.js +0 -1276
  491. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/DESIGN.md +0 -45
  492. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/card.js +0 -1401
  493. package/scaffold/.agent/skills/total-recall/plugins/security/scripts/build-ui.mjs +0 -4
  494. package/scaffold/.agent/skills/total-recall/plugins/security/ui/DESIGN.md +0 -41
  495. package/scaffold/.agent/skills/total-recall/plugins/security/ui/card.js +0 -396
  496. package/scaffold/.agent/skills/total-recall/plugins/security/ui/panel.js +0 -98
  497. package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/DESIGN.md +0 -15
  498. package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/card.js +0 -182
  499. package/src/core/append-log.mjs +0 -131
  500. package/src/core/plugin-tasks.mjs +0 -173
  501. package/templates/onboarding-interview.md +0 -82
  502. /package/scaffold/.agent/skills/total-recall/plugins/{git-sentinel → git}/LICENSE +0 -0
@@ -30,6 +30,19 @@ const PLUGIN_ROOT = fileURLToPath(new URL('..', import.meta.url));
30
30
  const RETENTION_NOTE = 'pages are a projection, not canonical memory';
31
31
  const DEFAULT_LOCK_MS = 6 * 60 * 60 * 1000;
32
32
 
33
+ const gitRun = (_command, args, options) => spawnSync('total-recall', ['git', ...args], options);
34
+
35
+ function readJson(file) {
36
+ try { return JSON.parse(fs.readFileSync(file, 'utf8')); } catch { return null; }
37
+ }
38
+
39
+ /** An unfinished init must resume as init, even after it has written pages. */
40
+ export function generationMode(root) {
41
+ const state = readJson(path.join(root, 'openwiki', '.run.json'));
42
+ if (state?.mode === 'init' && state.phase && !['complete', 'idle'].includes(state.phase)) return 'init';
43
+ return hasWiki(root) ? 'update' : 'init';
44
+ }
45
+
33
46
  export function registryPath(home = os.homedir()) {
34
47
  return path.join(home, '.agent', 'skills', 'total-recall', 'config', 'project-registry.json');
35
48
  }
@@ -69,7 +82,7 @@ export function readProjects({ registry = registryPath() } = {}) {
69
82
  });
70
83
  }
71
84
 
72
- /** Does this project carry generated pages at all? A repo with no openwiki/ is skipped, never created. */
85
+ /** Does this project carry generated Markdown pages? */
73
86
  export function hasWiki(root) {
74
87
  const dir = path.join(root, 'openwiki');
75
88
  const stat = fs.lstatSync(dir, { throwIfNoEntry: false });
@@ -82,15 +95,18 @@ export function hasWiki(root) {
82
95
  * since the recorded generation, which is the same measure the per-repo driver
83
96
  * used. Uncommitted work is not counted, so an open edit does not read as drift.
84
97
  */
85
- export function isGitRepo(root, { git = spawnSync } = {}) {
98
+ export function isGitRepo(root, { git = gitRun } = {}) {
86
99
  if (fs.existsSync(path.join(root, '.git'))) return true;
87
100
  const res = git('git', ['-C', root, 'rev-parse', '--is-inside-work-tree'], { encoding: 'utf8' });
88
- return !res.error && res.status === 0;
101
+ if (res.error || res.status !== 0 || String(res.stdout).trim() !== 'true') return false;
102
+ const top = git('git', ['-C', root, 'rev-parse', '--show-toplevel'], { encoding: 'utf8' });
103
+ if (top.error || top.status !== 0) return false;
104
+ return fs.realpathSync(root) === fs.realpathSync(String(top.stdout).trim());
89
105
  }
90
106
 
91
- export function staleness(root, { git = spawnSync } = {}) {
107
+ export function staleness(root, { git = gitRun } = {}) {
92
108
  if (!isGitRepo(root, { git })) {
93
- return { root, head: '', generatedAt: null, generatedStatus: null, files: null, lastCodeChange: null, commitsSince: 0, stale: false };
109
+ return { root, head: '', generationCommit: null, generationTime: null, generatedAt: null, generatedStatus: null, files: null, lastCodeChange: null, commitsSince: 0, stale: false };
94
110
  }
95
111
  const marker = path.join(root, 'openwiki', '.last-update.json');
96
112
  let head = '';
@@ -104,6 +120,11 @@ export function staleness(root, { git = spawnSync } = {}) {
104
120
  generatedAt = typeof parsed.updatedAt === 'string' ? parsed.updatedAt : null;
105
121
  generatedStatus = typeof parsed.status === 'string' ? parsed.status : null;
106
122
  } catch { /* no marker: never generated, or unreadable */ }
123
+ const receipt = readJson(path.join(root, 'openwiki', '.generation.json'));
124
+ const validReceipt = typeof receipt?.commit === 'string' && /^[a-f0-9]{7,64}$/i.test(receipt.commit)
125
+ && typeof receipt.completedAt === 'string' && Number.isFinite(Date.parse(receipt.completedAt));
126
+ const generationCommit = validReceipt ? receipt.commit : null;
127
+ const generationTime = validReceipt ? receipt.completedAt : null;
107
128
 
108
129
  // The page contents, so a refresh can be judged on what it actually rewrote.
109
130
  // openwiki writes its marker when generation begins, so the marker alone
@@ -122,12 +143,15 @@ export function staleness(root, { git = spawnSync } = {}) {
122
143
  const lastCodeChange = !log.error && log.status === 0 ? String(log.stdout || '').trim() || null : null;
123
144
 
124
145
  let commitsSince = null;
125
- if (generatedAt) {
126
- const count = git('git', ['-C', root, 'rev-list', '--count', `--since=${generatedAt}`, 'HEAD', '--', '.', ':!openwiki'], { encoding: 'utf8' });
127
- if (!count.error && count.status === 0) commitsSince = Number(String(count.stdout || '').trim());
128
- }
129
- const stale = generatedAt === null || (Number.isFinite(commitsSince) && commitsSince > 0);
130
- return { root, head, generatedAt, generatedStatus, files, lastCodeChange, commitsSince, stale };
146
+ if (generationCommit || generatedAt) {
147
+ const range = generationCommit ? [`${generationCommit}..HEAD`] : [`--since=${generatedAt}`, 'HEAD'];
148
+ const count = git('git', ['-C', root, 'rev-list', '--count', ...range, '--', '.', ':!openwiki'], { encoding: 'utf8' });
149
+ const value = String(count.stdout || '').trim();
150
+ if (!count.error && count.status === 0 && /^\d+$/.test(value)) commitsSince = Number(value);
151
+ }
152
+ const incomplete = generatedStatus === 'interrupted' || stillGenerating(root);
153
+ const stale = incomplete || generatedAt === null || commitsSince === null || commitsSince > 0;
154
+ return { root, head, generationCommit, generationTime, generatedAt, generatedStatus, files, lastCodeChange, commitsSince, stale, mode: generationMode(root) };
131
155
  }
132
156
 
133
157
  /**
@@ -250,14 +274,84 @@ export function stillGenerating(root) {
250
274
  }
251
275
  }
252
276
 
277
+ function writeReceipt(root, name, value) {
278
+ const dir = path.join(root, 'openwiki');
279
+ fs.mkdirSync(dir, { recursive: true });
280
+ const target = path.join(dir, name);
281
+ const tmp = `${target}.${process.pid}.${Date.now()}.tmp`;
282
+ try {
283
+ fs.writeFileSync(tmp, `${JSON.stringify(value, null, 2)}\n`, { flag: 'wx', mode: 0o600 });
284
+ fs.renameSync(tmp, target);
285
+ } finally {
286
+ fs.rmSync(tmp, { force: true });
287
+ }
288
+ }
289
+
290
+ function redact(value, key) {
291
+ let text = String(value || '');
292
+ if (key) text = text.split(key).join('[REDACTED]');
293
+ return text.replace(/\bBearer\s+\S+/gi, 'Bearer [REDACTED]').replace(/\bsk-[\w-]+/g, '[REDACTED]');
294
+ }
295
+
296
+ function finishRefresh(project, { before, result, git, key, mode, startedAt, via, clock }) {
297
+ const after = staleness(project.root, { git });
298
+ const exitCode = result.error ? (result.error.code || 1) : result.signal ? 1 : result.status;
299
+ const completedAt = new Date(clock()).toISOString();
300
+ const stdout = redact(result.stdout, key), stderr = redact(result.stderr, key);
301
+ const error = redact(result.error?.message, key);
302
+ const clean = text => String(text || '').replace(/\x1b\[[0-9;]*m/g, '').split(/\r?\n/)
303
+ .map(line => line.trim().replace(/^\[ERR\]\s*/, '')).filter(line => line && line !== 'Error Diagnostics');
304
+ const errLines = clean(stderr), outLines = clean(stdout);
305
+ const diagnostic = [...errLines, ...outLines].find(line => /context_length_exceeded|Provider returned error|exited without|Could not restore|interrupted OpenWiki|fetch failed/.test(line));
306
+ // The generator's own first error line names the cause; a trailing "Status: 400" does not.
307
+ const reason = error || (result.signal ? `generator stopped by ${result.signal}` : diagnostic || errLines[0] || outLines.at(-1) || `exit ${exitCode}`);
308
+ const wrote = pagesWritten(before, after) || (!before.files && hasWiki(project.root) ? 1 : 0);
309
+ const advanced = after.generatedAt !== before.generatedAt;
310
+ let action, failureReason;
311
+ if (after.generatedStatus === 'interrupted' || stillGenerating(project.root)) {
312
+ action = 'partial';
313
+ failureReason = `${wrote} page(s) rewritten, but the run did not finish; it resumes on the next refresh (${reason})`;
314
+ } else if (exitCode !== 0) {
315
+ action = 'failed'; failureReason = reason;
316
+ } else if (!advanced && !wrote) {
317
+ action = 'failed'; failureReason = 'command exited 0 and no page changed';
318
+ } else if (!before.head) {
319
+ action = 'failed'; failureReason = 'Cannot record generation without a source commit';
320
+ } else {
321
+ action = mode === 'init' ? 'initialized' : 'refreshed';
322
+ }
323
+ const logPath = path.join(project.root, 'openwiki', '.refresh-attempt.json');
324
+ const report = { ...project, ...after, action, reason: failureReason, exitCode, signal: result.signal || null, from: before.generatedAt, to: after.generatedAt, durationMs: clock() - startedAt, via, mode, logPath };
325
+ try {
326
+ writeReceipt(project.root, '.refresh-attempt.json', { startedAt: new Date(startedAt).toISOString(), completedAt, sourceCommit: before.head || null, action, mode, exitCode, signal: result.signal || null, error, stdout, stderr });
327
+ if (action === 'initialized' || action === 'refreshed') {
328
+ writeReceipt(project.root, '.generation.json', { commit: before.head, completedAt });
329
+ report.generationCommit = before.head;
330
+ report.generationTime = completedAt;
331
+ report.commitsSince = after.head === before.head ? 0 : null;
332
+ report.stale = after.head !== before.head;
333
+ } else if (before.generationCommit && before.generationTime) {
334
+ // Init can replace openwiki/ before it fails. Retain the last success.
335
+ writeReceipt(project.root, '.generation.json', { commit: before.generationCommit, completedAt: before.generationTime });
336
+ report.generationCommit = before.generationCommit;
337
+ report.generationTime = before.generationTime;
338
+ }
339
+ } catch (error) {
340
+ report.action = 'failed'; report.reason = `Could not save refresh receipt: ${error.message}`;
341
+ }
342
+ return report;
343
+ }
344
+
253
345
  export function refreshProject(project, {
254
- key, model = null, provider = null, binary = null, binaryArgs = [], timeoutMs = 30 * 60 * 1000, run = spawnSync, now = Date.now(), targetVersion = null, pluginRoot = PLUGIN_ROOT,
346
+ key, model = null, provider = null, binary = null, binaryArgs = [], timeoutMs = 30 * 60 * 1000, run = spawnSync, now = Date.now(), clock = Date.now, targetVersion = null, pluginRoot = PLUGIN_ROOT,
255
347
  } = {}) {
256
- if (!isGitRepo(project.root, { git: run })) {
348
+ const git = run === spawnSync ? gitRun : run;
349
+ if (!isGitRepo(project.root, { git })) {
257
350
  return { ...project, action: 'skipped', reason: 'not a git repository' };
258
351
  }
259
- const before = staleness(project.root, { git: run });
352
+ const before = staleness(project.root, { git });
260
353
  const uninitialized = !hasWiki(project.root);
354
+ const mode = generationMode(project.root);
261
355
 
262
356
  let command = binary, args = binaryArgs, via = binary ? 'explicit' : null;
263
357
  if (!command) {
@@ -273,19 +367,12 @@ export function refreshProject(project, {
273
367
  const selectedModel = model || config.model;
274
368
  const selectedProvider = provider || config.provider;
275
369
 
276
- const modeFlag = uninitialized ? '--init' : '--update';
370
+ const modeFlag = `--${mode}`;
277
371
  const cmdArgs = [...args, modeFlag, '-p'];
278
372
  if (selectedModel) {
279
373
  cmdArgs.push('--modelId', selectedModel);
280
374
  }
281
375
 
282
- if (uninitialized) {
283
- const runFile = path.join(project.root, 'openwiki', '.run.json');
284
- if (fs.existsSync(runFile)) {
285
- try { fs.unlinkSync(runFile); } catch {}
286
- }
287
- }
288
-
289
376
  const childEnv = { ...process.env };
290
377
  if (selectedProvider === 'google') {
291
378
  childEnv.GOOGLE_API_KEY = key;
@@ -312,47 +399,18 @@ export function refreshProject(project, {
312
399
  timeout: timeoutMs,
313
400
  });
314
401
 
315
- const after = staleness(project.root, { git: run });
316
- const exitCode = result.error ? (result.error.code || 1) : result.status;
317
- const advanced = after.generatedAt !== before.generatedAt || (uninitialized && hasWiki(project.root));
318
- const wrote = pagesWritten(before, after) || (uninitialized && hasWiki(project.root) ? 1 : 0);
319
-
320
- const outcome = after.generatedStatus === 'interrupted' || stillGenerating(project.root)
321
- ? 'partial'
322
- : (advanced ? (uninitialized ? 'initialized' : 'refreshed') : 'unchanged');
323
-
324
- if (exitCode !== 0 && !wrote) {
325
- return { ...project, action: 'failed', reason: result.error?.message || `exit ${exitCode}`, exitCode, ...after };
326
- }
327
- if (!advanced && !wrote) {
328
- return { ...project, action: 'failed', reason: `command exited ${exitCode} and no page changed`, exitCode, ...after };
329
- }
330
- if (outcome === 'partial') {
331
- return {
332
- ...project,
333
- action: 'partial',
334
- reason: `${wrote} page(s) rewritten, but the run did not finish (the generator was cut off); it resumes on the next refresh`,
335
- exitCode,
336
- from: before.generatedAt,
337
- to: after.generatedAt,
338
- via,
339
- ...after,
340
- };
341
- }
342
- if (exitCode !== 0) {
343
- return { ...project, action: 'failed', reason: result.error?.message || `exit ${exitCode}`, exitCode, ...after };
344
- }
345
- return { ...project, action: uninitialized ? 'initialized' : 'refreshed', from: before.generatedAt, to: after.generatedAt, durationMs: Date.now() - startedAt, via, ...after };
402
+ return finishRefresh(project, { before, result, git, key, mode, startedAt, via, clock });
346
403
  }
347
404
 
348
405
  export async function refreshProjectAsync(project, {
349
- key, model = null, provider = null, binary = null, binaryArgs = [], timeoutMs = 30 * 60 * 1000, now = Date.now(), targetVersion = null, pluginRoot = PLUGIN_ROOT,
406
+ key, model = null, provider = null, binary = null, binaryArgs = [], timeoutMs = 30 * 60 * 1000, now = Date.now(), clock = Date.now, targetVersion = null, pluginRoot = PLUGIN_ROOT, git = gitRun, spawnProcess = spawn,
350
407
  } = {}) {
351
- if (!isGitRepo(project.root, { git: spawnSync })) {
408
+ if (!isGitRepo(project.root, { git })) {
352
409
  return { ...project, action: 'skipped', reason: 'not a git repository' };
353
410
  }
354
- const before = staleness(project.root, { git: spawnSync });
411
+ const before = staleness(project.root, { git });
355
412
  const uninitialized = !hasWiki(project.root);
413
+ const mode = generationMode(project.root);
356
414
  let command = binary, args = binaryArgs, via = binary ? 'explicit' : null;
357
415
  if (!command) {
358
416
  const resolved = resolveGenerator({ run: spawnSync, targetVersion, pluginRoot, requireBundled: uninitialized });
@@ -367,19 +425,12 @@ export async function refreshProjectAsync(project, {
367
425
  const selectedModel = model || config.model;
368
426
  const selectedProvider = provider || config.provider;
369
427
 
370
- const modeFlag = uninitialized ? '--init' : '--update';
428
+ const modeFlag = `--${mode}`;
371
429
  const cmdArgs = [...args, modeFlag, '-p'];
372
430
  if (selectedModel) {
373
431
  cmdArgs.push('--modelId', selectedModel);
374
432
  }
375
433
 
376
- if (uninitialized) {
377
- const runFile = path.join(project.root, 'openwiki', '.run.json');
378
- if (fs.existsSync(runFile)) {
379
- try { fs.unlinkSync(runFile); } catch {}
380
- }
381
- }
382
-
383
434
  const childEnv = { ...process.env };
384
435
  if (selectedProvider === 'google') {
385
436
  childEnv.GOOGLE_API_KEY = key;
@@ -399,74 +450,33 @@ export async function refreshProjectAsync(project, {
399
450
 
400
451
  const startedAt = now;
401
452
  const result = await new Promise((resolve) => {
402
- const proc = spawn(command, cmdArgs, {
453
+ const proc = spawnProcess(command, cmdArgs, {
403
454
  cwd: project.root,
404
455
  env: childEnv,
405
456
  stdio: ['ignore', 'pipe', 'pipe'],
406
457
  timeout: timeoutMs,
407
458
  });
408
- let stdout = '', stderr = '';
459
+ let stdout = '', stderr = '', error = null;
409
460
  proc.stdout?.on('data', (d) => { stdout += d; });
410
461
  proc.stderr?.on('data', (d) => { stderr += d; });
411
- proc.on('error', (err) => resolve({ error: err, status: 1, stdout, stderr }));
412
- proc.on('close', (status) => resolve({ status: status ?? 0, stdout, stderr }));
462
+ proc.on('error', (err) => { error = err; });
463
+ proc.on('close', (status, signal) => resolve({ error, status, signal, stdout, stderr }));
413
464
  });
414
-
415
- const after = staleness(project.root, { git: spawnSync });
416
- const exitCode = result.error ? (result.error.code || 1) : result.status;
417
- const advanced = after.generatedAt !== before.generatedAt || (uninitialized && hasWiki(project.root));
418
- const wrote = pagesWritten(before, after) || (uninitialized && hasWiki(project.root) ? 1 : 0);
419
-
420
- const outcome = after.generatedStatus === 'interrupted' || stillGenerating(project.root)
421
- ? 'partial'
422
- : (advanced ? (uninitialized ? 'initialized' : 'refreshed') : 'unchanged');
423
-
424
- const extractReason = (rawErr, rawOut) => {
425
- if (result.error?.message) return result.error.message;
426
- const combined = `${rawErr || ''}\n${rawOut || ''}`.trim();
427
- if (!combined) return `exit ${exitCode}`;
428
- const lines = combined.split('\n').map((l) => l.trim()).filter(Boolean);
429
- const diag = lines.find((l) => l.includes('Error Diagnostics') || l.includes('exited without') || l.includes('Could not restore') || l.includes('Provider returned error') || l.includes('fetch failed'));
430
- if (diag) return diag.replace(/^\[ERR\]\s*/, '');
431
- const last = lines[lines.length - 1];
432
- return last ? last.replace(/^\[ERR\]\s*/, '') : `exit ${exitCode}`;
433
- };
434
- const failReason = extractReason(result.stderr, result.stdout);
435
-
436
- if (exitCode !== 0 && !wrote) {
437
- return { ...project, action: 'failed', reason: failReason, exitCode, ...after };
438
- }
439
- if (!advanced && !wrote) {
440
- return { ...project, action: 'failed', reason: failReason || `command exited ${exitCode} and no page changed`, exitCode, ...after };
441
- }
442
- if (outcome === 'partial') {
443
- return {
444
- ...project,
445
- action: 'partial',
446
- reason: `${wrote} page(s) rewritten, but the run did not finish (the generator was cut off); it resumes on the next refresh`,
447
- exitCode,
448
- from: before.generatedAt,
449
- to: after.generatedAt,
450
- via,
451
- ...after,
452
- };
453
- }
454
- if (exitCode !== 0) {
455
- return { ...project, action: 'failed', reason: failReason, exitCode, ...after };
456
- }
457
- return { ...project, action: uninitialized ? 'initialized' : 'refreshed', from: before.generatedAt, to: after.generatedAt, durationMs: Date.now() - startedAt, via, ...after };
465
+ return finishRefresh(project, { before, result, git, key, mode, startedAt, via, clock });
458
466
  }
459
467
 
460
468
  /** Is a refresh due for this project under the configured interval? */
461
- export function isDue(project, { lockMs = DEFAULT_LOCK_MS, now = Date.now(), git = spawnSync } = {}) {
469
+ export function isDue(project, { lockMs = DEFAULT_LOCK_MS, now = Date.now(), git = gitRun, force = false } = {}) {
462
470
  if (!isGitRepo(project.root, { git })) {
463
471
  return { due: false, skipped: true, reason: 'not a git repository' };
464
472
  }
465
473
  const state = staleness(project.root, { git });
474
+ if (force) return { due: true, uninitialized: !hasWiki(project.root), ...state };
466
475
  if (!hasWiki(project.root)) {
467
476
  return { due: true, uninitialized: true, reason: 'uninitialized (missing openwiki/ pages)', ...state };
468
477
  }
469
478
  if (!state.stale) return { due: false, ...state };
479
+ if (state.generatedStatus === 'interrupted' || stillGenerating(project.root)) return { due: true, reason: 'resume incomplete generation', ...state };
470
480
  if (state.generatedAt) {
471
481
  const at = Date.parse(state.generatedAt);
472
482
  if (Number.isFinite(at) && now - at < lockMs) return { due: false, reason: 'refreshed recently', ...state };
@@ -36,11 +36,9 @@ export async function searchWikiHubs(query, {
36
36
 
37
37
  // If remote mesh node specified, dispatch via mesh
38
38
  if (node && node !== 'local' && node !== 'self') {
39
- const escapedQuery = query.replace(/"/g, '\\"');
40
- const meshRes = execOnMeshNode(
41
- node,
42
- `total-recall openwiki search "${escapedQuery}" ${allVaults ? '--all-vaults' : ''} --json`
43
- );
39
+ const meshRes = execOnMeshNode(node, [
40
+ 'search', query, ...(allVaults ? ['--all-vaults'] : []), '--limit', String(limit), '--json',
41
+ ]);
44
42
  if (meshRes.ok) {
45
43
  try {
46
44
  return JSON.parse(meshRes.stdout);
@@ -15,60 +15,34 @@ const PROVIDER_KEY_MAP = {
15
15
  /**
16
16
  * Checks token readiness across supported providers.
17
17
  */
18
- export function getTokenStatus() {
19
- const result = spawnSync('total-recall', ['auth', 'secret', 'list', '--json'], {
18
+ export function getTokenStatus({ run = spawnSync } = {}) {
19
+ const result = run('total-recall', ['auth', 'secret', 'list', '--json'], {
20
20
  encoding: 'utf8',
21
21
  timeout: 5000,
22
22
  });
23
23
 
24
- const configured = {
25
- openrouter: false,
26
- google: false,
27
- };
28
-
29
- if (result.status === 0 && result.stdout) {
30
- try {
31
- const parsed = JSON.parse(result.stdout);
32
- const keys = Array.isArray(parsed)
33
- ? parsed.map((k) => (typeof k === 'string' ? k : k.key || k.name))
34
- : (parsed.keys || []);
35
-
36
- configured.openrouter = keys.includes('OPENROUTER_API_KEY') || Boolean(process.env.OPENROUTER_API_KEY);
37
- configured.google = keys.includes('GOOGLE_API_KEY') || Boolean(process.env.GOOGLE_API_KEY);
38
- } catch {
39
- configured.openrouter = Boolean(process.env.OPENROUTER_API_KEY);
40
- configured.google = Boolean(process.env.GOOGLE_API_KEY);
41
- }
42
- } else {
43
- configured.openrouter = Boolean(process.env.OPENROUTER_API_KEY);
44
- configured.google = Boolean(process.env.GOOGLE_API_KEY);
45
- }
46
-
47
- return {
48
- ok: true,
49
- tokens: {
50
- openrouter: {
51
- key: 'OPENROUTER_API_KEY',
52
- configured: configured.openrouter,
53
- status: configured.openrouter ? 'configured' : 'missing',
54
- },
55
- google: {
56
- key: 'GOOGLE_API_KEY',
57
- configured: configured.google,
58
- status: configured.google ? 'configured' : 'missing',
59
- },
60
- },
61
- };
24
+ if (result.status !== 0) throw new Error('Auth credential metadata is unavailable');
25
+ let payload;
26
+ try { payload = JSON.parse(result.stdout); }
27
+ catch { throw new Error('Auth credential metadata is invalid'); }
28
+ const rows = Array.isArray(payload) ? payload : payload?.keys;
29
+ if (!Array.isArray(rows)) throw new Error('Auth credential metadata is invalid');
30
+ const saved = new Set(rows.filter(row => row?.set !== false)
31
+ .map(row => typeof row === 'string' ? row : row?.key ?? row?.name));
32
+ const tokens = Object.fromEntries(Object.entries(PROVIDER_KEY_MAP).map(([provider, key]) => {
33
+ const configured = saved.has(key);
34
+ return [provider, { key, configured, status: configured ? 'configured' : 'missing' }];
35
+ }));
36
+ return { ok: true, tokens };
62
37
  }
63
38
 
64
39
  /**
65
40
  * Securely writes a token into Total Recall auth secrets store using --stdin.
66
41
  */
67
- export function setTokenValue(provider, secretValue) {
68
- const keyName = PROVIDER_KEY_MAP[provider?.toLowerCase()] || provider;
69
- if (!keyName) {
70
- throw new Error(`Unsupported token provider '${provider}'. Allowed: openrouter, google`);
71
- }
42
+ export function setTokenValue(provider, secretValue, { run = spawnSync } = {}) {
43
+ const id = typeof provider === 'string' && provider.toLowerCase();
44
+ if (!Object.hasOwn(PROVIDER_KEY_MAP, id)) throw new Error('Supported token providers are openrouter and google');
45
+ const keyName = PROVIDER_KEY_MAP[id];
72
46
 
73
47
  if (!secretValue || typeof secretValue !== 'string' || !secretValue.trim()) {
74
48
  throw new Error(`Token value for ${keyName} must be a non-empty string`);
@@ -77,14 +51,14 @@ export function setTokenValue(provider, secretValue) {
77
51
  const trimmed = secretValue.trim();
78
52
 
79
53
  // Pipe into total-recall auth secret set <KEY> --stdin
80
- const child = spawnSync('total-recall', ['auth', 'secret', 'set', keyName, '--stdin'], {
54
+ const child = run('total-recall', ['auth', 'secret', 'set', keyName, '--stdin'], {
81
55
  input: trimmed,
82
56
  encoding: 'utf8',
83
57
  timeout: 5000,
84
58
  });
85
59
 
86
60
  if (child.status !== 0) {
87
- throw new Error(child.stderr || child.error?.message || `Failed to set ${keyName} in secrets store`);
61
+ throw new Error(`Auth could not save ${keyName}`);
88
62
  }
89
63
 
90
64
  return {
@@ -15,6 +15,15 @@ import { hasWiki, readProjects, refreshProject, resolveKey } from './refresh.mjs
15
15
  export const UPSTREAM_NPM_URL = 'https://registry.npmjs.org/openwiki/latest';
16
16
  export const UPSTREAM_GITHUB_URL = 'https://api.github.com/repos/langchain-ai/openwiki/releases/latest';
17
17
 
18
+ export function bundledGeneratorVersion() {
19
+ try {
20
+ if (!fs.existsSync(new URL('../vendor/openwiki.mjs', import.meta.url))) return null;
21
+ const build = JSON.parse(fs.readFileSync(new URL('../vendor/build.json', import.meta.url), 'utf8'));
22
+ return typeof build.version === 'string' && /^\d+\.\d+\.\d+(?:[-+][a-zA-Z0-9.-]+)?$/.test(build.version)
23
+ ? build.version : null;
24
+ } catch { return null; }
25
+ }
26
+
18
27
  /**
19
28
  * Resolves the path to the persistent upstream state file.
20
29
  * @param {string} [home] Home directory override
@@ -34,20 +43,21 @@ export function stateFile(home = os.homedir()) {
34
43
  * @returns {{ currentRecordedVersion: string, latestKnownVersion: string, lastCheckedAt: string | null, announcements: Array<object> }}
35
44
  */
36
45
  export function readUpstreamState({ statePath = stateFile() } = {}) {
46
+ const baseline = bundledGeneratorVersion() || '0.0.0';
37
47
  try {
38
48
  const raw = fs.readFileSync(statePath, 'utf8');
39
49
  const parsed = JSON.parse(raw);
40
50
  return {
41
- currentRecordedVersion: typeof parsed.currentRecordedVersion === 'string' ? parsed.currentRecordedVersion : '0.7.2',
42
- latestKnownVersion: typeof parsed.latestKnownVersion === 'string' ? parsed.latestKnownVersion : '0.7.2',
51
+ currentRecordedVersion: typeof parsed.currentRecordedVersion === 'string' ? parsed.currentRecordedVersion : baseline,
52
+ latestKnownVersion: typeof parsed.latestKnownVersion === 'string' ? parsed.latestKnownVersion : baseline,
43
53
  lastCheckedAt: typeof parsed.lastCheckedAt === 'string' ? parsed.lastCheckedAt : null,
44
54
  lastPropagatedAt: typeof parsed.lastPropagatedAt === 'string' ? parsed.lastPropagatedAt : null,
45
55
  announcements: Array.isArray(parsed.announcements) ? parsed.announcements : []
46
56
  };
47
57
  } catch {
48
58
  return {
49
- currentRecordedVersion: '0.7.2',
50
- latestKnownVersion: '0.7.2',
59
+ currentRecordedVersion: baseline,
60
+ latestKnownVersion: baseline,
51
61
  lastCheckedAt: null,
52
62
  lastPropagatedAt: null,
53
63
  announcements: []
@@ -62,13 +72,14 @@ export function readUpstreamState({ statePath = stateFile() } = {}) {
62
72
  * @param {string} [options.statePath] Custom state path
63
73
  */
64
74
  export function saveUpstreamState(state = {}, { statePath = stateFile() } = {}) {
75
+ const baseline = bundledGeneratorVersion() || '0.0.0';
65
76
  const dir = path.dirname(statePath);
66
77
  if (!fs.existsSync(dir)) {
67
78
  fs.mkdirSync(dir, { recursive: true });
68
79
  }
69
80
  const payload = {
70
- currentRecordedVersion: state.currentRecordedVersion || '0.7.2',
71
- latestKnownVersion: state.latestKnownVersion || '0.7.2',
81
+ currentRecordedVersion: state.currentRecordedVersion || baseline,
82
+ latestKnownVersion: state.latestKnownVersion || baseline,
72
83
  lastCheckedAt: state.lastCheckedAt || new Date().toISOString(),
73
84
  lastPropagatedAt: state.lastPropagatedAt || null,
74
85
  announcements: Array.isArray(state.announcements) ? state.announcements.slice(-20) : []
@@ -0,0 +1,18 @@
1
+ ---
2
+ type: ui-chunk:chunk
3
+ plugin: openwiki
4
+ id: auto-refresh
5
+ title: Scheduled wiki refresh
6
+ description: Understand the daemon operation that applies regeneration to due registered repositories.
7
+ timestamp: "2026-11-08T09:14:38Z"
8
+ intents: [inspect scheduled wiki refresh, understand automatic regeneration, review daemon wiki refresh]
9
+ surfaces: [page]
10
+ operations: [auto-refresh]
11
+ data: ["auto-refresh:/counts/current", "auto-refresh:/counts/refreshed"]
12
+ ---
13
+
14
+ <section style="border-inline-start:3px solid var(--color-primary,#8d3e10);padding-inline-start:1rem">
15
+ <h2>Scheduled wiki refresh</h2>
16
+ <p><code>auto-refresh</code> is the daemon's applying operation. It checks the selected registered repositories and regenerates due pages.</p>
17
+ <p>Use <code>total-recall openwiki refresh --json</code> for an operator preview. Review the scheduled run receipt to see what the daemon refreshed.</p>
18
+ </section>
@@ -0,0 +1,18 @@
1
+ ---
2
+ type: ui-chunk:chunk
3
+ plugin: openwiki
4
+ id: bootstrap-pages
5
+ title: Seed missing wiki pages
6
+ description: Preview which owner-provided pages would be created in an explicit brain or project.
7
+ timestamp: "2026-11-08T09:14:38Z"
8
+ intents: [bootstrap wiki pages, seed repository documentation, review missing starter pages]
9
+ surfaces: [page]
10
+ operations: [bootstrap]
11
+ data: ["bootstrap:/files_planned", "bootstrap:/files_preserved"]
12
+ ---
13
+
14
+ <section>
15
+ <h2>Seed missing wiki pages</h2>
16
+ <p>Choose an absolute brain path and, optionally, a project root. Run <code>total-recall openwiki bootstrap --brain &lt;path&gt; --dry-run --json</code> to see the planned pages.</p>
17
+ <p>Review the target paths before applying. The bootstrap receipt separates new pages from existing files that it preserved.</p>
18
+ </section>
@@ -0,0 +1,21 @@
1
+ ---
2
+ type: ui-chunk:chunk
3
+ plugin: openwiki
4
+ id: generate-wiki
5
+ title: Preview wiki generation
6
+ description: Inspect the selected repository and output location before generating documentation.
7
+ timestamp: "2026-11-08T09:14:38Z"
8
+ intents: [preview wiki generation, generate repo documentation, inspect generation destination]
9
+ surfaces: [page]
10
+ operations: [generate]
11
+ data: ["generate:/ok", "generate:/dryRun"]
12
+ ---
13
+
14
+ <section>
15
+ <h2>Preview wiki generation</h2>
16
+ <ol>
17
+ <li>Run <code>total-recall openwiki generate --dry-run --json</code> for the current workspace, or select a registered repository with <code>--repo</code>.</li>
18
+ <li>Review the selected repository and wiki output directory.</li>
19
+ <li>Start generation after approving the target and configured provider.</li>
20
+ </ol>
21
+ </section>
@@ -0,0 +1,18 @@
1
+ ---
2
+ type: ui-chunk:chunk
3
+ plugin: openwiki
4
+ id: generator-settings
5
+ title: Inspect generator configuration
6
+ description: Review the configured provider, model routing, token bound and timeout.
7
+ timestamp: "2026-11-08T09:14:38Z"
8
+ intents: [inspect OpenWiki configuration, review generation limits, change wiki generator settings]
9
+ surfaces: [page, right]
10
+ operations: [config]
11
+ data: ["config:/config/provider", "config:/config/max_tokens", "config:/config/timeout_ms"]
12
+ ---
13
+
14
+ <section>
15
+ <h2>Inspect generator configuration</h2>
16
+ <p>Run <code>total-recall openwiki config show --json</code> to inspect the active provider, routing, token bound and timeout.</p>
17
+ <p>Use <code>config get</code> for an individual setting. An explicit <code>config set</code> changes the chosen setting for future generation.</p>
18
+ </section>
@@ -0,0 +1,18 @@
1
+ ---
2
+ type: ui-chunk:chunk
3
+ plugin: openwiki
4
+ id: host-probe
5
+ title: Probe the Total Recall host
6
+ description: Check the configured host's health endpoint and observe response latency.
7
+ timestamp: "2026-11-08T09:14:38Z"
8
+ intents: [probe Total Recall host, inspect wiki host availability, check health response]
9
+ surfaces: [page, right]
10
+ operations: [probe]
11
+ data: ["probe:/ok", "probe:/status", "probe:/latency_ms"]
12
+ ---
13
+
14
+ <section>
15
+ <h2>Probe the Total Recall host</h2>
16
+ <p>Run <code>total-recall openwiki probe --json</code> to observe the HTTP status and response time for the configured host's health endpoint.</p>
17
+ <p>Use the wiki index or evidence search to check documentation coverage.</p>
18
+ </section>
@@ -0,0 +1,18 @@
1
+ ---
2
+ type: ui-chunk:chunk
3
+ plugin: openwiki
4
+ id: ingest-preview
5
+ title: Preview wiki ingestion
6
+ description: Count pages selected for import into the requested Total Recall brain.
7
+ timestamp: "2026-11-08T09:14:38Z"
8
+ intents: [preview wiki ingest, import markdown into project brain, inspect wiki import receipt]
9
+ surfaces: [page]
10
+ operations: [ingest]
11
+ data: ["ingest:/planned", "ingest:/imported", "ingest:/errors"]
12
+ ---
13
+
14
+ <section>
15
+ <h2>Preview wiki ingestion</h2>
16
+ <p>Run <code>total-recall openwiki ingest &lt;directory&gt; --project --dry-run --json</code> to count pages planned for the project brain. Select <code>--global</code> only when the shared brain is the intended target.</p>
17
+ <p>After approving the target, run the import and review the completed and failed counts. Confirm indexed passages through Total Recall recall.</p>
18
+ </section>