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
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
|
+
import { sessionOptions } from './session/run.mjs';
|
|
2
3
|
|
|
3
4
|
const DEFAULT_PERMISSIONS = Object.freeze({ read: true, write: false, send: false, destructive: false });
|
|
4
5
|
export { DEFAULT_PERMISSIONS };
|
|
@@ -14,11 +15,12 @@ export function commandPermissions(value = DEFAULT_PERMISSIONS) {
|
|
|
14
15
|
const PUBLIC_FIELDS = [
|
|
15
16
|
'agent', 'cwd', 'prompt', 'permissions', 'node', 'allowUnknownAuth', 'timeoutMs',
|
|
16
17
|
'model', 'tools', 'settingSources', 'allowedTools',
|
|
18
|
+
'goal', 'maxTurns', 'maxTokens', 'maxBudgetUsd', 'resultSchema', 'approvalPolicy', 'questionTimeoutMs', 'effort', 'fallbackModel', 'name',
|
|
17
19
|
];
|
|
18
20
|
|
|
19
21
|
export function validateDispatchRequest(request) {
|
|
20
22
|
if (!request || typeof request !== 'object' || Array.isArray(request)) throw new Error('Dispatch requires a JSON object');
|
|
21
|
-
if (Object.keys(request).some(key => !PUBLIC_FIELDS.includes(key))) throw new Error('Unsupported dispatch field; workspace context and containment are managed by
|
|
23
|
+
if (Object.keys(request).some(key => !PUBLIC_FIELDS.includes(key))) throw new Error('Unsupported dispatch field; workspace context and containment are managed by Metaharness');
|
|
22
24
|
if (typeof request.agent !== 'string' || !/^[a-z][a-z0-9-]{0,63}$/.test(request.agent) ||
|
|
23
25
|
typeof request.cwd !== 'string' || !path.isAbsolute(request.cwd) || request.cwd.includes('\0') ||
|
|
24
26
|
typeof request.prompt !== 'string' || !request.prompt.trim() || Buffer.byteLength(request.prompt) > 65536) {
|
|
@@ -28,7 +30,7 @@ export function validateDispatchRequest(request) {
|
|
|
28
30
|
if (request.allowUnknownAuth !== undefined && typeof request.allowUnknownAuth !== 'boolean') throw new Error('allowUnknownAuth must be a boolean');
|
|
29
31
|
const timeoutMs = request.timeoutMs === undefined ? 300000 : request.timeoutMs;
|
|
30
32
|
if (!Number.isInteger(timeoutMs) || timeoutMs < 1 || timeoutMs > 540000) throw new Error('Foreground dispatch timeout must be 1..540000 ms');
|
|
31
|
-
return { ...request, permissions: commandPermissions(request.permissions), timeoutMs };
|
|
33
|
+
return { ...request, ...sessionOptions(request), permissions: commandPermissions(request.permissions), timeoutMs };
|
|
32
34
|
}
|
|
33
35
|
|
|
34
36
|
/** The installed destination starts from its own project context and decides containment itself. */
|
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
/** One path for every agent run: contain it if needed, dispatch it, classify the outcome, write its receipt. */
|
|
2
2
|
import { executeOnNode } from './executor.mjs';
|
|
3
|
-
import { classifyFailure, INCLUDED_BILLING, READ_ONLY_ADAPTERS } from './worker.mjs';
|
|
3
|
+
import { classifyFailure, INCLUDED_BILLING, READ_ONLY_ADAPTERS, cancellationResult } from './worker.mjs';
|
|
4
4
|
import { recordRunReceipt } from './learner.mjs';
|
|
5
|
-
import { isGitRepo, createWorktree, removeWorktree } from './worktree.mjs';
|
|
5
|
+
import { isGitRepo, createWorktree, removeWorktree, commitAll, deleteBranch } from './worktree.mjs';
|
|
6
|
+
import { randomUUID } from 'node:crypto';
|
|
6
7
|
import { includedAdmission, openRouterAdmission, readIncludedPolicy } from './included-usage.mjs';
|
|
7
8
|
import { queueIncludedJob } from './usage-queue.mjs';
|
|
8
9
|
|
|
9
10
|
export async function dispatchWithReceipt(request, { dispatchFn, node = request.node || 'local', role, complexityScore, escalatedFrom,
|
|
10
|
-
record = recordRunReceipt, replay, retryId, usagePolicy = readIncludedPolicy, admit = includedAdmission, admitOpenRouter = openRouterAdmission } = {}) {
|
|
11
|
+
record = recordRunReceipt, replay, retryId, manageWrites = false, usagePolicy = readIncludedPolicy, admit = includedAdmission, admitOpenRouter = openRouterAdmission } = {}) {
|
|
11
12
|
const started = Date.now();
|
|
13
|
+
if (cancellationResult()) return cancellationResult();
|
|
12
14
|
// A harness that cannot be told not to write does read-only work in a checkout that is thrown away.
|
|
13
15
|
const contain = node === 'local' && request.permissions?.write !== true && !READ_ONLY_ADAPTERS.includes(request.agent) && request.isolated !== true && isGitRepo(request.cwd);
|
|
14
|
-
|
|
16
|
+
const ownWrites = manageWrites && node === 'local' && request.permissions?.write === true && isGitRepo(request.cwd);
|
|
17
|
+
let scratch = null, branch = null, result, billingMode = null, launchPrevented = false;
|
|
15
18
|
try {
|
|
16
19
|
let effective = request;
|
|
17
20
|
const policy = await usagePolicy();
|
|
@@ -24,19 +27,32 @@ export async function dispatchWithReceipt(request, { dispatchFn, node = request.
|
|
|
24
27
|
launchPrevented = true;
|
|
25
28
|
} else effective = { ...request, [INCLUDED_BILLING]: { key: admission.key, claudePlan: admission.claudePlan, openRouter: admission.openRouter } };
|
|
26
29
|
}
|
|
30
|
+
result = cancellationResult() || result;
|
|
27
31
|
if (!result) {
|
|
28
|
-
if (contain) {
|
|
29
|
-
|
|
30
|
-
|
|
32
|
+
if (contain || ownWrites) {
|
|
33
|
+
branch = ownWrites ? `meta-harness/dispatch-${randomUUID()}` : null;
|
|
34
|
+
scratch = createWorktree(request.cwd, { ...(branch ? { branch } : {}), prefix: ownWrites ? 'meta-harness-dispatch-' : 'meta-harness-readonly-' });
|
|
35
|
+
effective = { ...effective, ...(branch ? { branch } : {}), cwd: scratch, contextCwd: request.contextCwd || request.cwd, isolated: true };
|
|
31
36
|
}
|
|
32
37
|
result = dispatchFn ? await dispatchFn(effective) : await executeOnNode(node, { ...effective, operation: 'dispatch' });
|
|
38
|
+
if (cancellationResult()) result = { ...result, ...cancellationResult() };
|
|
33
39
|
if (contain) result = { ...result, readOnly: 'disposable-checkout' };
|
|
34
40
|
}
|
|
35
41
|
} catch (error) {
|
|
36
42
|
const message = String(error?.message || error);
|
|
37
43
|
result = { ok: false, error: message, agent: request.agent, ...(error?.code === 'NOT_READY' ? { failureKind: 'not-ready' } : classifyFailure(message)) };
|
|
38
44
|
} finally {
|
|
39
|
-
if (scratch)
|
|
45
|
+
if (scratch) {
|
|
46
|
+
try {
|
|
47
|
+
if (branch) {
|
|
48
|
+
const commit = commitAll(scratch, result?.cancelled ? 'meta-harness: unfinished cancelled dispatch' : 'meta-harness: dispatch changes');
|
|
49
|
+
if (commit) result = { ...result, branch, ...(result?.ok ? { commit } : { wip: commit }) };
|
|
50
|
+
else if (result?.sessionId) result = { ...result, branch };
|
|
51
|
+
else deleteBranch(request.cwd, branch);
|
|
52
|
+
}
|
|
53
|
+
} finally { removeWorktree(request.cwd, scratch); }
|
|
54
|
+
if (branch && !result?.branch) deleteBranch(request.cwd, branch);
|
|
55
|
+
}
|
|
40
56
|
}
|
|
41
57
|
const durationMs = Date.now() - started;
|
|
42
58
|
if (result.execution?.receiptOwner === 'destination' && result.receiptId) return { ...result, durationMs };
|
|
@@ -52,7 +68,15 @@ export async function dispatchWithReceipt(request, { dispatchFn, node = request.
|
|
|
52
68
|
}
|
|
53
69
|
}
|
|
54
70
|
}
|
|
55
|
-
if (launchPrevented)
|
|
71
|
+
if (launchPrevented) {
|
|
72
|
+
// A launch refused for quota is a quota wall too (A-124): record it, so routing sees the harness as
|
|
73
|
+
// exhausted until its reset and picks another included harness instead of choosing it again.
|
|
74
|
+
if (result.failureKind === 'quota') {
|
|
75
|
+
try { await record({ harness: request.agent, role, task: String(request.contextTask || request.prompt || '').slice(0, 200), success: false,
|
|
76
|
+
failureKind: 'quota', error: result.error, resetsAt: result.resetsAt || null }); } catch { /* bookkeeping must not hide the refusal */ }
|
|
77
|
+
}
|
|
78
|
+
return { ...result, launchPrevented, durationMs };
|
|
79
|
+
}
|
|
56
80
|
// A finished run keeps its result: the worktree and any cost are real even when bookkeeping fails.
|
|
57
81
|
let receipt, receiptError;
|
|
58
82
|
try {
|
|
@@ -3,7 +3,11 @@ import fs from 'node:fs';
|
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import os from 'node:os';
|
|
5
5
|
import crypto from 'node:crypto';
|
|
6
|
-
import {
|
|
6
|
+
import { execFile } from 'node:child_process';
|
|
7
|
+
import { promisify } from 'node:util';
|
|
8
|
+
import { agentEnvironment, loadCustomAdapters } from './worker.mjs';
|
|
9
|
+
|
|
10
|
+
const exec = promisify(execFile);
|
|
7
11
|
|
|
8
12
|
export const DOC_SOURCES = [
|
|
9
13
|
{ id: 'claude', index: 'https://code.claude.com/docs/llms.txt', prefix: 'https://code.claude.com/docs/', catalog:true },
|
|
@@ -69,7 +73,7 @@ async function download(url, fetchImpl, declaredOrigin) {
|
|
|
69
73
|
if (declaredOrigin) allowed.add(declaredOrigin);
|
|
70
74
|
for(let redirects=0;redirects<5;redirects++) {
|
|
71
75
|
if(target.protocol!=='https:' || target.username || target.password || !allowed.has(target.hostname)) throw new Error(`Unapproved official documentation origin: ${target.hostname}`);
|
|
72
|
-
const response=await fetchImpl(target,{redirect:'manual',signal:AbortSignal.timeout(20000),headers:{'User-Agent':'Total-Recall-
|
|
76
|
+
const response=await fetchImpl(target,{redirect:'manual',signal:AbortSignal.timeout(20000),headers:{'User-Agent':'Total-Recall-Metaharness-Docs','Accept':'*/*'}});
|
|
73
77
|
if(response.status>=300 && response.status<400){target=new URL(response.headers.get('location'),target);continue;}
|
|
74
78
|
// Some entries advertise Markdown exports which no longer exist while the
|
|
75
79
|
// same official HTML document remains available. Fetch that representation.
|
|
@@ -91,7 +95,27 @@ function links(text,base,prefix) {
|
|
|
91
95
|
return [...new Set(values.map(value=>{try{const url=new URL(value);url.hash='';url.search='';url.pathname=url.pathname.replace(/\/{2,}/g,'/').replace(/\/$/,'') || '/';return url.href;}catch{return '';}}))]
|
|
92
96
|
.filter(url=>url.startsWith(prefix) && !/%3[CE]|[<>"'`\s]/i.test(url) && !/\.(png|jpg|jpeg|svg|gif|css|js|woff2?|ico|pdf|json|ya?ml|xml|zip|gz|tgz|lock)$/i.test(url));
|
|
93
97
|
}
|
|
94
|
-
|
|
98
|
+
async function gitDocumentationPaths(source) {
|
|
99
|
+
const checkout = fs.mkdtempSync(path.join(os.tmpdir(), 'meta-harness-doc-tree-'));
|
|
100
|
+
const options = {
|
|
101
|
+
cwd: checkout, timeout: 30000, maxBuffer: 4 * 1024 * 1024,
|
|
102
|
+
env: { ...agentEnvironment(), GIT_TERMINAL_PROMPT: '0', GIT_CONFIG_NOSYSTEM: '1', GIT_CONFIG_GLOBAL: os.devNull },
|
|
103
|
+
};
|
|
104
|
+
try {
|
|
105
|
+
await exec('git', ['-c', 'http.followRedirects=false', 'clone', '--quiet', '--filter=blob:none',
|
|
106
|
+
'--depth=1', '--single-branch', '--branch', source.branch, '--no-checkout',
|
|
107
|
+
'--', `https://github.com/${source.repo}.git`, checkout], options);
|
|
108
|
+
const { stdout } = await exec('git', ['ls-tree', '-r', '-z', 'HEAD', '--', ...source.directories], options);
|
|
109
|
+
return stdout.split('\0').flatMap(entry => {
|
|
110
|
+
const match = /^100(?:644|755) blob [a-f0-9]+\t([\s\S]+)$/.exec(entry);
|
|
111
|
+
return match ? [match[1]] : [];
|
|
112
|
+
});
|
|
113
|
+
} catch {
|
|
114
|
+
throw new Error(`Could not read the official documentation tree through Git for ${source.repo}`);
|
|
115
|
+
} finally { fs.rmSync(checkout, { recursive: true, force: true }); }
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export async function refreshDocumentation({ directory = documentationDirectory(), agent, fetchImpl = fetch, now = () => new Date(), maxPages = 1500, readGitPaths = gitDocumentationPaths } = {}) {
|
|
95
119
|
const sources=sourcesFor(agent);
|
|
96
120
|
if(!sources.length)throw new Error('Unknown documentation adapter');
|
|
97
121
|
const reports=[];
|
|
@@ -99,11 +123,27 @@ export async function refreshDocumentation({ directory = documentationDirectory(
|
|
|
99
123
|
const previous=metadata(directory,source.id), pages=[], queue=[source.index], seen=new Set(), queued=new Set(queue), errors=[], discovered=new Set(), skipped=[];
|
|
100
124
|
// `found` marks a link taken from HTML navigation. The vendor's catalog, the index and the repository tree are authoritative; a link found by scraping is not.
|
|
101
125
|
const enqueue=(url,found=false)=>{if(!queued.has(url)){queued.add(url);queue.push(url);if(found)discovered.add(url);}};
|
|
126
|
+
let treeSource;
|
|
102
127
|
try {
|
|
103
128
|
if(source.repo) {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
129
|
+
let paths;
|
|
130
|
+
try {
|
|
131
|
+
const tree = JSON.parse(await download(`https://api.github.com/repos/${source.repo}/git/trees/${source.branch}?recursive=1`, fetchImpl));
|
|
132
|
+
if (tree.truncated) throw new Error('Official repository documentation tree is truncated');
|
|
133
|
+
if (!Array.isArray(tree.tree)) throw new Error('Invalid official repository documentation tree');
|
|
134
|
+
paths = tree.tree.filter(entry => entry.type === 'blob').map(entry => entry.path);
|
|
135
|
+
treeSource = 'github-rest';
|
|
136
|
+
} catch (error) {
|
|
137
|
+
if (!/^Documentation HTTP (403|429):|^Official repository documentation tree is truncated$/.test(error.message)) throw error;
|
|
138
|
+
paths = await readGitPaths(source);
|
|
139
|
+
treeSource = 'github-git';
|
|
140
|
+
}
|
|
141
|
+
for (const file of paths) {
|
|
142
|
+
if (!/\.(md|mdx)$/i.test(file) || !source.directories.some(dir => file.startsWith(dir))) continue;
|
|
143
|
+
const encoded = file.split('/').map(encodeURIComponent).join('/');
|
|
144
|
+
enqueue(`https://raw.githubusercontent.com/${source.repo}/${source.branch}/${encoded}`);
|
|
145
|
+
}
|
|
146
|
+
if (queue.length === 1) throw new Error('Official repository documentation tree contains no additional pages');
|
|
107
147
|
}
|
|
108
148
|
// Bounded batches; follow the official index/navigation to cover agent features.
|
|
109
149
|
while(queue.length) {
|
|
@@ -138,7 +178,7 @@ export async function refreshDocumentation({ directory = documentationDirectory(
|
|
|
138
178
|
reports.push({id:source.id,ok:false,error,pages:preserved.pages?.length || 0,downloadedPages:pages.length,failedCount:errors.length,failures:errors,...(skipped.length?{skippedCount:skipped.length,skipped}:{})});continue;
|
|
139
179
|
}
|
|
140
180
|
atomic(path.join(directory,source.id,'index.json'),JSON.stringify({id:source.id,complete:true,checkedAt,lastAttempt:checkedAt,pages,...(skipped.length?{skipped}:{})},null,2));
|
|
141
|
-
reports.push({id:source.id,ok:true,pages:pages.length,...(skipped.length?{skippedCount:skipped.length,skipped}:{})});
|
|
181
|
+
reports.push({id:source.id,ok:true,pages:pages.length,...(treeSource?{treeSource}:{}),...(skipped.length?{skippedCount:skipped.length,skipped}:{})});
|
|
142
182
|
} catch(error) {
|
|
143
183
|
atomic(path.join(directory,source.id,'index.json'),JSON.stringify({...previous,id:source.id,lastAttempt:now().toISOString(),error:error.message},null,2));
|
|
144
184
|
reports.push({id:source.id,ok:false,error:error.message,pages:previous?.pages?.length || 0});
|
|
@@ -156,11 +196,15 @@ export async function ensureDocumentation(options={}) {
|
|
|
156
196
|
|
|
157
197
|
export async function maintainDocumentation(options={}) {
|
|
158
198
|
const status=documentationStatus(options);
|
|
159
|
-
const
|
|
160
|
-
|
|
161
|
-
|
|
199
|
+
const pending=status.agents.filter(row=>!row.fresh).sort((a,b)=>String(a.lastAttempt || '').localeCompare(String(b.lastAttempt || '')));
|
|
200
|
+
const reports=[];
|
|
201
|
+
// Missing documentation for one harness must not prevent attempts for the others.
|
|
202
|
+
for(const row of pending) {
|
|
203
|
+
try { reports.push(...(await refreshDocumentation({...options,agent:row.id})).agents); }
|
|
204
|
+
catch(error) { reports.push({id:row.id,ok:false,error:error.message}); }
|
|
205
|
+
}
|
|
162
206
|
const current=documentationStatus(options);
|
|
163
|
-
return {...
|
|
207
|
+
return {...current,ok:current.ok && reports.every(row=>row.ok),scope:'all-agent-documentation',refresh:reports,coverage_complete:current.ok,pending:current.agents.filter(row=>!row.fresh).map(row=>row.id)};
|
|
164
208
|
}
|
|
165
209
|
|
|
166
210
|
export function readDocumentation({agent,url,directory=documentationDirectory()}) {
|
|
@@ -34,15 +34,35 @@ export async function listTargets() {
|
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
export function workerProgram(request) {
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
// Materialize a portable module graph. The stdin launcher imports only Node
|
|
38
|
+
// built-ins. Relative imports resolve inside this owned bundle on the node.
|
|
39
|
+
const names = ['worker.mjs', 'control.mjs', 'jobs.mjs', 'paths.mjs', 'mcp-server.mjs',
|
|
40
|
+
...fs.readdirSync(new URL('./session/', import.meta.url)).filter(name => name.endsWith('.mjs')).map(name => `session/${name}`)];
|
|
41
|
+
const files = Object.fromEntries(names.map(name => [name, fs.readFileSync(new URL(name, import.meta.url), 'utf8')]));
|
|
42
|
+
return `import fs from 'node:fs';
|
|
43
|
+
import os from 'node:os';
|
|
44
|
+
import path from 'node:path';
|
|
45
|
+
import { pathToFileURL } from 'node:url';
|
|
46
|
+
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'metaharness-worker-'));
|
|
47
|
+
try {
|
|
48
|
+
for (const [name, source] of Object.entries(${JSON.stringify(files)})) {
|
|
49
|
+
const file = path.join(directory, name);
|
|
50
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
51
|
+
fs.writeFileSync(file, source, { mode: 0o600 });
|
|
52
|
+
}
|
|
53
|
+
const { runWorker } = await import(pathToFileURL(path.join(directory, 'worker.mjs')).href);
|
|
54
|
+
console.log(JSON.stringify(await runWorker(${JSON.stringify(request)})));
|
|
55
|
+
} catch (error) { console.error(String(error?.message || 'Selected agent worker failed')); process.exitCode = 1; }
|
|
56
|
+
finally { fs.rmSync(directory, { recursive: true, force: true }); }
|
|
57
|
+
`;
|
|
58
|
+
|
|
39
59
|
}
|
|
40
60
|
|
|
41
61
|
function destinationDispatchResult(result, node, request) {
|
|
42
62
|
let payload;
|
|
43
63
|
try { payload = JSON.parse(result.output); } catch { /* No structured result from the installed owner. */ }
|
|
44
64
|
if (!payload || typeof payload.ok !== 'boolean' || (payload.ok && !result.ok)) {
|
|
45
|
-
throw notReady(`Installed
|
|
65
|
+
throw notReady(`Installed Metaharness on ${node} returned no valid dispatch outcome (exit ${result.exitCode ?? 'unknown'})`);
|
|
46
66
|
}
|
|
47
67
|
return { ...payload, execution: { node, workspace: request.cwd, remote: true,
|
|
48
68
|
...(typeof payload.receiptId === 'string' ? { receiptOwner: 'destination' } : {}) } };
|
|
@@ -60,7 +80,9 @@ export async function executeOnNode(node, request, { worker = runWorker, process
|
|
|
60
80
|
if (dispatch) {
|
|
61
81
|
const input = JSON.stringify(destinationDispatchRequest(request));
|
|
62
82
|
if (Buffer.byteLength(input) > 65536) throw new Error('Remote dispatch request is too large');
|
|
63
|
-
transport
|
|
83
|
+
// The transport outlives the attempt it carries by a minute, so the destination reports its own timeout (A-101).
|
|
84
|
+
transport = { operation: 'direct', cwd: request.cwd, argv: ['total-recall', 'meta-harness', 'dispatch', '--stdin', '--json'], input,
|
|
85
|
+
timeoutMs: Number.isInteger(request.timeoutMs) && request.timeoutMs > 0 ? request.timeoutMs + 60_000 : 600000 };
|
|
64
86
|
}
|
|
65
87
|
const managed = dispatch || (transport.argv?.[1] === 'meta-harness' &&
|
|
66
88
|
['route', 'coordinate', 'review', 'process', 'run-command', 'usage-retry'].includes(transport.argv[2]));
|
package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/gate-adapters/hermes.mjs
CHANGED
|
@@ -27,6 +27,32 @@ function withGate(text) {
|
|
|
27
27
|
return `${text.replace(/\n*$/, text ? '\n' : '')}\nhooks:\n pre_tool_call:\n${entry}`;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
+
/**
|
|
31
|
+
* Remove every hook list item whose command runs the gate. Other tools rewrite config.yaml (the
|
|
32
|
+
* lesson hooks re-serialize it), so the item is found by indentation, not by its exact text: the
|
|
33
|
+
* item runs from its `- ` line to the next line indented no deeper than that dash.
|
|
34
|
+
*/
|
|
35
|
+
export function withoutGate(text) {
|
|
36
|
+
if (!text.includes(GATE)) return text;
|
|
37
|
+
const exact = text.replace(ENTRY_LINES, '');
|
|
38
|
+
if (!exact.includes(GATE)) return exact;
|
|
39
|
+
let lines = text.split('\n');
|
|
40
|
+
const indent = (line) => line.match(/^ */)[0].length;
|
|
41
|
+
for (let guard = 0; guard < 50; guard++) {
|
|
42
|
+
const hit = lines.findIndex((line) => line.includes(GATE));
|
|
43
|
+
if (hit < 0) break;
|
|
44
|
+
let start = hit;
|
|
45
|
+
while (start >= 0 && !/^ *- /.test(lines[start])) start--;
|
|
46
|
+
if (start < 0 || indent(lines[start]) > indent(lines[hit])) break;
|
|
47
|
+
const dash = indent(lines[start]);
|
|
48
|
+
let end = start + 1;
|
|
49
|
+
while (end < lines.length && (lines[end].trim() === '' || indent(lines[end]) > dash)) end++;
|
|
50
|
+
while (end > start + 1 && lines[end - 1].trim() === '') end--;
|
|
51
|
+
lines = [...lines.slice(0, start), ...lines.slice(end)];
|
|
52
|
+
}
|
|
53
|
+
return lines.join('\n');
|
|
54
|
+
}
|
|
55
|
+
|
|
30
56
|
export const hermesAdapter = {
|
|
31
57
|
id: 'hermes',
|
|
32
58
|
level: 'enforced',
|
|
@@ -118,7 +144,9 @@ export const hermesAdapter = {
|
|
|
118
144
|
const present = text.includes(GATE);
|
|
119
145
|
if (remove || off) {
|
|
120
146
|
if (present) {
|
|
121
|
-
|
|
147
|
+
const next = withoutGate(text);
|
|
148
|
+
if (next.includes(GATE)) throw new Error(`could not remove the gate from ${configPath}; remove the pre_tool_call entry that runs "${GATE}" by hand`);
|
|
149
|
+
if (!dryRun) fs.writeFileSync(configPath, next);
|
|
122
150
|
removed.push('managed pre_tool_call gate');
|
|
123
151
|
}
|
|
124
152
|
return { settings: configPath, added, removed };
|
package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/gate-adapters/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Gate Adapters registry for
|
|
2
|
+
* Gate Adapters registry for Metaharness (tr-plugin-cli-agents).
|
|
3
3
|
* Provides harness-specific parsing, emission, installation and verification.
|
|
4
4
|
*/
|
|
5
5
|
import { claudeAdapter } from './claude.mjs';
|
|
@@ -195,7 +195,7 @@ export function queryCodexAccount(cwd, { env = process.env, timeoutMs = 10000 }
|
|
|
195
195
|
child.kill('SIGTERM');
|
|
196
196
|
}
|
|
197
197
|
});
|
|
198
|
-
send({ id: 1, method: 'initialize', params: { clientInfo: { name: 'meta_harness', title: '
|
|
198
|
+
send({ id: 1, method: 'initialize', params: { clientInfo: { name: 'meta_harness', title: 'Metaharness', version: '1' } } });
|
|
199
199
|
});
|
|
200
200
|
}
|
|
201
201
|
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/** Local job identity and cancellation. A terminal log result is the completion record. */
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { randomUUID } from 'node:crypto';
|
|
5
|
+
import { configDir } from './paths.mjs';
|
|
6
|
+
import { createProgress } from './worker.mjs';
|
|
7
|
+
|
|
8
|
+
const jobsDir = () => path.join(configDir(), 'jobs');
|
|
9
|
+
export const newJobId = () => `${Date.now().toString(36)}-${randomUUID().slice(0, 8)}`;
|
|
10
|
+
|
|
11
|
+
export function startJob(operation, { id = newJobId() } = {}) {
|
|
12
|
+
if (!/^[a-z0-9-]+$/.test(id)) throw new Error('Invalid job ID.');
|
|
13
|
+
const directory = jobsDir();
|
|
14
|
+
fs.mkdirSync(directory, { recursive: true, mode: 0o700 });
|
|
15
|
+
const log = path.join(directory, `${id}.log`);
|
|
16
|
+
const pidFile = path.join(directory, `${id}.pid`);
|
|
17
|
+
const record = { job: id, pid: process.pid, operation, startedAt: new Date().toISOString() };
|
|
18
|
+
fs.appendFileSync(log, `${JSON.stringify(record)}\n`, { mode: 0o600 });
|
|
19
|
+
fs.writeFileSync(pidFile, `${process.pid}\n`, { mode: 0o600, flag: 'wx' });
|
|
20
|
+
const progress = createProgress({ file: path.join(directory, `${id}.events.jsonl`), harness: operation });
|
|
21
|
+
return { ...record, log, finish(result) {
|
|
22
|
+
progress.close(result);
|
|
23
|
+
fs.appendFileSync(log, `${JSON.stringify(result)}\n`, { mode: 0o600 });
|
|
24
|
+
fs.rmSync(pidFile, { force: true });
|
|
25
|
+
} };
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function readJob(log) {
|
|
29
|
+
const lines = fs.readFileSync(log, 'utf8').trim().split('\n');
|
|
30
|
+
let record;
|
|
31
|
+
try { record = JSON.parse(lines[0]); } catch { /* old log without PID */ }
|
|
32
|
+
let result = null;
|
|
33
|
+
for (const line of lines.slice(1).reverse()) {
|
|
34
|
+
try {
|
|
35
|
+
const value = JSON.parse(line);
|
|
36
|
+
if (typeof value.ok === 'boolean') { result = value; break; }
|
|
37
|
+
} catch { /* progress text */ }
|
|
38
|
+
}
|
|
39
|
+
return { record, result };
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function resolveJob(target) {
|
|
43
|
+
if (!target) throw new Error('cancel requires a job ID or log path.');
|
|
44
|
+
const directory = jobsDir();
|
|
45
|
+
const prefix = path.basename(target).replace(/\.(?:log|pid|events\.jsonl|status\.json)$/, '');
|
|
46
|
+
const files = fs.existsSync(directory) ? fs.readdirSync(directory) : [];
|
|
47
|
+
let names = files.filter(name => name.endsWith('.log') && name.startsWith(prefix));
|
|
48
|
+
if (!names.length) {
|
|
49
|
+
// An attempt ID from watch resolves to its owning job, never directly to a PID.
|
|
50
|
+
const events = files.filter(name => name.endsWith('.events.jsonl') && name.startsWith(prefix))
|
|
51
|
+
.sort((a, b) => fs.statSync(path.join(directory, b)).mtimeMs - fs.statSync(path.join(directory, a)).mtimeMs);
|
|
52
|
+
let pid;
|
|
53
|
+
try { pid = JSON.parse(fs.readFileSync(path.join(directory, events[0].replace('.events.jsonl', '.status.json')), 'utf8')).pid; } catch { /* no matching status */ }
|
|
54
|
+
if (pid) names = files.filter(name => name.endsWith('.log') && readJob(path.join(directory, name)).record?.pid === pid);
|
|
55
|
+
}
|
|
56
|
+
const exact = names.find(name => name === `${prefix}.log`);
|
|
57
|
+
if (!names.length) throw new Error(`No job log matches ${target}.`);
|
|
58
|
+
if (!exact && names.length > 1) throw new Error(`More than one job matches ${target}. Use a longer job ID.`);
|
|
59
|
+
const log = path.join(directory, exact || names[0]);
|
|
60
|
+
return { id: path.basename(log, '.log'), log, ...readJob(log) };
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export async function cancelJob(target, { timeoutMs = 60_000, pollMs = 100 } = {}) {
|
|
64
|
+
const job = resolveJob(target);
|
|
65
|
+
if (job.result) throw new Error(`Job ${job.id} has finished${job.result.cancelled ? ' (cancelled)' : ''}.`);
|
|
66
|
+
const pidFile = path.join(jobsDir(), `${job.id}.pid`);
|
|
67
|
+
let pid;
|
|
68
|
+
try { pid = Number(fs.readFileSync(pidFile, 'utf8').trim()); } catch { /* stale or old job */ }
|
|
69
|
+
if (!Number.isSafeInteger(pid) || pid <= 1 || job.record?.pid !== pid || job.record?.job !== job.id) {
|
|
70
|
+
throw new Error(`Job ${job.id} has no active PID record.`);
|
|
71
|
+
}
|
|
72
|
+
try { process.kill(pid, 'SIGTERM'); }
|
|
73
|
+
catch (error) { throw new Error(`Cannot cancel job ${job.id}: ${error.code === 'ESRCH' ? 'the process has stopped' : error.message}.`); }
|
|
74
|
+
const deadline = Date.now() + Math.min(timeoutMs, 60_000);
|
|
75
|
+
do {
|
|
76
|
+
const { result } = readJob(job.log);
|
|
77
|
+
if (result) {
|
|
78
|
+
if (!result.cancelled) throw new Error(`Job ${job.id} finished before it could be cancelled.`);
|
|
79
|
+
return { ...result, job: job.id, log: job.log };
|
|
80
|
+
}
|
|
81
|
+
await new Promise(resolve => setTimeout(resolve, pollMs));
|
|
82
|
+
} while (Date.now() < deadline);
|
|
83
|
+
throw new Error(`Job ${job.id} did not report cancellation within ${Math.min(timeoutMs, 60_000) / 1000} seconds. Log: ${job.log}`);
|
|
84
|
+
}
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
* Execution receipts and the learning loop.
|
|
3
3
|
* Receipts are an append-only SSSS ledger. Scorecards, quota walls and proposals fold from it.
|
|
4
4
|
*/
|
|
5
|
-
import { spawnSync } from 'node:child_process';
|
|
6
5
|
import { computeEmpiricalScorecard } from '../capability/index.mjs';
|
|
7
6
|
import { receiptsFile } from './paths.mjs';
|
|
8
7
|
import { classifyFailure } from './worker.mjs';
|
|
@@ -105,18 +104,10 @@ export function activeCredentialBlocks(entries = [], now = Date.now(), holdMs =
|
|
|
105
104
|
return blocks;
|
|
106
105
|
}
|
|
107
106
|
|
|
108
|
-
/**
|
|
109
|
-
export async function learnFromHistory(
|
|
107
|
+
/** Read the same receipts the router uses. Proposals stay in this report. */
|
|
108
|
+
export async function learnFromHistory() {
|
|
110
109
|
const entries = await readReceipts();
|
|
111
110
|
const scorecard = computeEmpiricalScorecard(entries);
|
|
112
111
|
const proposals = proposalsFrom(scorecard, entries);
|
|
113
|
-
|
|
114
|
-
if (emit) for (const proposal of proposals) {
|
|
115
|
-
const result = runner(process.env.TOTAL_RECALL_BIN || 'total-recall', ['remember', 'fact', `${proposal.reason} ${proposal.recommendation}`, '--project', '--slug', proposal.id, '--tags', `meta-harness,${proposal.id}`], { encoding: 'utf8', timeout: 30000 });
|
|
116
|
-
const output = `${result.stdout || ''}\n${result.stderr || ''}`;
|
|
117
|
-
// The slug is the proposal's identity, so an open proposal is reported once, however often learn runs.
|
|
118
|
-
const existing = result.status !== 0 && /already exists/i.test(output);
|
|
119
|
-
emitted.push({ id: proposal.id, ok: result.status === 0 || existing, ...(existing ? { existing: true } : {}), error: result.status === 0 || existing ? undefined : String(result.stderr || result.error || 'remember failed').slice(0, 300) });
|
|
120
|
-
}
|
|
121
|
-
return { ok: emitted.every(row => row.ok), totalHistoryRuns: entries.length, scorecard, walls: activeQuotaWalls(entries), credentialBlocks: activeCredentialBlocks(entries), proposals, ...(emit ? { emitted } : {}) };
|
|
112
|
+
return { ok: true, totalHistoryRuns: entries.length, scorecard, walls: activeQuotaWalls(entries), credentialBlocks: activeCredentialBlocks(entries), proposals };
|
|
122
113
|
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** Run each maintenance owner even when another owner fails. The daemon records the result. */
|
|
2
|
+
import { setupIntegrations } from './setup.mjs';
|
|
3
|
+
import { maintainDocumentation } from './documentation.mjs';
|
|
4
|
+
|
|
5
|
+
export async function maintainIntegrations(options = {}, owners = {}) {
|
|
6
|
+
const steps = {
|
|
7
|
+
setup: owners.setup || (() => setupIntegrations()),
|
|
8
|
+
gates: owners.gates || (async () => (await import('./gate-adapters/index.mjs')).installAll()),
|
|
9
|
+
docs: owners.docs || (() => maintainDocumentation(options)),
|
|
10
|
+
};
|
|
11
|
+
const result = {};
|
|
12
|
+
for (const [name, execute] of Object.entries(steps)) {
|
|
13
|
+
try { result[name] = await execute(); }
|
|
14
|
+
catch (error) { result[name] = { ok: false, error: error.message }; }
|
|
15
|
+
}
|
|
16
|
+
return { ...result, ok: Object.values(result).every(step => step?.ok === true) };
|
|
17
|
+
}
|