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
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
import fs from 'node:fs';
|
|
11
11
|
import path from 'node:path';
|
|
12
12
|
import { createRequire } from 'node:module';
|
|
13
|
-
import { readPluginsDir, globalPluginsDir, PACKAGE_ROOT, resolvePluginFile } from './plugin-loader.mjs';
|
|
13
|
+
import { readPluginsDir, globalPluginsDir, PACKAGE_ROOT, resolvePluginFile, validatePluginManifest } from './plugin-loader.mjs';
|
|
14
14
|
import { DEFAULT_PLUGIN_IDS, REQUIRED_INSTALLATION_PLUGIN_IDS } from './default-plugins.mjs';
|
|
15
15
|
import { comparePackageVersions } from './package-version.mjs';
|
|
16
16
|
import { preparePluginDependencies } from './plugin-dependencies.mjs';
|
|
@@ -113,14 +113,39 @@ export function inspectRequiredPlugins(brainDir, { pluginsDir, sharedBrainDir =
|
|
|
113
113
|
return { status: errors.length ? 'failed' : 'ready', errors, source, installations };
|
|
114
114
|
}
|
|
115
115
|
|
|
116
|
-
|
|
116
|
+
const LEGACY_PRESENTATION_FIELDS = ['card', 'card_face', 'card_layout'];
|
|
117
|
+
|
|
118
|
+
function hasLegacyPresentation(manifest) {
|
|
119
|
+
return LEGACY_PRESENTATION_FIELDS.some(field => Object.hasOwn(manifest, field))
|
|
120
|
+
|| (Array.isArray(manifest.ui?.elements) && manifest.ui.elements.some(element => ['card', 'card-face'].includes(element?.kind)));
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function hasPluginFiles(directory, files) {
|
|
124
|
+
return files.every(file => fs.statSync(resolvePluginFile(directory, file)).isFile());
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function runtimeFiles(manifest) {
|
|
128
|
+
return ['package.json', ...(manifest.cli ? [manifest.cli.handler] : []), ...Object.values(manifest.runtime?.modules || {})];
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/** Refresh older copies and migrate the retired presentation of an otherwise intact same-release copy. */
|
|
117
132
|
function isStaleInstall(target, source) {
|
|
118
133
|
try {
|
|
119
134
|
// A link is its owner's checkout. Replacing it would delete that repository's files, .git included.
|
|
120
135
|
if (fs.lstatSync(target).isSymbolicLink()) return false;
|
|
121
|
-
const installed = JSON.parse(fs.readFileSync(path.join(target, 'plugin.json'), 'utf8'))
|
|
122
|
-
const bundled = JSON.parse(fs.readFileSync(path.join(source, 'plugin.json'), 'utf8'))
|
|
123
|
-
|
|
136
|
+
const installed = JSON.parse(fs.readFileSync(path.join(target, 'plugin.json'), 'utf8'));
|
|
137
|
+
const bundled = JSON.parse(fs.readFileSync(path.join(source, 'plugin.json'), 'utf8'));
|
|
138
|
+
if (comparePackageVersions(installed.version, bundled.version) === -1) return true;
|
|
139
|
+
if (installed.version !== bundled.version || installed.id !== bundled.id || bundled.id !== path.basename(source)
|
|
140
|
+
|| installed.cli?.command !== bundled.cli?.command || !hasLegacyPresentation(installed)
|
|
141
|
+
|| hasLegacyPresentation(bundled) || !bundled.ui?.home || !validatePluginManifest(bundled).valid) return false;
|
|
142
|
+
|
|
143
|
+
const migrated = { ...installed, ui: bundled.ui };
|
|
144
|
+
for (const field of LEGACY_PRESENTATION_FIELDS) delete migrated[field];
|
|
145
|
+
if (!validatePluginManifest(migrated).valid || !hasPluginFiles(target, runtimeFiles(installed))) return false;
|
|
146
|
+
return hasPluginFiles(source, [
|
|
147
|
+
...runtimeFiles(bundled), bundled.ui.design_tokens, ...bundled.ui.elements.map(element => element.module),
|
|
148
|
+
]);
|
|
124
149
|
} catch { return false; }
|
|
125
150
|
}
|
|
126
151
|
|
|
@@ -165,7 +190,7 @@ function installDefaultsInto(brainDir, sourceDir) {
|
|
|
165
190
|
fs.mkdirSync(path.dirname(target), { recursive: true });
|
|
166
191
|
fs.cpSync(source, target, { recursive: true, force: false, errorOnExist: true });
|
|
167
192
|
} else if (isStaleInstall(target, source)) {
|
|
168
|
-
//
|
|
193
|
+
// Keep installed dependencies when refreshing the bundled plugin files.
|
|
169
194
|
for (const entry of fs.readdirSync(target)) if (entry !== 'node_modules') fs.rmSync(path.join(target, entry), { recursive: true, force: true });
|
|
170
195
|
for (const entry of fs.readdirSync(source)) if (entry !== 'node_modules') fs.cpSync(path.join(source, entry), path.join(target, entry), { recursive: true });
|
|
171
196
|
}
|
package/src/core/schema.mjs
CHANGED
|
@@ -1034,6 +1034,8 @@ export const PluginRecordSchema = z.object({
|
|
|
1034
1034
|
task_runs: z.record(z.string()).optional(),
|
|
1035
1035
|
/** Explicit mesh node for commands with selected-node placement. */
|
|
1036
1036
|
task_nodes: z.record(z.string().min(1)).optional(),
|
|
1037
|
+
runtime_enabled: z.boolean().optional(),
|
|
1038
|
+
runtime_on_use: z.boolean().optional(),
|
|
1037
1039
|
}).passthrough();
|
|
1038
1040
|
|
|
1039
1041
|
const SECRET_KEY_PATTERN = /^(.*_)?(secret|token|password|api[_-]?key|private[_-]?key|credentials|auth[_-]?header|bearer)$/i;
|
|
@@ -46,6 +46,7 @@ export function patchVfsDocument(vfsPath, patches, options = {}) {
|
|
|
46
46
|
type: 'patch',
|
|
47
47
|
...envelopeBase(vfsPath, options),
|
|
48
48
|
patches,
|
|
49
|
+
...(options.expectedBeforeHash === undefined ? {} : { expected_before_hash: options.expectedBeforeHash }),
|
|
49
50
|
}, options);
|
|
50
51
|
}
|
|
51
52
|
|
|
@@ -10,6 +10,23 @@ import { CLI_COMMANDS } from './cli-commands.mjs';
|
|
|
10
10
|
const packageRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../..');
|
|
11
11
|
export const cliEntry = path.join(packageRoot, 'bin/total-recall.mjs');
|
|
12
12
|
|
|
13
|
+
/** Whether this package's dashboard bundle is as new as its frontend sources (the server rebuilds it). */
|
|
14
|
+
async function defaultDashboardCheck() {
|
|
15
|
+
try {
|
|
16
|
+
const { checkDistFreshness, dashboardTargets } = await import('./dashboard-bundle.mjs');
|
|
17
|
+
if (!fs.existsSync(path.join(packageRoot, 'frontend', 'package.json'))) return { status: 'not-shipped' };
|
|
18
|
+
const result = await checkDistFreshness(dashboardTargets(packageRoot));
|
|
19
|
+
const status = result.ok ? 'current' : result.reason === 'missing-bundle' ? 'missing' : 'stale';
|
|
20
|
+
return {
|
|
21
|
+
status,
|
|
22
|
+
...(result.bundle ? { built_at: new Date(result.bundle.mtimeMs).toISOString() } : {}),
|
|
23
|
+
...(!result.ok && result.source ? { newer_source: path.relative(packageRoot, result.source.path) } : {}),
|
|
24
|
+
};
|
|
25
|
+
} catch (error) {
|
|
26
|
+
return { status: 'unknown', reason: error.message };
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
13
30
|
export function runBounded(binary, args, { cwd = process.cwd(), timeoutMs = 15000, maxBytes = 262144 } = {}) {
|
|
14
31
|
return new Promise(resolve => {
|
|
15
32
|
let child, output = '', stderr = '', size = 0, reason = null, settled = false, timer, escalation;
|
|
@@ -81,8 +98,8 @@ export function processIdentity(pidFile, hint, { alive = pid => { try { process.
|
|
|
81
98
|
}
|
|
82
99
|
|
|
83
100
|
/** The single installation-aware daemon observation for status and lifecycle. */
|
|
84
|
-
export function observeDaemon(brainDir, { identity = processIdentity } = {}) {
|
|
85
|
-
const expected_entry =
|
|
101
|
+
export function observeDaemon(brainDir, { identity = processIdentity, expectedEntry = path.join(packageRoot, 'src', 'core', 'daemon-loop.mjs') } = {}) {
|
|
102
|
+
const expected_entry = expectedEntry;
|
|
86
103
|
return { ...identity(path.join(brainDir, 'daemon.pid'), expected_entry), expected_entry, source: 'local-pid' };
|
|
87
104
|
}
|
|
88
105
|
|
|
@@ -130,7 +147,8 @@ export async function fetchStartup(url, options = {}, fetchImpl = fetch) {
|
|
|
130
147
|
}
|
|
131
148
|
|
|
132
149
|
export async function startupHealth({ cwd = process.cwd(), brainDir, brainUrl = null, token = null, brainId = null, ensure = false,
|
|
133
|
-
appCheck = null, appStart = null, run = runBounded, fetchImpl = fetch, onDiskVersion = packageVersionOnDisk, listener = verifyListener, platform = process.platform, home = os.homedir(), identity = processIdentity
|
|
150
|
+
appCheck = null, appStart = null, run = runBounded, fetchImpl = fetch, onDiskVersion = packageVersionOnDisk, listener = verifyListener, platform = process.platform, home = os.homedir(), identity = processIdentity,
|
|
151
|
+
dashboardCheck = null, pluginChecks = null } = {}) {
|
|
134
152
|
const actions = [];
|
|
135
153
|
const serverFile = path.join(brainDir, 'server.pid');
|
|
136
154
|
const report = { checked_at: new Date().toISOString(), server: { status: 'not-configured' }, brain: { status: 'unknown' }, daemon: { status: 'unknown' },
|
|
@@ -235,6 +253,13 @@ export async function startupHealth({ cwd = process.cwd(), brainDir, brainUrl =
|
|
|
235
253
|
}
|
|
236
254
|
const { inspectRequiredPlugins } = await import('./required-plugins.mjs');
|
|
237
255
|
report.required_plugins = inspectRequiredPlugins(brainDir);
|
|
256
|
+
// Reported, not part of readiness: a stale dashboard or unfinished work still
|
|
257
|
+
// leaves the runtime usable, but neither may stay invisible.
|
|
258
|
+
report.dashboard = await (dashboardCheck ?? defaultDashboardCheck)();
|
|
259
|
+
report.plugin_checks = await (pluginChecks ?? (async () => {
|
|
260
|
+
const { runPluginStartupChecks } = await import('./plugin-startup-checks.mjs');
|
|
261
|
+
return runPluginStartupChecks({ cwd });
|
|
262
|
+
}))();
|
|
238
263
|
report.shared_ready = report.required_plugins.status === 'ready' && report.server.status === 'ready' && report.brain.status === 'ready' && report.daemon.status === 'running' && report.ssss.status === 'available';
|
|
239
264
|
report.ready_scope = appCheck ? 'shared-and-declared-current-repo-app' : 'shared-runtime-only';
|
|
240
265
|
report.ready = report.shared_ready && (!appCheck || report.app.status === 'ready');
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Fixture manifests for specs that exercise plumbing rather than
|
|
2
|
+
* Fixture manifests for specs that exercise plumbing rather than Home design.
|
|
3
3
|
*
|
|
4
|
-
* Every real plugin has a bespoke
|
|
4
|
+
* Every real plugin has a bespoke native Home declared in `ui.elements[]`, and the
|
|
5
5
|
* validator enforces it. Specs that install, copy, vendor, discover or compile a
|
|
6
6
|
* plugin still need a manifest that satisfies that contract, or they fail on a
|
|
7
|
-
* rule they are not testing. This module supplies
|
|
7
|
+
* rule they are not testing. This module supplies a minimal native Home so
|
|
8
8
|
* those specs keep asserting what they mean to assert.
|
|
9
9
|
*
|
|
10
|
-
* The
|
|
10
|
+
* The Home here is deliberately generic and exists only in tests. Production
|
|
11
11
|
* plugin UI is always hand-authored per plugin (invariants-b6e8fcac).
|
|
12
12
|
*/
|
|
13
13
|
import fs from 'node:fs';
|
|
@@ -16,45 +16,46 @@ import path from 'node:path';
|
|
|
16
16
|
const nodeFs = fs;
|
|
17
17
|
const nodePath = path;
|
|
18
18
|
|
|
19
|
-
/** The smallest valid
|
|
20
|
-
export const
|
|
19
|
+
/** The smallest valid native Home. Declared once, as every plugin declares one. */
|
|
20
|
+
export const FIXTURE_HOME = Object.freeze({
|
|
21
|
+
home: 'home',
|
|
21
22
|
design_tokens: 'ui/DESIGN.md',
|
|
22
23
|
elements: [
|
|
23
24
|
{
|
|
24
|
-
id: '
|
|
25
|
-
kind: '
|
|
26
|
-
tag: 'tr-fixture-
|
|
27
|
-
module: 'ui/
|
|
28
|
-
description: 'Fixture
|
|
25
|
+
id: 'home',
|
|
26
|
+
kind: 'panel',
|
|
27
|
+
tag: 'tr-fixture-home',
|
|
28
|
+
module: 'ui/home.js',
|
|
29
|
+
description: 'Fixture native Home',
|
|
29
30
|
},
|
|
30
31
|
],
|
|
31
32
|
});
|
|
32
33
|
|
|
33
|
-
/** Source of the element module referenced by
|
|
34
|
-
export const
|
|
34
|
+
/** Source of the element module referenced by FIXTURE_HOME. */
|
|
35
|
+
export const FIXTURE_HOME_SOURCE = 'export const tag = "tr-fixture-home";\n';
|
|
35
36
|
|
|
36
37
|
/**
|
|
37
|
-
* Merge a
|
|
38
|
+
* Merge a native Home into a fixture manifest.
|
|
38
39
|
*
|
|
39
|
-
* Pass `ui: null` to omit the
|
|
40
|
+
* Pass `ui: null` to omit the Home deliberately, e.g. when asserting that a
|
|
40
41
|
* plugin without one is rejected.
|
|
41
42
|
*/
|
|
42
|
-
export function
|
|
43
|
+
export function withFixtureHome(manifest = {}) {
|
|
43
44
|
if (manifest.ui === null) {
|
|
44
45
|
const { ui: _omitted, ...rest } = manifest;
|
|
45
46
|
return rest;
|
|
46
47
|
}
|
|
47
|
-
return { ...manifest, ui: manifest.ui ?? { ...
|
|
48
|
+
return { ...manifest, ui: manifest.ui ?? { ...FIXTURE_HOME } };
|
|
48
49
|
}
|
|
49
50
|
|
|
50
51
|
/**
|
|
51
|
-
* Write `plugin.json` for a fixture plugin, declaring a
|
|
52
|
+
* Write `plugin.json` for a fixture plugin, declaring a Home unless the manifest
|
|
52
53
|
* explicitly opts out with `ui: null`.
|
|
53
54
|
*
|
|
54
55
|
* Returns the manifest that was written.
|
|
55
56
|
*/
|
|
56
57
|
export function writeFixturePlugin(pluginDir, manifest, { fs = nodeFs, path = nodePath } = {}) {
|
|
57
|
-
const written =
|
|
58
|
+
const written = withFixtureHome(manifest);
|
|
58
59
|
nodeFs.writeFileSync(
|
|
59
60
|
nodePath.join(pluginDir, 'plugin.json'),
|
|
60
61
|
JSON.stringify(written, null, 2),
|
|
@@ -62,8 +63,8 @@ export function writeFixturePlugin(pluginDir, manifest, { fs = nodeFs, path = no
|
|
|
62
63
|
if (written.ui?.elements?.length) {
|
|
63
64
|
const uiDir = nodePath.join(pluginDir, 'ui');
|
|
64
65
|
nodeFs.mkdirSync(uiDir, { recursive: true });
|
|
65
|
-
nodeFs.writeFileSync(nodePath.join(uiDir, '
|
|
66
|
-
nodeFs.writeFileSync(nodePath.join(uiDir, 'DESIGN.md'), '# Fixture
|
|
66
|
+
nodeFs.writeFileSync(nodePath.join(uiDir, 'home.js'), FIXTURE_HOME_SOURCE);
|
|
67
|
+
nodeFs.writeFileSync(nodePath.join(uiDir, 'DESIGN.md'), '# Fixture Home\n');
|
|
67
68
|
}
|
|
68
69
|
return written;
|
|
69
70
|
}
|
|
@@ -135,31 +135,38 @@ export async function loadFirewallPolicy(brainDir) {
|
|
|
135
135
|
|
|
136
136
|
applyPolicy();
|
|
137
137
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
138
|
+
const watch = (target, onChange, clear) => {
|
|
139
|
+
try {
|
|
140
|
+
const watcher = fs.watch(target, onChange);
|
|
141
|
+
watcher.on('error', error => {
|
|
142
|
+
watcher.close();
|
|
143
|
+
clear(watcher);
|
|
144
|
+
logger.warn('throttled-fetch', `Network policy watcher unavailable: ${error.message}`);
|
|
145
|
+
});
|
|
146
|
+
watcher.unref();
|
|
147
|
+
return watcher;
|
|
148
|
+
} catch (error) {
|
|
149
|
+
logger.warn('throttled-fetch', `Network policy watcher unavailable: ${error.message}`);
|
|
150
|
+
return null;
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
const watchPolicy = () => {
|
|
154
|
+
if (policyWatcher || !fs.existsSync(policyPath)) return;
|
|
155
|
+
policyWatcher = watch(policyPath, event => {
|
|
156
|
+
if (event === 'change') applyPolicy();
|
|
157
|
+
}, watcher => { if (policyWatcher === watcher) policyWatcher = null; });
|
|
158
|
+
};
|
|
159
|
+
watchPolicy();
|
|
147
160
|
|
|
148
161
|
// Also watch the parent directory so we pick up the policy file being
|
|
149
162
|
// created after boot (e.g. first-run setups where the doc doesn't exist
|
|
150
163
|
// yet). Attach the direct file watcher once it appears.
|
|
151
164
|
if (!parentWatcher && fs.existsSync(systemDir)) {
|
|
152
|
-
parentWatcher =
|
|
165
|
+
parentWatcher = watch(systemDir, (_event, filename) => {
|
|
153
166
|
if (filename !== 'network-policy.md') return;
|
|
154
167
|
applyPolicy();
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
if (evt === 'change') applyPolicy();
|
|
158
|
-
});
|
|
159
|
-
policyWatcher.unref();
|
|
160
|
-
}
|
|
161
|
-
});
|
|
162
|
-
parentWatcher.unref();
|
|
168
|
+
watchPolicy();
|
|
169
|
+
}, watcher => { if (parentWatcher === watcher) parentWatcher = null; });
|
|
163
170
|
}
|
|
164
171
|
} catch (err) {
|
|
165
172
|
logger.error('throttled-fetch', `Failed to load network policy: ${err.message}`);
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { getPluginById } from './plugin-loader.mjs';
|
|
2
|
+
import { pluginActivation } from './plugin-state.mjs';
|
|
3
|
+
|
|
4
|
+
const decisionLimit = 20;
|
|
5
|
+
|
|
6
|
+
async function requestChoice(state, questions, { projectRoot = process.cwd(), brainDir } = {}) {
|
|
7
|
+
const plugin = getPluginById('decision', projectRoot);
|
|
8
|
+
if (!plugin?.valid || !pluginActivation(plugin, { projectRoot }).enabled ||
|
|
9
|
+
!plugin.manifest.cli?.subcommands?.some(command => command.name === 'run')) return null;
|
|
10
|
+
const { runPluginCommand } = await import('./plugin-runner.mjs');
|
|
11
|
+
const run = await runPluginCommand(plugin, {
|
|
12
|
+
subcommand: 'run',
|
|
13
|
+
args: ['--state', JSON.stringify(state), '--questions', JSON.stringify(questions), '--json'],
|
|
14
|
+
timeoutMs: 15_000,
|
|
15
|
+
cwd: projectRoot ?? brainDir ?? process.cwd(),
|
|
16
|
+
projectRoot,
|
|
17
|
+
});
|
|
18
|
+
if ((!run.ok && run.exitCode !== 4) || run.truncated) return null;
|
|
19
|
+
return JSON.parse(run.stdout);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export async function chooseUiChunk(chunks, query, surface, decide = requestChoice) {
|
|
23
|
+
const result = await chooseBlocks(chunks, query, surface, ['selected_chunk'], decide);
|
|
24
|
+
const { keys, ...selection } = result;
|
|
25
|
+
return { ...selection, key: keys[0] ?? null };
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export async function chooseUiComposition(chunks, query, decide, target) {
|
|
29
|
+
const choose = decide ?? ((state, questions) => requestChoice(state, questions, target));
|
|
30
|
+
return chooseBlocks(chunks, query, 'page', ['selected_chunk', 'supporting_chunk', 'reference_chunk'], choose, false);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const instructions = {
|
|
34
|
+
selected_chunk: 'Choose the primary block that best accomplishes the requested intent.',
|
|
35
|
+
supporting_chunk: 'Choose an additional block that helps accomplish the same task without repeating the primary block.',
|
|
36
|
+
reference_chunk: 'Choose an optional readout or reference block that gives useful context for the task.',
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
async function chooseBlocks(chunks, query, surface, slots, decide, skipSingle = true) {
|
|
40
|
+
const shortlist = chunks.slice(0, decisionLimit);
|
|
41
|
+
if (!shortlist.length) return { source: 'lexical', keys: [], reason: 'no-matches' };
|
|
42
|
+
const fallback = { source: 'lexical', keys: shortlist.slice(0, slots.length).map(chunk => chunk.key) };
|
|
43
|
+
if (skipSingle && shortlist.length === 1) return { ...fallback, reason: 'single-match' };
|
|
44
|
+
|
|
45
|
+
const criteria = Object.fromEntries(shortlist.map(chunk => {
|
|
46
|
+
const description = [chunk.title, chunk.description, ...chunk.intents, ...(chunk.operations || []), ...(chunk.data || [])].join(' ').slice(0, 600);
|
|
47
|
+
return [chunk.key, description];
|
|
48
|
+
}));
|
|
49
|
+
criteria.none = 'No eligible chunk fits this intent.';
|
|
50
|
+
const questions = Object.fromEntries(slots.slice(0, shortlist.length).map(slot => [slot, {
|
|
51
|
+
type: 'choice',
|
|
52
|
+
instructions: `${instructions[slot]} Choose none when nothing fits.`,
|
|
53
|
+
criteria,
|
|
54
|
+
}]));
|
|
55
|
+
let result;
|
|
56
|
+
try {
|
|
57
|
+
result = await decide({ intent: query, surface: surface ?? null }, questions);
|
|
58
|
+
} catch {
|
|
59
|
+
return { ...fallback, reason: 'decision-unavailable' };
|
|
60
|
+
}
|
|
61
|
+
if (result?.ok !== true) return { ...fallback, reason: 'decision-unavailable' };
|
|
62
|
+
const eligible = new Set(shortlist.map(chunk => chunk.key));
|
|
63
|
+
const primary = result.answers?.selected_chunk;
|
|
64
|
+
if (!confident(primary)) return { ...fallback, reason: 'decision-abstained' };
|
|
65
|
+
if (primary.choice === 'none') return { source: 'decision', keys: [], reason: 'no-fit', confidence: primary.confidence };
|
|
66
|
+
if (!eligible.has(primary.choice)) return { source: 'decision', keys: [], reason: 'invalid-choice' };
|
|
67
|
+
const keys = new Set([primary.choice]);
|
|
68
|
+
for (const slot of Object.keys(questions).slice(1)) {
|
|
69
|
+
const answer = result.answers?.[slot];
|
|
70
|
+
if (confident(answer) && eligible.has(answer.choice)) keys.add(answer.choice);
|
|
71
|
+
}
|
|
72
|
+
return { source: 'decision', keys: [...keys], confidence: primary.confidence };
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function confident(answer) {
|
|
76
|
+
return answer?.act === true && Number.isFinite(answer.confidence) && answer.confidence >= 0.5 && answer.confidence <= 1;
|
|
77
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"registry": "ui-chunk",
|
|
3
|
+
"extends": "ssss",
|
|
4
|
+
"version": "1.1.0",
|
|
5
|
+
"description": "Portable owner-authored HTML chunks for Total Recall workspace surfaces.",
|
|
6
|
+
"document_primitives": {
|
|
7
|
+
"chunk": {
|
|
8
|
+
"family": "capability",
|
|
9
|
+
"append_only": false,
|
|
10
|
+
"portability": "structural",
|
|
11
|
+
"filename_convention": "A kebab-case chunk ID under ui/chunks/ with the .md extension.",
|
|
12
|
+
"required_fields": ["type", "title", "description", "timestamp", "plugin", "id", "intents", "surfaces"],
|
|
13
|
+
"optional_fields": ["panel", "operations", "data"],
|
|
14
|
+
"immutable_fields": ["plugin", "id"],
|
|
15
|
+
"enums": { "surfaces": ["page", "left", "right", "bottom"] },
|
|
16
|
+
"patterns": {
|
|
17
|
+
"plugin": "^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$",
|
|
18
|
+
"id": "^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$"
|
|
19
|
+
},
|
|
20
|
+
"notes": "The body holds HTML. The host validates surface membership, file ownership and native panel bindings before publishing the catalog."
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|