total-recall-brain 3.45.0 → 3.46.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/total-recall.mjs +4 -2
- package/frontend/dist/assets/index-BRYE1jmv.css +1 -0
- package/frontend/dist/assets/index-D1goIPjC.js +5598 -0
- package/frontend/dist/index.html +2 -2
- package/frontend/dist/sw.js +5 -4
- package/frontend/src/App.tsx +183 -236
- package/frontend/src/api/auth-inventory.ts +62 -0
- package/frontend/src/api/memory.ts +13 -8
- package/frontend/src/api/plugin-credentials.ts +23 -0
- package/frontend/src/api/plugins.ts +37 -53
- package/frontend/src/api/workspace-drawers.ts +97 -0
- package/frontend/src/components/BrainSelector.tsx +9 -3
- package/frontend/src/components/plugins/PluginPanel.tsx +83 -42
- package/frontend/src/components/plugins/PluginSettings.tsx +10 -20
- package/frontend/src/components/plugins/PluginWorkspace.tsx +367 -0
- package/frontend/src/components/plugins/ScopedPluginCommands.tsx +142 -0
- package/frontend/src/components/plugins/plugin-frame.ts +44 -33
- package/frontend/src/components/plugins/scoped-plugin-operations.ts +28 -0
- package/frontend/src/components/workspace/DrawerChat.tsx +110 -0
- package/frontend/src/components/workspace/DrawerLayout.tsx +196 -0
- package/frontend/src/components/workspace/DrawerMarkup.tsx +49 -0
- package/frontend/src/components/workspace/PluginChunkLibrary.tsx +92 -0
- package/frontend/src/components/workspace/PluginHome.tsx +76 -0
- package/frontend/src/components/workspace/WorkspaceDrawers.tsx +96 -0
- package/frontend/src/components/workspace/WorkspacePage.tsx +95 -0
- package/frontend/src/components/workspace/usePluginDesign.ts +38 -0
- package/frontend/src/index.css +409 -136
- package/frontend/src/pages/HelpPage.tsx +15 -46
- package/frontend/src/pages/MemoryPage.tsx +19 -36
- package/frontend/src/pages/SettingsPage.tsx +1 -1
- package/metadata.plugin.schema.json +53 -227
- package/package.json +1 -1
- package/scaffold/.agent/skills/plugin/SKILL.md +13 -11
- package/scaffold/.agent/skills/plugin/evals/README.md +14 -21
- package/scaffold/.agent/skills/plugin/evals/cases/01-fabricated-seed.mjs +15 -18
- package/scaffold/.agent/skills/plugin/evals/cases/02-reassuring-default.mjs +19 -24
- package/scaffold/.agent/skills/plugin/evals/cases/03-declared-template.mjs +12 -20
- package/scaffold/.agent/skills/plugin/evals/cases/04-home-collects-credential.mjs +35 -0
- package/scaffold/.agent/skills/plugin/evals/cases/05-host-leak-in-scaffold.mjs +8 -28
- package/scaffold/.agent/skills/plugin/evals/cases/06-correct-plugin.mjs +85 -47
- package/scaffold/.agent/skills/plugin/evals/run.mjs +17 -18
- package/scaffold/.agent/skills/plugin/prompts/05-credentials.md +4 -4
- package/scaffold/.agent/skills/plugin/prompts/07-scaffold.md +2 -2
- package/scaffold/.agent/skills/plugin/prompts/08-verify.md +4 -4
- package/scaffold/.agent/skills/plugin/references/anti-patterns.md +2 -2
- package/scaffold/.agent/skills/plugin/references/generative-home.md +38 -0
- package/scaffold/.agent/skills/plugin/references/scaffold.md +5 -5
- package/scaffold/.agent/skills/plugin/references/surfaces.md +13 -4
- package/scaffold/.agent/skills/plugin/scripts/record.mjs +75 -153
- package/scaffold/.agent/skills/plugin/subagents/plugin-reviewer.md +4 -4
- package/scaffold/.agent/skills/total-recall/plugins/auth/DESIGN.md +76 -0
- package/scaffold/.agent/skills/total-recall/plugins/auth/README.md +3 -1
- package/scaffold/.agent/skills/total-recall/plugins/auth/cli.mjs +20 -15
- package/scaffold/.agent/skills/total-recall/plugins/auth/package-lock.json +6 -6
- package/scaffold/.agent/skills/total-recall/plugins/auth/package.json +2 -1
- package/scaffold/.agent/skills/total-recall/plugins/auth/plugin.json +13 -51
- package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/access-overview.md +17 -0
- package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/agent-login.md +20 -0
- package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/baseline-audit.md +22 -0
- package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/credential-repository-binding.md +17 -0
- package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/credential-store-maintenance.md +17 -0
- package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/dashboard-password.md +18 -0
- package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/dashboard-sessions.md +18 -0
- package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/endpoint-probe.md +23 -0
- package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/google-sign-in.md +21 -0
- package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/mesh-machines.md +16 -0
- package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/passkey-enrollment.md +21 -0
- package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/registered-brains.md +16 -0
- package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/scoped-access-keys.md +17 -0
- package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/secret-inventory.md +25 -0
- package/scaffold/.agent/skills/total-recall/plugins/auth/ui/chunks/signing-key-rotation.md +22 -0
- package/scaffold/.agent/skills/total-recall/plugins/auth/ui/home.js +375 -0
- package/scaffold/.agent/skills/total-recall/plugins/automations/{ui/DESIGN.md → DESIGN.md} +32 -21
- package/scaffold/.agent/skills/total-recall/plugins/automations/adapters.mjs +17 -1
- package/scaffold/.agent/skills/total-recall/plugins/automations/cli.mjs +10 -1
- package/scaffold/.agent/skills/total-recall/plugins/automations/package-lock.json +6 -6
- package/scaffold/.agent/skills/total-recall/plugins/automations/package.json +4 -3
- package/scaffold/.agent/skills/total-recall/plugins/automations/plugin.json +11 -27
- package/scaffold/.agent/skills/total-recall/plugins/automations/ui/automations.js +2 -2
- package/scaffold/.agent/skills/total-recall/plugins/automations/ui/chunks/control-ledger.md +42 -0
- package/scaffold/.agent/skills/total-recall/plugins/automations/ui/chunks/local-inventory-triage.md +17 -0
- package/scaffold/.agent/skills/total-recall/plugins/automations/ui/chunks/pending-control.md +39 -0
- package/scaffold/.agent/skills/total-recall/plugins/automations/ui/chunks/run-evidence.md +41 -0
- package/scaffold/.agent/skills/total-recall/plugins/automations/ui/chunks/schedule-vs-run-evidence.md +17 -0
- package/scaffold/.agent/skills/total-recall/plugins/automations/ui/chunks/source-coverage.md +41 -0
- package/scaffold/.agent/skills/total-recall/plugins/automations/ui/{card.js → home.js} +32 -27
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/DESIGN.md +53 -0
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/cli.mjs +23 -0
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/commands/run-core.mjs +4 -2
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/core/check.mjs +4 -2
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/package-lock.json +6 -6
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/package.json +2 -1
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/plugin.json +40 -40
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/chunks/config.md +15 -0
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/chunks/detect.md +15 -0
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/chunks/gate.md +15 -0
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/chunks/init.md +15 -0
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/chunks/report.md +17 -0
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/chunks/run.md +17 -0
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/chunks/snapshot.md +15 -0
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/code-quality-report.mjs +55 -23
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/home.mjs +214 -0
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/DESIGN.md +146 -0
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/package-lock.json +6 -6
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/package.json +2 -1
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/plugin.json +51 -34
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/src/command.mjs +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/create.md +35 -0
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/history.md +35 -0
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/library.md +49 -0
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/list.md +42 -0
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/promote.md +40 -0
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/read.md +25 -0
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/remove.md +26 -0
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/rollback.md +26 -0
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/show.md +53 -0
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/status.md +40 -0
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/test-path.md +38 -0
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/test.md +46 -0
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/chunks/update.md +32 -0
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/home.js +533 -0
- package/scaffold/.agent/skills/total-recall/plugins/embeddings/DESIGN.md +110 -0
- package/scaffold/.agent/skills/total-recall/plugins/embeddings/package-lock.json +6 -6
- package/scaffold/.agent/skills/total-recall/plugins/embeddings/package.json +2 -1
- package/scaffold/.agent/skills/total-recall/plugins/embeddings/plugin.json +13 -10
- package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/chunks/benchmark.md +49 -0
- package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/chunks/coverage.md +53 -0
- package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/chunks/models.md +43 -0
- package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/chunks/pull.md +41 -0
- package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/chunks/status.md +59 -0
- package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/home.js +353 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/DESIGN.md +31 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/README.md +25 -1
- package/scaffold/.agent/skills/total-recall/plugins/git/cli.mjs +5 -1
- package/scaffold/.agent/skills/total-recall/plugins/git/package-lock.json +6 -6
- package/scaffold/.agent/skills/total-recall/plugins/git/package.json +2 -1
- package/scaffold/.agent/skills/total-recall/plugins/git/plugin.json +17 -27
- package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/commit-memory.mjs +30 -6
- package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/fleet.mjs +24 -6
- package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/secret-firewall.mjs +33 -7
- package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/undo.mjs +29 -5
- package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/unmerged.mjs +182 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/change-comparison.md +27 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/commit-identity.md +22 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/create-worktree.md +25 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/registered-worktrees.md +22 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/remove-worktree.md +23 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/repository-ledger.md +25 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/unmerged-work.md +22 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/upstream-divergence.md +17 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/worktree-conflict-triage.md +17 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/ui/chunks/worktree-terminal.md +22 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/ui/home.js +273 -0
- package/scaffold/.agent/skills/total-recall/plugins/mesh/DESIGN.md +35 -0
- package/scaffold/.agent/skills/total-recall/plugins/mesh/README.md +4 -5
- package/scaffold/.agent/skills/total-recall/plugins/mesh/cli.mjs +9 -3
- package/scaffold/.agent/skills/total-recall/plugins/mesh/package-lock.json +6 -6
- package/scaffold/.agent/skills/total-recall/plugins/mesh/package.json +2 -1
- package/scaffold/.agent/skills/total-recall/plugins/mesh/plugin.json +37 -39
- package/scaffold/.agent/skills/total-recall/plugins/mesh/src/cli/mesh.mjs +5 -3
- package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/active-device-dispatch.md +22 -0
- package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/control-probe.md +25 -0
- package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/control-server.md +22 -0
- package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/credential-readiness.md +23 -0
- package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/elected-leader.md +22 -0
- package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/enrollment-key.md +22 -0
- package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/file-receipt.md +25 -0
- package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/fleet-execution.md +23 -0
- package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/fleet-presence.md +23 -0
- package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/interactive-ssh.md +22 -0
- package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/local-enrollment.md +23 -0
- package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/mesh-policy.md +23 -0
- package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/network-atlas.md +25 -0
- package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/node-roster.md +26 -0
- package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/node-selection-proof.md +17 -0
- package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/owner-observations.md +23 -0
- package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/peer-path.md +23 -0
- package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/pinned-leader.md +24 -0
- package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/reachability-evidence-ladder.md +17 -0
- package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/recorded-login.md +23 -0
- package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/remote-execution.md +22 -0
- package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/chunks/secret-grants.md +26 -0
- package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/{card.js → home.js} +93 -22
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/DESIGN.md +86 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/README.md +19 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/cli.mjs +5 -1
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/package-lock.json +6 -6
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/package.json +2 -1
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/plugin.json +43 -22
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/chat.mjs +80 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/adapter-docs-freshness.md +16 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/chat-handoff.md +26 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/fleet-maintenance.md +21 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/harness-inventory.md +21 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/included-access.md +18 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/included-usage-verification.md +15 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/independent-review.md +17 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/managed-execution.md +20 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/official-documentation.md +18 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/quota-recovery.md +21 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/review-routing-decision.md +16 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/route-work.md +18 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/routing-evidence.md +18 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/chunks/run-ledger.md +18 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/home.js +198 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/DESIGN.md +75 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/README.md +2 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/cli.mjs +17 -14
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/package-lock.json +6 -6
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/package.json +2 -1
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/plugin.json +10 -44
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/generate.mjs +5 -4
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/graph.mjs +3 -4
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/ingest.mjs +23 -18
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/mesh-vaults.mjs +8 -3
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/refresh.mjs +6 -3
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/search.mjs +3 -5
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/token.mjs +21 -47
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/upstream-watcher.mjs +17 -6
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/auto-refresh.md +18 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/bootstrap-pages.md +18 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/generate-wiki.md +21 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/generator-settings.md +18 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/host-probe.md +18 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/ingest-preview.md +18 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/link-hygiene.md +21 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/link-topology.md +19 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/passage-search.md +19 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/propagation-plan.md +18 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/provider-credentials.md +18 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/refresh-report.md +18 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/task-evidence.md +22 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/upstream-record.md +18 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/watch-upstream.md +18 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/chunks/wiki-atlas.md +19 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/panel.js +261 -513
- package/scaffold/.agent/skills/total-recall/plugins/security/DESIGN.md +84 -0
- package/scaffold/.agent/skills/total-recall/plugins/security/README.md +4 -2
- package/scaffold/.agent/skills/total-recall/plugins/security/cli.mjs +7 -19
- package/scaffold/.agent/skills/total-recall/plugins/security/package-lock.json +6 -6
- package/scaffold/.agent/skills/total-recall/plugins/security/package.json +2 -3
- package/scaffold/.agent/skills/total-recall/plugins/security/plugin.json +19 -52
- package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/device-evidence.md +21 -0
- package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/evidence-desk.md +18 -0
- package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/guided-device-review.md +17 -0
- package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/host-and-network.md +21 -0
- package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/https-headers.md +17 -0
- package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/mesh-coverage.md +18 -0
- package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/private-security-tools.md +16 -0
- package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/single-origin-header-check.md +17 -0
- package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/source-review.md +21 -0
- package/scaffold/.agent/skills/total-recall/plugins/security/ui/chunks/ssh-permission-plan.md +17 -0
- package/scaffold/.agent/skills/total-recall/plugins/security/ui/home.js +283 -0
- package/scaffold/.agent/skills/total-recall/plugins/ssss/DESIGN.md +93 -0
- package/scaffold/.agent/skills/total-recall/plugins/ssss/package-lock.json +2 -2
- package/scaffold/.agent/skills/total-recall/plugins/ssss/package.json +2 -1
- package/scaffold/.agent/skills/total-recall/plugins/ssss/plugin.json +5 -3
- package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/chunks/conformance.md +26 -0
- package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/chunks/registry.md +37 -0
- package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/chunks/repair.md +42 -0
- package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/chunks/scaffold.md +33 -0
- package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/chunks/status.md +43 -0
- package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/chunks/validate.md +34 -0
- package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/chunks/validation-diagnostics.md +17 -0
- package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/chunks/workspace-registry-preflight.md +17 -0
- package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/home.js +348 -0
- package/scaffold/.agent/skills/total-recall/references/operations.md +2 -0
- package/src/cli/api.mjs +3 -3
- package/src/cli/brief.mjs +3 -0
- package/src/cli/config.mjs +16 -0
- package/src/cli/connect.mjs +2 -7
- package/src/cli/plugin/chunks.mjs +145 -0
- package/src/cli/plugin/create.mjs +24 -52
- package/src/cli/plugin/index.mjs +20 -9
- package/src/cli/setup.mjs +2 -9
- package/src/cli/start.mjs +1 -0
- package/src/cli/startup.mjs +18 -0
- package/src/core/app-deploy/design-tokens.mjs +14 -9
- package/src/core/app-deploy/ui-elements.mjs +1 -1
- package/src/core/brain-registry.mjs +5 -0
- package/src/core/brain-updates.mjs +5 -1
- package/src/core/daemon-control.mjs +5 -1
- package/src/core/dashboard-bundle.mjs +261 -0
- package/src/core/ensure-dependencies.mjs +19 -15
- package/src/core/memory-brain.mjs +30 -8
- package/src/core/plugin-activation.mjs +63 -20
- package/src/core/plugin-contracts/{card.mjs → manifest.mjs} +23 -57
- package/src/core/plugin-contracts/startup-check.mjs +49 -0
- package/src/core/plugin-contracts/ui.mjs +9 -3
- package/src/core/plugin-distribution.mjs +6 -6
- package/src/core/plugin-lifecycle.mjs +58 -0
- package/src/core/plugin-loader.mjs +9 -5
- package/src/core/plugin-runner.mjs +21 -10
- package/src/core/plugin-startup-checks.mjs +44 -0
- package/src/core/plugin-state.mjs +19 -5
- package/src/core/plugin-store.mjs +30 -11
- package/src/core/project-id.mjs +15 -5
- package/src/core/required-plugins.mjs +31 -6
- package/src/core/schema.mjs +2 -0
- package/src/core/ssss-operation-service.mjs +1 -0
- package/src/core/startup-health.mjs +28 -3
- package/src/core/testing/plugin-fixture.mjs +22 -21
- package/src/core/throttled-fetch.mjs +25 -18
- package/src/core/ui-chunk-choice.mjs +77 -0
- package/src/core/ui-chunk.registry.json +23 -0
- package/src/core/ui-chunks.mjs +434 -0
- package/src/core/vault-cache.mjs +58 -59
- package/src/core/workspace-compositions.mjs +151 -0
- package/src/core/workspace-drawers.mjs +79 -0
- package/src/server/api.mjs +4 -27
- package/src/server/index.mjs +28 -21
- package/src/server/memory-events.mjs +31 -0
- package/src/server/plugin-brain-targets.mjs +89 -0
- package/src/server/rest.mjs +2 -0
- package/src/server/route-inventory.mjs +3 -2
- package/src/server/route-manifest.json +52 -4
- package/src/server/routes/_shared.mjs +7 -14
- package/src/server/routes/brains.mjs +29 -44
- package/src/server/routes/dashboard.mjs +26 -0
- package/src/server/routes/plugins.mjs +154 -45
- package/src/server/routes/ui-chunks.mjs +192 -0
- package/frontend/dist/assets/index-DACh1dhx.js +0 -5613
- package/frontend/dist/assets/index-DtwsDyFM.css +0 -1
- package/frontend/src/components/plugins/card/CardEngine.tsx +0 -108
- package/frontend/src/components/plugins/card/CardScenes.tsx +0 -103
- package/frontend/src/components/plugins/card/ExecutionPicker.tsx +0 -64
- package/frontend/src/components/plugins/card/args.ts +0 -28
- package/frontend/src/components/plugins/card/card.css +0 -32
- package/frontend/src/components/plugins/card/cli-line.ts +0 -13
- package/frontend/src/components/plugins/card/contract.ts +0 -91
- package/frontend/src/components/plugins/card/format.ts +0 -49
- package/frontend/src/components/plugins/card/runner-context.ts +0 -11
- package/frontend/src/components/plugins/card/runner.tsx +0 -43
- package/frontend/src/components/plugins/card/theme.ts +0 -35
- package/frontend/src/components/plugins/card/use-source.ts +0 -22
- package/frontend/src/components/plugins/card/widgets.tsx +0 -94
- package/frontend/src/components/plugins/workspace/WorkspaceHost.tsx +0 -23
- package/frontend/src/pages/PluginsPage.tsx +0 -1719
- package/scaffold/.agent/skills/plugin/evals/cases/04-card-collects-credential.mjs +0 -47
- package/scaffold/.agent/skills/plugin/prompts/06-card.md +0 -46
- package/scaffold/.agent/skills/plugin/references/card.md +0 -90
- package/scaffold/.agent/skills/plugin/subagents/card-designer.md +0 -60
- package/scaffold/.agent/skills/total-recall/plugins/auth/ui/DESIGN.md +0 -67
- package/scaffold/.agent/skills/total-recall/plugins/auth/ui/card.js +0 -1179
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/DESIGN.md +0 -32
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/ui/card.js +0 -588
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/ui/card.js +0 -575
- package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/DESIGN.md +0 -32
- package/scaffold/.agent/skills/total-recall/plugins/embeddings/ui/card.js +0 -482
- package/scaffold/.agent/skills/total-recall/plugins/git/ui/DESIGN.md +0 -100
- package/scaffold/.agent/skills/total-recall/plugins/git/ui/card.js +0 -637
- package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/DESIGN.md +0 -217
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/DESIGN.md +0 -32
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/card.js +0 -1276
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/DESIGN.md +0 -45
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/card.js +0 -1401
- package/scaffold/.agent/skills/total-recall/plugins/security/scripts/build-ui.mjs +0 -4
- package/scaffold/.agent/skills/total-recall/plugins/security/ui/DESIGN.md +0 -41
- package/scaffold/.agent/skills/total-recall/plugins/security/ui/card.js +0 -396
- package/scaffold/.agent/skills/total-recall/plugins/security/ui/panel.js +0 -98
- package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/DESIGN.md +0 -15
- package/scaffold/.agent/skills/total-recall/plugins/ssss/ui/card.js +0 -182
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { useEffect, useState } from 'react'
|
|
2
|
+
import { findWorkspaceChunks, readWorkspaceComposition, type WorkspaceChunk } from '../../api/workspace-drawers'
|
|
3
|
+
import type { PluginInfo } from '../../api/plugins'
|
|
4
|
+
import { drawerPanels, PublishedChunk } from './DrawerLayout'
|
|
5
|
+
import { PluginPanel } from '../plugins/PluginPanel'
|
|
6
|
+
import { scopedPluginOperations } from '../plugins/scoped-plugin-operations'
|
|
7
|
+
import { usePluginDesign } from './usePluginDesign'
|
|
8
|
+
|
|
9
|
+
export function PluginHome({ plugin, plugins, brainId, onCommand }: {
|
|
10
|
+
plugin: PluginInfo; plugins: PluginInfo[] | null; brainId?: string; onCommand: (name: string) => void
|
|
11
|
+
}) {
|
|
12
|
+
const [defaults, setDefaults] = useState<WorkspaceChunk[]>([])
|
|
13
|
+
const [published, setPublished] = useState<{ chunks: WorkspaceChunk[]; version: string | null }>()
|
|
14
|
+
const [loading, setLoading] = useState(true)
|
|
15
|
+
const liveDesign = usePluginDesign(plugin.id, brainId)
|
|
16
|
+
const designCss = liveDesign?.design?.css ?? ''
|
|
17
|
+
const panels = drawerPanels(plugin)
|
|
18
|
+
const home = (plugin.manifest?.ui as { home?: string } | undefined)?.home || plugin.ui?.home
|
|
19
|
+
const panel = panels.find(element => element.id === home) || panels[0]
|
|
20
|
+
const operations = scopedPluginOperations(plugin)
|
|
21
|
+
const chunks = published?.chunks.length ? published.chunks : defaults
|
|
22
|
+
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
const controller = new AbortController()
|
|
25
|
+
void findWorkspaceChunks('page', '', controller.signal, plugin.id, brainId).then(({ chunks }) => {
|
|
26
|
+
if (controller.signal.aborted) return
|
|
27
|
+
const ownerDefault = panel?.id && chunks.find(chunk => chunk.panel === panel.id)
|
|
28
|
+
setDefaults(ownerDefault ? [ownerDefault] : chunks.slice(0, 1))
|
|
29
|
+
}).catch(() => {}).finally(() => {
|
|
30
|
+
if (!controller.signal.aborted) setLoading(false)
|
|
31
|
+
})
|
|
32
|
+
return () => controller.abort()
|
|
33
|
+
}, [plugin.id, panel?.id, brainId])
|
|
34
|
+
|
|
35
|
+
useEffect(() => {
|
|
36
|
+
const controller = new AbortController()
|
|
37
|
+
let timer: ReturnType<typeof setTimeout>
|
|
38
|
+
const refresh = async () => {
|
|
39
|
+
try {
|
|
40
|
+
const next = await readWorkspaceComposition(plugin.id, controller.signal, brainId)
|
|
41
|
+
if (!controller.signal.aborted) {
|
|
42
|
+
setPublished(current => current?.version === next.version &&
|
|
43
|
+
current.chunks.map(chunk => chunk.sha256).join() === next.chunks.map(chunk => chunk.sha256).join() ? current : next)
|
|
44
|
+
}
|
|
45
|
+
} catch { /* The owner default remains available on an older or unreachable server. */ }
|
|
46
|
+
finally {
|
|
47
|
+
if (!controller.signal.aborted) timer = setTimeout(refresh, 2500)
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
void refresh()
|
|
51
|
+
return () => { controller.abort(); clearTimeout(timer) }
|
|
52
|
+
}, [plugin.id, brainId])
|
|
53
|
+
|
|
54
|
+
return <div className="plugin-home">
|
|
55
|
+
{loading && <p role="status">Loading published blocks…</p>}
|
|
56
|
+
{liveDesign?.issue && <p role="status">{liveDesign.issue}</p>}
|
|
57
|
+
{!loading && chunks.map(chunk =>
|
|
58
|
+
<div key={`${chunk.key}:${chunk.sha256}`} className="plugin-home">
|
|
59
|
+
<PublishedChunk name={chunk.key} side="page" plugins={plugins} brainId={brainId} design={chunk.plugin === plugin.id ? liveDesign?.design : undefined}
|
|
60
|
+
designOwner={chunk.plugin === plugin.id ? undefined : chunk.plugin} />
|
|
61
|
+
</div>
|
|
62
|
+
)}
|
|
63
|
+
{!loading && !published?.chunks.length && panel && !chunks.some(chunk => chunk.panel === panel.id) &&
|
|
64
|
+
<PluginPanel plugin={plugin} elementId={panel.id} designCss={designCss} brainId={brainId} />}
|
|
65
|
+
{!published?.chunks.length && !chunks.some(chunk => chunk.operations?.length) && operations.length > 0 && <section aria-label="Plugin operations">
|
|
66
|
+
<h2>Start a workflow</h2>
|
|
67
|
+
<ul className="plugin-home-operations">
|
|
68
|
+
{operations.slice(0, 6).map(command => <li key={command.name}>
|
|
69
|
+
<button type="button" className="btn btn-ghost" onClick={() => onCommand(command.name)}>{command.name}</button>
|
|
70
|
+
{command.description && <span>{command.description}</span>}
|
|
71
|
+
</li>)}
|
|
72
|
+
</ul>
|
|
73
|
+
</section>}
|
|
74
|
+
{!panel && !loading && !chunks.length && <p className="plugin-muted">This plugin has yet to publish a dedicated Home interface.</p>}
|
|
75
|
+
</div>
|
|
76
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { useEffect, useRef, useState, type ReactNode } from 'react'
|
|
2
|
+
import type { PluginInfo } from '../../api/plugins'
|
|
3
|
+
import type { DrawerSide } from '../../api/workspace-drawers'
|
|
4
|
+
import HelpPage from '../../pages/HelpPage'
|
|
5
|
+
import { DrawerChat } from './DrawerChat'
|
|
6
|
+
import { DrawerLayout, DrawerPanel } from './DrawerLayout'
|
|
7
|
+
|
|
8
|
+
export type WorkspaceEdge = 'left' | DrawerSide
|
|
9
|
+
const tools = ['Phone', 'Text', 'Shortcuts', 'Chat', 'Custom'] as const
|
|
10
|
+
type Tool = (typeof tools)[number]
|
|
11
|
+
|
|
12
|
+
function EdgeDrawer({ side, title, open, onChange, children }: {
|
|
13
|
+
side: DrawerSide; title: string; open: boolean; onChange: (edge: WorkspaceEdge | null) => void; children: ReactNode
|
|
14
|
+
}) {
|
|
15
|
+
const toggle = useRef<HTMLButtonElement>(null)
|
|
16
|
+
const closeButton = useRef<HTMLButtonElement>(null)
|
|
17
|
+
const content = useRef<HTMLElement>(null)
|
|
18
|
+
const panelId = `workspace-drawer-${side}`
|
|
19
|
+
|
|
20
|
+
useEffect(() => {
|
|
21
|
+
if (open) closeButton.current?.focus()
|
|
22
|
+
return () => {
|
|
23
|
+
if (open && content.current?.contains(document.activeElement)) toggle.current?.focus()
|
|
24
|
+
}
|
|
25
|
+
}, [open])
|
|
26
|
+
const close = () => {
|
|
27
|
+
toggle.current?.focus()
|
|
28
|
+
onChange(null)
|
|
29
|
+
}
|
|
30
|
+
return <>
|
|
31
|
+
<button type="button" className={`workspace-edge-handle workspace-edge-handle--${side}`}
|
|
32
|
+
ref={toggle} aria-label={side === 'right' ? 'Help drawer' : 'Bottom drawer'}
|
|
33
|
+
aria-controls={panelId} aria-expanded={open} onClick={() => open ? close() : onChange(side)}
|
|
34
|
+
onKeyDown={event => { if (event.key === 'Escape' && open) close() }}>
|
|
35
|
+
<svg width="13" height="13" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5" aria-hidden="true">
|
|
36
|
+
<path d={side === 'right' ? (open ? 'm6 3 5 5-5 5' : 'm10 3-5 5 5 5') : (open ? 'm3 6 5 5 5-5' : 'm3 10 5-5 5 5')} />
|
|
37
|
+
</svg>
|
|
38
|
+
{title}
|
|
39
|
+
</button>
|
|
40
|
+
<aside ref={content} id={panelId} aria-label={title} inert={!open}
|
|
41
|
+
className={`workspace-edge-panel workspace-edge-panel--${side}${open ? ' open' : ''}`}
|
|
42
|
+
onKeyDown={event => { if (event.key === 'Escape') { event.stopPropagation(); close() } }}>
|
|
43
|
+
<header className="workspace-edge-header">
|
|
44
|
+
<h2>{title}</h2>
|
|
45
|
+
<button type="button" ref={closeButton} className="btn btn-ghost btn-sm" onClick={close}>Close</button>
|
|
46
|
+
</header>
|
|
47
|
+
{open && <div className="workspace-edge-body">{children}</div>}
|
|
48
|
+
</aside>
|
|
49
|
+
</>
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function HelpDrawer({ plugins, brainId }: { plugins: PluginInfo[] | null; brainId?: string }) {
|
|
53
|
+
const [custom, setCustom] = useState(false)
|
|
54
|
+
return <>
|
|
55
|
+
<div className="drawer-section-tabs" role="group" aria-label="Help sections">
|
|
56
|
+
<button type="button" className="btn btn-ghost btn-sm" aria-pressed={!custom} onClick={() => setCustom(false)}>Reference</button>
|
|
57
|
+
<button type="button" className="btn btn-ghost btn-sm" aria-pressed={custom} onClick={() => setCustom(true)}>Custom</button>
|
|
58
|
+
</div>
|
|
59
|
+
{custom ? (brainId ? <DrawerLayout key={brainId} side="right" view="custom" plugins={plugins} brainId={brainId} />
|
|
60
|
+
: <p className="drawer-note">Select one local brain to open custom help.</p>) : <HelpPage embedded />}
|
|
61
|
+
</>
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function ToolsDrawer({ plugins, activeBrainId, brainId }: { plugins: PluginInfo[] | null; activeBrainId: string; brainId?: string }) {
|
|
65
|
+
const [section, setSection] = useState<Tool>('Shortcuts')
|
|
66
|
+
return <>
|
|
67
|
+
<div className="drawer-section-tabs" role="group" aria-label="Bottom drawer tools">
|
|
68
|
+
{tools.map(tool => <button key={tool} type="button" className="btn btn-ghost btn-sm"
|
|
69
|
+
aria-pressed={tool === section} onClick={() => setSection(tool)}>{tool}</button>)}
|
|
70
|
+
</div>
|
|
71
|
+
{(section === 'Phone' || section === 'Text') && (brainId
|
|
72
|
+
? <DrawerPanel plugins={plugins} reference={{ plugin: section.toLowerCase(), element: section.toLowerCase() }} brainId={brainId} />
|
|
73
|
+
: <p className="drawer-note">Select one local brain to open {section}.</p>)}
|
|
74
|
+
{section === 'Chat' && (plugins ? <DrawerChat plugin={plugins.find(plugin => plugin.id === 'meta-harness')}
|
|
75
|
+
activeBrainId={activeBrainId} /> : <p role="status">Loading Metaharness…</p>)}
|
|
76
|
+
{section === 'Shortcuts' && <DrawerLayout side="bottom" view="shortcuts" plugins={plugins} brainId={brainId} />}
|
|
77
|
+
{section === 'Custom' && (brainId ? <DrawerLayout key={brainId} side="bottom" view="custom" plugins={plugins} brainId={brainId} />
|
|
78
|
+
: <p className="drawer-note">Select one local brain to open custom tools.</p>)}
|
|
79
|
+
</>
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export function WorkspaceDrawers({ edge, onChange, plugins, activeBrainId }: {
|
|
83
|
+
edge: WorkspaceEdge | null
|
|
84
|
+
onChange: (edge: WorkspaceEdge | null) => void
|
|
85
|
+
plugins: PluginInfo[] | null
|
|
86
|
+
activeBrainId: string
|
|
87
|
+
}) {
|
|
88
|
+
const brainId = !activeBrainId.includes(',') && (activeBrainId === 'global' || activeBrainId.startsWith('project:'))
|
|
89
|
+
? activeBrainId : undefined
|
|
90
|
+
return <>
|
|
91
|
+
<EdgeDrawer side="right" title="Help" open={edge === 'right'} onChange={onChange}><HelpDrawer plugins={plugins} brainId={brainId} /></EdgeDrawer>
|
|
92
|
+
<EdgeDrawer side="bottom" title="Tools" open={edge === 'bottom'} onChange={onChange}>
|
|
93
|
+
<ToolsDrawer plugins={plugins} activeBrainId={activeBrainId} brainId={brainId} />
|
|
94
|
+
</EdgeDrawer>
|
|
95
|
+
</>
|
|
96
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { useEffect, useState } from 'react'
|
|
2
|
+
import { Link } from 'react-router-dom'
|
|
3
|
+
import type { PluginInfo } from '../../api/plugins'
|
|
4
|
+
import { listSavedPages, readSavedPage, type SavedPage, type SavedPageSummary } from '../../api/workspace-drawers'
|
|
5
|
+
import { PublishedChunk } from './DrawerLayout'
|
|
6
|
+
|
|
7
|
+
export function SavedPages({ brainId, drawerOpen, activePageId, onOpenPage }: {
|
|
8
|
+
brainId?: string
|
|
9
|
+
drawerOpen: boolean
|
|
10
|
+
activePageId: string | null
|
|
11
|
+
onOpenPage: () => void
|
|
12
|
+
}) {
|
|
13
|
+
const [expanded, setExpanded] = useState(false)
|
|
14
|
+
return <details className="sidebar-memory sidebar-saved-pages" onToggle={event => setExpanded(event.currentTarget.open)}>
|
|
15
|
+
<summary className="nav-link">
|
|
16
|
+
Saved pages <span className="plugin-folder-chevron" aria-hidden="true">{expanded ? '▾' : '›'}</span>
|
|
17
|
+
</summary>
|
|
18
|
+
{drawerOpen && expanded && (brainId
|
|
19
|
+
? <SavedPageLinks key={brainId} brainId={brainId} activePageId={activePageId} onOpenPage={onOpenPage} />
|
|
20
|
+
: <p className="plugin-folder-message">Select one brain to see its saved pages.</p>)}
|
|
21
|
+
</details>
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function SavedPageLinks({ brainId, activePageId, onOpenPage }: {
|
|
25
|
+
brainId: string
|
|
26
|
+
activePageId: string | null
|
|
27
|
+
onOpenPage: () => void
|
|
28
|
+
}) {
|
|
29
|
+
const [result, setResult] = useState<{ pages: SavedPageSummary[] } | { error: string }>()
|
|
30
|
+
useEffect(() => {
|
|
31
|
+
const controller = new AbortController()
|
|
32
|
+
void listSavedPages(brainId, controller.signal).then(
|
|
33
|
+
data => { if (!controller.signal.aborted) setResult(data) },
|
|
34
|
+
() => { if (!controller.signal.aborted) setResult({ error: 'Could not load saved pages.' }) },
|
|
35
|
+
)
|
|
36
|
+
return () => controller.abort()
|
|
37
|
+
}, [brainId])
|
|
38
|
+
|
|
39
|
+
if (!result) return <p className="plugin-folder-message" role="status">Loading saved pages…</p>
|
|
40
|
+
if ('error' in result) return <p className="plugin-folder-message" role="alert">{result.error}</p>
|
|
41
|
+
if (!result.pages.length) return <p className="plugin-folder-message">No saved pages</p>
|
|
42
|
+
|
|
43
|
+
return <ul className="plugin-folder-list" aria-label="Saved pages">
|
|
44
|
+
{result.pages.map(page => {
|
|
45
|
+
const query = new URLSearchParams({ page: page.id, brain: brainId })
|
|
46
|
+
const current = page.id === activePageId
|
|
47
|
+
return <li key={page.id}>
|
|
48
|
+
<Link to={`/memory?${query}`} className={`nav-link ${current ? 'active' : ''}`}
|
|
49
|
+
aria-current={current ? 'page' : undefined} onClick={onOpenPage}>{page.title}</Link>
|
|
50
|
+
</li>
|
|
51
|
+
})}
|
|
52
|
+
</ul>
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function WorkspacePage({ id, brainId, plugins }: {
|
|
56
|
+
id: string
|
|
57
|
+
brainId?: string
|
|
58
|
+
plugins: PluginInfo[] | null
|
|
59
|
+
}) {
|
|
60
|
+
return brainId
|
|
61
|
+
? <SavedPageContent key={`${brainId}:${id}`} id={id} brainId={brainId} plugins={plugins} />
|
|
62
|
+
: <section className="plugin-workspace-page" aria-label="Saved page">
|
|
63
|
+
<p>Select one brain to open this saved page.</p>
|
|
64
|
+
</section>
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function SavedPageContent({ id, brainId, plugins }: {
|
|
68
|
+
id: string
|
|
69
|
+
brainId: string
|
|
70
|
+
plugins: PluginInfo[] | null
|
|
71
|
+
}) {
|
|
72
|
+
const [result, setResult] = useState<SavedPage | { error: string }>()
|
|
73
|
+
useEffect(() => {
|
|
74
|
+
const controller = new AbortController()
|
|
75
|
+
void readSavedPage(id, brainId, controller.signal).then(
|
|
76
|
+
page => { if (!controller.signal.aborted) setResult(page) },
|
|
77
|
+
() => { if (!controller.signal.aborted) setResult({ error: 'Could not open this saved page in the selected brain.' }) },
|
|
78
|
+
)
|
|
79
|
+
return () => controller.abort()
|
|
80
|
+
}, [id, brainId])
|
|
81
|
+
|
|
82
|
+
const page = result && 'chunks' in result ? result : undefined
|
|
83
|
+
return <section className="plugin-workspace-page" aria-labelledby="saved-page-title">
|
|
84
|
+
<header className="plugin-drawer-header">
|
|
85
|
+
<h1 id="saved-page-title">{page?.title || 'Saved page'}</h1>
|
|
86
|
+
<Link className="btn btn-ghost btn-sm" to="/memory">Close</Link>
|
|
87
|
+
</header>
|
|
88
|
+
{!result && <p role="status">Loading saved page…</p>}
|
|
89
|
+
{result && 'error' in result && <p role="alert">{result.error}</p>}
|
|
90
|
+
{page && !page.chunks.length && <p className="plugin-muted">No page blocks are available in this brain.</p>}
|
|
91
|
+
{page?.chunks.map(chunk =>
|
|
92
|
+
<PublishedChunk key={`${chunk.key}:${chunk.sha256}`} name={chunk.key} side="page" plugins={plugins}
|
|
93
|
+
brainId={brainId} designOwner={chunk.plugin} />)}
|
|
94
|
+
</section>
|
|
95
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { useEffect, useState } from 'react'
|
|
2
|
+
import { readPluginDesign, type PluginDesign } from '../../api/workspace-drawers'
|
|
3
|
+
|
|
4
|
+
export function usePluginDesign(pluginId: string | undefined, brainId?: string) {
|
|
5
|
+
const [current, setCurrent] = useState<{ pluginId: string; brainId?: string; design?: PluginDesign; issue?: string }>()
|
|
6
|
+
useEffect(() => {
|
|
7
|
+
if (!pluginId) return
|
|
8
|
+
const controller = new AbortController()
|
|
9
|
+
let timer: ReturnType<typeof setTimeout>
|
|
10
|
+
let revision: string | null = null
|
|
11
|
+
const refresh = async () => {
|
|
12
|
+
try {
|
|
13
|
+
const result = await readPluginDesign(pluginId, revision, controller.signal, brainId)
|
|
14
|
+
if (controller.signal.aborted) return
|
|
15
|
+
if ('unchanged' in result) {
|
|
16
|
+
setCurrent(current => current?.issue ? { ...current, issue: undefined } : current)
|
|
17
|
+
} else {
|
|
18
|
+
revision = result.revision
|
|
19
|
+
setCurrent(current => current?.pluginId === pluginId && current.brainId === brainId && current.design?.revision === result.revision && !current.issue
|
|
20
|
+
? current : { pluginId, brainId, design: result })
|
|
21
|
+
}
|
|
22
|
+
} catch (error) {
|
|
23
|
+
if (!controller.signal.aborted) {
|
|
24
|
+
const issue = error instanceof Error ? error.message : 'Could not refresh the plugin design.'
|
|
25
|
+
setCurrent(current => ({ pluginId, brainId, design: current?.pluginId === pluginId && current.brainId === brainId ? current.design : undefined, issue }))
|
|
26
|
+
}
|
|
27
|
+
} finally {
|
|
28
|
+
if (!controller.signal.aborted) timer = setTimeout(refresh, 2500)
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
void refresh()
|
|
32
|
+
return () => {
|
|
33
|
+
controller.abort()
|
|
34
|
+
clearTimeout(timer)
|
|
35
|
+
}
|
|
36
|
+
}, [pluginId, brainId])
|
|
37
|
+
return current?.pluginId === pluginId && current?.brainId === brainId ? current : undefined
|
|
38
|
+
}
|