total-recall-brain 3.44.0 → 3.46.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/total-recall.mjs +10 -6
- package/docs/ARCHITECTURE.md +10 -7
- package/docs/reference/cli-reference.md +13 -8
- 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 +185 -238
- 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 +7 -7
- 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/src/cli-secret.mjs +20 -1
- package/scaffold/.agent/skills/total-recall/plugins/auth/src/secrets-store.mjs +12 -1
- 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/BRICK.md +7 -0
- package/scaffold/.agent/skills/total-recall/plugins/automations/DESIGN.md +53 -0
- package/scaffold/.agent/skills/total-recall/plugins/automations/LICENSE +21 -0
- package/scaffold/.agent/skills/total-recall/plugins/automations/README.md +66 -0
- package/scaffold/.agent/skills/total-recall/plugins/automations/adapters.mjs +247 -0
- package/scaffold/.agent/skills/total-recall/plugins/automations/capability/index.mjs +16 -0
- package/scaffold/.agent/skills/total-recall/plugins/automations/cli.mjs +130 -0
- package/{src/core/plugin-cron.mjs → scaffold/.agent/skills/total-recall/plugins/automations/cron.mjs} +1 -3
- package/scaffold/.agent/skills/total-recall/plugins/automations/inventory.mjs +88 -0
- package/scaffold/.agent/skills/total-recall/plugins/automations/package-lock.json +7661 -0
- package/scaffold/.agent/skills/total-recall/plugins/automations/package.json +36 -0
- package/scaffold/.agent/skills/total-recall/plugins/automations/plugin.json +151 -0
- package/scaffold/.agent/skills/total-recall/plugins/automations/scheduler.mjs +246 -0
- package/scaffold/.agent/skills/total-recall/plugins/automations/ui/automations.js +2 -0
- 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/home.js +278 -0
- 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 +5 -3
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/core/check.mjs +61 -7
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/core/report-data.mjs +40 -14
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/core/report.mjs +15 -40
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/package-lock.json +7 -7
- 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 +7 -7
- 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 +7 -7
- 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 +136 -0
- package/scaffold/.agent/skills/total-recall/plugins/{git-sentinel → git}/cli.mjs +140 -24
- package/scaffold/.agent/skills/total-recall/plugins/{git-sentinel → git}/package-lock.json +9 -9
- package/scaffold/.agent/skills/total-recall/plugins/{git-sentinel → git}/package.json +4 -2
- package/scaffold/.agent/skills/total-recall/plugins/git/plugin.json +151 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/src/lib/context.mjs +94 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/src/lib/phase3-spec-support.mjs +50 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/src/lib/runtime.mjs +40 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/src/lib/spec-support.mjs +51 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/_support.mjs +195 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/auth.mjs +201 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/bisect.mjs +40 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/cli-meta.mjs +159 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/commit-memory.mjs +54 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/commit.mjs +46 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/fleet.mjs +174 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/force-push.mjs +58 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/group.mjs +119 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/handoff.mjs +59 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/message.mjs +22 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/resolve.mjs +60 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/rules.mjs +81 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/secret-firewall.mjs +92 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/undo.mjs +156 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/unmerged.mjs +182 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/why.mjs +16 -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 +7 -7
- 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 +44 -9
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/capability/BRICK.md +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/capability/index.mjs +18 -6
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/cli.mjs +128 -24
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/package-lock.json +7 -7
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/package.json +3 -2
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/plugin.json +188 -34
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/skills/meta-harness/SKILL.md +17 -3
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/adoption.mjs +2 -2
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/alerts.mjs +3 -3
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/cascade.mjs +92 -18
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/chat.mjs +80 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/control.mjs +145 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/coordinator.mjs +42 -21
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/dispatch-request.mjs +4 -2
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/dispatch.mjs +33 -9
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/documentation.mjs +55 -11
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/executor.mjs +26 -4
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/gate-adapters/hermes.mjs +29 -1
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/gate-adapters/index.mjs +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/included-usage.mjs +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/jobs.mjs +84 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/learner.mjs +3 -12
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/maintenance.mjs +17 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/mcp-server.mjs +228 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/process-manager.mjs +25 -2
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/reasoning.mjs +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/remote-operation.mjs +5 -1
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/review.mjs +34 -3
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/reviews.mjs +25 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/router.mjs +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/session/claude.mjs +319 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/session/codex.mjs +387 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/session/result.mjs +67 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/session/resume.mjs +373 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/session/run.mjs +223 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/session-jobs.mjs +72 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/setup.mjs +6 -3
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/termination.mjs +16 -12
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/threads.mjs +32 -1
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/usage-queue.mjs +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/verify-ssss.mjs +3 -3
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/worker.mjs +285 -40
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/worktree.mjs +76 -9
- 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 +64 -32
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/package-lock.json +7 -7
- 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-diagnostics.mjs +44 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/refresh.mjs +123 -113
- 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 +7 -7
- 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 +3 -1
- package/src/cli/agent.mjs +1 -1
- package/src/cli/api.mjs +3 -3
- package/src/cli/brief.mjs +3 -0
- package/src/cli/command.mjs +41 -2
- package/src/cli/config.mjs +16 -0
- package/src/cli/connect.mjs +2 -7
- package/src/cli/dream.mjs +93 -69
- package/src/cli/harness.mjs +4 -4
- package/src/cli/help.mjs +1 -1
- package/src/cli/init.mjs +0 -25
- package/src/cli/lessons.mjs +51 -0
- package/src/cli/memory-plugin.mjs +1 -1
- package/src/cli/plugin/chunks.mjs +145 -0
- package/src/cli/plugin/copies.mjs +64 -14
- package/src/cli/plugin/create.mjs +30 -59
- package/src/cli/plugin/index.mjs +31 -16
- package/src/cli/plugin/install.mjs +10 -15
- package/src/cli/plugin/remove.mjs +1 -1
- package/src/cli/plugin/search.mjs +2 -2
- package/src/cli/preflight.mjs +19 -6
- package/src/cli/proposals.mjs +1 -1
- package/src/cli/recall.mjs +66 -23
- package/src/cli/remember.mjs +3 -14
- package/src/cli/server.mjs +18 -0
- package/src/cli/setup.mjs +2 -9
- package/src/cli/start.mjs +1 -0
- package/src/cli/startup.mjs +19 -0
- package/src/cli/task.mjs +9 -2
- package/src/cli/update.mjs +6 -2
- package/src/core/access-ledger.mjs +78 -0
- package/src/core/agent-manager.mjs +2 -2
- package/src/core/app-deploy/design-tokens.mjs +14 -9
- package/src/core/app-deploy/ui-elements.mjs +1 -1
- package/src/core/brain-locate.mjs +15 -0
- package/src/core/brain-registry.mjs +5 -0
- package/src/core/brain-updates.mjs +35 -11
- package/src/core/claude-hooks.mjs +3 -1
- package/src/core/cleanup-task.mjs +15 -0
- package/src/core/cli-commands.mjs +2 -0
- package/src/core/cli-maintenance.mjs +4 -1
- package/src/core/cli-semantic-index.mjs +23 -3
- package/src/core/context-compiler.mjs +20 -0
- package/src/core/daemon-control.mjs +5 -1
- package/src/core/daemon-loop.mjs +39 -62
- package/src/core/dashboard-bundle.mjs +261 -0
- package/src/core/default-plugins.mjs +1 -1
- package/src/core/dream.mjs +33 -105
- package/src/core/ensure-dependencies.mjs +152 -0
- package/src/core/fast-recall.mjs +2 -2
- package/src/core/field-evaluation.mjs +23 -0
- package/src/core/gate-mode.mjs +1 -1
- package/src/core/harness-hooks.mjs +14 -2
- package/src/core/lesson-hooks.mjs +74 -0
- package/src/core/lesson-memory.mjs +24 -0
- package/src/core/lesson-sessions.mjs +52 -0
- package/src/core/lessons.mjs +96 -0
- package/src/core/memory-brain.mjs +30 -8
- package/src/core/meta-harness.mjs +2 -2
- package/src/core/optimizer.mjs +66 -165
- package/src/core/plugin-activation.mjs +63 -20
- package/src/core/plugin-contracts/{card.mjs → manifest.mjs} +26 -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 +21 -8
- package/src/core/plugin-runner.mjs +21 -10
- package/src/core/plugin-runtime.mjs +40 -1
- package/src/core/plugin-startup-checks.mjs +44 -0
- package/src/core/plugin-state.mjs +19 -5
- package/src/core/plugin-store.mjs +64 -33
- package/src/core/post-mortem.mjs +52 -36
- package/src/core/preflight-gate.mjs +23 -2
- package/src/core/project-id.mjs +15 -5
- package/src/core/proposal-applier.mjs +31 -2
- package/src/core/repo-sync.mjs +4 -6
- package/src/core/required-plugins.mjs +57 -10
- package/src/core/rule-length.mjs +23 -0
- package/src/core/runtime.mjs +1 -1
- package/src/core/scheduler.mjs +35 -43
- package/src/core/schema.mjs +3 -2
- package/src/core/search.mjs +4 -3
- package/src/core/server-service.mjs +148 -0
- package/src/core/session-watcher.mjs +19 -1
- package/src/core/skill-gap.mjs +16 -0
- package/src/core/ssss-kernel-bridge.mjs +32 -4
- package/src/core/ssss-operation-service.mjs +1 -0
- package/src/core/startup-health.mjs +34 -4
- package/src/core/surface.mjs +65 -54
- package/src/core/task-executors.mjs +54 -106
- 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/validated-write.mjs +1 -0
- package/src/core/vault-cache.mjs +58 -59
- package/src/core/vector-field.mjs +134 -192
- 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/invoke-core-child.mjs +24 -0
- package/src/server/invoke-core-operations.mjs +102 -0
- 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 +47 -55
- package/src/server/routes/_shared.mjs +7 -14
- package/src/server/routes/brains.mjs +29 -62
- package/src/server/routes/context.mjs +0 -41
- package/src/server/routes/dashboard.mjs +26 -0
- package/src/server/routes/invoke.mjs +26 -1
- package/src/server/routes/plugins.mjs +154 -45
- package/src/server/routes/ssss.mjs +0 -169
- package/src/server/routes/system.mjs +0 -15
- package/src/server/routes/tasks.mjs +0 -26
- package/src/server/routes/ui-chunks.mjs +192 -0
- package/src/server/routes/vault.mjs +2 -23
- package/frontend/dist/assets/index-DD4qONvH.js +0 -5607
- 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-sentinel/README.md +0 -53
- package/scaffold/.agent/skills/total-recall/plugins/git-sentinel/plugin.json +0 -129
- package/scaffold/.agent/skills/total-recall/plugins/git-sentinel/ui/DESIGN.md +0 -100
- package/scaffold/.agent/skills/total-recall/plugins/git-sentinel/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
- package/src/core/append-log.mjs +0 -131
- package/src/core/plugin-tasks.mjs +0 -173
- package/templates/onboarding-interview.md +0 -82
- /package/scaffold/.agent/skills/total-recall/plugins/{git-sentinel → git}/LICENSE +0 -0
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
import fs from 'node:fs';
|
|
11
11
|
import path from 'node:path';
|
|
12
12
|
import { createRequire } from 'node:module';
|
|
13
|
-
import { readPluginsDir, globalPluginsDir, PACKAGE_ROOT, resolvePluginFile } from './plugin-loader.mjs';
|
|
13
|
+
import { readPluginsDir, globalPluginsDir, PACKAGE_ROOT, resolvePluginFile, validatePluginManifest } from './plugin-loader.mjs';
|
|
14
14
|
import { DEFAULT_PLUGIN_IDS, REQUIRED_INSTALLATION_PLUGIN_IDS } from './default-plugins.mjs';
|
|
15
15
|
import { comparePackageVersions } from './package-version.mjs';
|
|
16
16
|
import { preparePluginDependencies } from './plugin-dependencies.mjs';
|
|
@@ -113,14 +113,39 @@ export function inspectRequiredPlugins(brainDir, { pluginsDir, sharedBrainDir =
|
|
|
113
113
|
return { status: errors.length ? 'failed' : 'ready', errors, source, installations };
|
|
114
114
|
}
|
|
115
115
|
|
|
116
|
-
|
|
116
|
+
const LEGACY_PRESENTATION_FIELDS = ['card', 'card_face', 'card_layout'];
|
|
117
|
+
|
|
118
|
+
function hasLegacyPresentation(manifest) {
|
|
119
|
+
return LEGACY_PRESENTATION_FIELDS.some(field => Object.hasOwn(manifest, field))
|
|
120
|
+
|| (Array.isArray(manifest.ui?.elements) && manifest.ui.elements.some(element => ['card', 'card-face'].includes(element?.kind)));
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function hasPluginFiles(directory, files) {
|
|
124
|
+
return files.every(file => fs.statSync(resolvePluginFile(directory, file)).isFile());
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function runtimeFiles(manifest) {
|
|
128
|
+
return ['package.json', ...(manifest.cli ? [manifest.cli.handler] : []), ...Object.values(manifest.runtime?.modules || {})];
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/** Refresh older copies and migrate the retired presentation of an otherwise intact same-release copy. */
|
|
117
132
|
function isStaleInstall(target, source) {
|
|
118
133
|
try {
|
|
119
134
|
// A link is its owner's checkout. Replacing it would delete that repository's files, .git included.
|
|
120
135
|
if (fs.lstatSync(target).isSymbolicLink()) return false;
|
|
121
|
-
const installed = JSON.parse(fs.readFileSync(path.join(target, 'plugin.json'), 'utf8'))
|
|
122
|
-
const bundled = JSON.parse(fs.readFileSync(path.join(source, 'plugin.json'), 'utf8'))
|
|
123
|
-
|
|
136
|
+
const installed = JSON.parse(fs.readFileSync(path.join(target, 'plugin.json'), 'utf8'));
|
|
137
|
+
const bundled = JSON.parse(fs.readFileSync(path.join(source, 'plugin.json'), 'utf8'));
|
|
138
|
+
if (comparePackageVersions(installed.version, bundled.version) === -1) return true;
|
|
139
|
+
if (installed.version !== bundled.version || installed.id !== bundled.id || bundled.id !== path.basename(source)
|
|
140
|
+
|| installed.cli?.command !== bundled.cli?.command || !hasLegacyPresentation(installed)
|
|
141
|
+
|| hasLegacyPresentation(bundled) || !bundled.ui?.home || !validatePluginManifest(bundled).valid) return false;
|
|
142
|
+
|
|
143
|
+
const migrated = { ...installed, ui: bundled.ui };
|
|
144
|
+
for (const field of LEGACY_PRESENTATION_FIELDS) delete migrated[field];
|
|
145
|
+
if (!validatePluginManifest(migrated).valid || !hasPluginFiles(target, runtimeFiles(installed))) return false;
|
|
146
|
+
return hasPluginFiles(source, [
|
|
147
|
+
...runtimeFiles(bundled), bundled.ui.design_tokens, ...bundled.ui.elements.map(element => element.module),
|
|
148
|
+
]);
|
|
124
149
|
} catch { return false; }
|
|
125
150
|
}
|
|
126
151
|
|
|
@@ -165,7 +190,7 @@ function installDefaultsInto(brainDir, sourceDir) {
|
|
|
165
190
|
fs.mkdirSync(path.dirname(target), { recursive: true });
|
|
166
191
|
fs.cpSync(source, target, { recursive: true, force: false, errorOnExist: true });
|
|
167
192
|
} else if (isStaleInstall(target, source)) {
|
|
168
|
-
//
|
|
193
|
+
// Keep installed dependencies when refreshing the bundled plugin files.
|
|
169
194
|
for (const entry of fs.readdirSync(target)) if (entry !== 'node_modules') fs.rmSync(path.join(target, entry), { recursive: true, force: true });
|
|
170
195
|
for (const entry of fs.readdirSync(source)) if (entry !== 'node_modules') fs.cpSync(path.join(source, entry), path.join(target, entry), { recursive: true });
|
|
171
196
|
}
|
|
@@ -195,23 +220,45 @@ export function auditProjectPluginCopies(projectRoot, { sharedDir = globalPlugin
|
|
|
195
220
|
return { copies: [], count: 0, sourceDir };
|
|
196
221
|
}
|
|
197
222
|
const copies = [];
|
|
198
|
-
|
|
223
|
+
const realpath = (p) => { try { return fs.realpathSync(p); } catch { return null; } };
|
|
224
|
+
// A link in a repository that resolves to the same plugin as the shared
|
|
225
|
+
// install only shadows it: state and records split between brains and the
|
|
226
|
+
// repository can drift onto another checkout. Defaults never belong to a
|
|
227
|
+
// repository, so any linked default is a shadow too.
|
|
228
|
+
const isShadowLink = (id, copyDir, shared) => {
|
|
229
|
+
if (!fs.lstatSync(copyDir).isSymbolicLink() || !fs.existsSync(shared)) return false;
|
|
230
|
+
return DEFAULT_PLUGIN_IDS.includes(id) || realpath(copyDir) === realpath(shared);
|
|
231
|
+
};
|
|
232
|
+
const entries = fs.readdirSync(pluginsDir).filter((name) => !name.startsWith('.'));
|
|
233
|
+
const ids = [...new Set([...DEFAULT_PLUGIN_IDS, ...entries])];
|
|
234
|
+
for (const id of ids) {
|
|
199
235
|
const copyDir = path.join(pluginsDir, id);
|
|
200
|
-
if (!fs.
|
|
236
|
+
if (!fs.lstatSync(copyDir, { throwIfNoEntry: false })) continue;
|
|
201
237
|
const source = path.join(sourceDir, id);
|
|
202
238
|
const shared = path.join(sharedDir, id);
|
|
239
|
+
const linked = fs.lstatSync(copyDir).isSymbolicLink();
|
|
240
|
+
// The source checkout a shared link points at is not a copy.
|
|
241
|
+
if (!linked && fs.existsSync(shared) && realpath(shared) === realpath(copyDir)) continue;
|
|
242
|
+
const shadow = isShadowLink(id, copyDir, shared);
|
|
243
|
+
// Nothing is installed per repository. A plugin found only here must be
|
|
244
|
+
// installed in the shared folder before its repository entry can go.
|
|
245
|
+
const repoOnly = !fs.existsSync(shared);
|
|
203
246
|
const row = {
|
|
204
247
|
id, dir: copyDir,
|
|
205
248
|
sourceDir: fs.existsSync(source) ? source : null,
|
|
206
249
|
sharedDir: fs.existsSync(shared) ? shared : null,
|
|
207
250
|
edited: null, version: null, sourceVersion: null, sharedVersion: null,
|
|
208
|
-
linked
|
|
251
|
+
linked,
|
|
252
|
+
shadow,
|
|
253
|
+
repoOnly,
|
|
254
|
+
target: fs.lstatSync(copyDir).isSymbolicLink() ? fs.readlinkSync(copyDir) : null,
|
|
209
255
|
};
|
|
210
256
|
const version = (dir) => { try { return JSON.parse(fs.readFileSync(path.join(dir, 'plugin.json'), 'utf8')).version; } catch { return null; } };
|
|
211
257
|
row.version = version(copyDir);
|
|
212
258
|
row.sourceVersion = row.sourceDir ? version(row.sourceDir) : null;
|
|
213
259
|
row.sharedVersion = row.sharedDir ? version(row.sharedDir) : null;
|
|
214
|
-
|
|
260
|
+
// A link is owned by its target checkout, so its tree is never "edited" here; a dangling link has no tree.
|
|
261
|
+
row.edited = row.linked || !fs.existsSync(copyDir) ? null : row.sourceDir ? !sameTree(copyDir, row.sourceDir) : null;
|
|
215
262
|
// Older copies shadow the shared install. Version skew identifies stale
|
|
216
263
|
// candidates for archival but does not prove the local source is disposable.
|
|
217
264
|
row.stale = Boolean(row.version && row.sharedVersion && comparePackageVersions(row.version, row.sharedVersion) < 0);
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/** Shared rule policy. Diagnostics contain counts and limits, never rule text. */
|
|
2
|
+
export const RULE_SOFT_LIMIT = 300;
|
|
3
|
+
export const RULE_HARD_LIMIT = 800;
|
|
4
|
+
let rejections = 0;
|
|
5
|
+
|
|
6
|
+
export function ruleLengthStats() {
|
|
7
|
+
return { rejections, scope: 'process' };
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function checkRuleLength(data, body, { allowLong = false } = {}) {
|
|
11
|
+
const errors = [], warnings = [];
|
|
12
|
+
const rule = data.type === 'rule' || (data.type === 'memory' &&
|
|
13
|
+
['invariants', 'preferences', 'anti-patterns'].includes(data.category));
|
|
14
|
+
if (!rule || data.tags?.includes('context:policy')) return { errors, warnings };
|
|
15
|
+
const length = String(body || '').trim().length;
|
|
16
|
+
if (length > RULE_HARD_LIMIT && allowLong !== true) {
|
|
17
|
+
rejections++;
|
|
18
|
+
errors.push(`Rule is ${length} characters (limit ${RULE_HARD_LIMIT}). Shorten the rule. Save history and examples as a fact, or use the explicit allow-long exception.`);
|
|
19
|
+
} else if (length > RULE_SOFT_LIMIT) {
|
|
20
|
+
warnings.push(`Rule is ${length} characters. Keep rules brief (under ${RULE_SOFT_LIMIT} characters). Save history and examples as a fact.`);
|
|
21
|
+
}
|
|
22
|
+
return { errors, warnings };
|
|
23
|
+
}
|
package/src/core/runtime.mjs
CHANGED
|
@@ -11,7 +11,7 @@ let configOwner, configError;
|
|
|
11
11
|
try { configOwner = await loadPluginModule('meta-harness', 'reasoning-runtime'); }
|
|
12
12
|
catch (error) { configError = error; }
|
|
13
13
|
function reasoningConfigOwner() {
|
|
14
|
-
if (!configOwner) throw new Error(`
|
|
14
|
+
if (!configOwner) throw new Error(`Metaharness reasoning is unavailable: ${configError?.message || 'install the plugin'}`);
|
|
15
15
|
return configOwner;
|
|
16
16
|
}
|
|
17
17
|
|
package/src/core/scheduler.mjs
CHANGED
|
@@ -7,14 +7,13 @@ import config from './config.mjs';
|
|
|
7
7
|
import { getNodes } from './vault-cache.mjs';
|
|
8
8
|
import { logger } from './logger.mjs';
|
|
9
9
|
import { loadQueue, updateQueueItem } from './research-queue.mjs';
|
|
10
|
-
import { transitionTaskStatus } from './task-envelope.mjs';
|
|
10
|
+
import { transitionTaskStatus, getTask } from './task-envelope.mjs';
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* Total Recall Task Scheduler
|
|
14
14
|
*
|
|
15
15
|
* A priority queue that dispatches tasks to cognitive layer engines.
|
|
16
|
-
*
|
|
17
|
-
* auto-generates idle improvement tasks from vault analysis.
|
|
16
|
+
* An empty queue stays empty. Automations schedules maintenance explicitly.
|
|
18
17
|
*
|
|
19
18
|
* Task categories map to cognitive layers:
|
|
20
19
|
* conscious-enforcement → Conscious Layer (weight 1.0)
|
|
@@ -34,7 +33,6 @@ export const LAYER_WEIGHTS = Object.freeze({
|
|
|
34
33
|
'skill-engineering': 0.5,
|
|
35
34
|
'proactive-research': 0.4,
|
|
36
35
|
'self-evaluation': 0.3,
|
|
37
|
-
'exploration': 0.2,
|
|
38
36
|
});
|
|
39
37
|
|
|
40
38
|
// ─── Priority Queue ─────────────────────────────────────────────────────────────
|
|
@@ -198,9 +196,8 @@ const RESEARCH_PHASE_COUNT = Object.keys(RESEARCH_PHASES).length;
|
|
|
198
196
|
let _idleCycleCounter = 0;
|
|
199
197
|
|
|
200
198
|
/**
|
|
201
|
-
* Generate
|
|
202
|
-
* Purely local maintenance
|
|
203
|
-
* review, memory compaction. Idle ticks never research on their own; research
|
|
199
|
+
* Generate a maintenance candidate for an explicit scheduled run.
|
|
200
|
+
* Purely local maintenance: inference, clarity review and compaction. Research
|
|
204
201
|
* only runs for topics a human asked for or the project gate approved.
|
|
205
202
|
*/
|
|
206
203
|
export function generateIdleTask({ vaultDir, sessionsDir }) {
|
|
@@ -208,7 +205,6 @@ export function generateIdleTask({ vaultDir, sessionsDir }) {
|
|
|
208
205
|
// Absolutely no automated/proactive web searches or staleness checks that make internet queries.
|
|
209
206
|
const cleanStrategies = [
|
|
210
207
|
() => generateInferenceTask(vaultDir),
|
|
211
|
-
() => generatePostMortemTask(sessionsDir),
|
|
212
208
|
() => generateClarityReviewTask(vaultDir),
|
|
213
209
|
() => generateMemoryCompactionTask(vaultDir),
|
|
214
210
|
];
|
|
@@ -224,6 +220,26 @@ export function generateIdleTask({ vaultDir, sessionsDir }) {
|
|
|
224
220
|
}
|
|
225
221
|
}
|
|
226
222
|
|
|
223
|
+
/** Called by an automations manifest task, never by queue exhaustion. */
|
|
224
|
+
export async function enqueueScheduledIdleTasks({ vaultDir, queueDir, now = new Date(),
|
|
225
|
+
leader = async () => (await import('./leader-election.mjs')).isLeader() } = {}) {
|
|
226
|
+
if (!await leader()) return { enqueued: [], skipped: 'not-leader' };
|
|
227
|
+
const tasks = [generateInferenceTask(vaultDir), generateClarityReviewTask(vaultDir), generateMemoryCompactionTask(vaultDir)];
|
|
228
|
+
const enqueued = [];
|
|
229
|
+
for (const task of tasks) {
|
|
230
|
+
if (task.slug.startsWith('idle-')) continue;
|
|
231
|
+
const kind = task.slug.startsWith('inference-') ? 'inference' : task.slug.startsWith('clarity-') ? 'clarity-review' : 'memory-compaction';
|
|
232
|
+
const identity = crypto.createHash('sha256').update(String(task.target)).digest('hex').slice(0, 12);
|
|
233
|
+
task.slug = `${kind}-${now.toISOString().slice(0, 10)}-${identity}`;
|
|
234
|
+
if (getTask(queueDir, task.slug) || fs.existsSync(path.join(queueDir, 'archive', `${task.slug}.md`))) continue;
|
|
235
|
+
task.created_by = 'automations';
|
|
236
|
+
task.payload = { scheduledIdle: true };
|
|
237
|
+
persistTaskToDisk(task, queueDir);
|
|
238
|
+
enqueued.push(task.slug);
|
|
239
|
+
}
|
|
240
|
+
return { enqueued };
|
|
241
|
+
}
|
|
242
|
+
|
|
227
243
|
/**
|
|
228
244
|
* Pick a random active memory node and create a clarity review task.
|
|
229
245
|
*/
|
|
@@ -259,7 +275,7 @@ function generateMemoryCompactionTask(vaultDir) {
|
|
|
259
275
|
status: 'pending',
|
|
260
276
|
created_by: 'scheduler-idle',
|
|
261
277
|
reason: `Idle task: scan vault for fragmented nodes to merge into comprehensive master documents.`,
|
|
262
|
-
body: `
|
|
278
|
+
body: `File memory-cleanup proposals for overlapping memory nodes. Keep canonical nodes unchanged until proposal review.`,
|
|
263
279
|
};
|
|
264
280
|
}
|
|
265
281
|
|
|
@@ -344,23 +360,6 @@ function generatePostMortemTask(sessionsDir) {
|
|
|
344
360
|
};
|
|
345
361
|
}
|
|
346
362
|
|
|
347
|
-
/**
|
|
348
|
-
* Generate a cutoff audit task — scans vault for nodes with intrinsic LLM
|
|
349
|
-
* knowledge that may have drifted since the model's training cutoff.
|
|
350
|
-
*/
|
|
351
|
-
function generateCutoffAuditTask() {
|
|
352
|
-
return {
|
|
353
|
-
type: 'task',
|
|
354
|
-
slug: `cutoff-audit-${Date.now().toString(36)}`,
|
|
355
|
-
priority: 60,
|
|
356
|
-
category: 'cutoff-audit',
|
|
357
|
-
status: 'pending',
|
|
358
|
-
created_by: 'scheduler-idle',
|
|
359
|
-
reason: 'Idle task: scan vault for training-cutoff assumption drift',
|
|
360
|
-
body: 'Identify memory nodes containing time-sensitive claims based on intrinsic LLM knowledge. Flag high-drift items (API versions, pricing, model specs, framework changes) for verification against current real-world sources.',
|
|
361
|
-
};
|
|
362
|
-
}
|
|
363
|
-
|
|
364
363
|
function makeFallbackTask(category, reason) {
|
|
365
364
|
return {
|
|
366
365
|
type: 'task',
|
|
@@ -385,7 +384,7 @@ function makeFallbackTask(category, reason) {
|
|
|
385
384
|
* @param {string} opts.sessionsDir Path to .agent/skills/total-recall/sessions/
|
|
386
385
|
* @returns {{ queue: TaskQueue, stats: object }}
|
|
387
386
|
*/
|
|
388
|
-
export function createScheduler({ queueDir, vaultDir, sessionsDir }) {
|
|
387
|
+
export function createScheduler({ queueDir, vaultDir, sessionsDir, localOnly = false }) {
|
|
389
388
|
const queue = new TaskQueue();
|
|
390
389
|
|
|
391
390
|
// Load explicit tasks from disk
|
|
@@ -397,7 +396,7 @@ export function createScheduler({ queueDir, vaultDir, sessionsDir }) {
|
|
|
397
396
|
// Optional remote vault sync job (env-configured only)
|
|
398
397
|
try {
|
|
399
398
|
const { remoteVaultSync } = config;
|
|
400
|
-
if (remoteVaultSync.enabled) {
|
|
399
|
+
if (!localOnly && remoteVaultSync.enabled) {
|
|
401
400
|
const statusFile = path.join(path.dirname(remoteVaultSync.vaultDir), 'sync-status.json');
|
|
402
401
|
let lastRunMs = 0;
|
|
403
402
|
if (fs.existsSync(statusFile)) {
|
|
@@ -442,7 +441,7 @@ export function createScheduler({ queueDir, vaultDir, sessionsDir }) {
|
|
|
442
441
|
: 60 * 60 * 1000; // 1 hour default
|
|
443
442
|
|
|
444
443
|
let resetCount = 0;
|
|
445
|
-
for (const item of loadQueue()) {
|
|
444
|
+
for (const item of localOnly ? [] : loadQueue()) {
|
|
446
445
|
if (item.status !== 'failed') continue;
|
|
447
446
|
if ((item.attempts || 0) >= MAX_RESEARCH_ATTEMPTS) continue;
|
|
448
447
|
const failedAt = new Date(item.updated_at || item.created_at || 0).getTime();
|
|
@@ -469,7 +468,7 @@ export function createScheduler({ queueDir, vaultDir, sessionsDir }) {
|
|
|
469
468
|
}
|
|
470
469
|
|
|
471
470
|
// User requests run before autonomous background research; oldest first within each.
|
|
472
|
-
const researchItems = loadQueue()
|
|
471
|
+
const researchItems = (localOnly ? [] : loadQueue())
|
|
473
472
|
.filter((i) => i.status === 'pending' && RESEARCH_PHASES[i.research_phase || 'acquisition'])
|
|
474
473
|
.sort((a, b) => {
|
|
475
474
|
const ua = a.origin === 'autonomous' ? 1 : 0;
|
|
@@ -532,27 +531,20 @@ export function createScheduler({ queueDir, vaultDir, sessionsDir }) {
|
|
|
532
531
|
* Get the next task.
|
|
533
532
|
*
|
|
534
533
|
* Default: only explicit (and research-queue) tasks — never invent work.
|
|
535
|
-
*
|
|
534
|
+
* Automations is the only recurring maintenance trigger.
|
|
536
535
|
*
|
|
537
536
|
* @param {{ allowIdle?: boolean }} [opts]
|
|
538
537
|
* @returns {{ task: object|null, source: 'explicit'|'idle'|'empty' }}
|
|
539
538
|
*/
|
|
540
539
|
next(opts = {}) {
|
|
540
|
+
if (opts.localOnly) {
|
|
541
|
+
const local = queue._items.findIndex(({ task }) => ['lesson-review', 'skill-manager'].includes(task.executor) || ['lesson-review', 'self-evaluation', 'skill-engineering'].includes(task.category));
|
|
542
|
+
return local < 0 ? { task: null, source: 'empty' } : { task: queue._items.splice(local, 1)[0].task, source: 'explicit' };
|
|
543
|
+
}
|
|
541
544
|
const explicit = queue.dequeue();
|
|
542
545
|
if (explicit) return { task: explicit, source: 'explicit' };
|
|
543
546
|
|
|
544
|
-
|
|
545
|
-
opts.allowIdle === true ||
|
|
546
|
-
process.env.TR_IDLE_TASKS === '1' ||
|
|
547
|
-
process.env.TR_IDLE_TASKS === 'true';
|
|
548
|
-
|
|
549
|
-
if (!allowIdle) {
|
|
550
|
-
return { task: null, source: 'empty' };
|
|
551
|
-
}
|
|
552
|
-
|
|
553
|
-
const idle = generateIdleTask({ vaultDir, sessionsDir });
|
|
554
|
-
persistTaskToDisk(idle, queueDir);
|
|
555
|
-
return { task: idle, source: 'idle' };
|
|
547
|
+
return { task: null, source: 'empty' };
|
|
556
548
|
},
|
|
557
549
|
};
|
|
558
550
|
}
|
package/src/core/schema.mjs
CHANGED
|
@@ -41,8 +41,7 @@ export const TaskSchema = z.object({
|
|
|
41
41
|
'system2-deliberation',
|
|
42
42
|
'skill-engineering',
|
|
43
43
|
'proactive-research',
|
|
44
|
-
'self-evaluation'
|
|
45
|
-
'exploration'
|
|
44
|
+
'self-evaluation'
|
|
46
45
|
]),
|
|
47
46
|
status: z.enum(['pending', 'in_progress', 'done', 'failed']),
|
|
48
47
|
target: z.string().optional(),
|
|
@@ -1035,6 +1034,8 @@ export const PluginRecordSchema = z.object({
|
|
|
1035
1034
|
task_runs: z.record(z.string()).optional(),
|
|
1036
1035
|
/** Explicit mesh node for commands with selected-node placement. */
|
|
1037
1036
|
task_nodes: z.record(z.string().min(1)).optional(),
|
|
1037
|
+
runtime_enabled: z.boolean().optional(),
|
|
1038
|
+
runtime_on_use: z.boolean().optional(),
|
|
1038
1039
|
}).passthrough();
|
|
1039
1040
|
|
|
1040
1041
|
const SECRET_KEY_PATTERN = /^(.*_)?(secret|token|password|api[_-]?key|private[_-]?key|credentials|auth[_-]?header|bearer)$/i;
|
package/src/core/search.mjs
CHANGED
|
@@ -98,7 +98,8 @@ export async function semanticSearch(query, {
|
|
|
98
98
|
tags = null,
|
|
99
99
|
modality = null,
|
|
100
100
|
importance = null,
|
|
101
|
-
priority = null
|
|
101
|
+
priority = null,
|
|
102
|
+
rankResults = null
|
|
102
103
|
} = {}) {
|
|
103
104
|
const k = Math.min(Number(top_k) || 5, 20);
|
|
104
105
|
|
|
@@ -234,7 +235,7 @@ export async function semanticSearch(query, {
|
|
|
234
235
|
}
|
|
235
236
|
|
|
236
237
|
// Slice top results
|
|
237
|
-
for (const { node, score } of blendedRanked.slice(0, k)) {
|
|
238
|
+
for (const { node, score } of blendedRanked.slice(0, rankResults ? undefined : k)) {
|
|
238
239
|
if (node) {
|
|
239
240
|
const similarity = similarityBySlug.get(node.slug);
|
|
240
241
|
results.push({
|
|
@@ -297,7 +298,7 @@ export async function semanticSearch(query, {
|
|
|
297
298
|
}
|
|
298
299
|
|
|
299
300
|
results.sort((a, b) => b.score - a.score);
|
|
300
|
-
const finalResults = results.slice(0, k);
|
|
301
|
+
const finalResults = (rankResults ? rankResults(results) : results).slice(0, k);
|
|
301
302
|
if (!queryEmbedding || vaultEntries.length === 0) {
|
|
302
303
|
finalResults.degradedTextSearch = true;
|
|
303
304
|
// Say WHICH failure this is. The caller renders remediation from it, and
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/** Repair this installation's macOS server LaunchAgent. Never manages systemd. */
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import os from 'node:os';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
6
|
+
import { spawnSync } from 'node:child_process';
|
|
7
|
+
import { processIdentity } from './startup-health.mjs';
|
|
8
|
+
|
|
9
|
+
const PACKAGE_ROOT = fileURLToPath(new URL('../..', import.meta.url));
|
|
10
|
+
const LABEL = 'com.totalrecall.server';
|
|
11
|
+
const corePathEnv = new Set(['AGENT_DIR', 'TR_SECRETS_BRAIN', 'TR_SERVER_PID_FILE']);
|
|
12
|
+
const inside = (root, value) => value === root || value.startsWith(root + path.sep);
|
|
13
|
+
const real = value => { try { return fs.realpathSync(value); } catch { return path.resolve(value); } };
|
|
14
|
+
|
|
15
|
+
export function stableNodePath(env = process.env) {
|
|
16
|
+
for (const dir of (env.PATH || '').split(path.delimiter)) {
|
|
17
|
+
if (!dir || !path.isAbsolute(dir)) continue;
|
|
18
|
+
const candidate = path.join(dir, 'node');
|
|
19
|
+
if (candidate.split(path.sep).includes('Cellar')) continue;
|
|
20
|
+
try { fs.accessSync(candidate, fs.constants.X_OK); if (fs.statSync(candidate).isFile()) return candidate; } catch {}
|
|
21
|
+
}
|
|
22
|
+
throw new Error('No stable node executable on PATH. Add the node symlink directory to PATH.');
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function convert(input, format, exec) {
|
|
26
|
+
const result = exec('plutil', ['-convert', format, '-o', '-', '-'], { input, encoding: 'utf8', timeout: 5000 });
|
|
27
|
+
if (result.status !== 0 || result.error) throw new Error(`Cannot convert server plist to ${format}.`);
|
|
28
|
+
return result.stdout;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** Detect foreign installations without naming any operator repository. */
|
|
32
|
+
function checkoutFor(value, oldRoot, packageRoot) {
|
|
33
|
+
if (inside(packageRoot, value) || inside(real(packageRoot), value)) return null;
|
|
34
|
+
if (oldRoot && real(oldRoot) !== real(packageRoot) && inside(oldRoot, value)) return oldRoot;
|
|
35
|
+
for (let dir = value; ; dir = path.dirname(dir)) {
|
|
36
|
+
try {
|
|
37
|
+
if (JSON.parse(fs.readFileSync(path.join(dir, 'package.json'), 'utf8')).name === 'total-recall-brain'
|
|
38
|
+
&& real(dir) !== real(packageRoot)) return dir;
|
|
39
|
+
} catch {}
|
|
40
|
+
if (dir === path.dirname(dir)) return null;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function serverEnvironment(existing, { packageRoot, oldRoot }) {
|
|
45
|
+
const env = {};
|
|
46
|
+
for (const [key, value] of Object.entries(existing || {})) {
|
|
47
|
+
if (typeof value !== 'string') throw new Error(`Server environment ${key} must be a string.`);
|
|
48
|
+
if (key === 'PATH') {
|
|
49
|
+
env[key] = value.split(path.delimiter).map(part => {
|
|
50
|
+
const foreign = path.isAbsolute(part) && checkoutFor(part, oldRoot, packageRoot);
|
|
51
|
+
return foreign ? path.join(packageRoot, path.relative(foreign, part)) : part;
|
|
52
|
+
}).join(path.delimiter);
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
const foreign = path.isAbsolute(value) && checkoutFor(value, oldRoot, packageRoot);
|
|
56
|
+
if (!foreign) env[key] = value;
|
|
57
|
+
else if (corePathEnv.has(key)) env[key] = path.join(packageRoot, path.relative(foreign, value));
|
|
58
|
+
// Obsolete settings must not retain a path into another installation.
|
|
59
|
+
}
|
|
60
|
+
return env;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function publicPlist(plist) {
|
|
64
|
+
const copy = structuredClone(plist);
|
|
65
|
+
for (const key of Object.keys(copy.EnvironmentVariables || {})) {
|
|
66
|
+
if (/password|secret(?!s_brain)|token|api.?key|credential/i.test(key)) copy.EnvironmentVariables[key] = '[redacted]';
|
|
67
|
+
}
|
|
68
|
+
return copy;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function plistDiff(before, after) {
|
|
72
|
+
const lines = [];
|
|
73
|
+
const walk = (a, b, key) => {
|
|
74
|
+
if (JSON.stringify(a) === JSON.stringify(b)) return;
|
|
75
|
+
if (a && b && !Array.isArray(a) && !Array.isArray(b) && typeof a === 'object' && typeof b === 'object') {
|
|
76
|
+
for (const part of new Set([...Object.keys(a), ...Object.keys(b)])) walk(a[part], b[part], key ? `${key}.${part}` : part);
|
|
77
|
+
} else {
|
|
78
|
+
if (a !== undefined) lines.push(`- ${key}: ${JSON.stringify(a)}`);
|
|
79
|
+
if (b !== undefined) lines.push(`+ ${key}: ${JSON.stringify(b)}`);
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
walk(publicPlist(before), publicPlist(after), '');
|
|
83
|
+
return lines.join('\n') || 'No plist changes.';
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export async function ensureServerService({ dryRun = false, platform = process.platform, home = os.homedir(),
|
|
87
|
+
packageRoot = PACKAGE_ROOT, env = process.env, exec = spawnSync, identity = processIdentity,
|
|
88
|
+
uid = process.getuid?.(), sleep = ms => new Promise(resolve => setTimeout(resolve, ms)), attempts = 40 } = {}) {
|
|
89
|
+
if (platform !== 'darwin') return { status: 'unchanged', reason: 'server-release owns the server on systemd hosts; no changes made.' };
|
|
90
|
+
packageRoot = path.resolve(packageRoot);
|
|
91
|
+
const plistPath = path.join(home, 'Library/LaunchAgents', `${LABEL}.plist`);
|
|
92
|
+
const oldBytes = fs.existsSync(plistPath) ? fs.readFileSync(plistPath) : null;
|
|
93
|
+
const existing = oldBytes ? JSON.parse(convert(oldBytes, 'json', exec)) : {};
|
|
94
|
+
const template = fs.readFileSync(path.join(packageRoot, 'templates', `${LABEL}.plist`), 'utf8');
|
|
95
|
+
const desired = JSON.parse(convert(template, 'json', exec));
|
|
96
|
+
const substitute = value => typeof value === 'string' ? value.replaceAll('__ROOT__', packageRoot).replaceAll('__HOME__', home)
|
|
97
|
+
: Array.isArray(value) ? value.map(substitute) : value && typeof value === 'object'
|
|
98
|
+
? Object.fromEntries(Object.entries(value).map(([key, val]) => [key, substitute(val)])) : value;
|
|
99
|
+
const plist = substitute(desired);
|
|
100
|
+
plist.WorkingDirectory = packageRoot;
|
|
101
|
+
plist.ProgramArguments[0] = stableNodePath(env);
|
|
102
|
+
plist.EnvironmentVariables = { ...plist.EnvironmentVariables,
|
|
103
|
+
...serverEnvironment(existing.EnvironmentVariables, { packageRoot, oldRoot: existing.WorkingDirectory }) };
|
|
104
|
+
const diff = plistDiff(existing, plist);
|
|
105
|
+
if (dryRun) return { status: 'dry_run', plistPath, diff };
|
|
106
|
+
|
|
107
|
+
const xml = convert(JSON.stringify(plist), 'xml1', exec);
|
|
108
|
+
const domain = `gui/${uid}`;
|
|
109
|
+
const service = `${domain}/${LABEL}`;
|
|
110
|
+
const run = args => exec('launchctl', args, { encoding: 'utf8', timeout: 10000 });
|
|
111
|
+
const ok = result => result.status === 0 && !result.error;
|
|
112
|
+
const must = args => { if (!ok(run(args))) throw new Error(`launchctl ${args[0]} failed for ${service}.`); };
|
|
113
|
+
const agentDir = plist.EnvironmentVariables.AGENT_DIR || path.join(home, '.agent');
|
|
114
|
+
const pidFile = plist.EnvironmentVariables.TR_SERVER_PID_FILE || path.join(agentDir, 'skills/total-recall/server.pid');
|
|
115
|
+
const entry = path.join(packageRoot, 'src/server/index.mjs');
|
|
116
|
+
const previous = identity(pidFile, entry);
|
|
117
|
+
if (previous.status === 'unknown') throw new Error('Server process identity is unknown. Nothing changed.');
|
|
118
|
+
const loaded = ok(run(['print', service]));
|
|
119
|
+
if (!loaded && ['running', 'conflict'].includes(previous.status)) throw new Error('A server runs outside this LaunchAgent. Nothing changed.');
|
|
120
|
+
fs.mkdirSync(path.dirname(plistPath), { recursive: true });
|
|
121
|
+
for (const log of [plist.StandardOutPath, plist.StandardErrorPath]) if (log) fs.mkdirSync(path.dirname(log), { recursive: true });
|
|
122
|
+
const pending = `${plistPath}.${process.pid}.tmp`;
|
|
123
|
+
try {
|
|
124
|
+
fs.writeFileSync(pending, xml, { mode: 0o600 });
|
|
125
|
+
fs.renameSync(pending, plistPath);
|
|
126
|
+
if (loaded) {
|
|
127
|
+
must(['bootout', service]);
|
|
128
|
+
let retired = false;
|
|
129
|
+
for (let i = 0; i < attempts; i++) {
|
|
130
|
+
if (!ok(run(['print', service]))) { retired = true; break; }
|
|
131
|
+
await sleep(250);
|
|
132
|
+
}
|
|
133
|
+
if (!retired) throw new Error('LaunchAgent did not retire.');
|
|
134
|
+
}
|
|
135
|
+
must(['bootstrap', domain, plistPath]);
|
|
136
|
+
for (let i = 0; i < attempts; i++) {
|
|
137
|
+
const observed = identity(pidFile, entry);
|
|
138
|
+
if (observed.status === 'running' && (!loaded || observed.pid !== previous.pid)) return { status: 'ready', plistPath, pid: observed.pid, entry: observed.entry };
|
|
139
|
+
await sleep(250);
|
|
140
|
+
}
|
|
141
|
+
throw new Error('Server process verification failed after launchd reload.');
|
|
142
|
+
} catch (error) {
|
|
143
|
+
// Keep the previous definition available for operator recovery. Never report success.
|
|
144
|
+
if (oldBytes !== null) fs.writeFileSync(plistPath, oldBytes, { mode: 0o600 });
|
|
145
|
+
else fs.rmSync(plistPath, { force: true });
|
|
146
|
+
throw error;
|
|
147
|
+
} finally { fs.rmSync(pending, { force: true }); }
|
|
148
|
+
}
|
|
@@ -4,6 +4,7 @@ import os from 'os';
|
|
|
4
4
|
import crypto from 'crypto';
|
|
5
5
|
import { atomicWrite } from './vault.mjs';
|
|
6
6
|
import { logger } from './logger.mjs';
|
|
7
|
+
import { readLessonEntries } from './lesson-sessions.mjs';
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* Total Recall Session Watcher
|
|
@@ -30,6 +31,12 @@ const HOME = os.homedir();
|
|
|
30
31
|
* of unified SSSS session entries.
|
|
31
32
|
*/
|
|
32
33
|
const SOURCES = [
|
|
34
|
+
{
|
|
35
|
+
name: 'openclaw',
|
|
36
|
+
root: path.join(HOME, '.openclaw', 'agents'),
|
|
37
|
+
filter: filename => filename.endsWith('.jsonl'),
|
|
38
|
+
adapter: file => parseClaudeCode(file).map(entry => ({ ...entry, source: 'openclaw' })),
|
|
39
|
+
},
|
|
33
40
|
{
|
|
34
41
|
name: 'claude-code',
|
|
35
42
|
root: path.join(HOME, '.claude', 'projects'),
|
|
@@ -248,6 +255,15 @@ export function parseClaudeCode(filePath) {
|
|
|
248
255
|
*/
|
|
249
256
|
export function parseCodex(filePath) {
|
|
250
257
|
const raw = fs.readFileSync(filePath, 'utf8');
|
|
258
|
+
if (/"type"\s*:\s*"(?:response_item|event_msg)"/.test(raw)) {
|
|
259
|
+
let parentId = null;
|
|
260
|
+
return readLessonEntries(filePath).map(message => {
|
|
261
|
+
const entry = createSessionEntry({ ...message, parentId, source: 'codex',
|
|
262
|
+
type: message.role === 'user' ? 'task' : message.role === 'tool' ? 'tool_call' : 'observation' });
|
|
263
|
+
parentId = entry.id;
|
|
264
|
+
return entry;
|
|
265
|
+
});
|
|
266
|
+
}
|
|
251
267
|
const lines = raw.split('\n').filter(Boolean);
|
|
252
268
|
const entries = [];
|
|
253
269
|
let prevId = null;
|
|
@@ -661,7 +677,9 @@ export function writeSession(entries, sessionsDir, sourceFile) {
|
|
|
661
677
|
// Skip if already ingested and unchanged
|
|
662
678
|
if (fs.existsSync(sessionFile)) {
|
|
663
679
|
try {
|
|
664
|
-
|
|
680
|
+
const previous = fs.readFileSync(sessionFile, 'utf8');
|
|
681
|
+
const semantic = rows => JSON.stringify(rows.map(({ role, type, content, source, cwd }) => ({ role, type, content, source, cwd })));
|
|
682
|
+
if (previous === jsonl || semantic(previous.trim().split('\n').filter(Boolean).map(line => JSON.parse(line))) === semantic(entries)) {
|
|
665
683
|
return null;
|
|
666
684
|
}
|
|
667
685
|
} catch { /* ignore */ }
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { discoverPlugins } from './plugin-loader.mjs';
|
|
2
|
+
import { runPluginCommand } from './plugin-runner.mjs';
|
|
3
|
+
|
|
4
|
+
/** Skill engineering belongs to skill-manager. Missing operations fail closed. */
|
|
5
|
+
export async function requestSkillGap(topic, evidence, { projectRoot = process.cwd(), discover = discoverPlugins, run = runPluginCommand } = {}) {
|
|
6
|
+
if (typeof topic !== 'string' || !topic.trim() || typeof evidence !== 'string' || !evidence.trim()) {
|
|
7
|
+
throw new Error('Skill gap requires a topic and an evidence reference');
|
|
8
|
+
}
|
|
9
|
+
const plugin = discover(projectRoot).find(item => item.id === 'skill-manager' && item.valid);
|
|
10
|
+
if (!plugin?.manifest.cli?.subcommands?.some(item => item.name === 'gap')) {
|
|
11
|
+
throw new Error('Skill-manager gap is unavailable. Install an owner version that provides: total-recall skill-manager gap "<topic>" --evidence <ref>');
|
|
12
|
+
}
|
|
13
|
+
const result = await run(plugin, { subcommand: 'gap', args: [topic.trim(), '--evidence', evidence], cwd: projectRoot });
|
|
14
|
+
if (!result.ok || result.truncated) throw new Error(`Skill-manager gap failed: ${result.stderr || result.output || result.exitCode}`);
|
|
15
|
+
return { success: true, output: result.stdout || result.output, executor: 'skill-manager' };
|
|
16
|
+
}
|
|
@@ -12,7 +12,8 @@ import fs from 'node:fs';
|
|
|
12
12
|
import path from 'node:path';
|
|
13
13
|
import crypto from 'node:crypto';
|
|
14
14
|
import matter from './frontmatter.mjs';
|
|
15
|
-
import {
|
|
15
|
+
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
16
|
+
import { createEngine, resolveContainedPath } from '@ssss/cli/engine';
|
|
16
17
|
import { createValidator } from '@ssss/cli/validator';
|
|
17
18
|
import {
|
|
18
19
|
composeRegistryLayers,
|
|
@@ -20,6 +21,7 @@ import {
|
|
|
20
21
|
resolvePrimitiveDefinition,
|
|
21
22
|
} from '@ssss/cli/registry';
|
|
22
23
|
import { detectDirectWrites } from '@ssss/cli/guard';
|
|
24
|
+
import { checkRuleLength } from './rule-length.mjs';
|
|
23
25
|
import { validateMemoryNode } from './total-recall-memory-validator.mjs';
|
|
24
26
|
import {
|
|
25
27
|
TOTAL_RECALL_HOST_EXTENSION,
|
|
@@ -66,6 +68,7 @@ const DIRECT_WRITE_APPROVED = [
|
|
|
66
68
|
|
|
67
69
|
let cachedEngine = null;
|
|
68
70
|
let cachedRegistryKey = '';
|
|
71
|
+
const writePolicy = new AsyncLocalStorage();
|
|
69
72
|
|
|
70
73
|
export function getKernelMode() {
|
|
71
74
|
// Default to package-kernel cutover for core types (memory/workflow/low-risk).
|
|
@@ -187,7 +190,27 @@ export function getTotalRecallEngine(options = {}) {
|
|
|
187
190
|
const registrySet = createTotalRecallRegistrySet(options);
|
|
188
191
|
const key = `${[...registrySet.types.keys()].sort().join(',')}|${options.leaseStore || ''}`;
|
|
189
192
|
if (!cachedEngine || cachedRegistryKey !== key || options.forceNew) {
|
|
190
|
-
const
|
|
193
|
+
const baseValidator = createValidator({ registrySet });
|
|
194
|
+
const validator = {
|
|
195
|
+
...baseValidator,
|
|
196
|
+
validateData(data, callOptions) {
|
|
197
|
+
const result = baseValidator.validateData(data, callOptions);
|
|
198
|
+
const context = writePolicy.getStore();
|
|
199
|
+
if (context?.envelope.type !== 'patch') return result;
|
|
200
|
+
// The kernel calls validateData with the merged frontmatter. Check the
|
|
201
|
+
// replacement body against that category and those exception tags.
|
|
202
|
+
// A metadata-only patch keeps the current document body.
|
|
203
|
+
const { envelope, vaultRoot, options } = context;
|
|
204
|
+
const body = envelope.patches.__body__ === undefined
|
|
205
|
+
? matter(fs.readFileSync(resolveContainedPath(vaultRoot, envelope.path), 'utf8')).content
|
|
206
|
+
: String(envelope.patches.__body__);
|
|
207
|
+
const policy = checkRuleLength(data, body, options);
|
|
208
|
+
context.warnings.push(...policy.warnings);
|
|
209
|
+
return { ...result, valid: result.valid && !policy.errors.length,
|
|
210
|
+
errors: [...result.errors, ...policy.errors],
|
|
211
|
+
field_errors: [...result.field_errors, ...policy.errors.map(issue => ({ field: '__body__', issue }))] };
|
|
212
|
+
},
|
|
213
|
+
};
|
|
191
214
|
cachedEngine = createEngine({
|
|
192
215
|
registrySet,
|
|
193
216
|
validator,
|
|
@@ -277,6 +300,9 @@ export function prepareEnvelopeForKernel(envelope, options = {}) {
|
|
|
277
300
|
return { envelope: env, warnings, errors: [`Content parsing error: ${error.message}`] };
|
|
278
301
|
}
|
|
279
302
|
const data = { ...parsed.data };
|
|
303
|
+
const length = checkRuleLength(data, parsed.content, options);
|
|
304
|
+
errors.push(...length.errors);
|
|
305
|
+
warnings.push(...length.warnings);
|
|
280
306
|
|
|
281
307
|
// Package 0.9 universal frontmatter.
|
|
282
308
|
if (!data.title && data.name) data.title = data.name;
|
|
@@ -392,11 +418,13 @@ export async function processViaPackageKernel(envelope, vaultRoot, options = {})
|
|
|
392
418
|
|
|
393
419
|
const eventsDir = path.join(vaultRoot, '.events');
|
|
394
420
|
if (!env.dry_run && !fs.existsSync(eventsDir)) fs.mkdirSync(eventsDir, { recursive: true });
|
|
395
|
-
const
|
|
421
|
+
const context = { envelope: env, vaultRoot, options, warnings: [] };
|
|
422
|
+
const response = await writePolicy.run(context, () => engine.processOperation(env, vaultRoot, {
|
|
396
423
|
...options,
|
|
397
424
|
vaultRoot,
|
|
398
425
|
principal: options.principal || mapTrPrincipal(env, options, vaultRoot),
|
|
399
|
-
});
|
|
426
|
+
}));
|
|
427
|
+
prepared.warnings.push(...context.warnings);
|
|
400
428
|
|
|
401
429
|
if (prepared.warnings.length && response?.validation) {
|
|
402
430
|
response.validation.warnings = [
|