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.
- package/bin/total-recall.mjs +4 -2
- package/frontend/dist/assets/index-BRYE1jmv.css +1 -0
- package/frontend/dist/assets/index-D1goIPjC.js +5598 -0
- package/frontend/dist/index.html +2 -2
- package/frontend/dist/sw.js +5 -4
- package/frontend/src/App.tsx +183 -236
- package/frontend/src/api/auth-inventory.ts +62 -0
- package/frontend/src/api/memory.ts +13 -8
- package/frontend/src/api/plugin-credentials.ts +23 -0
- package/frontend/src/api/plugins.ts +37 -53
- package/frontend/src/api/workspace-drawers.ts +97 -0
- package/frontend/src/components/BrainSelector.tsx +9 -3
- package/frontend/src/components/plugins/PluginPanel.tsx +83 -42
- package/frontend/src/components/plugins/PluginSettings.tsx +10 -20
- package/frontend/src/components/plugins/PluginWorkspace.tsx +367 -0
- package/frontend/src/components/plugins/ScopedPluginCommands.tsx +142 -0
- package/frontend/src/components/plugins/plugin-frame.ts +44 -33
- package/frontend/src/components/plugins/scoped-plugin-operations.ts +28 -0
- package/frontend/src/components/workspace/DrawerChat.tsx +110 -0
- package/frontend/src/components/workspace/DrawerLayout.tsx +196 -0
- package/frontend/src/components/workspace/DrawerMarkup.tsx +49 -0
- package/frontend/src/components/workspace/PluginChunkLibrary.tsx +92 -0
- package/frontend/src/components/workspace/PluginHome.tsx +76 -0
- package/frontend/src/components/workspace/WorkspaceDrawers.tsx +96 -0
- package/frontend/src/components/workspace/WorkspacePage.tsx +95 -0
- package/frontend/src/components/workspace/usePluginDesign.ts +38 -0
- package/frontend/src/index.css +409 -136
- package/frontend/src/pages/HelpPage.tsx +15 -46
- package/frontend/src/pages/MemoryPage.tsx +19 -36
- package/frontend/src/pages/SettingsPage.tsx +1 -1
- package/metadata.plugin.schema.json +53 -227
- package/package.json +1 -1
- package/scaffold/.agent/skills/plugin/SKILL.md +13 -11
- package/scaffold/.agent/skills/plugin/evals/README.md +14 -21
- package/scaffold/.agent/skills/plugin/evals/cases/01-fabricated-seed.mjs +15 -18
- package/scaffold/.agent/skills/plugin/evals/cases/02-reassuring-default.mjs +19 -24
- package/scaffold/.agent/skills/plugin/evals/cases/03-declared-template.mjs +12 -20
- package/scaffold/.agent/skills/plugin/evals/cases/04-home-collects-credential.mjs +35 -0
- package/scaffold/.agent/skills/plugin/evals/cases/05-host-leak-in-scaffold.mjs +8 -28
- package/scaffold/.agent/skills/plugin/evals/cases/06-correct-plugin.mjs +85 -47
- package/scaffold/.agent/skills/plugin/evals/run.mjs +17 -18
- package/scaffold/.agent/skills/plugin/prompts/05-credentials.md +4 -4
- package/scaffold/.agent/skills/plugin/prompts/07-scaffold.md +2 -2
- package/scaffold/.agent/skills/plugin/prompts/08-verify.md +4 -4
- package/scaffold/.agent/skills/plugin/references/anti-patterns.md +2 -2
- package/scaffold/.agent/skills/plugin/references/generative-home.md +38 -0
- package/scaffold/.agent/skills/plugin/references/scaffold.md +5 -5
- package/scaffold/.agent/skills/plugin/references/surfaces.md +13 -4
- package/scaffold/.agent/skills/plugin/scripts/record.mjs +75 -153
- package/scaffold/.agent/skills/plugin/subagents/plugin-reviewer.md +4 -4
- package/scaffold/.agent/skills/total-recall/plugins/auth/DESIGN.md +76 -0
- package/scaffold/.agent/skills/total-recall/plugins/auth/README.md +3 -1
- package/scaffold/.agent/skills/total-recall/plugins/auth/cli.mjs +20 -15
- package/scaffold/.agent/skills/total-recall/plugins/auth/package-lock.json +6 -6
- package/scaffold/.agent/skills/total-recall/plugins/auth/package.json +2 -1
- package/scaffold/.agent/skills/total-recall/plugins/auth/plugin.json +13 -51
- package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/access-overview.md +17 -0
- package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/agent-login.md +20 -0
- package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/baseline-audit.md +22 -0
- package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/credential-repository-binding.md +17 -0
- package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/credential-store-maintenance.md +17 -0
- package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/dashboard-password.md +18 -0
- package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/dashboard-sessions.md +18 -0
- package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/endpoint-probe.md +23 -0
- package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/google-sign-in.md +21 -0
- package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/mesh-machines.md +16 -0
- package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/passkey-enrollment.md +21 -0
- package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/registered-brains.md +16 -0
- package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/scoped-access-keys.md +17 -0
- package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/secret-inventory.md +25 -0
- package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/signing-key-rotation.md +22 -0
- package/scaffold/.agent/skills/total-recall/plugins/auth/ui/home.js +375 -0
- package/scaffold/.agent/skills/total-recall/plugins/automations/{ui/DESIGN.md → DESIGN.md} +32 -21
- package/scaffold/.agent/skills/total-recall/plugins/automations/adapters.mjs +17 -1
- package/scaffold/.agent/skills/total-recall/plugins/automations/cli.mjs +10 -1
- package/scaffold/.agent/skills/total-recall/plugins/automations/package-lock.json +6 -6
- package/scaffold/.agent/skills/total-recall/plugins/automations/package.json +4 -3
- package/scaffold/.agent/skills/total-recall/plugins/automations/plugin.json +11 -27
- package/scaffold/.agent/skills/total-recall/plugins/automations/ui/automations.js +2 -2
- package/scaffold/.agent/skills/total-recall/plugins/automations/ui/chunks/control-ledger.md +42 -0
- package/scaffold/.agent/skills/total-recall/plugins/automations/ui/chunks/local-inventory-triage.md +17 -0
- package/scaffold/.agent/skills/total-recall/plugins/automations/ui/chunks/pending-control.md +39 -0
- package/scaffold/.agent/skills/total-recall/plugins/automations/ui/chunks/run-evidence.md +41 -0
- package/scaffold/.agent/skills/total-recall/plugins/automations/ui/chunks/schedule-vs-run-evidence.md +17 -0
- package/scaffold/.agent/skills/total-recall/plugins/automations/ui/chunks/source-coverage.md +41 -0
- package/scaffold/.agent/skills/total-recall/plugins/automations/ui/{card.js → home.js} +32 -27
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/DESIGN.md +53 -0
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/cli.mjs +23 -0
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/commands/run-core.mjs +4 -2
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/core/check.mjs +4 -2
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/package-lock.json +6 -6
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/package.json +2 -1
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/plugin.json +40 -40
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/chunks/config.md +15 -0
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/chunks/detect.md +15 -0
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/chunks/gate.md +15 -0
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/chunks/init.md +15 -0
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/chunks/report.md +17 -0
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/chunks/run.md +17 -0
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/chunks/snapshot.md +15 -0
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/code-quality-report.mjs +55 -23
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/home.mjs +214 -0
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/DESIGN.md +146 -0
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/package-lock.json +6 -6
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/package.json +2 -1
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/plugin.json +51 -34
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/src/command.mjs +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/create.md +35 -0
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/history.md +35 -0
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/library.md +49 -0
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/list.md +42 -0
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/promote.md +40 -0
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/read.md +25 -0
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/remove.md +26 -0
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/rollback.md +26 -0
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/show.md +53 -0
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/status.md +40 -0
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/test-path.md +38 -0
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/test.md +46 -0
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/update.md +32 -0
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/home.js +533 -0
- package/scaffold/.agent/skills/total-recall/plugins/embeddings/DESIGN.md +110 -0
- package/scaffold/.agent/skills/total-recall/plugins/embeddings/package-lock.json +6 -6
- package/scaffold/.agent/skills/total-recall/plugins/embeddings/package.json +2 -1
- package/scaffold/.agent/skills/total-recall/plugins/embeddings/plugin.json +13 -10
- package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/chunks/benchmark.md +49 -0
- package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/chunks/coverage.md +53 -0
- package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/chunks/models.md +43 -0
- package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/chunks/pull.md +41 -0
- package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/chunks/status.md +59 -0
- package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/home.js +353 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/DESIGN.md +31 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/README.md +25 -1
- package/scaffold/.agent/skills/total-recall/plugins/git/cli.mjs +5 -1
- package/scaffold/.agent/skills/total-recall/plugins/git/package-lock.json +6 -6
- package/scaffold/.agent/skills/total-recall/plugins/git/package.json +2 -1
- package/scaffold/.agent/skills/total-recall/plugins/git/plugin.json +17 -27
- package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/commit-memory.mjs +30 -6
- package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/fleet.mjs +24 -6
- package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/secret-firewall.mjs +33 -7
- package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/undo.mjs +29 -5
- package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/unmerged.mjs +182 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/change-comparison.md +27 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/commit-identity.md +22 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/create-worktree.md +25 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/registered-worktrees.md +22 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/remove-worktree.md +23 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/repository-ledger.md +25 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/unmerged-work.md +22 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/upstream-divergence.md +17 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/worktree-conflict-triage.md +17 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/worktree-terminal.md +22 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/ui/home.js +273 -0
- package/scaffold/.agent/skills/total-recall/plugins/mesh/DESIGN.md +35 -0
- package/scaffold/.agent/skills/total-recall/plugins/mesh/README.md +4 -5
- package/scaffold/.agent/skills/total-recall/plugins/mesh/cli.mjs +9 -3
- package/scaffold/.agent/skills/total-recall/plugins/mesh/package-lock.json +6 -6
- package/scaffold/.agent/skills/total-recall/plugins/mesh/package.json +2 -1
- package/scaffold/.agent/skills/total-recall/plugins/mesh/plugin.json +37 -39
- package/scaffold/.agent/skills/total-recall/plugins/mesh/src/cli/mesh.mjs +5 -3
- package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/active-device-dispatch.md +22 -0
- package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/control-probe.md +25 -0
- package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/control-server.md +22 -0
- package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/credential-readiness.md +23 -0
- package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/elected-leader.md +22 -0
- package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/enrollment-key.md +22 -0
- package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/file-receipt.md +25 -0
- package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/fleet-execution.md +23 -0
- package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/fleet-presence.md +23 -0
- package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/interactive-ssh.md +22 -0
- package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/local-enrollment.md +23 -0
- package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/mesh-policy.md +23 -0
- package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/network-atlas.md +25 -0
- package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/node-roster.md +26 -0
- package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/node-selection-proof.md +17 -0
- package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/owner-observations.md +23 -0
- package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/peer-path.md +23 -0
- package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/pinned-leader.md +24 -0
- package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/reachability-evidence-ladder.md +17 -0
- package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/recorded-login.md +23 -0
- package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/remote-execution.md +22 -0
- package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/secret-grants.md +26 -0
- package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/{card.js → home.js} +93 -22
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/DESIGN.md +86 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/README.md +19 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/cli.mjs +5 -1
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/package-lock.json +6 -6
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/package.json +2 -1
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/plugin.json +43 -22
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/chat.mjs +80 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/adapter-docs-freshness.md +16 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/chat-handoff.md +26 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/fleet-maintenance.md +21 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/harness-inventory.md +21 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/included-access.md +18 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/included-usage-verification.md +15 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/independent-review.md +17 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/managed-execution.md +20 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/official-documentation.md +18 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/quota-recovery.md +21 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/review-routing-decision.md +16 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/route-work.md +18 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/routing-evidence.md +18 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/run-ledger.md +18 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/home.js +198 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/DESIGN.md +75 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/README.md +2 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/cli.mjs +17 -14
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/package-lock.json +6 -6
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/package.json +2 -1
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/plugin.json +10 -44
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/generate.mjs +5 -4
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/graph.mjs +3 -4
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/ingest.mjs +23 -18
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/mesh-vaults.mjs +8 -3
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/refresh.mjs +6 -3
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/search.mjs +3 -5
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/token.mjs +21 -47
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/upstream-watcher.mjs +17 -6
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/auto-refresh.md +18 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/bootstrap-pages.md +18 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/generate-wiki.md +21 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/generator-settings.md +18 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/host-probe.md +18 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/ingest-preview.md +18 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/link-hygiene.md +21 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/link-topology.md +19 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/passage-search.md +19 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/propagation-plan.md +18 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/provider-credentials.md +18 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/refresh-report.md +18 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/task-evidence.md +22 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/upstream-record.md +18 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/watch-upstream.md +18 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/wiki-atlas.md +19 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/panel.js +261 -513
- package/scaffold/.agent/skills/total-recall/plugins/security/DESIGN.md +84 -0
- package/scaffold/.agent/skills/total-recall/plugins/security/README.md +4 -2
- package/scaffold/.agent/skills/total-recall/plugins/security/cli.mjs +7 -19
- package/scaffold/.agent/skills/total-recall/plugins/security/package-lock.json +6 -6
- package/scaffold/.agent/skills/total-recall/plugins/security/package.json +2 -3
- package/scaffold/.agent/skills/total-recall/plugins/security/plugin.json +19 -52
- package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/device-evidence.md +21 -0
- package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/evidence-desk.md +18 -0
- package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/guided-device-review.md +17 -0
- package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/host-and-network.md +21 -0
- package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/https-headers.md +17 -0
- package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/mesh-coverage.md +18 -0
- package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/private-security-tools.md +16 -0
- package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/single-origin-header-check.md +17 -0
- package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/source-review.md +21 -0
- package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/ssh-permission-plan.md +17 -0
- package/scaffold/.agent/skills/total-recall/plugins/security/ui/home.js +283 -0
- package/scaffold/.agent/skills/total-recall/plugins/ssss/DESIGN.md +93 -0
- package/scaffold/.agent/skills/total-recall/plugins/ssss/package-lock.json +2 -2
- package/scaffold/.agent/skills/total-recall/plugins/ssss/package.json +2 -1
- package/scaffold/.agent/skills/total-recall/plugins/ssss/plugin.json +5 -3
- package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/chunks/conformance.md +26 -0
- package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/chunks/registry.md +37 -0
- package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/chunks/repair.md +42 -0
- package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/chunks/scaffold.md +33 -0
- package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/chunks/status.md +43 -0
- package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/chunks/validate.md +34 -0
- package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/chunks/validation-diagnostics.md +17 -0
- package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/chunks/workspace-registry-preflight.md +17 -0
- package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/home.js +348 -0
- package/scaffold/.agent/skills/total-recall/references/operations.md +2 -0
- package/src/cli/api.mjs +3 -3
- package/src/cli/brief.mjs +3 -0
- package/src/cli/config.mjs +16 -0
- package/src/cli/connect.mjs +2 -7
- package/src/cli/plugin/chunks.mjs +145 -0
- package/src/cli/plugin/create.mjs +24 -52
- package/src/cli/plugin/index.mjs +20 -9
- package/src/cli/setup.mjs +2 -9
- package/src/cli/start.mjs +1 -0
- package/src/cli/startup.mjs +18 -0
- package/src/core/app-deploy/design-tokens.mjs +14 -9
- package/src/core/app-deploy/ui-elements.mjs +1 -1
- package/src/core/brain-registry.mjs +5 -0
- package/src/core/brain-updates.mjs +5 -1
- package/src/core/daemon-control.mjs +5 -1
- package/src/core/dashboard-bundle.mjs +261 -0
- package/src/core/ensure-dependencies.mjs +19 -15
- package/src/core/memory-brain.mjs +30 -8
- package/src/core/plugin-activation.mjs +63 -20
- package/src/core/plugin-contracts/{card.mjs → manifest.mjs} +23 -57
- package/src/core/plugin-contracts/startup-check.mjs +49 -0
- package/src/core/plugin-contracts/ui.mjs +9 -3
- package/src/core/plugin-distribution.mjs +6 -6
- package/src/core/plugin-lifecycle.mjs +58 -0
- package/src/core/plugin-loader.mjs +9 -5
- package/src/core/plugin-runner.mjs +21 -10
- package/src/core/plugin-startup-checks.mjs +44 -0
- package/src/core/plugin-state.mjs +19 -5
- package/src/core/plugin-store.mjs +30 -11
- package/src/core/project-id.mjs +15 -5
- package/src/core/required-plugins.mjs +31 -6
- package/src/core/schema.mjs +2 -0
- package/src/core/ssss-operation-service.mjs +1 -0
- package/src/core/startup-health.mjs +28 -3
- package/src/core/testing/plugin-fixture.mjs +22 -21
- package/src/core/throttled-fetch.mjs +25 -18
- package/src/core/ui-chunk-choice.mjs +77 -0
- package/src/core/ui-chunk.registry.json +23 -0
- package/src/core/ui-chunks.mjs +434 -0
- package/src/core/vault-cache.mjs +58 -59
- package/src/core/workspace-compositions.mjs +151 -0
- package/src/core/workspace-drawers.mjs +79 -0
- package/src/server/api.mjs +4 -27
- package/src/server/index.mjs +28 -21
- package/src/server/memory-events.mjs +31 -0
- package/src/server/plugin-brain-targets.mjs +89 -0
- package/src/server/rest.mjs +2 -0
- package/src/server/route-inventory.mjs +3 -2
- package/src/server/route-manifest.json +52 -4
- package/src/server/routes/_shared.mjs +7 -14
- package/src/server/routes/brains.mjs +29 -44
- package/src/server/routes/dashboard.mjs +26 -0
- package/src/server/routes/plugins.mjs +154 -45
- package/src/server/routes/ui-chunks.mjs +192 -0
- package/frontend/dist/assets/index-DACh1dhx.js +0 -5613
- package/frontend/dist/assets/index-DtwsDyFM.css +0 -1
- package/frontend/src/components/plugins/card/CardEngine.tsx +0 -108
- package/frontend/src/components/plugins/card/CardScenes.tsx +0 -103
- package/frontend/src/components/plugins/card/ExecutionPicker.tsx +0 -64
- package/frontend/src/components/plugins/card/args.ts +0 -28
- package/frontend/src/components/plugins/card/card.css +0 -32
- package/frontend/src/components/plugins/card/cli-line.ts +0 -13
- package/frontend/src/components/plugins/card/contract.ts +0 -91
- package/frontend/src/components/plugins/card/format.ts +0 -49
- package/frontend/src/components/plugins/card/runner-context.ts +0 -11
- package/frontend/src/components/plugins/card/runner.tsx +0 -43
- package/frontend/src/components/plugins/card/theme.ts +0 -35
- package/frontend/src/components/plugins/card/use-source.ts +0 -22
- package/frontend/src/components/plugins/card/widgets.tsx +0 -94
- package/frontend/src/components/plugins/workspace/WorkspaceHost.tsx +0 -23
- package/frontend/src/pages/PluginsPage.tsx +0 -1719
- package/scaffold/.agent/skills/plugin/evals/cases/04-card-collects-credential.mjs +0 -47
- package/scaffold/.agent/skills/plugin/prompts/06-card.md +0 -46
- package/scaffold/.agent/skills/plugin/references/card.md +0 -90
- package/scaffold/.agent/skills/plugin/subagents/card-designer.md +0 -60
- package/scaffold/.agent/skills/total-recall/plugins/auth/ui/DESIGN.md +0 -67
- package/scaffold/.agent/skills/total-recall/plugins/auth/ui/card.js +0 -1179
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/DESIGN.md +0 -32
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/card.js +0 -588
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/card.js +0 -575
- package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/DESIGN.md +0 -32
- package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/card.js +0 -482
- package/scaffold/.agent/skills/total-recall/plugins/git/ui/DESIGN.md +0 -100
- package/scaffold/.agent/skills/total-recall/plugins/git/ui/card.js +0 -637
- package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/DESIGN.md +0 -217
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/DESIGN.md +0 -32
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/card.js +0 -1276
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/DESIGN.md +0 -45
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/card.js +0 -1401
- package/scaffold/.agent/skills/total-recall/plugins/security/scripts/build-ui.mjs +0 -4
- package/scaffold/.agent/skills/total-recall/plugins/security/ui/DESIGN.md +0 -41
- package/scaffold/.agent/skills/total-recall/plugins/security/ui/card.js +0 -396
- package/scaffold/.agent/skills/total-recall/plugins/security/ui/panel.js +0 -98
- package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/DESIGN.md +0 -15
- package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/card.js +0 -182
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { parseArgs } from 'node:util';
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { auditUiChunkCoverage, getUiChunk, searchUiChunks, uiChunkRegistryPath, validateUiChunkFile } from '../../core/ui-chunks.mjs';
|
|
5
|
+
import { chooseUiChunk } from '../../core/ui-chunk-choice.mjs';
|
|
6
|
+
import { callApi } from '../api.mjs';
|
|
7
|
+
|
|
8
|
+
const help = [
|
|
9
|
+
'Usage: total-recall plugin chunks [query] [--plugin ID] [--surface page|left|right|bottom] [--limit N] [--decision|--workspace] [--brain ID] [--json]',
|
|
10
|
+
' total-recall plugin chunks get <plugin:id> [--surface SURFACE] [--workspace] [--brain ID] [--json]',
|
|
11
|
+
' total-recall plugin chunks validate <file> [--plugin-dir DIR] [--json]',
|
|
12
|
+
' total-recall plugin chunks registry',
|
|
13
|
+
' total-recall plugin chunks coverage [--plugin ID] [--json]',
|
|
14
|
+
' total-recall plugin chunks add <id.md> --plugin ID [--brain ID] [--json]',
|
|
15
|
+
' total-recall plugin chunks page <id> --brain ID [--json]',
|
|
16
|
+
' total-recall plugin chunks page <id> <plugin:block>... --brain ID (--title TITLE | --revision VERSION) [--json]',
|
|
17
|
+
'',
|
|
18
|
+
'Use --decision with a concise, non-sensitive query to request a ranked choice through the configured Decision plugin.',
|
|
19
|
+
'Search and validation run locally by default. Decision requests send only the query and up to 20 eligible metadata records.',
|
|
20
|
+
'Agents use total-recall decision compose to publish a Jev-selected page.',
|
|
21
|
+
].join('\n');
|
|
22
|
+
|
|
23
|
+
export async function runPluginChunks(args) {
|
|
24
|
+
const asJson = args.includes('--json');
|
|
25
|
+
try {
|
|
26
|
+
const { values, positionals } = parseArgs({
|
|
27
|
+
args,
|
|
28
|
+
allowPositionals: true,
|
|
29
|
+
options: {
|
|
30
|
+
json: { type: 'boolean' },
|
|
31
|
+
help: { type: 'boolean', short: 'h' },
|
|
32
|
+
decision: { type: 'boolean' },
|
|
33
|
+
workspace: { type: 'boolean' },
|
|
34
|
+
brain: { type: 'string' },
|
|
35
|
+
surface: { type: 'string' },
|
|
36
|
+
plugin: { type: 'string' },
|
|
37
|
+
limit: { type: 'string' },
|
|
38
|
+
'plugin-dir': { type: 'string' },
|
|
39
|
+
title: { type: 'string' },
|
|
40
|
+
revision: { type: 'string' },
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
if (values.help) return console.log(help);
|
|
44
|
+
|
|
45
|
+
const [verb, target, ...extra] = positionals;
|
|
46
|
+
if (verb === 'page') {
|
|
47
|
+
const { brain, title, revision } = values;
|
|
48
|
+
if (!target || !brain?.trim() || values.plugin || values.workspace || values.decision || values.surface || values.limit || values['plugin-dir']) throw new Error(help);
|
|
49
|
+
const writing = extra.length > 0;
|
|
50
|
+
const create = typeof title === 'string' && title.trim() && revision === undefined;
|
|
51
|
+
const edit = typeof revision === 'string' && revision.trim() && title === undefined;
|
|
52
|
+
if (writing ? !create && !edit : title !== undefined || revision !== undefined) throw new Error(help);
|
|
53
|
+
const collection = '/api/workspace/pages';
|
|
54
|
+
const detail = collection + '/' + encodeURIComponent(target);
|
|
55
|
+
const response = !writing
|
|
56
|
+
? await callApi('GET', detail, { query: { brain } })
|
|
57
|
+
: await callApi(edit ? 'PUT' : 'POST', edit ? detail : collection, {
|
|
58
|
+
data: JSON.stringify({ id: target, brainId: brain, title, revision, keys: extra }),
|
|
59
|
+
});
|
|
60
|
+
if (!response.ok) throw new Error(response.body?.error || 'Could not access the saved page.');
|
|
61
|
+
const page = response.body;
|
|
62
|
+
if (asJson) return console.log(JSON.stringify({ ok: true, ...page }));
|
|
63
|
+
console.log(page.path || `${page.title} (${page.version})`);
|
|
64
|
+
for (const chunk of page.chunks) console.log(chunk.key);
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
if (values.title !== undefined || values.revision !== undefined) throw new Error(help);
|
|
68
|
+
if (values.brain !== undefined && ((!values.workspace && verb !== 'add') || !values.brain.trim())) {
|
|
69
|
+
throw new Error('--brain requires a registered brain ID and --workspace, or an add operation.');
|
|
70
|
+
}
|
|
71
|
+
if (values.workspace && (values.decision || ['add', 'coverage', 'registry', 'validate'].includes(verb))) throw new Error(help);
|
|
72
|
+
if (verb === 'add') {
|
|
73
|
+
if (!target || !values.plugin || extra.length || values.decision || values.surface || values.limit || values['plugin-dir'] || path.extname(target) !== '.md') throw new Error(help);
|
|
74
|
+
const stat = fs.statSync(target);
|
|
75
|
+
if (!stat.isFile() || stat.size > 64 * 1024) throw new Error('Choose a Markdown block no larger than 64 KiB.');
|
|
76
|
+
const markdown = fs.readFileSync(target, 'utf8');
|
|
77
|
+
const { ok, body } = await callApi('POST', '/api/ui-chunks/pool', {
|
|
78
|
+
data: JSON.stringify({ plugin: values.plugin, id: path.basename(target, '.md'), markdown, brainId: values.brain }),
|
|
79
|
+
});
|
|
80
|
+
if (!ok) throw new Error(body?.error || 'The dashboard could not add the block.');
|
|
81
|
+
return console.log(asJson ? JSON.stringify({ ok, ...body }) : 'Added ' + body.chunk.key);
|
|
82
|
+
}
|
|
83
|
+
if (verb === 'coverage') {
|
|
84
|
+
if (target || values.decision || values.surface || values.limit || values['plugin-dir']) throw new Error(help);
|
|
85
|
+
const plugins = auditUiChunkCoverage({ plugin: values.plugin });
|
|
86
|
+
if (values.plugin && !plugins.length) throw new Error('Plugin is not installed.');
|
|
87
|
+
if (asJson) return console.log(JSON.stringify({ ok: true, plugins }));
|
|
88
|
+
for (const item of plugins) {
|
|
89
|
+
const bound = item.operations.total - item.operations.missing.length;
|
|
90
|
+
console.log(`${item.plugin}: ${item.pageBlocks} page blocks, ${bound}/${item.operations.total} operations, ${item.dataBindings.length} data bindings, design ${item.design || 'missing'}${item.partial ? ' (partial audit)' : ''}`);
|
|
91
|
+
}
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
if (verb === 'registry') {
|
|
95
|
+
if (target || values.decision || values.surface || values.plugin || values.limit || values['plugin-dir']) throw new Error(help);
|
|
96
|
+
return console.log(asJson ? JSON.stringify({ ok: true, file: uiChunkRegistryPath }) : uiChunkRegistryPath);
|
|
97
|
+
}
|
|
98
|
+
if (verb === 'validate') {
|
|
99
|
+
if (!target || extra.length || values.decision || values.surface || values.plugin || values.limit) throw new Error(help);
|
|
100
|
+
const chunk = validateUiChunkFile(target, { pluginDir: values['plugin-dir'] });
|
|
101
|
+
return console.log(asJson ? JSON.stringify({ ok: true, chunk }) : 'Validated ' + chunk.key);
|
|
102
|
+
}
|
|
103
|
+
if (values['plugin-dir']) throw new Error('--plugin-dir is only available with validate.');
|
|
104
|
+
if (verb === 'get') {
|
|
105
|
+
if (!target || extra.length || values.decision || values.plugin || values.limit) throw new Error(help);
|
|
106
|
+
const [plugin, id, ...rest] = target.split(':');
|
|
107
|
+
if (!plugin || !id || rest.length) throw new Error('Specify a chunk as plugin:id.');
|
|
108
|
+
const query = values.surface ? { surface: values.surface } : {};
|
|
109
|
+
if (values.brain) query.brain = values.brain;
|
|
110
|
+
const chunk = values.workspace
|
|
111
|
+
? (await callApi('GET', `/api/ui-chunks/${encodeURIComponent(plugin)}/${encodeURIComponent(id)}`, { query })).body?.chunk
|
|
112
|
+
: getUiChunk(plugin, id, { surface: values.surface });
|
|
113
|
+
if (!chunk) throw new Error('UI chunk unavailable.');
|
|
114
|
+
return console.log(asJson ? JSON.stringify({ ok: true, chunk }) : chunk.html);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const query = positionals.join(' ').trim();
|
|
118
|
+
const limit = values.limit === undefined ? undefined : Number(values.limit);
|
|
119
|
+
if (values.decision && !query) throw new Error('--decision requires an explicit query.');
|
|
120
|
+
let result;
|
|
121
|
+
if (values.workspace) {
|
|
122
|
+
const filters = Object.fromEntries(Object.entries({ plugin: values.plugin, surface: values.surface, q: query, limit, brain: values.brain }).filter(([, value]) => value !== undefined));
|
|
123
|
+
const response = await callApi('GET', '/api/ui-chunks', { query: filters });
|
|
124
|
+
if (!response.ok) throw new Error(response.body?.error || 'The dashboard could not read the workspace pool.');
|
|
125
|
+
result = response.body;
|
|
126
|
+
} else {
|
|
127
|
+
result = searchUiChunks({ plugin: values.plugin, surface: values.surface, query, limit });
|
|
128
|
+
}
|
|
129
|
+
if (values.decision) result.selection = await chooseUiChunk(result.chunks, query, values.surface);
|
|
130
|
+
if (asJson) return console.log(JSON.stringify({ ok: true, ...result }));
|
|
131
|
+
for (const chunk of result.chunks) console.log(chunk.key + ' ' + chunk.title + ' [' + chunk.surfaces.join(', ') + ']');
|
|
132
|
+
if (!result.chunks.length) console.log('No eligible UI chunks.');
|
|
133
|
+
for (const issue of result.diagnostics) {
|
|
134
|
+
console.error(issue.plugin + (issue.id ? ':' + issue.id : '') + ' ' + issue.message);
|
|
135
|
+
}
|
|
136
|
+
if (result.selection) {
|
|
137
|
+
const { key, source, reason } = result.selection;
|
|
138
|
+
console.log('Selection (' + source + '): ' + (key ?? 'none') + (reason ? ' (' + reason + ')' : ''));
|
|
139
|
+
}
|
|
140
|
+
} catch (error) {
|
|
141
|
+
process.exitCode = 1;
|
|
142
|
+
if (asJson) console.log(JSON.stringify({ ok: false, error: error.message }));
|
|
143
|
+
else console.error(error.message);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
@@ -113,10 +113,7 @@ export async function createPlugin(args = []) {
|
|
|
113
113
|
// Every plugin is installed in the shared folder; --global is accepted and changes nothing.
|
|
114
114
|
let withCli = args.includes("--with-cli");
|
|
115
115
|
const withGenerator = args.includes("--with-generator");
|
|
116
|
-
//
|
|
117
|
-
// function is understood. The scaffold deliberately ships without one, so
|
|
118
|
-
// there is nothing to generate here; `--with-ui` is accepted only to explain
|
|
119
|
-
// that to anyone who asks for it.
|
|
116
|
+
// The owner authors the native Home after defining the plugin's workflows.
|
|
120
117
|
const asksForUi = args.includes("--with-ui");
|
|
121
118
|
const withTask = args.includes("--with-task");
|
|
122
119
|
const createGithub = args.includes("--github");
|
|
@@ -251,17 +248,15 @@ export async function createPlugin(args = []) {
|
|
|
251
248
|
version: "0.1.0",
|
|
252
249
|
description: pluginDesc,
|
|
253
250
|
license: "MIT",
|
|
254
|
-
|
|
255
|
-
//
|
|
251
|
+
auth: { plugin: "auth", methods: ["passkey", "google-oauth2"], session_verification: true },
|
|
252
|
+
// An unfinished scaffold can install while the owner writes its Home.
|
|
256
253
|
scaffold: true,
|
|
257
254
|
// How work reaches this plugin. `preflight coverage` reports it until tasks are written.
|
|
258
255
|
gate: { tasks: [], owned_commands: [] }
|
|
259
256
|
};
|
|
260
257
|
if (useCases.length > 0) manifest.use_cases = useCases;
|
|
261
258
|
|
|
262
|
-
//
|
|
263
|
-
// it, so it works the moment the key is pasted. Its card face is authored by
|
|
264
|
-
// hand later, like every other face.
|
|
259
|
+
// A plugin with a provider credential can save it through the shared Auth CLI.
|
|
265
260
|
if (apiKeys.length) {
|
|
266
261
|
withCli = true;
|
|
267
262
|
manifest.secrets = apiKeys.map((key) => ({ key, description: `${pluginName} service API key (paste it in the plugin UI)`, required: true }));
|
|
@@ -301,8 +296,7 @@ export async function createPlugin(args = []) {
|
|
|
301
296
|
]
|
|
302
297
|
});
|
|
303
298
|
}
|
|
304
|
-
//
|
|
305
|
-
// command; a scaffold without this shows no live status.
|
|
299
|
+
// Give the Home a declared read operation for live status.
|
|
306
300
|
manifest.status = { command: "status", refresh_seconds: 60 };
|
|
307
301
|
|
|
308
302
|
const cliContent = `#!/usr/bin/env node
|
|
@@ -358,12 +352,6 @@ export default run;
|
|
|
358
352
|
manifest.tasks = [{ intent: taskIntent, schedule: taskSchedule, command: taskCommand, placement: 'selected-node' }];
|
|
359
353
|
}
|
|
360
354
|
|
|
361
|
-
// No UI is generated. Every plugin must have a card face, but a face is
|
|
362
|
-
// bespoke owner code authored by hand once the plugin's function is known:
|
|
363
|
-
// a generated stub is what produced a ecosystem of identical cards. The
|
|
364
|
-
// scaffold therefore reports the face as outstanding rather than faking one.
|
|
365
|
-
const cardOutstanding = true;
|
|
366
|
-
|
|
367
355
|
if (isCapability) {
|
|
368
356
|
manifest.deploy = {
|
|
369
357
|
targets: ["ssss-app", "nextjs", "react", "flask"],
|
|
@@ -445,19 +433,12 @@ export default generateContext;
|
|
|
445
433
|
fs.writeFileSync(path.join(pluginDir, "generator.mjs"), generatorContent, "utf8");
|
|
446
434
|
}
|
|
447
435
|
|
|
448
|
-
manifest.capability = {
|
|
449
|
-
entry: "capability/index.mjs",
|
|
450
|
-
exports: ["getCapabilityStatus"]
|
|
451
|
-
};
|
|
452
|
-
|
|
453
436
|
const validation = validatePluginManifest(manifest);
|
|
454
437
|
if (!validation.valid) {
|
|
455
438
|
console.error("❌ Validation failed for generated manifest:", validation.errors);
|
|
456
439
|
fs.rmSync(pluginDir, { recursive: true, force: true });
|
|
457
440
|
process.exit(1);
|
|
458
441
|
}
|
|
459
|
-
// The scaffold installs without a card face, and says so. Its face is
|
|
460
|
-
// authored by hand next; the warning is the reminder, not a failure.
|
|
461
442
|
if (validation.warnings?.length) {
|
|
462
443
|
for (const warning of validation.warnings) console.log(`⚠️ ${warning}`);
|
|
463
444
|
}
|
|
@@ -492,7 +473,7 @@ export default generateContext;
|
|
|
492
473
|
if (category) lines.push(`- **SSSS Category**: \`${category}\``);
|
|
493
474
|
if (withCli) lines.push(`- **CLI Command**: \`npx total-recall ${id}\``);
|
|
494
475
|
if (withTask) lines.push(`- **Scheduled task**: \`${taskCommand}\` at \`${taskSchedule}\` (selected node; implement the command and choose a node before use)`);
|
|
495
|
-
if (asksForUi) lines.push('- **UI**:
|
|
476
|
+
if (asksForUi) lines.push('- **UI**: author the plugin workspace and its native panels for this plugin’s own function. Declare the panels in `ui.elements[]`.');
|
|
496
477
|
if (apiKeys.length) lines.push('- **API key**: paste it in the plugin UI (`save-token` event) or pipe it to `npx total-recall ' + id + ' token set --stdin`; stored as `' + apiKeys[0] + '` in the secrets store');
|
|
497
478
|
lines.push(
|
|
498
479
|
"",
|
|
@@ -506,6 +487,24 @@ export default generateContext;
|
|
|
506
487
|
""
|
|
507
488
|
);
|
|
508
489
|
|
|
490
|
+
lines.push(
|
|
491
|
+
"## Authoring generative UI",
|
|
492
|
+
"",
|
|
493
|
+
"Keep a bespoke `DESIGN.md` at the plugin root. Describe the palette, typography, layout, interaction and accessibility. Work with the user on the design and assets. Package this file and the authored blocks with the plugin.",
|
|
494
|
+
"",
|
|
495
|
+
"Author one SSSS Markdown document per reusable block at `ui/chunks/<id>.md`. Use `type: ui-chunk:chunk`, the manifest ID as `plugin`, the filename stem as `id`, a `title`, `description`, ISO `timestamp`, meaningful `intents` and supported `surfaces` from `page`, `left`, `right` and `bottom`. Use raw HTML for the body.",
|
|
496
|
+
"",
|
|
497
|
+
"Declare the native workspace entry in `ui.home` and its design in `ui.design_tokens`. Bind each block to exact manifest operation names in `operations` and verified fields in `data` using `operation:/json/pointer`. Declare browser-safe inputs so users can run the operation in place. Use a native `panel` for specialized editable controls. Keep credentials and private data out of routing metadata.",
|
|
498
|
+
"",
|
|
499
|
+
"Find the extension with `total-recall plugin chunks registry` and verify each block with `total-recall plugin chunks validate <file>`. Compare `total-recall plugin chunks coverage --plugin <id>` with the owner inventory. Use `total-recall plugin chunks <intent> --surface <surface>` to find blocks. Add `--decision` to request an explicit typed choice. The result identifies a block by its stable `plugin:id`.",
|
|
500
|
+
"",
|
|
501
|
+
"Keep packaged defaults in the owner repository. Users can choose and arrange installed blocks, provide their own HTML and edit the design with their agent. Submit broadly useful owner changes to the plugin repository.",
|
|
502
|
+
"",
|
|
503
|
+
"An agent can author any additional SSSS block for an enabled plugin. For a task-specific block, use `total-recall plugin chunks add <id.md> --plugin <owner> --brain <brain> --json` to validate and publish it. Read the result back by its stable `owner:id` key.",
|
|
504
|
+
"",
|
|
505
|
+
"For contextual selection, use `total-recall decision compose --plugin <owner> --intent <intent> --page <id> --title <title> --brain <brain>`. For exact placement, use `total-recall plugin chunks page <id> <owner:block>... --title <title> --brain <brain>`. To edit an existing page, read it with the same command without block keys, then pass its complete ordered keys and `--revision <version>` instead of `--title`. Reopen the saved page and verify each workflow against real data.",
|
|
506
|
+
""
|
|
507
|
+
);
|
|
509
508
|
fs.writeFileSync(path.join(pluginDir, "README.md"), lines.join("\n"), "utf8");
|
|
510
509
|
|
|
511
510
|
// ── Standalone repository files ──────────────────────────────────────────
|
|
@@ -533,34 +532,7 @@ export default generateContext;
|
|
|
533
532
|
fs.writeFileSync(path.join(pluginDir, '.gitignore'), 'node_modules/\n.env*\n.agent/skills/total-recall/\ndist/\nreports/\n.DS_Store\nINSTRUCTIONS.md\nAGENTS.md\n', 'utf8');
|
|
534
533
|
fs.writeFileSync(path.join(pluginDir, 'LICENSE'), mitLicense(holder), 'utf8');
|
|
535
534
|
|
|
536
|
-
// Capability brick
|
|
537
|
-
fs.mkdirSync(path.join(pluginDir, 'capability'), { recursive: true });
|
|
538
|
-
fs.writeFileSync(path.join(pluginDir, 'capability', 'index.mjs'), `/**
|
|
539
|
-
* Portable capability brick for ${pluginName}.
|
|
540
|
-
* Zero host dependencies; pure portable JavaScript.
|
|
541
|
-
*/
|
|
542
|
-
export async function getCapabilityStatus() {
|
|
543
|
-
return { ready: true, initialized: true };
|
|
544
|
-
}
|
|
545
|
-
`, 'utf8');
|
|
546
|
-
fs.writeFileSync(path.join(pluginDir, 'capability', 'BRICK.md'), `# ${pluginName} — Capability Brick
|
|
547
|
-
|
|
548
|
-
Portable core capability for ${pluginName}.
|
|
549
|
-
|
|
550
|
-
## Exported Functions
|
|
551
|
-
- \`getCapabilityStatus()\`: Returns capability readiness and initialization status.
|
|
552
|
-
`, 'utf8');
|
|
553
|
-
|
|
554
535
|
fs.mkdirSync(path.join(pluginDir, 'test'), { recursive: true });
|
|
555
|
-
fs.writeFileSync(path.join(pluginDir, 'test', 'capability.test.mjs'), `import test from 'node:test';
|
|
556
|
-
import assert from 'node:assert/strict';
|
|
557
|
-
import { getCapabilityStatus } from '../capability/index.mjs';
|
|
558
|
-
|
|
559
|
-
test('capability brick loads and exports status', async () => {
|
|
560
|
-
const status = await getCapabilityStatus();
|
|
561
|
-
assert.equal(status.ready, true);
|
|
562
|
-
});
|
|
563
|
-
`, 'utf8');
|
|
564
536
|
fs.writeFileSync(path.join(pluginDir, 'test', 'manifest.test.mjs'), `import test from 'node:test';
|
|
565
537
|
import assert from 'node:assert/strict';
|
|
566
538
|
import fs from 'node:fs';
|
package/src/cli/plugin/index.mjs
CHANGED
|
@@ -10,6 +10,7 @@ import { getPlugin, getPluginMonetization, globalPluginsDir, projectPluginsDir }
|
|
|
10
10
|
import { describePlugin, pruneReplacementArchives, replacementArchiveDir } from '../../core/plugin-store.mjs';
|
|
11
11
|
import { buildPluginCatalog } from '../../core/plugin-catalog.mjs';
|
|
12
12
|
import { setPluginActive } from '../../core/plugin-activation.mjs';
|
|
13
|
+
import { detectProjectBrain } from '../../core/brain-locate.mjs';
|
|
13
14
|
|
|
14
15
|
function printHelp() {
|
|
15
16
|
console.log(`
|
|
@@ -26,6 +27,7 @@ Usage:
|
|
|
26
27
|
Commands:
|
|
27
28
|
list Installed plugins (project & global) with source and sharing
|
|
28
29
|
library [--plugin ID] Installed CLI operation library (--json for agents)
|
|
30
|
+
chunks [query] Search installed SSSS UI chunks and validate owner files
|
|
29
31
|
refresh Rebuild installed command inventories and instruction surfaces
|
|
30
32
|
copies [dir] [--apply] Audit repository copies of shared defaults and shadow links. --apply
|
|
31
33
|
deletes bundled matches, unlinks shadows (on/off records are kept)
|
|
@@ -39,6 +41,7 @@ Commands:
|
|
|
39
41
|
on <id> / off <id> Enable/disable host execution for this repository alone
|
|
40
42
|
--all-repos Change the shared setting for every repository
|
|
41
43
|
--clear Drop this repository's override; follow the shared setting
|
|
44
|
+
on-use <id> Activate when deliberately opened or used in this repository
|
|
42
45
|
available [query] Plugins bundled with this Total Recall package
|
|
43
46
|
peers [query] Plugins your mesh peers share (queried live)
|
|
44
47
|
search <query> Search bundled plugins and mesh peers
|
|
@@ -75,7 +78,7 @@ Commands:
|
|
|
75
78
|
--category <cat> Declare an SSSS memory category
|
|
76
79
|
--with-cli Generate CLI command handler
|
|
77
80
|
--with-generator Generate context generator
|
|
78
|
-
--with-ui
|
|
81
|
+
--with-ui Include owner UI authoring instructions
|
|
79
82
|
--with-task Declare a selected-node scheduled task
|
|
80
83
|
--task-command <cmd> Task CLI subcommand (requires --with-task)
|
|
81
84
|
--task-schedule <cron> Five-field local-time schedule
|
|
@@ -116,33 +119,41 @@ export async function run(argv = []) {
|
|
|
116
119
|
if (!result.ok || !setup.ok) process.exitCode = 1;
|
|
117
120
|
return;
|
|
118
121
|
}
|
|
119
|
-
if (
|
|
122
|
+
if (['on', 'off', 'on-use'].includes(command)) {
|
|
123
|
+
const projectRoot = detectProjectBrain(process.cwd())?.projectRoot ?? process.cwd();
|
|
120
124
|
const id = rest.find(argument => !argument.startsWith('-'));
|
|
121
125
|
if (!id) throw new Error(`Usage: total-recall plugin ${command} <id> [--all-repos|--clear]`);
|
|
122
126
|
const flags = rest.filter(argument => argument.startsWith('-'));
|
|
127
|
+
if (command === 'on-use' && flags.some(flag => flag !== '--json')) throw new Error('Use on-use for one repository without --all-repos or --clear.');
|
|
123
128
|
const unknown = flags.find(flag => !['--all-repos', '--clear', '--json'].includes(flag));
|
|
124
129
|
if (unknown) throw new Error(`Unsupported plugin ${command} option: ${unknown}`);
|
|
125
130
|
if (flags.includes('--all-repos') && flags.includes('--clear')) throw new Error('Choose --all-repos or --clear, not both');
|
|
126
131
|
if (flags.includes('--clear')) {
|
|
127
132
|
if (command === 'off') throw new Error('--clear removes a repository override; use it with on, not off');
|
|
128
|
-
const cleared = await setPluginActive(id, true, { clear: true });
|
|
133
|
+
const cleared = await setPluginActive(id, true, { clear: true, projectRoot });
|
|
129
134
|
const activation = cleared.activation || {};
|
|
130
135
|
console.log(flags.includes('--json') ? JSON.stringify(cleared)
|
|
131
136
|
: `♻️ ${id} follows the shared setting again in this repository (${activation.state || 'unknown'})`);
|
|
132
137
|
if (!cleared.compilation.ok) process.exitCode = 1;
|
|
133
138
|
return;
|
|
134
139
|
}
|
|
135
|
-
const result = await setPluginActive(id, command === 'on', { scope: flags.includes('--all-repos') ? 'shared' : 'project' });
|
|
140
|
+
const result = await setPluginActive(id, command === 'on-use' ? command : command === 'on', { projectRoot, scope: flags.includes('--all-repos') ? 'shared' : 'project' });
|
|
136
141
|
const activation = result.activation || {};
|
|
137
142
|
if (flags.includes('--json')) console.log(JSON.stringify(result));
|
|
138
|
-
else
|
|
139
|
-
|
|
143
|
+
else if (command === 'on-use') console.log(`${id} will activate on use in this repository.`);
|
|
144
|
+
else {
|
|
145
|
+
console.log(`${command === 'on' ? '✅' : '⛔'} ${id} ${command === 'on' ? 'enabled' : 'disabled'} for ${result.scope === 'shared' ? 'every repository' : 'this repository'} (${activation.state || 'unknown'})`);
|
|
146
|
+
if (result.cleanup?.state === 'archived') console.log('Repository plugin state archived.');
|
|
147
|
+
if (result.cleanup?.state === 'restored') console.log('Repository plugin state restored.');
|
|
148
|
+
if (result.cleanup?.ok === false) console.error(`Cleanup pending. ${result.cleanup.error}`);
|
|
149
|
+
}
|
|
150
|
+
if (!result.compilation.ok || result.cleanup?.ok === false) process.exitCode = 1;
|
|
140
151
|
return;
|
|
141
152
|
}
|
|
142
153
|
|
|
143
|
-
if (command === '
|
|
144
|
-
await
|
|
145
|
-
return;
|
|
154
|
+
if (command === 'chunks') {
|
|
155
|
+
const { runPluginChunks } = await import('./chunks.mjs');
|
|
156
|
+
return runPluginChunks(rest);
|
|
146
157
|
}
|
|
147
158
|
|
|
148
159
|
if (rest.includes('--help') || rest.includes('-h')) {
|
package/src/cli/setup.mjs
CHANGED
|
@@ -22,6 +22,7 @@ import path from 'node:path';
|
|
|
22
22
|
import https from 'node:https';
|
|
23
23
|
import { fileURLToPath } from 'node:url';
|
|
24
24
|
import { resolveAgentDir, resolveBrainDir } from './agent-dir.mjs';
|
|
25
|
+
import { writeBrainConnection } from '../core/memory-brain.mjs';
|
|
25
26
|
const { loadSecrets, saveSecrets } = await __loadOwnedPlugin('auth', 'secrets-store');
|
|
26
27
|
|
|
27
28
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
@@ -375,15 +376,7 @@ async function getGitHubUser(githubToken) {
|
|
|
375
376
|
// ─── Store brain config ───────────────────────────────────────────────────────
|
|
376
377
|
|
|
377
378
|
async function storeBrainConfig(brDir, brainUrl, token, provider, apiKey, extra = {}) {
|
|
378
|
-
|
|
379
|
-
fs.mkdirSync(configDir, { recursive: true });
|
|
380
|
-
|
|
381
|
-
// brain.json
|
|
382
|
-
fs.writeFileSync(
|
|
383
|
-
path.join(configDir, 'brain.json'),
|
|
384
|
-
JSON.stringify({ url: brainUrl, token, provider, ...extra }, null, 2),
|
|
385
|
-
'utf8'
|
|
386
|
-
);
|
|
379
|
+
writeBrainConnection(brDir, { url: brainUrl, token, provider, ...extra });
|
|
387
380
|
|
|
388
381
|
// secrets.enc
|
|
389
382
|
let secrets = {};
|
package/src/cli/start.mjs
CHANGED
|
@@ -39,6 +39,7 @@ export default function start(args) {
|
|
|
39
39
|
--help Show this help
|
|
40
40
|
|
|
41
41
|
The server reads config from ~/.agent/config/security.yml.
|
|
42
|
+
TR_DASHBOARD_BRAIN_DIR can select the dashboard's global memory and project registry.
|
|
42
43
|
Use Cloudflare or Caddy in front for HTTPS when accessing remotely.
|
|
43
44
|
`);
|
|
44
45
|
return;
|
package/src/cli/startup.mjs
CHANGED
|
@@ -16,6 +16,23 @@ export async function inspectStartup(options = {}) {
|
|
|
16
16
|
return startupHealth({ brainDir: globalBrain, brainUrl: url, token, brainId: cfg.layer === 'project' && cfg.name ? `project:${cfg.name}` : null, ...options });
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
+
/**
|
|
20
|
+
* One line per thing a session should see at start: a dashboard older than its
|
|
21
|
+
* sources, and each plugin startup check that needs attention or could not run.
|
|
22
|
+
*/
|
|
23
|
+
export function startupFindings(report) {
|
|
24
|
+
const lines = [];
|
|
25
|
+
const dashboard = report.dashboard;
|
|
26
|
+
if (dashboard && ['stale', 'missing'].includes(dashboard.status)) {
|
|
27
|
+
lines.push(`Dashboard: bundle ${dashboard.status}${dashboard.newer_source ? ` (${dashboard.newer_source} is newer)` : ''}; the server rebuilds it, see /health dashboard.`);
|
|
28
|
+
} else if (dashboard?.status === 'unknown') lines.push(`Dashboard: freshness unknown (${dashboard.reason}).`);
|
|
29
|
+
for (const check of report.plugin_checks || []) {
|
|
30
|
+
if (check.status === 'attention') lines.push(`${check.command}: ${check.summary}`);
|
|
31
|
+
else if (check.status === 'unavailable') lines.push(`${check.command}: unavailable (${check.reason})${check.summary ? ` ${check.summary}` : ''}`);
|
|
32
|
+
}
|
|
33
|
+
return lines;
|
|
34
|
+
}
|
|
35
|
+
|
|
19
36
|
export default async function startup(args = []) {
|
|
20
37
|
if (!args.length || args.includes('--help') || args.includes('-h')) {
|
|
21
38
|
console.log('Usage: total-recall startup check|ensure [--json] [--app-check <registered-repo-command>] [--app-start <registered-repo-command>]\ncheck is read-only. ensure starts only missing configured local managed services and an explicitly declared current-repo app command; never restarts running/unknown or remote services. SSSS is checked as tooling, not a fabricated daemon. App health JSON must contain ok:true and status:ready|healthy|running. No declaration means app readiness is unknown.');
|
|
@@ -39,6 +56,7 @@ export default async function startup(args = []) {
|
|
|
39
56
|
if (report.server?.reason) console.log(`Server: ${report.server.reason}`);
|
|
40
57
|
if (report.server?.stale) console.log(`Server: running ${report.server.stale.running} with ${report.server.stale.on_disk} on disk; it has not been replaced.`);
|
|
41
58
|
for (const error of report.required_plugins?.errors || []) console.log(`Required plugin: ${error}`);
|
|
59
|
+
for (const line of startupFindings(report)) console.log(line);
|
|
42
60
|
const harnesses = await queryHarnessUsage().catch(() => []);
|
|
43
61
|
const availH = harnesses.filter(h => h.available);
|
|
44
62
|
const readyH = availH.filter(h => h.authed);
|
|
@@ -62,38 +62,43 @@ export function extractFrontmatter(content) {
|
|
|
62
62
|
* @returns {object}
|
|
63
63
|
*/
|
|
64
64
|
export function resolveTokenReferences(tokens) {
|
|
65
|
+
let visits = 0;
|
|
66
|
+
function checkBudget(depth) {
|
|
67
|
+
if (++visits > 20_000 || depth > 64) throw new DesignTokenError(['token references exceed the expansion limit']);
|
|
68
|
+
}
|
|
69
|
+
|
|
65
70
|
function getNested(obj, pathParts) {
|
|
66
71
|
let curr = obj;
|
|
67
72
|
for (const p of pathParts) {
|
|
68
|
-
if (curr
|
|
73
|
+
if (!isPlainObject(curr) || !Object.hasOwn(curr, p)) return undefined;
|
|
69
74
|
curr = curr[p];
|
|
70
75
|
}
|
|
71
76
|
return curr;
|
|
72
77
|
}
|
|
73
78
|
|
|
74
|
-
function resolveVal(val, seen) {
|
|
79
|
+
function resolveVal(val, seen, depth) {
|
|
80
|
+
checkBudget(depth);
|
|
75
81
|
if (typeof val !== 'string') return val;
|
|
76
82
|
const whole = val.match(/^\{([a-zA-Z0-9_.-]+)\}$/);
|
|
77
83
|
if (whole && !seen.has(whole[1])) {
|
|
78
84
|
const target = getNested(tokens, whole[1].split('.'));
|
|
79
85
|
// A whole-value reference may point at a composite (e.g. a typography style).
|
|
80
|
-
if (isPlainObject(target)) return walk(target, new Set([...seen, whole[1]]));
|
|
86
|
+
if (isPlainObject(target)) return walk(target, new Set([...seen, whole[1]]), depth + 1);
|
|
81
87
|
}
|
|
82
88
|
return val.replace(/\{([a-zA-Z0-9_.-]+)\}/g, (match, tokenPath) => {
|
|
83
89
|
if (seen.has(tokenPath)) return match;
|
|
84
90
|
const resolved = getNested(tokens, tokenPath.split('.'));
|
|
85
91
|
if (typeof resolved === 'string' || typeof resolved === 'number') {
|
|
86
|
-
return String(resolveVal(resolved, new Set([...seen, tokenPath])));
|
|
92
|
+
return String(resolveVal(resolved, new Set([...seen, tokenPath]), depth + 1));
|
|
87
93
|
}
|
|
88
94
|
return match;
|
|
89
95
|
});
|
|
90
96
|
}
|
|
91
97
|
|
|
92
|
-
function walk(node, seen = new Set()) {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
return out;
|
|
98
|
+
function walk(node, seen = new Set(), depth = 0) {
|
|
99
|
+
checkBudget(depth);
|
|
100
|
+
if (!isPlainObject(node)) return resolveVal(node, seen, depth);
|
|
101
|
+
return Object.fromEntries(Object.entries(node).map(([k, v]) => [k, walk(v, seen, depth + 1)]));
|
|
97
102
|
}
|
|
98
103
|
|
|
99
104
|
return walk(tokens);
|
|
@@ -251,7 +251,7 @@ export function generateUiElements(manifest, { pluginDir, target, tokens, typesc
|
|
|
251
251
|
};
|
|
252
252
|
add(UI_MANIFEST_FILE, `${JSON.stringify(uiManifest, null, 2)}\n`);
|
|
253
253
|
|
|
254
|
-
const first = elements[0];
|
|
254
|
+
const first = elements.find(element => element.id === spec.home) ?? elements[0];
|
|
255
255
|
const hasTokens = Boolean(tokenInfo.source);
|
|
256
256
|
const usage = (target === 'react'
|
|
257
257
|
? [
|
|
@@ -24,6 +24,11 @@ export function globalBrainDirFor(env = process.env) {
|
|
|
24
24
|
return path.join(agentDir, 'skills', 'total-recall');
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
+
/** The dashboard can read a host brain while preview plugin state stays isolated. */
|
|
28
|
+
export function dashboardBrainDir(env = process.env, fallback = globalBrainDirFor(env)) {
|
|
29
|
+
return env.TR_DASHBOARD_BRAIN_DIR ? path.resolve(env.TR_DASHBOARD_BRAIN_DIR) : fallback;
|
|
30
|
+
}
|
|
31
|
+
|
|
27
32
|
function togglesPath(globalBrainDir) {
|
|
28
33
|
return path.join(globalBrainDir, 'config', 'brain-toggles.json');
|
|
29
34
|
}
|
|
@@ -340,7 +340,11 @@ export async function updateAllBrains(opts = {}) {
|
|
|
340
340
|
// A lockfile-only update builds no tree, so it runs no lifecycle scripts: npm still
|
|
341
341
|
// ran a checkout's own postinstall here, which fails in a repository that was never
|
|
342
342
|
// installed (a postinstall calling a tool that is not yet installed, 2026-11-09).
|
|
343
|
-
|
|
343
|
+
// Only where no tree exists: npm's lockfile-only mode also rewrites the tree record
|
|
344
|
+
// (node_modules/.package-lock.json) to versions it never installs, and npm then reports the
|
|
345
|
+
// stale tree "up to date" forever (21 plugins on @ssss/cli 0.14.4 under 0.14.5, 2026-11-12).
|
|
346
|
+
// A tree that exists gets a real install, so the tree and its record agree.
|
|
347
|
+
else if (!needsInstall && noInstallTree(group.owner)) args.push(group.manager === 'pnpm' ? '--lockfile-only' : '--package-lock-only', '--ignore-scripts');
|
|
344
348
|
const install = exec(group.manager, args, { cwd: group.owner, env: installEnv(), encoding: 'utf8',
|
|
345
349
|
timeout: 600000, maxBuffer: 8 * 1024 * 1024 });
|
|
346
350
|
if (install.status !== 0) throw new Error(install.error?.message || install.stderr?.trim().slice(-1500) || `Install exited ${install.status}`);
|
|
@@ -33,7 +33,11 @@ export function getDaemonObservation() { return observeDaemon(brainDir); }
|
|
|
33
33
|
* @returns {'running'|'dead'|'not_started'|'conflict'|'unknown'}
|
|
34
34
|
*/
|
|
35
35
|
export function getDaemonStatus() {
|
|
36
|
-
|
|
36
|
+
// A supervised daemon can run from a different verified installation than the server.
|
|
37
|
+
const entry = process.env.TR_SUPERVISED_DAEMON_ENTRY;
|
|
38
|
+
const { status } = process.env.DISABLE_DAEMON === 'true' && entry && path.isAbsolute(entry)
|
|
39
|
+
? observeDaemon(brainDir, { expectedEntry: entry })
|
|
40
|
+
: getDaemonObservation();
|
|
37
41
|
return status === 'not-started' ? 'not_started' : status === 'stopped' ? 'dead' : status;
|
|
38
42
|
}
|
|
39
43
|
|