total-recall-brain 3.45.0 → 3.46.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/total-recall.mjs +7 -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/default-plugin-refresh.mjs +39 -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
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/** Mesh Home uses owner commands for independent fleet observations. */
|
|
2
2
|
const DASH = '—';
|
|
3
3
|
const words = value => typeof value === 'string' && value ? value : DASH;
|
|
4
4
|
const list = value => Array.isArray(value) ? value : [];
|
|
@@ -65,9 +65,9 @@ export function capabilityState(node, column) {
|
|
|
65
65
|
function hostName(url) { try { return new URL(url).host; } catch { return DASH; } }
|
|
66
66
|
const sourceLabels = { grants: 'Secrets', plugins: 'Plugins', updates: 'Updates', tasks: 'Scheduled work', agents: 'Agents', alerts: 'Alerts', deployments: 'Deployments', policy: 'Policy', presence: 'Presence' };
|
|
67
67
|
|
|
68
|
-
export class
|
|
68
|
+
export class MeshHome extends HTMLElement {
|
|
69
69
|
constructor() {
|
|
70
|
-
super(); this.status = null; this.doctor = null; this.leader = null;
|
|
70
|
+
super(); this.status = null; this.nodes = null; this.credential = null; this.doctor = null; this.leader = null;
|
|
71
71
|
this.errors = {}; this.views = {}; this.loading = {}; this.pings = {};
|
|
72
72
|
this.screen = 'machines'; this.selected = null; this.filters = new Set();
|
|
73
73
|
this.loginDrafts = {};
|
|
@@ -80,11 +80,8 @@ export class MeshlinkControlCard extends HTMLElement {
|
|
|
80
80
|
connectedCallback() {
|
|
81
81
|
if (!this.shadowRoot) this.attachShadow({ mode: 'open' });
|
|
82
82
|
this.render();
|
|
83
|
-
this.onScreen = event => { if ((!event.detail?.pluginId || event.detail.pluginId === this.host?.pluginId) && this.screens.some(s => s.id === event.detail?.screen)) void this.show(event.detail.screen); };
|
|
84
|
-
window.addEventListener('plugin-show-screen', this.onScreen);
|
|
85
83
|
void this.read();
|
|
86
84
|
}
|
|
87
|
-
disconnectedCallback() { window.removeEventListener('plugin-show-screen', this.onScreen); }
|
|
88
85
|
async call(operation, args = []) {
|
|
89
86
|
if (!this.host?.run) throw new Error('Mesh command runner unavailable. Open this view in the dashboard.');
|
|
90
87
|
const result = await this.host.run(operation, args);
|
|
@@ -96,19 +93,29 @@ export class MeshlinkControlCard extends HTMLElement {
|
|
|
96
93
|
try {
|
|
97
94
|
const value = asObject(await this.call(op, args));
|
|
98
95
|
if (!value || key === 'doctor' && !Array.isArray(value) || key !== 'doctor' && Array.isArray(value)) throw new Error('Command returned an unreadable observation.');
|
|
96
|
+
if (key === 'nodes' && !Array.isArray(value.nodes)) throw new Error('Mesh did not return a node list.');
|
|
97
|
+
if (key === 'credential' && typeof value.present !== 'boolean') throw new Error('Auth did not return credential presence.');
|
|
99
98
|
this[key] = value;
|
|
100
|
-
} catch (error) { this.errors[key] = error.message; }
|
|
99
|
+
} catch (error) { this.errors[key] = key === 'credential' ? 'Credential status is unavailable from Auth.' : error.message; }
|
|
101
100
|
this.paint();
|
|
102
101
|
}
|
|
103
102
|
read() {
|
|
104
103
|
if (this.busy) return this.readPromise;
|
|
104
|
+
if (!this.loading.doctor) { this.doctor = null; delete this.errors.doctor; }
|
|
105
105
|
this.busy = true; this.lastAttempt = new Date().toISOString(); this.pings = {}; this.paint();
|
|
106
106
|
this.readPromise = Promise.all([
|
|
107
|
-
this.readOne('status', 'status', ['--json']), this.readOne('
|
|
107
|
+
this.readOne('status', 'status', ['--json']), this.readOne('nodes', 'nodes', ['--json']),
|
|
108
|
+
this.readOne('credential', 'token-status', ['--json']),
|
|
108
109
|
this.readOne('leader', 'leader', ['--json']), this.readView(this.screen, true),
|
|
109
110
|
]).finally(() => { this.busy = false; this.paint(); });
|
|
110
111
|
return this.readPromise;
|
|
111
112
|
}
|
|
113
|
+
async readDoctor() {
|
|
114
|
+
if (this.loading.doctor) return;
|
|
115
|
+
this.loading.doctor = true;
|
|
116
|
+
try { await this.readOne('doctor', 'doctor', ['--json']); }
|
|
117
|
+
finally { delete this.loading.doctor; this.paint(); }
|
|
118
|
+
}
|
|
112
119
|
async readView(screen, force = false) {
|
|
113
120
|
if (this.loading[screen]) return this.loading[screen];
|
|
114
121
|
if (this.views[screen] && !force) return;
|
|
@@ -126,7 +133,6 @@ export class MeshlinkControlCard extends HTMLElement {
|
|
|
126
133
|
async show(screen) {
|
|
127
134
|
if (!this.screens.some(s => s.id === screen)) return;
|
|
128
135
|
this.screen = screen; this.confirmEnrollment = false; this.paint();
|
|
129
|
-
this.host?.screenChanged?.(screen);
|
|
130
136
|
if (this.busy) await this.readPromise;
|
|
131
137
|
await this.readView(screen);
|
|
132
138
|
}
|
|
@@ -168,29 +174,92 @@ export class MeshlinkControlCard extends HTMLElement {
|
|
|
168
174
|
render() {
|
|
169
175
|
this.shadowRoot.innerHTML = `
|
|
170
176
|
<style>
|
|
171
|
-
:host {
|
|
172
|
-
|
|
173
|
-
|
|
177
|
+
:host {
|
|
178
|
+
display:block; container-type:inline-size;
|
|
179
|
+
color:var(--color-text,CanvasText); background:var(--color-background,Canvas);
|
|
180
|
+
border:1px solid var(--color-border,currentColor); border-radius:var(--radius-md,8px);
|
|
181
|
+
padding:var(--spacing-md,16px); font:14px/1.5 var(--typography-body-font-family,system-ui,sans-serif);
|
|
182
|
+
}
|
|
183
|
+
* { box-sizing:border-box; min-width:0; }
|
|
184
|
+
h2,h3,p { margin:0 0 8px; }
|
|
185
|
+
h2 { font:600 clamp(1.5rem,5vw,2rem)/1.2 var(--typography-heading-font-family,Georgia,serif); }
|
|
186
|
+
h3 { font-size:1rem; }
|
|
187
|
+
header svg { width:1.1em; height:1.1em; vertical-align:middle; color:var(--color-accent,currentColor); }
|
|
188
|
+
button,input {
|
|
189
|
+
font:inherit; min-height:44px; color:inherit; background:var(--color-background,Canvas);
|
|
190
|
+
border:1px solid var(--color-border,currentColor); border-radius:var(--radius-md,8px); padding:8px 12px;
|
|
191
|
+
}
|
|
192
|
+
button { cursor:pointer; text-align:left; }
|
|
193
|
+
button:disabled { opacity:.65; cursor:wait; }
|
|
194
|
+
button:hover,nav button[aria-selected=true],.roster button[aria-pressed=true] { border-color:var(--color-accent,currentColor); }
|
|
195
|
+
button:focus-visible,input:focus-visible,summary:focus-visible { outline:2px solid var(--color-accent,currentColor); outline-offset:2px; }
|
|
196
|
+
[data-tone=ok] { color:var(--color-ok,currentColor); }
|
|
197
|
+
[data-tone=warn] { color:var(--color-warn,currentColor); }
|
|
198
|
+
[data-tone=danger],.error { color:var(--color-danger,currentColor); }
|
|
199
|
+
.muted,dt,small { color:var(--color-muted,currentColor); }
|
|
200
|
+
.strip { display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); gap:12px; margin:14px 0; }
|
|
201
|
+
.strip div { border-top:1px solid var(--color-border,currentColor); padding-top:8px; }
|
|
202
|
+
.strip strong { display:block; overflow-wrap:anywhere; }
|
|
203
|
+
.verdict { border-inline-start:3px solid currentColor; padding:8px 12px; background:var(--color-surface,Canvas); }
|
|
204
|
+
nav,.actions,.filters { display:flex; flex-wrap:wrap; gap:8px; margin:12px 0; }
|
|
205
|
+
nav button[aria-selected=true] { background:var(--color-surface,Canvas); }
|
|
206
|
+
.block { padding:14px; background:var(--color-surface,Canvas); border:1px solid var(--color-border,currentColor); border-radius:var(--radius-md,8px); margin-bottom:12px; overflow-wrap:anywhere; }
|
|
207
|
+
.panes { display:grid; grid-template-columns:minmax(190px,.8fr) minmax(0,1.6fr); gap:12px; align-items:start; }
|
|
208
|
+
.roster,.ladder { display:grid; gap:8px; }
|
|
209
|
+
.roster button { display:grid; gap:3px; width:100%; }
|
|
210
|
+
.rung { display:grid; grid-template-columns:70px 1fr; gap:8px; border:1px dashed var(--color-border,currentColor); padding:10px; }
|
|
211
|
+
.rung[data-state=passed] { border-style:solid; border-inline-start:4px solid var(--color-ok,currentColor); }
|
|
212
|
+
.rung[data-state=failed] { border-style:double; border-inline-start:4px solid var(--color-danger,currentColor); }
|
|
213
|
+
.rung[data-state=na] { border-style:dotted; color:var(--color-muted,currentColor); }
|
|
214
|
+
.filters label { display:flex; align-items:center; gap:6px; min-height:44px; padding:0 8px; border:1px solid var(--color-border,currentColor); }
|
|
215
|
+
.filters input { min-height:20px; width:20px; }
|
|
216
|
+
dl { display:grid; grid-template-columns:minmax(80px,.6fr) minmax(0,1.4fr); gap:5px 12px; margin:10px 0; }
|
|
217
|
+
dd { margin:0; overflow-wrap:anywhere; }
|
|
218
|
+
.command { white-space:pre-wrap; overflow-wrap:anywhere; font:12px/1.6 var(--typography-mono-font-family,ui-monospace,monospace); background:var(--color-background,Canvas); padding:12px; border:1px solid var(--color-border,currentColor); }
|
|
219
|
+
.error { padding:10px; border:1px solid currentColor; margin:8px 0; overflow-wrap:anywhere; }
|
|
220
|
+
.flow { border-bottom:1px solid var(--color-border,currentColor); padding:12px 0; }
|
|
221
|
+
.flow:last-child { border:0; }
|
|
222
|
+
.table-wrap { max-width:100%; overflow:auto; }
|
|
223
|
+
table { border-collapse:collapse; width:100%; font-size:12px; }
|
|
224
|
+
th,td { text-align:left; padding:9px; border:1px solid var(--color-border,currentColor); vertical-align:top; }
|
|
225
|
+
th { background:var(--color-background,Canvas); }
|
|
226
|
+
summary { min-height:44px; cursor:pointer; padding:10px 0; }
|
|
227
|
+
.recorded,.foot { margin-top:12px; }
|
|
228
|
+
.login-form { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:8px; }
|
|
229
|
+
.login-form label { display:grid; gap:3px; }
|
|
230
|
+
.login-form button { grid-column:1/-1; }
|
|
231
|
+
.danger { border-color:var(--color-danger,currentColor); }
|
|
232
|
+
.foot { font-size:12px; color:var(--color-muted,currentColor); }
|
|
233
|
+
@container(max-width:690px) {
|
|
234
|
+
.panes,.login-form { grid-template-columns:1fr; }
|
|
235
|
+
.strip { grid-template-columns:repeat(2,minmax(0,1fr)); }
|
|
236
|
+
}
|
|
174
237
|
</style>
|
|
175
|
-
<header><h2><svg
|
|
176
|
-
<nav id="tabs" role="tablist" aria-label="Mesh views"></nav><div id="errors" role="status"></div><main id="body" role="tabpanel"></main><footer id="foot" class="foot"></footer>`;
|
|
238
|
+
<header><h2><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" aria-hidden="true"><circle cx="12" cy="4" r="3"/><circle cx="4" cy="19" r="3"/><circle cx="20" cy="19" r="3"/><path d="M10 7 5 16m9-9 5 9M7 19h10"/></svg> Network atlas</h2><div id="strip" class="strip"></div><p id="verdict" class="verdict"></p></header>
|
|
239
|
+
<div id="controls" class="actions"></div><nav id="tabs" role="tablist" aria-label="Mesh views"></nav><div id="errors" role="status"></div><main id="body" role="tabpanel"></main><footer id="foot" class="foot"></footer>`;
|
|
177
240
|
this.paint();
|
|
178
241
|
}
|
|
179
242
|
paint() {
|
|
180
243
|
const root = this.shadowRoot; if (!root?.querySelector('#body')) return;
|
|
181
244
|
const focused = root.activeElement;
|
|
182
245
|
const focusKey = focused && ['id', 'aria-label', 'name'].map(attribute => [attribute, focused.getAttribute(attribute)]).find(([, value]) => value);
|
|
183
|
-
const
|
|
246
|
+
const roster = this.nodes ? { ...this.status, nodes: this.nodes.nodes } : this.status;
|
|
247
|
+
const verdict = meshVerdict(this.status && roster, this.doctor, this.leader);
|
|
184
248
|
root.querySelector('#verdict').textContent = verdict.text; root.querySelector('#verdict').dataset.tone = verdict.tone;
|
|
185
249
|
const status = this.status;
|
|
186
250
|
root.querySelector('#strip').replaceChildren(...[
|
|
187
251
|
['Control', `${hostName(status?.control?.url)} · ${status?.control?.verified === true ? 'Verified' : 'Not verified'}`],
|
|
252
|
+
['Auth credential', this.credential?.present === true ? 'Saved in Auth' : this.credential?.present === false ? 'Missing' : this.errors.credential ? 'Unavailable' : 'Checking'],
|
|
188
253
|
['Leader', `${words(this.leader?.leader?.hostname)} · ${words(this.leader?.leader?.strategy)}`],
|
|
189
254
|
['This machine', `${words(status?.enrollment?.hostname)} · ${words(status?.enrollment?.state)}`],
|
|
190
255
|
].map(([title, value]) => this.el('div', {}, this.el('strong', { text: title }), this.el('span', { text: value }))));
|
|
191
|
-
root.querySelector('#tabs').replaceChildren(...this.screens.map(screen => this.button(screen.label, () => void this.show(screen.id), { role: 'tab', id: `tab-${screen.id}`, 'aria-selected': String(this.screen === screen.id), 'aria-controls': 'body' }))
|
|
256
|
+
root.querySelector('#tabs').replaceChildren(...this.screens.map(screen => this.button(screen.label, () => void this.show(screen.id), { role: 'tab', id: `tab-${screen.id}`, 'aria-selected': String(this.screen === screen.id), 'aria-controls': 'body' })));
|
|
257
|
+
root.querySelector('#controls').replaceChildren(
|
|
258
|
+
this.button(this.busy ? 'Reading…' : 'Refresh network', () => void this.read(), { id: 'refresh', ...(this.busy ? { disabled: '' } : {}) }),
|
|
259
|
+
...(this.canRun('doctor') ? [this.button(this.loading.doctor ? 'Verifying…' : 'Verify fleet execution', () => void this.readDoctor(), { id: 'verify-fleet', ...(this.loading.doctor ? { disabled: '' } : {}) })] : [])
|
|
260
|
+
);
|
|
192
261
|
root.querySelector('#errors').replaceChildren(...Object.entries(this.errors).map(([key, error]) => this.text(`${key}: ${error}`, 'error')), ...(status?.control?.error || status?.control?.reason ? [this.text(`Control: ${status.control.error || status.control.reason}`, 'error')] : []), ...(this.actionMessage ? [this.text(this.actionMessage)] : []));
|
|
193
|
-
const nodes = joinNodes(
|
|
262
|
+
const nodes = joinNodes(roster, this.doctor);
|
|
194
263
|
const body = root.querySelector('#body'); body.setAttribute('aria-labelledby', `tab-${this.screen}`);
|
|
195
264
|
const firstRun = status?.configured === false && ['no-headscale-api-key', 'no-control-url'].includes(status.control?.reason);
|
|
196
265
|
body.replaceChildren(firstRun ? this.firstRun() : this.screen === 'machines' ? this.machines(nodes) : this.screen === 'flows' ? this.flows() : this.screen === 'placement' ? this.placement(nodes) : this.screen === 'boundary' ? this.boundary(nodes) : this.join());
|
|
@@ -216,7 +285,8 @@ export class MeshlinkControlCard extends HTMLElement {
|
|
|
216
285
|
[...roster.children].forEach((button, index) => button.append(this.el('strong', { text: words(live[index].hostname) }), this.el('span', { text: live[index].label, dataset: { tone: live[index].tone } }), this.el('small', { text: this.presenceFor(live[index]) })));
|
|
217
286
|
const recorded = nodes.filter(node => node.vaultOnly);
|
|
218
287
|
if (recorded.length) roster.append(this.el('details', { class: 'recorded' }, this.el('summary', { text: `${recorded.length} recorded-only record${recorded.length === 1 ? '' : 's'}` }), recorded.map(node => this.text(`${words(node.hostname)} · recorded ${words(node.last_heartbeat)}`, 'muted'))));
|
|
219
|
-
|
|
288
|
+
const inventoryRead = Boolean(this.nodes || this.status);
|
|
289
|
+
return this.el('div', { class: 'panes' }, this.section(`${inventoryRead ? live.length : DASH} members`, roster), selected ? this.machineDetail(selected) : this.section('Machines', this.text(inventoryRead ? 'No member machines returned.' : 'Machine inventory is unreadable.')));
|
|
220
290
|
}
|
|
221
291
|
machineDetail(node) {
|
|
222
292
|
const ping = this.pings[node.ip];
|
|
@@ -227,11 +297,12 @@ export class MeshlinkControlCard extends HTMLElement {
|
|
|
227
297
|
['Login', node.self || !applicable ? 'na' : node.access_state === 'configured' ? 'passed' : 'failed', node.self ? 'Not applicable · local execution' : !applicable ? 'Not applicable · no remote shell on this device' : node.access_state === 'configured' ? `Recorded ${words(node.access?.ssh_user)} · verified ${words(node.access?.verified_at)}` : 'No SSH login recorded'],
|
|
228
298
|
['Run', !applicable ? 'na' : node.reach === 'reachable' ? 'passed' : node.reach === 'unreachable' ? 'failed' : 'checking', !applicable ? 'Not applicable' : node.reach === 'reachable' ? 'Probe command executed' : node.reason || 'Not yet checked'],
|
|
229
299
|
];
|
|
230
|
-
const actions =
|
|
300
|
+
const actions = !node.self && node.ip && this.canRun('ping')
|
|
301
|
+
? this.el('div', { class: 'actions' }, this.button('Ping now', () => void this.ping(node))) : null;
|
|
231
302
|
const detail = this.section(words(node.hostname), this.text(`${words(node.ip)} · ${words(node.os)}`, 'muted'), this.el('div', { class: 'ladder' }, rungs.map(([name, state, evidence]) => this.el('div', { class: 'rung', dataset: { state } }, this.el('strong', { text: name }), this.el('div', {}, this.el('b', { text: state === 'na' ? 'Not applicable' : state === 'checking' ? 'Not yet checked' : state === 'passed' ? 'Passed' : 'Failed' }), this.text(evidence, 'muted'))))), actions);
|
|
232
303
|
if (node.loginApplicable && node.access_state !== 'configured') {
|
|
233
304
|
if (this.canRun('access')) detail.append(this.button('Find a login', () => void this.action('access', ['discover', node.ip], 'Login discovery')), this.loginForm(node));
|
|
234
|
-
else detail.append(this.text('This
|
|
305
|
+
else detail.append(this.text('This Home is read-only. Find or record a login through the CLI.'), this.command(`total-recall mesh access discover ${node.ip}\ntotal-recall mesh access ${node.ip} --user <login>`));
|
|
235
306
|
}
|
|
236
307
|
if (node.reach === 'reachable' && !node.self) detail.append(this.text('SSH handoff'), this.command(`total-recall mesh ssh ${node.ip}`));
|
|
237
308
|
detail.append(this.el('h3', { text: 'Recorded earlier' }), this.fields([
|
|
@@ -362,8 +433,8 @@ export class MeshlinkControlCard extends HTMLElement {
|
|
|
362
433
|
view.append(this.button(`Re-enroll ${target}`, () => { this.confirmEnrollment = true; this.paint(); }, { class: 'danger' }));
|
|
363
434
|
if (this.confirmEnrollment) view.append(this.text(`Re-enroll ${target}? This may interrupt its mesh connection.`, 'error'), this.button(`Confirm re-enrollment of ${target}`, () => { this.confirmEnrollment = false; void this.action('enroll', ['--force'], 'Re-enrollment'); }, { class: 'danger', 'data-action': 'confirm-enroll' }), this.button('Cancel', () => { this.confirmEnrollment = false; this.paint(); }));
|
|
364
435
|
}
|
|
365
|
-
else if (enrollment.hostname) view.append(this.text(`This
|
|
436
|
+
else if (enrollment.hostname) view.append(this.text(`This Home is read-only. Re-enrolling ${target} can interrupt its connection. Use the CLI after confirming that target.`), this.command('total-recall mesh enroll --force'));
|
|
366
437
|
return view;
|
|
367
438
|
}
|
|
368
439
|
}
|
|
369
|
-
|
|
440
|
+
customElements.define('mesh-home', MeshHome);
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Metaharness
|
|
3
|
+
description: A clear handoff from Total Recall's brain selection to the operator's chosen Chat harness.
|
|
4
|
+
colors:
|
|
5
|
+
canvas: '#0c1427'
|
|
6
|
+
background: '{colors.canvas}'
|
|
7
|
+
surface: '#1e293b'
|
|
8
|
+
text: '#f1f5f9'
|
|
9
|
+
muted: '#94a3b8'
|
|
10
|
+
signal: '#38bdf8'
|
|
11
|
+
primary: '#3b82f6'
|
|
12
|
+
line: '#334155'
|
|
13
|
+
success: '#10b981'
|
|
14
|
+
warning: '#f59e0b'
|
|
15
|
+
danger: '#ef4444'
|
|
16
|
+
typography:
|
|
17
|
+
title:
|
|
18
|
+
fontFamily: system-ui, sans-serif
|
|
19
|
+
fontSize: 18px
|
|
20
|
+
fontWeight: 650
|
|
21
|
+
lineHeight: 1.2
|
|
22
|
+
body:
|
|
23
|
+
fontFamily: system-ui, sans-serif
|
|
24
|
+
fontSize: 14px
|
|
25
|
+
lineHeight: 1.5
|
|
26
|
+
label:
|
|
27
|
+
fontFamily: ui-monospace, monospace
|
|
28
|
+
fontSize: 11px
|
|
29
|
+
fontWeight: 600
|
|
30
|
+
letterSpacing: 0.08em
|
|
31
|
+
rounded:
|
|
32
|
+
frame: 8px
|
|
33
|
+
spacing:
|
|
34
|
+
inset: 16px
|
|
35
|
+
row: 12px
|
|
36
|
+
components:
|
|
37
|
+
chat-handoff:
|
|
38
|
+
backgroundColor: '{colors.canvas}'
|
|
39
|
+
textColor: '{colors.text}'
|
|
40
|
+
typography: '{typography.body}'
|
|
41
|
+
rounded: '{rounded.frame}'
|
|
42
|
+
padding: '{spacing.inset}'
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## Overview
|
|
46
|
+
|
|
47
|
+
Metaharness works like a dispatch board. Readers should understand the selected
|
|
48
|
+
harness, the brain scope and the next action from a quick scan.
|
|
49
|
+
|
|
50
|
+
## Colors
|
|
51
|
+
|
|
52
|
+
Use the deep navy {colors.canvas} under pale {colors.text}. Reserve blue
|
|
53
|
+
{colors.signal} for the route between the brain selection and its destination.
|
|
54
|
+
Use status colors for verified outcomes from the host.
|
|
55
|
+
|
|
56
|
+
## Typography
|
|
57
|
+
|
|
58
|
+
Use the quiet, compact {typography.label} for handoff stages. Use
|
|
59
|
+
{typography.title} for the section heading and {typography.body} for instructions.
|
|
60
|
+
|
|
61
|
+
## Layout
|
|
62
|
+
|
|
63
|
+
Give the heading and route a full-width row at narrow drawer sizes. Stack route
|
|
64
|
+
stages when their labels would wrap. In a wider drawer, use one route line.
|
|
65
|
+
|
|
66
|
+
## Elevation & Depth
|
|
67
|
+
|
|
68
|
+
Separate the saved route from its controls with a single border. Keep the
|
|
69
|
+
workflow blocks flat so their order stays clear when combined in a drawer.
|
|
70
|
+
|
|
71
|
+
## Shapes
|
|
72
|
+
|
|
73
|
+
Use compact rounded frames and controls. Label the route stages with text.
|
|
74
|
+
|
|
75
|
+
## Components
|
|
76
|
+
|
|
77
|
+
The Chat handoff block explains the route. The native Home shows the saved
|
|
78
|
+
harness, registered choices and the optional destination. The bottom drawer
|
|
79
|
+
supplies brain selection and the launch and copy controls. Each operational
|
|
80
|
+
block describes one separate workflow and its observed owner data.
|
|
81
|
+
|
|
82
|
+
## Do's and Don'ts
|
|
83
|
+
|
|
84
|
+
Show the route in reading order. Keep operational state sourced from Metaharness.
|
|
85
|
+
Keep the handoff marker still and show clear focus and loading states. Use text
|
|
86
|
+
to distinguish saved configuration, draft behavior and unavailable reads.
|
|
@@ -173,6 +173,25 @@ follows this foundation and requires its own current audit and plan.
|
|
|
173
173
|
|
|
174
174
|
Use the installed plugin for CLI execution and maintenance. The repository has a pure planning capability under `capability/`. The current manifest does not declare it for vendoring. See the [Metaharness tracker](docs/projects/in-progress/META_HARNESS_UNIFICATION/META_HARNESS_UNIFICATION_PROJECT_TRACKER.md) for current package, execution and hook acceptance.
|
|
175
175
|
|
|
176
|
+
## Default Chat
|
|
177
|
+
|
|
178
|
+
Open **Metaharness** from the dashboard's Plugins folder to select and save a
|
|
179
|
+
default harness. The Chat drawer uses that default with the selected brains.
|
|
180
|
+
Customize the native Home in `DESIGN.md`. The owner blocks in `ui/chunks/`
|
|
181
|
+
cover execution, routing, usage, documentation, maintenance and run evidence.
|
|
182
|
+
|
|
183
|
+
`total-recall meta-harness chat-default codex --json` sets the host's default
|
|
184
|
+
Chat harness. Choose an adapter from the catalog or from the choices returned
|
|
185
|
+
by `total-recall meta-harness chat-target --json`. The default applies to every
|
|
186
|
+
brain selection.
|
|
187
|
+
|
|
188
|
+
For example, `total-recall meta-harness chat-target --brains global,project:docs --json`
|
|
189
|
+
returns the chosen harness and draft context for those two brain IDs. A Codex
|
|
190
|
+
target opens a native draft that the operator can review before sending. Other
|
|
191
|
+
harnesses can use an explicit HTTPS launch URL configured with `--url` and
|
|
192
|
+
copyable context. Use a launch URL without embedded credentials, a query, or a
|
|
193
|
+
fragment. Omitting `--url` selects the adapter's built-in handoff, if available.
|
|
194
|
+
|
|
176
195
|
## Using this from an agent
|
|
177
196
|
|
|
178
197
|
Send work here to run it in another agent harness, or to find out which harness should take it. Native subagents are separate and never need this.
|
|
@@ -29,7 +29,9 @@ import { appendCommand, waitingRequests } from './src/control.mjs';
|
|
|
29
29
|
import { sessionOptions } from './src/session/run.mjs';
|
|
30
30
|
import { continueJob } from './src/session-jobs.mjs';
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
import { chatTarget, setChatDefault } from './src/chat.mjs';
|
|
33
|
+
|
|
34
|
+
const VALUE_FLAGS = ['--result-schema-json', '--goal', '--max-turns', '--max-budget-usd', '--max-tokens', '--result-schema', '--at', '--node', '--mode', '--orchestrator', '--branch', '--reviewer', '--thread', '--status', '--platform', '--agent', '--url', '--query', '--tier', '--threshold', '--author', '--explorer', '--architect', '--implementer', '--verifier', '--title', '--summary', '--cwd', '--tools', '--setting-sources', '--model', '--name', '--tail', '--timeout-ms', '--void', '--reason', '--approvals', '--question-timeout-ms', '--brains'];
|
|
33
35
|
export function parseArguments(args) {
|
|
34
36
|
const positional = [];
|
|
35
37
|
for (let index = 1; index < args.length; index += 1) {
|
|
@@ -135,6 +137,8 @@ async function runOperation(argv) {
|
|
|
135
137
|
let result;
|
|
136
138
|
if (operation === 'status') result = {...await inspectNode(value('--node') || 'local'),documentation:documentationStatus()};
|
|
137
139
|
else if (operation === 'catalog') result = { adapters: getActiveAdapters(), permissions: ['read', 'write', 'send', 'destructive'] };
|
|
140
|
+
else if (operation === 'chat-target') result = chatTarget(value('--brains'));
|
|
141
|
+
else if (operation === 'chat-default') result = setChatDefault(positional[0], value('--url'));
|
|
138
142
|
else if (operation === 'nodes') result = await listTargets();
|
|
139
143
|
else if (operation === 'adoption') {
|
|
140
144
|
const node = value('--node');
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tr-plugin-meta-harness",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "tr-plugin-meta-harness",
|
|
9
|
-
"version": "0.
|
|
9
|
+
"version": "0.4.0",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"@gregiteen/ssss-cli": "0.14.5"
|
|
12
12
|
},
|
|
13
13
|
"devDependencies": {
|
|
14
|
-
"total-recall-brain": "3.
|
|
14
|
+
"total-recall-brain": "3.45.0"
|
|
15
15
|
}
|
|
16
16
|
},
|
|
17
17
|
"node_modules/@alcalzone/ansi-tokenize": {
|
|
@@ -5546,9 +5546,9 @@
|
|
|
5546
5546
|
}
|
|
5547
5547
|
},
|
|
5548
5548
|
"node_modules/total-recall-brain": {
|
|
5549
|
-
"version": "3.
|
|
5550
|
-
"resolved": "https://registry.npmjs.org/total-recall-brain/-/total-recall-brain-3.
|
|
5551
|
-
"integrity": "sha512-
|
|
5549
|
+
"version": "3.45.0",
|
|
5550
|
+
"resolved": "https://registry.npmjs.org/total-recall-brain/-/total-recall-brain-3.45.0.tgz",
|
|
5551
|
+
"integrity": "sha512-HDYfROazZbsLHQsFPnlBcSpe1HL1QEi7JG8x/eNRUI06RxVQsZWl8LwBo2lTWjWRDrKmCy7BUmSXQDuWF3lrEw==",
|
|
5552
5552
|
"dev": true,
|
|
5553
5553
|
"license": "MIT",
|
|
5554
5554
|
"workspaces": [
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tr-plugin-meta-harness",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Total Recall Metaharness plugin",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
"cli.mjs",
|
|
13
13
|
"plugin.json",
|
|
14
14
|
"README.md",
|
|
15
|
+
"DESIGN.md",
|
|
15
16
|
"src/",
|
|
16
17
|
"!src/**/*.spec.mjs",
|
|
17
18
|
"ui/",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "meta-harness",
|
|
3
3
|
"name": "Metaharness",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.4.0",
|
|
5
5
|
"description": "Discover, configure, document, track, and run coding agent harnesses through Total Recall across mesh nodes.",
|
|
6
6
|
"gate": {
|
|
7
7
|
"tasks": ["Run work in another agent harness", "Choose which harness takes a task", "Check harness versions, sign-in and quota", "Read a harness's official documentation"],
|
|
@@ -45,6 +45,41 @@
|
|
|
45
45
|
"output": "json",
|
|
46
46
|
"args": []
|
|
47
47
|
},
|
|
48
|
+
{
|
|
49
|
+
"name": "chat-target",
|
|
50
|
+
"description": "Resolve the default Chat harness and prepare a draft for the selected brains",
|
|
51
|
+
"effect": "read",
|
|
52
|
+
"output": "json",
|
|
53
|
+
"args": [
|
|
54
|
+
{
|
|
55
|
+
"name": "brains",
|
|
56
|
+
"flag": "--brains",
|
|
57
|
+
"type": "string",
|
|
58
|
+
"label": "Selected brain IDs, comma separated"
|
|
59
|
+
}
|
|
60
|
+
]
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"name": "chat-default",
|
|
64
|
+
"description": "Save the default Chat harness for every brain selection",
|
|
65
|
+
"effect": "write",
|
|
66
|
+
"output": "json",
|
|
67
|
+
"args": [
|
|
68
|
+
{
|
|
69
|
+
"name": "adapter",
|
|
70
|
+
"type": "string",
|
|
71
|
+
"label": "Metaharness adapter ID",
|
|
72
|
+
"required": true,
|
|
73
|
+
"positional": true
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
"name": "url",
|
|
77
|
+
"flag": "--url",
|
|
78
|
+
"type": "string",
|
|
79
|
+
"label": "Optional Chat launch URL"
|
|
80
|
+
}
|
|
81
|
+
]
|
|
82
|
+
},
|
|
48
83
|
{
|
|
49
84
|
"name": "nodes",
|
|
50
85
|
"description": "List recorded mesh targets without probing or changing them",
|
|
@@ -815,29 +850,15 @@
|
|
|
815
850
|
"font": "system"
|
|
816
851
|
},
|
|
817
852
|
"ui": {
|
|
853
|
+
"home": "home",
|
|
854
|
+
"design_tokens": "DESIGN.md",
|
|
818
855
|
"elements": [
|
|
819
856
|
{
|
|
820
|
-
"id": "
|
|
821
|
-
"kind": "
|
|
822
|
-
"tag": "
|
|
823
|
-
"module": "ui/
|
|
824
|
-
"description": "
|
|
825
|
-
}
|
|
826
|
-
]
|
|
827
|
-
},
|
|
828
|
-
"card_face": {
|
|
829
|
-
"quick_actions": [
|
|
830
|
-
{
|
|
831
|
-
"subcommand": "status",
|
|
832
|
-
"label": "Local agents"
|
|
833
|
-
},
|
|
834
|
-
{
|
|
835
|
-
"subcommand": "nodes",
|
|
836
|
-
"label": "Mesh nodes"
|
|
837
|
-
},
|
|
838
|
-
{
|
|
839
|
-
"subcommand": "catalog",
|
|
840
|
-
"label": "Adapters"
|
|
857
|
+
"id": "home",
|
|
858
|
+
"kind": "panel",
|
|
859
|
+
"tag": "tr-metaharness-home",
|
|
860
|
+
"module": "ui/home.js",
|
|
861
|
+
"description": "Default Chat harness and launch destination"
|
|
841
862
|
}
|
|
842
863
|
]
|
|
843
864
|
},
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { configDir } from './paths.mjs';
|
|
3
|
+
import { PluginStateStore } from './ssss-store.mjs';
|
|
4
|
+
import { getActiveAdapters } from './worker.mjs';
|
|
5
|
+
|
|
6
|
+
const CODEX_DRAFT = 'codex://threads/new';
|
|
7
|
+
const MAX_SELECTION_BYTES = 16_384;
|
|
8
|
+
const MAX_DRAFT_LINK_LENGTH = 8_192;
|
|
9
|
+
const UNSAFE_TEXT = /[\p{Cc}\p{Cf}\p{Zl}\p{Zp}]/u;
|
|
10
|
+
const BRAIN_ID = /^(?:global|project:[^,]+|tenant:[a-zA-Z0-9._-]+)$/u;
|
|
11
|
+
const ADAPTER_ID = /^[a-z][a-z0-9-]{0,63}$/;
|
|
12
|
+
|
|
13
|
+
// Chat preferences follow the dashboard's brain. The auth store override is
|
|
14
|
+
// exclusively for credentials and may point outside an isolated dashboard.
|
|
15
|
+
const chatStore = () => new PluginStateStore(
|
|
16
|
+
path.join(configDir({ ...process.env, TR_SECRETS_BRAIN: undefined }), 'chat-default.json'),
|
|
17
|
+
'meta-harness',
|
|
18
|
+
);
|
|
19
|
+
const displayAdapter = ({ id, name }) => ({ id, name });
|
|
20
|
+
|
|
21
|
+
function brainContext(selection) {
|
|
22
|
+
if (typeof selection !== 'string' || Buffer.byteLength(selection) > MAX_SELECTION_BYTES || UNSAFE_TEXT.test(selection)) {
|
|
23
|
+
throw new Error('Chat requires a bounded comma-separated list of brain IDs');
|
|
24
|
+
}
|
|
25
|
+
const ids = [...new Set(selection.split(',').map(id => id.trim()))];
|
|
26
|
+
if (ids.some(id => !BRAIN_ID.test(id))) throw new Error('Chat brain IDs must use global, project:<name>, or tenant:<name>');
|
|
27
|
+
return `Use this Total Recall brain selection for Chat: ${JSON.stringify(ids)}. Resolve the selected IDs through Total Recall before retrieving or writing memory.`;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function launchUrl(adapterId, value) {
|
|
31
|
+
if (value === undefined) return undefined;
|
|
32
|
+
const message = 'Use an HTTPS launch URL without credentials, a query or a fragment, or a Codex Chat link for Codex';
|
|
33
|
+
if (typeof value !== 'string' || value.length > 2048 || UNSAFE_TEXT.test(value) || /\s|\\/u.test(value)) {
|
|
34
|
+
throw new Error(message);
|
|
35
|
+
}
|
|
36
|
+
if (adapterId === 'codex' && /^codex:\/\/threads\/[a-zA-Z0-9_-]{1,128}$/.test(value)) return value;
|
|
37
|
+
if (!value.startsWith('https://') || /[?#]/.test(value)) throw new Error(message);
|
|
38
|
+
const url = URL.parse(value);
|
|
39
|
+
if (!url?.hostname || url.username || url.password) throw new Error(message);
|
|
40
|
+
return url.href;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function resolveTarget(settings, adapters, context) {
|
|
44
|
+
const choices = adapters.map(displayAdapter);
|
|
45
|
+
if (!settings) return { ok: true, configured: false, choices, context };
|
|
46
|
+
const adapter = adapters.find(({ id }) => id === settings.adapterId);
|
|
47
|
+
if (!adapter) {
|
|
48
|
+
return {
|
|
49
|
+
ok: true, configured: false, choices, context,
|
|
50
|
+
warning: 'The saved Chat harness is unavailable. Choose a new default.',
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const target = launchUrl(adapter.id, settings.url) ?? (adapter.id === 'codex' ? CODEX_DRAFT : undefined);
|
|
55
|
+
let href = target;
|
|
56
|
+
if (target === CODEX_DRAFT) {
|
|
57
|
+
const draft = `${target}?prompt=${encodeURIComponent(context)}`;
|
|
58
|
+
if (draft.length <= MAX_DRAFT_LINK_LENGTH) href = draft;
|
|
59
|
+
}
|
|
60
|
+
return { ok: true, configured: true, choices, context, harness: displayAdapter(adapter), ...(href ? { href } : {}) };
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** Return a draft target. The caller decides when to open it and the operator submits in the harness. */
|
|
64
|
+
export function chatTarget(brains = 'global') {
|
|
65
|
+
const context = brainContext(brains);
|
|
66
|
+
const settings = chatStore().read(null);
|
|
67
|
+
if (settings !== null && (!settings || typeof settings.adapterId !== 'string' || !ADAPTER_ID.test(settings.adapterId))) {
|
|
68
|
+
throw new Error('The saved Chat default is invalid');
|
|
69
|
+
}
|
|
70
|
+
return resolveTarget(settings, getActiveAdapters(), context);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** Only the adapter and optional launch URL are persistent. */
|
|
74
|
+
export function setChatDefault(adapterId, url) {
|
|
75
|
+
const adapters = getActiveAdapters();
|
|
76
|
+
if (!adapters.some(({ id }) => id === adapterId)) throw new Error('Choose a registered Metaharness adapter for Chat');
|
|
77
|
+
const settings = { adapterId, url: launchUrl(adapterId, url) };
|
|
78
|
+
chatStore().write(settings);
|
|
79
|
+
return resolveTarget(settings, adapters, brainContext('global'));
|
|
80
|
+
}
|
package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/adapter-docs-freshness.md
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: ui-chunk:chunk
|
|
3
|
+
plugin: meta-harness
|
|
4
|
+
id: adapter-docs-freshness
|
|
5
|
+
title: Check harness documentation freshness
|
|
6
|
+
description: Distinguish an absent documentation cache from an outdated snapshot, then inspect the official source that governs the adapter.
|
|
7
|
+
timestamp: "2026-11-08T23:12:00Z"
|
|
8
|
+
intents: [check harness docs freshness, find the official source for a harness, verify adapter behavior against current docs]
|
|
9
|
+
surfaces: [page]
|
|
10
|
+
operations: [docs-status, docs-sources, docs-search, docs-read]
|
|
11
|
+
data: ["docs-status:/ok", "docs-sources:/sources"]
|
|
12
|
+
---
|
|
13
|
+
<section>
|
|
14
|
+
<h2>Check the documentation cache before using it</h2>
|
|
15
|
+
<p>Read documentation status and identify the official source. Search the current snapshot for the behavior you need. Refresh stale or missing documentation through the owner before relying on it.</p>
|
|
16
|
+
</section>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: ui-chunk:chunk
|
|
3
|
+
title: Chat handoff
|
|
4
|
+
description: Explain how Total Recall passes the selected brain IDs to a draft in the default Metaharness Chat destination.
|
|
5
|
+
timestamp: '2026-11-08T04:00:00Z'
|
|
6
|
+
plugin: meta-harness
|
|
7
|
+
id: chat-handoff
|
|
8
|
+
intents:
|
|
9
|
+
- open the default chat harness
|
|
10
|
+
- carry selected brains into chat
|
|
11
|
+
- prepare a draft for review
|
|
12
|
+
surfaces: [page, bottom]
|
|
13
|
+
panel: home
|
|
14
|
+
operations: [chat-target, chat-default]
|
|
15
|
+
data: ["chat-target:/configured", "chat-target:/harness/id", "chat-default:/configured"]
|
|
16
|
+
---
|
|
17
|
+
<section aria-label="Metaharness Chat handoff" data-design-component="chat-handoff" style="box-sizing:border-box;min-width:0;padding:var(--spacing-inset,16px);border:1px solid var(--color-line,#334155);border-radius:var(--radius-frame,8px);background:var(--color-canvas,#0c1427);color:var(--color-text,#f1f5f9);font:14px/1.5 var(--typography-body-font-family,system-ui)">
|
|
18
|
+
<p style="margin:0 0 6px;color:var(--color-signal,#38bdf8);font:600 11px/1.4 var(--typography-label-font-family,monospace);letter-spacing:.08em;text-transform:uppercase">Metaharness / Chat</p>
|
|
19
|
+
<h2 style="margin:0 0 12px;font-size:var(--typography-title-font-size,18px);line-height:1.2;font-weight:650">Carry your brain selection into Chat</h2>
|
|
20
|
+
<ol aria-label="Handoff stages" style="display:flex;flex-wrap:wrap;gap:6px 24px;margin:0 0 12px;padding:8px 12px 8px 32px;border-left:2px solid var(--color-signal,#38bdf8);background:var(--color-surface,#1e293b)">
|
|
21
|
+
<li>Choose brains</li>
|
|
22
|
+
<li>Open the default harness</li>
|
|
23
|
+
<li>Review the draft</li>
|
|
24
|
+
</ol>
|
|
25
|
+
<p style="margin:0;color:var(--color-muted,#94a3b8)">Chat keeps the same default as you switch brains. The draft carries the selected brain IDs so the harness can resolve them through Total Recall.</p>
|
|
26
|
+
</section>
|