@cleocode/core 2026.5.134 → 2026.6.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/binaries/README.md +49 -27
- package/dist/agents/{agent-registry.d.ts → agent-capacity-tracker.d.ts} +2 -2
- package/dist/agents/agent-capacity-tracker.d.ts.map +1 -0
- package/dist/agents/{agent-registry.js → agent-capacity-tracker.js} +2 -2
- package/dist/agents/agent-capacity-tracker.js.map +1 -0
- package/dist/agents/index.d.ts +1 -1
- package/dist/agents/index.d.ts.map +1 -1
- package/dist/agents/index.js +4 -2
- package/dist/agents/index.js.map +1 -1
- package/dist/agents/seed-install.d.ts +1 -1
- package/dist/agents/seed-install.d.ts.map +1 -1
- package/dist/agents/seed-install.js +42 -36
- package/dist/agents/seed-install.js.map +1 -1
- package/dist/caamp-export.d.ts +18 -0
- package/dist/caamp-export.d.ts.map +1 -0
- package/dist/caamp-export.js +18 -0
- package/dist/caamp-export.js.map +1 -0
- package/dist/conduit/local-transport.d.ts +1 -1
- package/dist/conduit/local-transport.d.ts.map +1 -1
- package/dist/conduit/local-transport.js +69 -43
- package/dist/conduit/local-transport.js.map +1 -1
- package/dist/dispatch/mutate-projection.d.ts.map +1 -1
- package/dist/dispatch/mutate-projection.js +11 -0
- package/dist/dispatch/mutate-projection.js.map +1 -1
- package/dist/docs/docs-read-model.d.ts +7 -0
- package/dist/docs/docs-read-model.d.ts.map +1 -1
- package/dist/docs/docs-read-model.js +5 -0
- package/dist/docs/docs-read-model.js.map +1 -1
- package/dist/docs/supersede.d.ts.map +1 -1
- package/dist/docs/supersede.js +12 -7
- package/dist/docs/supersede.js.map +1 -1
- package/dist/doctor/db-substrate.d.ts.map +1 -1
- package/dist/doctor/db-substrate.js +10 -9
- package/dist/doctor/db-substrate.js.map +1 -1
- package/dist/git-shim-export.d.ts +18 -0
- package/dist/git-shim-export.d.ts.map +1 -0
- package/dist/git-shim-export.js +18 -0
- package/dist/git-shim-export.js.map +1 -0
- package/dist/hooks/payload-schemas.d.ts +2 -2
- package/dist/init.d.ts.map +1 -1
- package/dist/init.js +39 -32
- package/dist/init.js.map +1 -1
- package/dist/internal.d.ts +11 -3
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +14 -5
- package/dist/internal.js.map +1 -1
- package/dist/lafs-export.d.ts +18 -0
- package/dist/lafs-export.d.ts.map +1 -0
- package/dist/lafs-export.js +18 -0
- package/dist/lafs-export.js.map +1 -0
- package/dist/lifecycle/effective-stage.js +1 -1
- package/dist/lifecycle/index.js +1 -1
- package/dist/lifecycle/index.js.map +1 -1
- package/dist/lifecycle/rollup.js +1 -1
- package/dist/llm/credential-pool.d.ts +17 -0
- package/dist/llm/credential-pool.d.ts.map +1 -1
- package/dist/llm/credential-pool.js +40 -1
- package/dist/llm/credential-pool.js.map +1 -1
- package/dist/llm/plugin-facade.d.ts.map +1 -1
- package/dist/llm/plugin-facade.js +11 -19
- package/dist/llm/plugin-facade.js.map +1 -1
- package/dist/llm/role-executor.d.ts +8 -0
- package/dist/llm/role-executor.d.ts.map +1 -1
- package/dist/llm/role-executor.js +96 -4
- package/dist/llm/role-executor.js.map +1 -1
- package/dist/llm/role-resolver.d.ts.map +1 -1
- package/dist/llm/role-resolver.js +56 -1
- package/dist/llm/role-resolver.js.map +1 -1
- package/dist/llm/transports/codex-oauth-headers.d.ts +51 -0
- package/dist/llm/transports/codex-oauth-headers.d.ts.map +1 -0
- package/dist/llm/transports/codex-oauth-headers.js +89 -0
- package/dist/llm/transports/codex-oauth-headers.js.map +1 -0
- package/dist/memory/claude-mem-migration.d.ts.map +1 -1
- package/dist/memory/claude-mem-migration.js +1 -3
- package/dist/memory/claude-mem-migration.js.map +1 -1
- package/dist/memory/decisions.d.ts.map +1 -1
- package/dist/memory/decisions.js +77 -23
- package/dist/memory/decisions.js.map +1 -1
- package/dist/memory/graph-memory-bridge.d.ts.map +1 -1
- package/dist/memory/graph-memory-bridge.js +12 -6
- package/dist/memory/graph-memory-bridge.js.map +1 -1
- package/dist/memory/learnings.d.ts +2 -2
- package/dist/memory/nexus-plasticity.d.ts +21 -9
- package/dist/memory/nexus-plasticity.d.ts.map +1 -1
- package/dist/memory/nexus-plasticity.js +44 -22
- package/dist/memory/nexus-plasticity.js.map +1 -1
- package/dist/memory/patterns.d.ts +2 -2
- package/dist/memory/redaction.d.ts +19 -3
- package/dist/memory/redaction.d.ts.map +1 -1
- package/dist/memory/redaction.js +22 -94
- package/dist/memory/redaction.js.map +1 -1
- package/dist/metrics/token-service.d.ts +8 -2
- package/dist/metrics/token-service.d.ts.map +1 -1
- package/dist/metrics/token-service.js +1 -1
- package/dist/metrics/token-service.js.map +1 -1
- package/dist/nexus/analyze-orchestrator.d.ts.map +1 -1
- package/dist/nexus/analyze-orchestrator.js +6 -8
- package/dist/nexus/analyze-orchestrator.js.map +1 -1
- package/dist/nexus/api-extractors/http-extractor.d.ts.map +1 -1
- package/dist/nexus/api-extractors/http-extractor.js +3 -3
- package/dist/nexus/api-extractors/http-extractor.js.map +1 -1
- package/dist/nexus/clusters.d.ts.map +1 -1
- package/dist/nexus/clusters.js +3 -2
- package/dist/nexus/clusters.js.map +1 -1
- package/dist/nexus/context.d.ts.map +1 -1
- package/dist/nexus/context.js +10 -16
- package/dist/nexus/context.js.map +1 -1
- package/dist/nexus/diff.d.ts.map +1 -1
- package/dist/nexus/diff.js +6 -4
- package/dist/nexus/diff.js.map +1 -1
- package/dist/nexus/export.d.ts.map +1 -1
- package/dist/nexus/export.js +7 -4
- package/dist/nexus/export.js.map +1 -1
- package/dist/nexus/flows.d.ts.map +1 -1
- package/dist/nexus/flows.js +3 -1
- package/dist/nexus/flows.js.map +1 -1
- package/dist/nexus/impact.d.ts +1 -1
- package/dist/nexus/impact.d.ts.map +1 -1
- package/dist/nexus/impact.js +31 -17
- package/dist/nexus/impact.js.map +1 -1
- package/dist/nexus/living-brain.d.ts.map +1 -1
- package/dist/nexus/living-brain.js +27 -15
- package/dist/nexus/living-brain.js.map +1 -1
- package/dist/nexus/nexus-bridge.d.ts.map +1 -1
- package/dist/nexus/nexus-bridge.js +28 -29
- package/dist/nexus/nexus-bridge.js.map +1 -1
- package/dist/nexus/plasticity-queries.d.ts +4 -2
- package/dist/nexus/plasticity-queries.d.ts.map +1 -1
- package/dist/nexus/plasticity-queries.js +27 -15
- package/dist/nexus/plasticity-queries.js.map +1 -1
- package/dist/nexus/query.d.ts.map +1 -1
- package/dist/nexus/query.js +6 -2
- package/dist/nexus/query.js.map +1 -1
- package/dist/nexus/registry.d.ts.map +1 -1
- package/dist/nexus/registry.js +65 -30
- package/dist/nexus/registry.js.map +1 -1
- package/dist/nexus/route-analysis.d.ts +3 -2
- package/dist/nexus/route-analysis.d.ts.map +1 -1
- package/dist/nexus/route-analysis.js +11 -10
- package/dist/nexus/route-analysis.js.map +1 -1
- package/dist/nexus/sigil.d.ts.map +1 -1
- package/dist/nexus/sigil.js +60 -13
- package/dist/nexus/sigil.js.map +1 -1
- package/dist/nexus/user-profile.d.ts +2 -1
- package/dist/nexus/user-profile.d.ts.map +1 -1
- package/dist/nexus/user-profile.js +8 -4
- package/dist/nexus/user-profile.js.map +1 -1
- package/dist/orchestrate/index.d.ts +1 -1
- package/dist/orchestrate/index.d.ts.map +1 -1
- package/dist/orchestrate/index.js +1 -1
- package/dist/orchestrate/index.js.map +1 -1
- package/dist/orchestrate/plan.d.ts +3 -3
- package/dist/orchestrate/plan.d.ts.map +1 -1
- package/dist/orchestrate/plan.js +7 -7
- package/dist/orchestrate/plan.js.map +1 -1
- package/dist/orchestrate/spawn-ops.js +2 -2
- package/dist/orchestrate/spawn-ops.js.map +1 -1
- package/dist/orchestration/classify.d.ts +2 -2
- package/dist/orchestration/classify.js +3 -3
- package/dist/orchestration/classify.js.map +1 -1
- package/dist/orchestration/validate-spawn.d.ts.map +1 -1
- package/dist/orchestration/validate-spawn.js +5 -5
- package/dist/orchestration/validate-spawn.js.map +1 -1
- package/dist/paths-export.d.ts +18 -0
- package/dist/paths-export.d.ts.map +1 -0
- package/dist/paths-export.js +18 -0
- package/dist/paths-export.js.map +1 -0
- package/dist/paths.d.ts.map +1 -1
- package/dist/paths.js +24 -11
- package/dist/paths.js.map +1 -1
- package/dist/playbooks/index.d.ts +1 -0
- package/dist/playbooks/index.d.ts.map +1 -1
- package/dist/playbooks/index.js +4 -0
- package/dist/playbooks/index.js.map +1 -1
- package/dist/playbooks/skill-node-executor.d.ts +155 -0
- package/dist/playbooks/skill-node-executor.d.ts.map +1 -0
- package/dist/playbooks/skill-node-executor.js +156 -0
- package/dist/playbooks/skill-node-executor.js.map +1 -0
- package/dist/repair.d.ts +3 -7
- package/dist/repair.d.ts.map +1 -1
- package/dist/repair.js +5 -43
- package/dist/repair.js.map +1 -1
- package/dist/sagas/migrate-containment.js +7 -7
- package/dist/sagas/migrate-containment.js.map +1 -1
- package/dist/scaffold/ensure-dirs.d.ts +8 -2
- package/dist/scaffold/ensure-dirs.d.ts.map +1 -1
- package/dist/scaffold/ensure-dirs.js +24 -11
- package/dist/scaffold/ensure-dirs.js.map +1 -1
- package/dist/scaffold/project-detection.d.ts +5 -1
- package/dist/scaffold/project-detection.d.ts.map +1 -1
- package/dist/scaffold/project-detection.js +9 -5
- package/dist/scaffold/project-detection.js.map +1 -1
- package/dist/sentient/hygiene-scan.js +6 -6
- package/dist/sentient/hygiene-scan.js.map +1 -1
- package/dist/sentient/proposal-dedup.js +2 -2
- package/dist/sentient/proposal-rate-limiter.js +1 -1
- package/dist/sentient/propose-tick.js +5 -5
- package/dist/sentient/propose-tick.js.map +1 -1
- package/dist/sentient/stage-drift-tick.js +3 -3
- package/dist/sentient/stage-drift-tick.js.map +1 -1
- package/dist/sequence/index.d.ts.map +1 -1
- package/dist/sequence/index.js +6 -2
- package/dist/sequence/index.js.map +1 -1
- package/dist/setup/sections/verification.js +2 -2
- package/dist/setup/sections/verification.js.map +1 -1
- package/dist/shutdown.d.ts +81 -0
- package/dist/shutdown.d.ts.map +1 -0
- package/dist/shutdown.js +105 -0
- package/dist/shutdown.js.map +1 -0
- package/dist/skills/index.d.ts +2 -0
- package/dist/skills/index.d.ts.map +1 -1
- package/dist/skills/index.js +1 -0
- package/dist/skills/index.js.map +1 -1
- package/dist/skills/skill-executor-adapter.d.ts +136 -0
- package/dist/skills/skill-executor-adapter.d.ts.map +1 -0
- package/dist/skills/skill-executor-adapter.js +137 -0
- package/dist/skills/skill-executor-adapter.js.map +1 -0
- package/dist/skills/usage-recorder.d.ts.map +1 -1
- package/dist/skills/usage-recorder.js +30 -0
- package/dist/skills/usage-recorder.js.map +1 -1
- package/dist/skills-export.d.ts +23 -0
- package/dist/skills-export.d.ts.map +1 -0
- package/dist/skills-export.js +23 -0
- package/dist/skills-export.js.map +1 -0
- package/dist/stats/index.d.ts.map +1 -1
- package/dist/stats/index.js +8 -3
- package/dist/stats/index.js.map +1 -1
- package/dist/store/agent-doctor.d.ts +3 -3
- package/dist/store/agent-doctor.d.ts.map +1 -1
- package/dist/store/agent-doctor.js +18 -13
- package/dist/store/agent-doctor.js.map +1 -1
- package/dist/store/agent-install.d.ts +6 -5
- package/dist/store/agent-install.d.ts.map +1 -1
- package/dist/store/agent-install.js +20 -16
- package/dist/store/agent-install.js.map +1 -1
- package/dist/store/agent-registry-accessor.d.ts +66 -28
- package/dist/store/agent-registry-accessor.d.ts.map +1 -1
- package/dist/store/agent-registry-accessor.js +248 -167
- package/dist/store/agent-registry-accessor.js.map +1 -1
- package/dist/store/agent-registry-store.d.ts +242 -0
- package/dist/store/agent-registry-store.d.ts.map +1 -0
- package/dist/store/agent-registry-store.js +501 -0
- package/dist/store/agent-registry-store.js.map +1 -0
- package/dist/store/agent-resolver.d.ts +8 -8
- package/dist/store/agent-resolver.d.ts.map +1 -1
- package/dist/store/agent-resolver.js +19 -17
- package/dist/store/agent-resolver.js.map +1 -1
- package/dist/store/backup-pack.d.ts.map +1 -1
- package/dist/store/backup-pack.js +24 -8
- package/dist/store/backup-pack.js.map +1 -1
- package/dist/store/conduit-sqlite.d.ts +181 -74
- package/dist/store/conduit-sqlite.d.ts.map +1 -1
- package/dist/store/conduit-sqlite.js +307 -528
- package/dist/store/conduit-sqlite.js.map +1 -1
- package/dist/store/cross-db-cleanup.d.ts +5 -5
- package/dist/store/cross-db-cleanup.d.ts.map +1 -1
- package/dist/store/cross-db-cleanup.js +12 -10
- package/dist/store/cross-db-cleanup.js.map +1 -1
- package/dist/store/data-accessor.d.ts +4 -4
- package/dist/store/data-accessor.js +5 -5
- package/dist/store/data-accessor.js.map +1 -1
- package/dist/store/data-safety-central.d.ts +83 -1
- package/dist/store/data-safety-central.d.ts.map +1 -1
- package/dist/store/data-safety-central.js +257 -0
- package/dist/store/data-safety-central.js.map +1 -1
- package/dist/store/db-helpers.d.ts +8 -2
- package/dist/store/db-helpers.d.ts.map +1 -1
- package/dist/store/db-helpers.js +6 -2
- package/dist/store/db-helpers.js.map +1 -1
- package/dist/store/dual-scope-db.d.ts +46 -4
- package/dist/store/dual-scope-db.d.ts.map +1 -1
- package/dist/store/dual-scope-db.js +103 -9
- package/dist/store/dual-scope-db.js.map +1 -1
- package/dist/store/exodus/__fixtures__/representative-fixture.d.ts +116 -0
- package/dist/store/exodus/__fixtures__/representative-fixture.d.ts.map +1 -0
- package/dist/store/exodus/__fixtures__/representative-fixture.js +274 -0
- package/dist/store/exodus/__fixtures__/representative-fixture.js.map +1 -0
- package/dist/store/exodus/index.d.ts +3 -1
- package/dist/store/exodus/index.d.ts.map +1 -1
- package/dist/store/exodus/index.js +3 -1
- package/dist/store/exodus/index.js.map +1 -1
- package/dist/store/exodus/migrate.d.ts +120 -1
- package/dist/store/exodus/migrate.d.ts.map +1 -1
- package/dist/store/exodus/migrate.js +923 -119
- package/dist/store/exodus/migrate.js.map +1 -1
- package/dist/store/exodus/on-open.d.ts +189 -0
- package/dist/store/exodus/on-open.d.ts.map +1 -0
- package/dist/store/exodus/on-open.js +464 -0
- package/dist/store/exodus/on-open.js.map +1 -0
- package/dist/store/exodus/table-name-map.d.ts +173 -0
- package/dist/store/exodus/table-name-map.d.ts.map +1 -0
- package/dist/store/exodus/table-name-map.js +660 -0
- package/dist/store/exodus/table-name-map.js.map +1 -0
- package/dist/store/exodus/verify-migration.d.ts +72 -0
- package/dist/store/exodus/verify-migration.d.ts.map +1 -0
- package/dist/store/exodus/verify-migration.js +678 -0
- package/dist/store/exodus/verify-migration.js.map +1 -0
- package/dist/store/exodus/verify.d.ts +32 -8
- package/dist/store/exodus/verify.d.ts.map +1 -1
- package/dist/store/exodus/verify.js +48 -142
- package/dist/store/exodus/verify.js.map +1 -1
- package/dist/store/index.d.ts +2 -3
- package/dist/store/index.d.ts.map +1 -1
- package/dist/store/index.js +2 -3
- package/dist/store/index.js.map +1 -1
- package/dist/store/memory-accessor.d.ts +31 -0
- package/dist/store/memory-accessor.d.ts.map +1 -1
- package/dist/store/memory-accessor.js +38 -0
- package/dist/store/memory-accessor.js.map +1 -1
- package/dist/store/memory-sqlite.d.ts +86 -13
- package/dist/store/memory-sqlite.d.ts.map +1 -1
- package/dist/store/memory-sqlite.js +326 -528
- package/dist/store/memory-sqlite.js.map +1 -1
- package/dist/store/migrate-signaldock-to-conduit.d.ts +1 -1
- package/dist/store/migrate-signaldock-to-conduit.d.ts.map +1 -1
- package/dist/store/migrate-signaldock-to-conduit.js +126 -35
- package/dist/store/migrate-signaldock-to-conduit.js.map +1 -1
- package/dist/store/migration-manager.d.ts +49 -0
- package/dist/store/migration-manager.d.ts.map +1 -1
- package/dist/store/migration-manager.js +167 -67
- package/dist/store/migration-manager.js.map +1 -1
- package/dist/store/migration-sqlite.d.ts +1 -1
- package/dist/store/migration-sqlite.d.ts.map +1 -1
- package/dist/store/migration-sqlite.js +32 -3
- package/dist/store/migration-sqlite.js.map +1 -1
- package/dist/store/nexus-sqlite.d.ts +152 -29
- package/dist/store/nexus-sqlite.d.ts.map +1 -1
- package/dist/store/nexus-sqlite.js +496 -177
- package/dist/store/nexus-sqlite.js.map +1 -1
- package/dist/store/nexus-validation-schemas.d.ts +32 -32
- package/dist/store/open-cleo-db.d.ts +37 -40
- package/dist/store/open-cleo-db.d.ts.map +1 -1
- package/dist/store/open-cleo-db.js +76 -153
- package/dist/store/open-cleo-db.js.map +1 -1
- package/dist/store/role-accessors-impl.d.ts +4 -4
- package/dist/store/role-accessors-impl.d.ts.map +1 -1
- package/dist/store/role-accessors-impl.js +18 -15
- package/dist/store/role-accessors-impl.js.map +1 -1
- package/dist/store/schema/{signaldock-schema.d.ts → agent-registry-schema.d.ts} +15 -5
- package/dist/store/schema/agent-registry-schema.d.ts.map +1 -0
- package/dist/store/schema/{signaldock-schema.js → agent-registry-schema.js} +15 -5
- package/dist/store/schema/agent-registry-schema.js.map +1 -0
- package/dist/store/schema/agent-schema.d.ts +1 -1
- package/dist/store/schema/agent-schema.js +4 -4
- package/dist/store/schema/agent-schema.js.map +1 -1
- package/dist/store/schema/attachments.d.ts +1 -1
- package/dist/store/schema/audit.d.ts +15 -5
- package/dist/store/schema/audit.d.ts.map +1 -1
- package/dist/store/schema/audit.js +12 -2
- package/dist/store/schema/audit.js.map +1 -1
- package/dist/store/schema/background-jobs.d.ts +1 -1
- package/dist/store/schema/cleo-global/{signaldock.d.ts → agent-registry.d.ts} +277 -271
- package/dist/store/schema/cleo-global/agent-registry.d.ts.map +1 -0
- package/dist/store/schema/cleo-global/{signaldock.js → agent-registry.js} +136 -125
- package/dist/store/schema/cleo-global/agent-registry.js.map +1 -0
- package/dist/store/schema/cleo-global/index.d.ts +29 -22
- package/dist/store/schema/cleo-global/index.d.ts.map +1 -1
- package/dist/store/schema/cleo-global/index.js +29 -22
- package/dist/store/schema/cleo-global/index.js.map +1 -1
- package/dist/store/schema/cleo-global/nexus.d.ts +36 -1034
- package/dist/store/schema/cleo-global/nexus.d.ts.map +1 -1
- package/dist/store/schema/cleo-global/nexus.js +32 -337
- package/dist/store/schema/cleo-global/nexus.js.map +1 -1
- package/dist/store/schema/cleo-global/skills.d.ts +16 -0
- package/dist/store/schema/cleo-global/skills.d.ts.map +1 -1
- package/dist/store/schema/cleo-global/skills.js +11 -0
- package/dist/store/schema/cleo-global/skills.js.map +1 -1
- package/dist/store/schema/{cleo-project → cleo-global}/telemetry.d.ts +33 -17
- package/dist/store/schema/cleo-global/telemetry.d.ts.map +1 -0
- package/dist/store/schema/{cleo-project → cleo-global}/telemetry.js +30 -18
- package/dist/store/schema/cleo-global/telemetry.js.map +1 -0
- package/dist/store/schema/cleo-project/audit.d.ts +8 -8
- package/dist/store/schema/cleo-project/audit.d.ts.map +1 -1
- package/dist/store/schema/cleo-project/audit.js +2 -6
- package/dist/store/schema/cleo-project/audit.js.map +1 -1
- package/dist/store/schema/cleo-project/docs.d.ts +1 -1
- package/dist/store/schema/cleo-project/index.d.ts +29 -12
- package/dist/store/schema/cleo-project/index.d.ts.map +1 -1
- package/dist/store/schema/cleo-project/index.js +29 -12
- package/dist/store/schema/cleo-project/index.js.map +1 -1
- package/dist/store/schema/cleo-project/lifecycle.d.ts +2 -2
- package/dist/store/schema/cleo-project/nexus-graph.d.ts +1067 -0
- package/dist/store/schema/cleo-project/nexus-graph.d.ts.map +1 -0
- package/dist/store/schema/cleo-project/nexus-graph.js +407 -0
- package/dist/store/schema/cleo-project/nexus-graph.js.map +1 -0
- package/dist/store/schema/cleo-project/provenance-orphans.d.ts +385 -0
- package/dist/store/schema/cleo-project/provenance-orphans.d.ts.map +1 -0
- package/dist/store/schema/cleo-project/provenance-orphans.js +142 -0
- package/dist/store/schema/cleo-project/provenance-orphans.js.map +1 -0
- package/dist/store/schema/cleo-project/provenance-rest.d.ts +1 -1
- package/dist/store/schema/cleo-project/runtime.d.ts +1 -1
- package/dist/store/schema/cleo-project/tasks-core-batch2.d.ts +1 -1
- package/dist/store/schema/cleo-project/tasks-core.d.ts +3 -3
- package/dist/store/schema/cleo-shared/brain.d.ts +711 -494
- package/dist/store/schema/cleo-shared/brain.d.ts.map +1 -1
- package/dist/store/schema/cleo-shared/brain.js +215 -134
- package/dist/store/schema/cleo-shared/brain.js.map +1 -1
- package/dist/store/schema/conduit-schema.d.ts +63 -51
- package/dist/store/schema/conduit-schema.d.ts.map +1 -1
- package/dist/store/schema/conduit-schema.js +23 -11
- package/dist/store/schema/conduit-schema.js.map +1 -1
- package/dist/store/schema/goal.d.ts +3 -2
- package/dist/store/schema/goal.d.ts.map +1 -1
- package/dist/store/schema/goal.js +3 -2
- package/dist/store/schema/goal.js.map +1 -1
- package/dist/store/schema/index.d.ts +1 -0
- package/dist/store/schema/index.d.ts.map +1 -1
- package/dist/store/schema/index.js +1 -0
- package/dist/store/schema/index.js.map +1 -1
- package/dist/store/schema/lifecycle.d.ts +2 -2
- package/dist/store/schema/memory-schema.d.ts +2 -2
- package/dist/store/schema/nexus-schema.d.ts +174 -115
- package/dist/store/schema/nexus-schema.d.ts.map +1 -1
- package/dist/store/schema/nexus-schema.js +175 -55
- package/dist/store/schema/nexus-schema.js.map +1 -1
- package/dist/store/schema/provenance/releases.d.ts +1 -1
- package/dist/store/schema/schema-utils.d.ts +78 -0
- package/dist/store/schema/schema-utils.d.ts.map +1 -0
- package/dist/store/schema/schema-utils.js +49 -0
- package/dist/store/schema/schema-utils.js.map +1 -0
- package/dist/store/schema/skills-schema.d.ts +81 -44
- package/dist/store/schema/skills-schema.d.ts.map +1 -1
- package/dist/store/schema/skills-schema.js +49 -16
- package/dist/store/schema/skills-schema.js.map +1 -1
- package/dist/store/schema/tasks.d.ts +3 -3
- package/dist/store/skills-db.d.ts +90 -50
- package/dist/store/skills-db.d.ts.map +1 -1
- package/dist/store/skills-db.js +132 -146
- package/dist/store/skills-db.js.map +1 -1
- package/dist/store/sqlite-backup.d.ts +2 -2
- package/dist/store/sqlite-backup.d.ts.map +1 -1
- package/dist/store/sqlite-backup.js +11 -10
- package/dist/store/sqlite-backup.js.map +1 -1
- package/dist/store/sqlite-data-accessor.d.ts.map +1 -1
- package/dist/store/sqlite-data-accessor.js +25 -18
- package/dist/store/sqlite-data-accessor.js.map +1 -1
- package/dist/store/sqlite.d.ts +72 -12
- package/dist/store/sqlite.d.ts.map +1 -1
- package/dist/store/sqlite.js +153 -89
- package/dist/store/sqlite.js.map +1 -1
- package/dist/store/tasks-schema.d.ts +4 -0
- package/dist/store/tasks-schema.d.ts.map +1 -1
- package/dist/store/tasks-schema.js +60 -0
- package/dist/store/tasks-schema.js.map +1 -1
- package/dist/store/tasks-sqlite.d.ts +2 -2
- package/dist/store/tasks-sqlite.d.ts.map +1 -1
- package/dist/store/tasks-sqlite.js +10 -5
- package/dist/store/tasks-sqlite.js.map +1 -1
- package/dist/store/umbrella-data-accessor.d.ts +17 -6
- package/dist/store/umbrella-data-accessor.d.ts.map +1 -1
- package/dist/store/umbrella-data-accessor.js +8 -8
- package/dist/store/umbrella-data-accessor.js.map +1 -1
- package/dist/store/validation-schemas.d.ts +241 -208
- package/dist/store/validation-schemas.d.ts.map +1 -1
- package/dist/system/health.d.ts.map +1 -1
- package/dist/system/health.js +11 -6
- package/dist/system/health.js.map +1 -1
- package/dist/system/project-health.d.ts.map +1 -1
- package/dist/system/project-health.js +58 -12
- package/dist/system/project-health.js.map +1 -1
- package/dist/tasks/add.d.ts +8 -0
- package/dist/tasks/add.d.ts.map +1 -1
- package/dist/tasks/add.js +101 -0
- package/dist/tasks/add.js.map +1 -1
- package/dist/tasks/cancelled-child-waiver-audit.d.ts +47 -0
- package/dist/tasks/cancelled-child-waiver-audit.d.ts.map +1 -0
- package/dist/tasks/cancelled-child-waiver-audit.js +34 -0
- package/dist/tasks/cancelled-child-waiver-audit.js.map +1 -0
- package/dist/tasks/complete.d.ts +22 -2
- package/dist/tasks/complete.d.ts.map +1 -1
- package/dist/tasks/complete.js +71 -6
- package/dist/tasks/complete.js.map +1 -1
- package/dist/tasks/compute-task-view.js +1 -1
- package/dist/tasks/session-scope.d.ts +5 -0
- package/dist/tasks/session-scope.d.ts.map +1 -1
- package/dist/tasks/session-scope.js +4 -0
- package/dist/tasks/session-scope.js.map +1 -1
- package/dist/tools/guard.d.ts +71 -1
- package/dist/tools/guard.d.ts.map +1 -1
- package/dist/tools/guard.js +73 -1
- package/dist/tools/guard.js.map +1 -1
- package/dist/tools/index.d.ts +21 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +25 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/upgrade.d.ts.map +1 -1
- package/dist/upgrade.js +22 -13
- package/dist/upgrade.js.map +1 -1
- package/dist/workgraph/containment.js +18 -18
- package/dist/workgraph/relations.js +2 -2
- package/dist/worktree/list.d.ts +1 -1
- package/dist/worktree/list.d.ts.map +1 -1
- package/dist/worktree/list.js +19 -21
- package/dist/worktree/list.js.map +1 -1
- package/dist/worktree-export.d.ts +18 -0
- package/dist/worktree-export.d.ts.map +1 -0
- package/dist/worktree-export.js +18 -0
- package/dist/worktree-export.js.map +1 -0
- package/migrations/drizzle-agent-registry/20260412000000_initial-global-agent-registry/migration.sql +29 -0
- package/migrations/drizzle-brain/20260601000001_t11522-brain-task-observations/migration.sql +28 -0
- package/migrations/drizzle-brain/20260601000002_t11522-inline-only-brain-tables/migration.sql +75 -0
- package/migrations/drizzle-cleo-global/20260531000001_t11363-consolidation-cleo-global/migration.sql +49 -144
- package/migrations/drizzle-cleo-global/20260531000001_t11363-consolidation-cleo-global/snapshot.json +8 -8
- package/migrations/drizzle-cleo-global/20260531000002_t11546-brain-usage-log/migration.sql +16 -0
- package/migrations/drizzle-cleo-global/20260601000001_t11544-skills-usage-project-id/migration.sql +12 -0
- package/migrations/drizzle-cleo-global/20260602000001_t11622-agent-registry-rename/migration.sql +80 -0
- package/migrations/drizzle-cleo-project/20260531000001_t11363-consolidation-cleo-project/migration.sql +26 -167
- package/migrations/drizzle-cleo-project/20260531000001_t11363-consolidation-cleo-project/snapshot.json +8 -8
- package/migrations/drizzle-cleo-project/20260531000002_t11546-brain-usage-log/migration.sql +21 -0
- package/migrations/drizzle-cleo-project/20260601000001_t11549-agent-credentials-brain-release-links/migration.sql +49 -0
- package/migrations/drizzle-cleo-project/20260601000002_t11538-project-nexus-graph/migration.sql +140 -0
- package/migrations/drizzle-cleo-project/20260602000002_t11649-token-usage-transport-mcp/migration.sql +146 -0
- package/migrations/drizzle-conduit/20260601000003_t11523-conduit-inline-schema/migration.sql +82 -0
- package/migrations/drizzle-nexus/20260421200001_t1165-baseline-reset/migration.sql +26 -8
- package/migrations/drizzle-nexus/20260601000001_t11545-nexus-relation-weights-partition/migration.sql +97 -0
- package/package.json +44 -12
- package/scripts/install-supervisor-binary.mjs +50 -201
- package/scripts/napi-binary-picker.mjs +267 -0
- package/dist/agents/agent-registry.d.ts.map +0 -1
- package/dist/agents/agent-registry.js.map +0 -1
- package/dist/store/data-safety.d.ts +0 -92
- package/dist/store/data-safety.d.ts.map +0 -1
- package/dist/store/data-safety.js +0 -274
- package/dist/store/data-safety.js.map +0 -1
- package/dist/store/schema/cleo-global/signaldock.d.ts.map +0 -1
- package/dist/store/schema/cleo-global/signaldock.js.map +0 -1
- package/dist/store/schema/cleo-project/telemetry.d.ts.map +0 -1
- package/dist/store/schema/cleo-project/telemetry.js.map +0 -1
- package/dist/store/schema/signaldock-schema.d.ts.map +0 -1
- package/dist/store/schema/signaldock-schema.js.map +0 -1
- package/dist/store/signaldock-sqlite.d.ts +0 -173
- package/dist/store/signaldock-sqlite.d.ts.map +0 -1
- package/dist/store/signaldock-sqlite.js +0 -445
- package/dist/store/signaldock-sqlite.js.map +0 -1
- package/migrations/drizzle-nexus/20260318205558_initial/migration.sql +0 -46
- package/migrations/drizzle-nexus/20260412000001_t529-nexus-graph-tables/migration.sql +0 -49
- package/migrations/drizzle-nexus/20260415000001_t622-project-registry-paths/migration.sql +0 -12
- package/migrations/drizzle-nexus/20260419000001_t998-nexus-plasticity/migration.sql +0 -13
- package/migrations/drizzle-nexus/20260423052640_t1077-add-user-profile-table/migration.sql +0 -16
- package/migrations/drizzle-nexus/20260423052640_t1077-add-user-profile-table/snapshot.json +0 -1531
- package/migrations/drizzle-nexus/20260424140538_t1148-add-sigils-table/migration.sql +0 -13
- package/migrations/drizzle-nexus/20260424140538_t1148-add-sigils-table/snapshot.json +0 -1652
- package/migrations/drizzle-nexus/20260504000001_t1839-fts5-nexus-symbols/migration.sql +0 -68
- package/migrations/drizzle-nexus/20260507135519_t9163-nexus-is-external/migration.sql +0 -20
- package/migrations/drizzle-nexus/20260507135519_t9163-nexus-is-external/snapshot.json +0 -1652
- package/migrations/drizzle-nexus/20260526222449_t11025-project-id-aliases/migration.sql +0 -16
- package/migrations/drizzle-signaldock/20260412000000_initial-global-signaldock/migration.sql +0 -209
- package/migrations/drizzle-signaldock/20260412000000_initial-global-signaldock/snapshot.json +0 -2060
|
@@ -1,34 +1,56 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Agent Registry Accessor — cross-DB CRUD for agent data.
|
|
3
3
|
*
|
|
4
|
-
* Post-
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
4
|
+
* Post-T11622 cutover (folds T11578 AC2), agent identity lives in the GLOBAL
|
|
5
|
+
* PREFIXED `agent_registry_agents` table (+ `agent_registry_capabilities` /
|
|
6
|
+
* `agent_registry_skills` / `agent_registry_agent_capabilities` /
|
|
7
|
+
* `agent_registry_agent_skills`); per-project visibility and overrides live in the
|
|
8
|
+
* PROJECT `conduit_project_agent_refs` table (T11578 · AC4 — conduit namespace
|
|
9
|
+
* cutover). The bare legacy `agents` shape is no longer read or written.
|
|
8
10
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* `
|
|
11
|
+
* Post-E6-L5 (T11525) / E6-L6 (T11526), both tables are hosted inside the
|
|
12
|
+
* CONSOLIDATED dual-scope `cleo.db` files (global `$XDG_DATA_HOME/cleo/cleo.db`
|
|
13
|
+
* and project `.cleo/cleo.db`) — the standalone `signaldock.db` / `conduit.db`
|
|
14
|
+
* files are gone. The global `agent_registry_*` tables are owned by the
|
|
15
|
+
* consolidated cleo-global migration (T11622 rename of `signaldock_*`);
|
|
16
|
+
* `ensureGlobalAgentRegistryDb()` opens the shared consolidated handle. The
|
|
17
|
+
* prefixed conduit `conduit_project_agent_refs` table is created by the
|
|
18
|
+
* consolidated cleo-project migration (T11578 · AC4) and `ensureConduitDb()`
|
|
19
|
+
* ensures the project `cleo.db` is open. The read path MUST therefore go through
|
|
20
|
+
* those `ensure*` calls so it shares the same handle as the write path (T11562 —
|
|
21
|
+
* agents read/write path divergence regression).
|
|
22
|
+
*
|
|
23
|
+
* The consolidated `agent_registry_agents` table carries TEXT ISO-8601 timestamps
|
|
24
|
+
* (`created_at` / `updated_at` / `last_used_at`, each with a GLOB CHECK) — every
|
|
25
|
+
* write path below stamps ISO strings, not the legacy epoch integers (T11622
|
|
26
|
+
* write-path constraint reconciliation).
|
|
27
|
+
*
|
|
28
|
+
* This module provides three module-level functions that perform the in-memory
|
|
29
|
+
* cross-DB join, plus the backward-compatible `AgentRegistryAccessor` class that
|
|
30
|
+
* wraps them.
|
|
12
31
|
*
|
|
13
32
|
* Architecture:
|
|
14
|
-
* global
|
|
15
|
-
* project
|
|
33
|
+
* global cleo.db — canonical identity `agent_registry_agents` (openGlobalDb → ensureGlobalAgentRegistryDb)
|
|
34
|
+
* project cleo.db — `conduit_project_agent_refs` (openConduitDb)
|
|
16
35
|
* Join performed in Node (SQLite cannot cross-file-handle JOIN).
|
|
17
36
|
*
|
|
18
37
|
* @see .cleo/rcasd/T310/specification/T310-specification.md §3.5
|
|
19
38
|
* @see .cleo/adrs/ADR-037-conduit-signaldock-separation.md
|
|
20
39
|
* @task T355
|
|
40
|
+
* @task T11562
|
|
41
|
+
* @task T11622
|
|
21
42
|
* @epic T310
|
|
43
|
+
* @epic T11249
|
|
22
44
|
*/
|
|
23
45
|
import { randomBytes } from 'node:crypto';
|
|
24
46
|
import { existsSync, mkdirSync, readFileSync, statSync, writeFileSync } from 'node:fs';
|
|
25
47
|
import { createRequire } from 'node:module';
|
|
26
48
|
import { join } from 'node:path';
|
|
27
49
|
import { getCleoHome } from '../paths.js';
|
|
50
|
+
import { ensureGlobalAgentRegistryDb, getGlobalAgentRegistryNativeDb, } from './agent-registry-store.js';
|
|
28
51
|
import { deriveApiKey } from './api-key-kdf.js';
|
|
29
52
|
import { ensureConduitDb, getConduitDbPath } from './conduit-sqlite.js';
|
|
30
53
|
import { getGlobalSalt } from './global-salt.js';
|
|
31
|
-
import { ensureGlobalSignaldockDb, getGlobalSignaldockDbPath } from './signaldock-sqlite.js';
|
|
32
54
|
import { applyPerfPragmas } from './sqlite-pragmas.js';
|
|
33
55
|
// ---------------------------------------------------------------------------
|
|
34
56
|
// node:sqlite interop (createRequire for ESM / Vitest compat)
|
|
@@ -96,12 +118,12 @@ function rowToProjectRef(row) {
|
|
|
96
118
|
};
|
|
97
119
|
}
|
|
98
120
|
/**
|
|
99
|
-
* Convert a global
|
|
121
|
+
* Convert a global cleo.db:agent_registry_agents row to an `AgentCredential`.
|
|
100
122
|
* API key is stored as binary (derived via KDF) — returned as hex string.
|
|
101
123
|
* Legacy encrypted values (pre-T310) are left as-is; the reauth flag handles
|
|
102
124
|
* forced re-authentication at the CLI layer.
|
|
103
125
|
*
|
|
104
|
-
* @param row - Raw SQLite row from global
|
|
126
|
+
* @param row - Raw SQLite row from global cleo.db:agent_registry_agents.
|
|
105
127
|
* @returns Typed `AgentCredential` (apiKey is hex-encoded derived bytes or empty).
|
|
106
128
|
* @task T355
|
|
107
129
|
* @epic T310
|
|
@@ -122,9 +144,11 @@ function rowToCredential(row) {
|
|
|
122
144
|
transportType: (row.transport_type ?? 'http'),
|
|
123
145
|
transportConfig: JSON.parse(row.transport_config),
|
|
124
146
|
isActive: row.is_active === 1,
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
147
|
+
// T11622 cutover: `agent_registry_agents` timestamps are TEXT ISO-8601 — read
|
|
148
|
+
// through as-is (no epoch→ms conversion).
|
|
149
|
+
lastUsedAt: row.last_used_at ?? undefined,
|
|
150
|
+
createdAt: row.created_at,
|
|
151
|
+
updatedAt: row.updated_at,
|
|
128
152
|
};
|
|
129
153
|
}
|
|
130
154
|
/**
|
|
@@ -149,7 +173,7 @@ function coerceTier(value) {
|
|
|
149
173
|
* 'fallback', canSpawn: false, orchLevel: 2). Callers that need strict
|
|
150
174
|
* migration presence MUST check `row.tier !== undefined` before invoking.
|
|
151
175
|
*
|
|
152
|
-
* @param row - Raw SQLite row from
|
|
176
|
+
* @param row - Raw SQLite row from cleo.db:agent_registry_agents
|
|
153
177
|
* @returns The extended field block, with safe fallbacks for absent columns
|
|
154
178
|
* @task T897
|
|
155
179
|
* @epic T889
|
|
@@ -181,7 +205,7 @@ function rowToExtendedFields(row) {
|
|
|
181
205
|
* never been bound to a `.cant`). Callers that need a synthesized fallback
|
|
182
206
|
* envelope MUST handle the null return explicitly.
|
|
183
207
|
*
|
|
184
|
-
* @param row - Raw
|
|
208
|
+
* @param row - Raw agent_registry_agents row from the global cleo.db
|
|
185
209
|
* @returns A ResolvedAgent envelope, or null when provenance is missing
|
|
186
210
|
* @task T897
|
|
187
211
|
* @epic T889
|
|
@@ -209,7 +233,7 @@ export function rowToResolvedAgent(row) {
|
|
|
209
233
|
* Merge a global agent row with an optional project_agent_refs row into an
|
|
210
234
|
* `AgentWithProjectOverride` object.
|
|
211
235
|
*
|
|
212
|
-
* @param agentRow - Row from global
|
|
236
|
+
* @param agentRow - Row from global cleo.db:agent_registry_agents.
|
|
213
237
|
* @param refRow - Row from conduit.db:project_agent_refs, or null.
|
|
214
238
|
* @returns Merged `AgentWithProjectOverride`.
|
|
215
239
|
* @task T355
|
|
@@ -225,16 +249,43 @@ function mergeToAgentWithOverride(agentRow, refRow) {
|
|
|
225
249
|
// Database handle helpers (short-lived, caller closes)
|
|
226
250
|
// ---------------------------------------------------------------------------
|
|
227
251
|
/**
|
|
228
|
-
*
|
|
229
|
-
*
|
|
252
|
+
* Acquire the SHARED, fully-migrated handle to the GLOBAL agent identity DB —
|
|
253
|
+
* the consolidated dual-scope global `cleo.db` (post-E6-L5 / T11525).
|
|
254
|
+
*
|
|
255
|
+
* Routes through {@link ensureGlobalAgentRegistryDb}, which opens the consolidated
|
|
256
|
+
* `cleo.db` via `openDualScopeDb('global')` (whose consolidated cleo-global
|
|
257
|
+
* migration creates the prefixed `agent_registry_*` tables this accessor's raw SQL
|
|
258
|
+
* now queries, post-T11622 cutover), reconciles the health-probe ledger, and
|
|
259
|
+
* stores the native handle for reuse. The returned handle is the SAME one the
|
|
260
|
+
* write path uses — reads and writes are aligned to `cleo.db` (T11562).
|
|
261
|
+
*
|
|
262
|
+
* Replaces the previous `new DatabaseSync(getGlobalAgentRegistryDbPath())` raw-open,
|
|
263
|
+
* which diverged from the write path (T11562).
|
|
264
|
+
*
|
|
265
|
+
* The handle is SHARED and co-owned by the nexus / skills global domains — its
|
|
266
|
+
* lifecycle is owned by `openDualScopeDb`. Callers MUST NOT call `db.close()` on
|
|
267
|
+
* it (doing so would break in-flight sibling queries). This is why every former
|
|
268
|
+
* `globalDb.close()` in this module was removed (T11562).
|
|
230
269
|
*
|
|
270
|
+
* @returns The shared consolidated global `cleo.db` native handle.
|
|
271
|
+
* @throws {Error} If the shared handle is unexpectedly absent after ensure.
|
|
231
272
|
* @task T355
|
|
273
|
+
* @task T11562
|
|
232
274
|
* @epic T310
|
|
275
|
+
* @epic T11249
|
|
233
276
|
*/
|
|
234
|
-
function openGlobalDb() {
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
277
|
+
async function openGlobalDb() {
|
|
278
|
+
// Idempotent: opens the consolidated global cleo.db, runs the legacy
|
|
279
|
+
// (the consolidated cleo-global migration creates the agent_registry_* tables),
|
|
280
|
+
// and caches the shared native handle (T11622 cutover).
|
|
281
|
+
await ensureGlobalAgentRegistryDb();
|
|
282
|
+
const db = getGlobalAgentRegistryNativeDb();
|
|
283
|
+
if (!db) {
|
|
284
|
+
throw new Error('openGlobalDb: ensureGlobalAgentRegistryDb() did not yield a shared global ' +
|
|
285
|
+
'cleo.db handle (getGlobalAgentRegistryNativeDb() returned null). This indicates ' +
|
|
286
|
+
'the dual-scope global chokepoint failed to initialize — fix the caller, do ' +
|
|
287
|
+
'not suppress.');
|
|
288
|
+
}
|
|
238
289
|
return db;
|
|
239
290
|
}
|
|
240
291
|
/**
|
|
@@ -252,13 +303,13 @@ function openConduitDb(projectRoot) {
|
|
|
252
303
|
return db;
|
|
253
304
|
}
|
|
254
305
|
// ---------------------------------------------------------------------------
|
|
255
|
-
// junction table sync (global
|
|
306
|
+
// junction table sync (global cleo.db (Agent Registry) only)
|
|
256
307
|
// ---------------------------------------------------------------------------
|
|
257
308
|
/**
|
|
258
|
-
* Sync capabilities/skills to junction tables in global
|
|
309
|
+
* Sync capabilities/skills to junction tables in global cleo.db (Agent Registry).
|
|
259
310
|
* Junction tables are the SSoT — JSON columns are a materialized cache.
|
|
260
311
|
*
|
|
261
|
-
* @param db - Open handle to global
|
|
312
|
+
* @param db - Open handle to global cleo.db (Agent Registry).
|
|
262
313
|
* @param agentUuid - The `id` (UUID primary key) from the agents row.
|
|
263
314
|
* @param capabilities - Array of capability slugs.
|
|
264
315
|
* @param skills - Array of skill slugs.
|
|
@@ -266,18 +317,20 @@ function openConduitDb(projectRoot) {
|
|
|
266
317
|
* @epic T310
|
|
267
318
|
*/
|
|
268
319
|
function syncJunctionTables(db, agentUuid, capabilities, skills) {
|
|
269
|
-
db.prepare('DELETE FROM
|
|
270
|
-
db.prepare('DELETE FROM
|
|
320
|
+
db.prepare('DELETE FROM agent_registry_agent_capabilities WHERE agent_id = ?').run(agentUuid);
|
|
321
|
+
db.prepare('DELETE FROM agent_registry_agent_skills WHERE agent_id = ?').run(agentUuid);
|
|
271
322
|
for (const cap of capabilities) {
|
|
272
|
-
const capRow = db
|
|
323
|
+
const capRow = db
|
|
324
|
+
.prepare('SELECT id FROM agent_registry_capabilities WHERE slug = ?')
|
|
325
|
+
.get(cap);
|
|
273
326
|
if (capRow) {
|
|
274
|
-
db.prepare('INSERT OR IGNORE INTO
|
|
327
|
+
db.prepare('INSERT OR IGNORE INTO agent_registry_agent_capabilities (agent_id, capability_id) VALUES (?, ?)').run(agentUuid, capRow.id);
|
|
275
328
|
}
|
|
276
329
|
}
|
|
277
330
|
for (const skill of skills) {
|
|
278
|
-
const skillRow = db.prepare('SELECT id FROM
|
|
331
|
+
const skillRow = db.prepare('SELECT id FROM agent_registry_skills WHERE slug = ?').get(skill);
|
|
279
332
|
if (skillRow) {
|
|
280
|
-
db.prepare('INSERT OR IGNORE INTO
|
|
333
|
+
db.prepare('INSERT OR IGNORE INTO agent_registry_agent_skills (agent_id, skill_id) VALUES (?, ?)').run(agentUuid, skillRow.id);
|
|
281
334
|
}
|
|
282
335
|
}
|
|
283
336
|
}
|
|
@@ -285,7 +338,7 @@ function syncJunctionTables(db, agentUuid, capabilities, skills) {
|
|
|
285
338
|
// Module-level cross-DB functions (spec §3.5)
|
|
286
339
|
// ---------------------------------------------------------------------------
|
|
287
340
|
/**
|
|
288
|
-
* Cross-DB agent lookup. Opens both the global
|
|
341
|
+
* Cross-DB agent lookup. Opens both the global cleo.db (Agent Registry) and the
|
|
289
342
|
* current project's conduit.db, joins project_agent_refs ⨝ agents by
|
|
290
343
|
* agentId, and returns the merged view.
|
|
291
344
|
*
|
|
@@ -299,27 +352,42 @@ function syncJunctionTables(db, agentUuid, capabilities, skills) {
|
|
|
299
352
|
* Dangling soft-FK detection: if a project_agent_refs row exists but the
|
|
300
353
|
* referenced global agent does not, logs a WARN and returns null.
|
|
301
354
|
*
|
|
355
|
+
* Both `agents` (global) and `project_agent_refs` (project) tables are
|
|
356
|
+
* materialized into their consolidated `cleo.db` files lazily, so this function
|
|
357
|
+
* ensures both DBs (via the shared `openGlobalDb` / `ensureConduitDb`
|
|
358
|
+
* chokepoints) before reading — keeping the read path aligned with the write
|
|
359
|
+
* path (T11562). It is therefore async.
|
|
360
|
+
*
|
|
302
361
|
* @param projectRoot - Absolute path to the project root directory.
|
|
303
362
|
* @param agentId - Agent business identifier.
|
|
304
363
|
* @param opts.includeGlobal - When true, returns global identity even without project ref.
|
|
305
364
|
* @returns Merged agent record or null if not found.
|
|
306
365
|
*
|
|
307
366
|
* @task T355
|
|
367
|
+
* @task T11562
|
|
308
368
|
* @epic T310
|
|
369
|
+
* @epic T11249
|
|
309
370
|
*/
|
|
310
|
-
export function lookupAgent(projectRoot, agentId, opts) {
|
|
371
|
+
export async function lookupAgent(projectRoot, agentId, opts) {
|
|
311
372
|
const includeGlobal = opts?.includeGlobal ?? false;
|
|
312
|
-
|
|
373
|
+
// Ensure the consolidated project cleo.db has the prefixed
|
|
374
|
+
// `conduit_project_agent_refs` table (T11578 · AC4) before the raw-open read
|
|
375
|
+
// below (mirrors the global side, which is ensured inside openGlobalDb).
|
|
376
|
+
await ensureConduitDb(projectRoot);
|
|
377
|
+
// SHARED global cleo.db handle — do NOT close (lifecycle owned by openDualScopeDb).
|
|
378
|
+
const globalDb = await openGlobalDb();
|
|
313
379
|
const conduitDb = openConduitDb(projectRoot);
|
|
314
380
|
try {
|
|
315
|
-
const agentRow = globalDb
|
|
381
|
+
const agentRow = globalDb
|
|
382
|
+
.prepare('SELECT * FROM agent_registry_agents WHERE agent_id = ?')
|
|
383
|
+
.get(agentId);
|
|
316
384
|
const refRow = conduitDb
|
|
317
|
-
.prepare('SELECT * FROM
|
|
385
|
+
.prepare('SELECT * FROM conduit_project_agent_refs WHERE agent_id = ?')
|
|
318
386
|
.get(agentId);
|
|
319
387
|
// Dangling soft-FK: ref exists in conduit but not in global
|
|
320
388
|
if (refRow && !agentRow) {
|
|
321
389
|
console.warn(`[agent-registry-accessor] WARN: dangling project_agent_refs row for agent_id="${agentId}". ` +
|
|
322
|
-
`No matching row in global
|
|
390
|
+
`No matching row in global cleo.db:agents. Row will be ignored.`);
|
|
323
391
|
return null;
|
|
324
392
|
}
|
|
325
393
|
// Agent does not exist globally at all
|
|
@@ -336,7 +404,7 @@ export function lookupAgent(projectRoot, agentId, opts) {
|
|
|
336
404
|
return mergeToAgentWithOverride(agentRow, effectiveRef);
|
|
337
405
|
}
|
|
338
406
|
finally {
|
|
339
|
-
globalDb
|
|
407
|
+
// NOTE: globalDb is the SHARED dual-scope handle — never close it (T11562).
|
|
340
408
|
conduitDb.close();
|
|
341
409
|
}
|
|
342
410
|
}
|
|
@@ -352,25 +420,38 @@ export function lookupAgent(projectRoot, agentId, opts) {
|
|
|
352
420
|
* includeDisabled=true: also returns agents with enabled=0 in project_agent_refs.
|
|
353
421
|
* Ignored when includeGlobal=true (all global agents are returned regardless).
|
|
354
422
|
*
|
|
423
|
+
* Both `agents` (global) and `project_agent_refs` (project) tables are
|
|
424
|
+
* materialized into their consolidated `cleo.db` files lazily, so this function
|
|
425
|
+
* ensures both DBs (via the shared `openGlobalDb` / `ensureConduitDb`
|
|
426
|
+
* chokepoints) before reading — keeping the read path aligned with the write
|
|
427
|
+
* path (T11562). It is therefore async.
|
|
428
|
+
*
|
|
355
429
|
* @param projectRoot - Absolute path to the project root directory.
|
|
356
430
|
* @param opts.includeGlobal - Include all global agents (bypasses project filter).
|
|
357
431
|
* @param opts.includeDisabled - Include agents with enabled=0 in project_agent_refs.
|
|
358
432
|
* @returns Array of merged agent records.
|
|
359
433
|
*
|
|
360
434
|
* @task T355
|
|
435
|
+
* @task T11562
|
|
361
436
|
* @epic T310
|
|
437
|
+
* @epic T11249
|
|
362
438
|
*/
|
|
363
|
-
export function listAgentsForProject(projectRoot, opts) {
|
|
439
|
+
export async function listAgentsForProject(projectRoot, opts) {
|
|
364
440
|
const includeGlobal = opts?.includeGlobal ?? false;
|
|
365
441
|
const includeDisabled = opts?.includeDisabled ?? false;
|
|
366
|
-
|
|
442
|
+
// Ensure the consolidated project cleo.db has the prefixed
|
|
443
|
+
// `conduit_project_agent_refs` table (T11578 · AC4) before the raw-open read
|
|
444
|
+
// below (mirrors the global side, which is ensured inside openGlobalDb).
|
|
445
|
+
await ensureConduitDb(projectRoot);
|
|
446
|
+
// SHARED global cleo.db handle — do NOT close (lifecycle owned by openDualScopeDb).
|
|
447
|
+
const globalDb = await openGlobalDb();
|
|
367
448
|
const conduitDb = openConduitDb(projectRoot);
|
|
368
449
|
try {
|
|
369
450
|
const allAgents = globalDb
|
|
370
|
-
.prepare('SELECT * FROM
|
|
451
|
+
.prepare('SELECT * FROM agent_registry_agents ORDER BY name ASC')
|
|
371
452
|
.all();
|
|
372
453
|
const allRefs = conduitDb
|
|
373
|
-
.prepare('SELECT * FROM
|
|
454
|
+
.prepare('SELECT * FROM conduit_project_agent_refs')
|
|
374
455
|
.all();
|
|
375
456
|
// Build a map from agentId → ref row for O(1) lookup during join
|
|
376
457
|
const refMap = new Map();
|
|
@@ -397,12 +478,12 @@ export function listAgentsForProject(projectRoot, opts) {
|
|
|
397
478
|
return result;
|
|
398
479
|
}
|
|
399
480
|
finally {
|
|
400
|
-
globalDb
|
|
481
|
+
// NOTE: globalDb is the SHARED dual-scope handle — never close it (T11562).
|
|
401
482
|
conduitDb.close();
|
|
402
483
|
}
|
|
403
484
|
}
|
|
404
485
|
/**
|
|
405
|
-
* Creates a new agent: writes identity row to global
|
|
486
|
+
* Creates a new agent: writes identity row to global cleo.db (Agent Registry) AND attaches
|
|
406
487
|
* it to the current project via conduit.db:project_agent_refs.
|
|
407
488
|
*
|
|
408
489
|
* Write order: global first, then project ref. If the project ref write fails,
|
|
@@ -417,9 +498,12 @@ export function listAgentsForProject(projectRoot, opts) {
|
|
|
417
498
|
* @task T355
|
|
418
499
|
* @epic T310
|
|
419
500
|
*/
|
|
420
|
-
export function createProjectAgent(projectRoot, spec) {
|
|
421
|
-
|
|
422
|
-
|
|
501
|
+
export async function createProjectAgent(projectRoot, spec) {
|
|
502
|
+
// E6-L3 (T11523): ensureConduitDb is now async (routes through the dual-scope
|
|
503
|
+
// cleo.db chokepoint). ensureGlobalAgentRegistryDb is already async. Await both so
|
|
504
|
+
// the bare schema exists before the short-lived raw handles below read/write it.
|
|
505
|
+
await ensureGlobalAgentRegistryDb();
|
|
506
|
+
await ensureConduitDb(projectRoot);
|
|
423
507
|
const nowTs = Math.floor(Date.now() / 1000);
|
|
424
508
|
const nowIso = new Date(nowTs * 1000).toISOString();
|
|
425
509
|
// Derive API key using the T310 KDF
|
|
@@ -432,52 +516,53 @@ export function createProjectAgent(projectRoot, spec) {
|
|
|
432
516
|
});
|
|
433
517
|
// Store as hex string in the encrypted column
|
|
434
518
|
const apiKeyEncrypted = derivedKey.toString('hex');
|
|
435
|
-
|
|
436
|
-
|
|
519
|
+
// SHARED global cleo.db handle — do NOT close (lifecycle owned by openDualScopeDb).
|
|
520
|
+
const globalDb = await openGlobalDb();
|
|
521
|
+
{
|
|
437
522
|
const existing = globalDb
|
|
438
|
-
.prepare('SELECT id FROM
|
|
523
|
+
.prepare('SELECT id FROM agent_registry_agents WHERE agent_id = ?')
|
|
439
524
|
.get(spec.agentId);
|
|
440
525
|
let agentUuid;
|
|
441
526
|
if (!existing) {
|
|
442
527
|
agentUuid = crypto.randomUUID();
|
|
443
528
|
globalDb
|
|
444
|
-
.prepare(`INSERT INTO
|
|
529
|
+
.prepare(`INSERT INTO agent_registry_agents (id, agent_id, name, class, privacy_tier, capabilities, skills,
|
|
445
530
|
transport_type, api_key_encrypted, api_base_url, classification, transport_config,
|
|
446
531
|
is_active, last_used_at, status, created_at, updated_at, requires_reauth)
|
|
447
532
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'online', ?, ?, 0)`)
|
|
448
|
-
.run(agentUuid, spec.agentId, spec.displayName, spec.classification ?? 'custom', spec.privacyTier, JSON.stringify(spec.capabilities), JSON.stringify(spec.skills), spec.transportType ?? 'http', apiKeyEncrypted, spec.apiBaseUrl, spec.classification ?? null, JSON.stringify(spec.transportConfig), spec.isActive ? 1 : 0,
|
|
533
|
+
.run(agentUuid, spec.agentId, spec.displayName, spec.classification ?? 'custom', spec.privacyTier, JSON.stringify(spec.capabilities), JSON.stringify(spec.skills), spec.transportType ?? 'http', apiKeyEncrypted, spec.apiBaseUrl, spec.classification ?? null, JSON.stringify(spec.transportConfig), spec.isActive ? 1 : 0,
|
|
534
|
+
// T11622 cutover: TEXT ISO-8601 to satisfy the consolidated GLOB CHECK.
|
|
535
|
+
spec.lastUsedAt ? new Date(spec.lastUsedAt).toISOString() : null, nowIso, nowIso);
|
|
449
536
|
syncJunctionTables(globalDb, agentUuid, spec.capabilities, spec.skills);
|
|
450
537
|
}
|
|
451
538
|
else {
|
|
452
539
|
agentUuid = existing.id;
|
|
453
540
|
// Update identity in global DB (idempotent re-register)
|
|
454
541
|
globalDb
|
|
455
|
-
.prepare(`UPDATE
|
|
542
|
+
.prepare(`UPDATE agent_registry_agents SET name = ?, class = ?, privacy_tier = ?, capabilities = ?, skills = ?,
|
|
456
543
|
transport_type = ?, api_key_encrypted = ?, api_base_url = ?, classification = ?,
|
|
457
544
|
transport_config = ?, is_active = ?, updated_at = ? WHERE agent_id = ?`)
|
|
458
|
-
.run(spec.displayName, spec.classification ?? 'custom', spec.privacyTier, JSON.stringify(spec.capabilities), JSON.stringify(spec.skills), spec.transportType ?? 'http', apiKeyEncrypted, spec.apiBaseUrl, spec.classification ?? null, JSON.stringify(spec.transportConfig), spec.isActive ? 1 : 0,
|
|
545
|
+
.run(spec.displayName, spec.classification ?? 'custom', spec.privacyTier, JSON.stringify(spec.capabilities), JSON.stringify(spec.skills), spec.transportType ?? 'http', apiKeyEncrypted, spec.apiBaseUrl, spec.classification ?? null, JSON.stringify(spec.transportConfig), spec.isActive ? 1 : 0, nowIso, spec.agentId);
|
|
459
546
|
syncJunctionTables(globalDb, agentUuid, spec.capabilities, spec.skills);
|
|
460
547
|
}
|
|
461
548
|
}
|
|
462
|
-
|
|
463
|
-
globalDb.close();
|
|
464
|
-
}
|
|
549
|
+
// NOTE: globalDb is the SHARED dual-scope handle — never close it (T11562).
|
|
465
550
|
// Attach to project via conduit.db:project_agent_refs
|
|
466
551
|
const conduitDb = openConduitDb(projectRoot);
|
|
467
552
|
try {
|
|
468
553
|
const existingRef = conduitDb
|
|
469
|
-
.prepare('SELECT agent_id, enabled FROM
|
|
554
|
+
.prepare('SELECT agent_id, enabled FROM conduit_project_agent_refs WHERE agent_id = ?')
|
|
470
555
|
.get(spec.agentId);
|
|
471
556
|
if (!existingRef) {
|
|
472
557
|
conduitDb
|
|
473
|
-
.prepare(`INSERT INTO
|
|
558
|
+
.prepare(`INSERT INTO conduit_project_agent_refs (agent_id, attached_at, role, capabilities_override, last_used_at, enabled)
|
|
474
559
|
VALUES (?, ?, NULL, NULL, NULL, 1)`)
|
|
475
560
|
.run(spec.agentId, nowIso);
|
|
476
561
|
}
|
|
477
562
|
else if (existingRef.enabled === 0) {
|
|
478
563
|
// Re-enable a previously detached agent
|
|
479
564
|
conduitDb
|
|
480
|
-
.prepare(`UPDATE
|
|
565
|
+
.prepare(`UPDATE conduit_project_agent_refs SET enabled = 1, attached_at = ? WHERE agent_id = ?`)
|
|
481
566
|
.run(nowIso, spec.agentId);
|
|
482
567
|
}
|
|
483
568
|
// If enabled=1 already, leave the existing ref intact
|
|
@@ -485,7 +570,7 @@ export function createProjectAgent(projectRoot, spec) {
|
|
|
485
570
|
finally {
|
|
486
571
|
conduitDb.close();
|
|
487
572
|
}
|
|
488
|
-
const result = lookupAgent(projectRoot, spec.agentId, { includeGlobal: false });
|
|
573
|
+
const result = await lookupAgent(projectRoot, spec.agentId, { includeGlobal: false });
|
|
489
574
|
if (!result) {
|
|
490
575
|
throw new Error(`createProjectAgent: failed to retrieve agent after creation: ${spec.agentId}`);
|
|
491
576
|
}
|
|
@@ -501,7 +586,7 @@ export function createProjectAgent(projectRoot, spec) {
|
|
|
501
586
|
* with `enabled=0`, it is re-enabled (idempotent). If the row already has
|
|
502
587
|
* `enabled=1`, this is a no-op.
|
|
503
588
|
*
|
|
504
|
-
* The agent MUST already exist in the global `
|
|
589
|
+
* The agent MUST already exist in the global `cleo.db:agent_registry_agents` table.
|
|
505
590
|
* This function does NOT validate global existence — callers must check via
|
|
506
591
|
* `lookupAgent(..., { includeGlobal: true })` first.
|
|
507
592
|
*
|
|
@@ -518,17 +603,17 @@ export function attachAgentToProject(projectRoot, agentId, opts) {
|
|
|
518
603
|
const nowIso = new Date().toISOString();
|
|
519
604
|
try {
|
|
520
605
|
const existingRef = conduitDb
|
|
521
|
-
.prepare('SELECT agent_id, enabled FROM
|
|
606
|
+
.prepare('SELECT agent_id, enabled FROM conduit_project_agent_refs WHERE agent_id = ?')
|
|
522
607
|
.get(agentId);
|
|
523
608
|
if (!existingRef) {
|
|
524
609
|
conduitDb
|
|
525
|
-
.prepare(`INSERT INTO
|
|
610
|
+
.prepare(`INSERT INTO conduit_project_agent_refs (agent_id, attached_at, role, capabilities_override, last_used_at, enabled)
|
|
526
611
|
VALUES (?, ?, ?, ?, NULL, 1)`)
|
|
527
612
|
.run(agentId, nowIso, opts?.role ?? null, opts?.capabilitiesOverride ?? null);
|
|
528
613
|
}
|
|
529
614
|
else if (existingRef.enabled === 0) {
|
|
530
615
|
conduitDb
|
|
531
|
-
.prepare(`UPDATE
|
|
616
|
+
.prepare(`UPDATE conduit_project_agent_refs SET enabled = 1, attached_at = ?, role = ?, capabilities_override = ? WHERE agent_id = ?`)
|
|
532
617
|
.run(nowIso, opts?.role ?? null, opts?.capabilitiesOverride ?? null, agentId);
|
|
533
618
|
}
|
|
534
619
|
// enabled=1 already — no-op
|
|
@@ -540,7 +625,7 @@ export function attachAgentToProject(projectRoot, agentId, opts) {
|
|
|
540
625
|
/**
|
|
541
626
|
* Detach an agent from the current project by setting `project_agent_refs.enabled=0`.
|
|
542
627
|
*
|
|
543
|
-
* This is a soft-delete: the global `
|
|
628
|
+
* This is a soft-delete: the global `cleo.db:agent_registry_agents` row is preserved.
|
|
544
629
|
* The agent can be re-attached later via `attachAgentToProject`.
|
|
545
630
|
*
|
|
546
631
|
* Returns `false` if no row exists in `project_agent_refs` for the given agentId
|
|
@@ -557,11 +642,13 @@ export function detachAgentFromProject(projectRoot, agentId) {
|
|
|
557
642
|
const conduitDb = openConduitDb(projectRoot);
|
|
558
643
|
try {
|
|
559
644
|
const ref = conduitDb
|
|
560
|
-
.prepare('SELECT agent_id FROM
|
|
645
|
+
.prepare('SELECT agent_id FROM conduit_project_agent_refs WHERE agent_id = ?')
|
|
561
646
|
.get(agentId);
|
|
562
647
|
if (!ref)
|
|
563
648
|
return false;
|
|
564
|
-
conduitDb
|
|
649
|
+
conduitDb
|
|
650
|
+
.prepare('UPDATE conduit_project_agent_refs SET enabled = 0 WHERE agent_id = ?')
|
|
651
|
+
.run(agentId);
|
|
565
652
|
return true;
|
|
566
653
|
}
|
|
567
654
|
finally {
|
|
@@ -584,7 +671,7 @@ export function getProjectAgentRef(projectRoot, agentId) {
|
|
|
584
671
|
const conduitDb = openConduitDb(projectRoot);
|
|
585
672
|
try {
|
|
586
673
|
const row = conduitDb
|
|
587
|
-
.prepare('SELECT * FROM
|
|
674
|
+
.prepare('SELECT * FROM conduit_project_agent_refs WHERE agent_id = ?')
|
|
588
675
|
.get(agentId);
|
|
589
676
|
if (!row)
|
|
590
677
|
return null;
|
|
@@ -625,12 +712,14 @@ export class AgentRegistryAccessor {
|
|
|
625
712
|
* @task T355
|
|
626
713
|
* @epic T310
|
|
627
714
|
*/
|
|
628
|
-
ensureDbs() {
|
|
629
|
-
|
|
630
|
-
|
|
715
|
+
async ensureDbs() {
|
|
716
|
+
// E6-L3 (T11523): ensureConduitDb is now async (dual-scope cleo.db
|
|
717
|
+
// chokepoint); ensureGlobalAgentRegistryDb is already async. Await both.
|
|
718
|
+
await ensureGlobalAgentRegistryDb();
|
|
719
|
+
await ensureConduitDb(this.projectPath);
|
|
631
720
|
}
|
|
632
721
|
/**
|
|
633
|
-
* Register (create or update) an agent in global
|
|
722
|
+
* Register (create or update) an agent in global cleo.db (Agent Registry) and attach
|
|
634
723
|
* it to the current project via conduit.db:project_agent_refs.
|
|
635
724
|
*
|
|
636
725
|
* @param credential - Agent spec (without createdAt/updatedAt).
|
|
@@ -639,7 +728,7 @@ export class AgentRegistryAccessor {
|
|
|
639
728
|
* @epic T310
|
|
640
729
|
*/
|
|
641
730
|
async register(credential) {
|
|
642
|
-
this.ensureDbs();
|
|
731
|
+
await this.ensureDbs();
|
|
643
732
|
return createProjectAgent(this.projectPath, credential);
|
|
644
733
|
}
|
|
645
734
|
/**
|
|
@@ -652,7 +741,7 @@ export class AgentRegistryAccessor {
|
|
|
652
741
|
* @epic T310
|
|
653
742
|
*/
|
|
654
743
|
async get(agentId, opts) {
|
|
655
|
-
this.ensureDbs();
|
|
744
|
+
await this.ensureDbs();
|
|
656
745
|
return lookupAgent(this.projectPath, agentId, opts);
|
|
657
746
|
}
|
|
658
747
|
/**
|
|
@@ -664,8 +753,8 @@ export class AgentRegistryAccessor {
|
|
|
664
753
|
* @epic T310
|
|
665
754
|
*/
|
|
666
755
|
async list(filter) {
|
|
667
|
-
this.ensureDbs();
|
|
668
|
-
const results = listAgentsForProject(this.projectPath, { includeGlobal: false });
|
|
756
|
+
await this.ensureDbs();
|
|
757
|
+
const results = await listAgentsForProject(this.projectPath, { includeGlobal: false });
|
|
669
758
|
if (filter?.active !== undefined) {
|
|
670
759
|
return results.filter((a) => a.isActive === filter.active);
|
|
671
760
|
}
|
|
@@ -680,24 +769,20 @@ export class AgentRegistryAccessor {
|
|
|
680
769
|
* @epic T310
|
|
681
770
|
*/
|
|
682
771
|
async listGlobal(filter) {
|
|
683
|
-
this.ensureDbs();
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
}
|
|
695
|
-
finally {
|
|
696
|
-
globalDb.close();
|
|
697
|
-
}
|
|
772
|
+
await this.ensureDbs();
|
|
773
|
+
// SHARED global cleo.db handle — do NOT close (lifecycle owned by openDualScopeDb).
|
|
774
|
+
const globalDb = await openGlobalDb();
|
|
775
|
+
const rows = filter?.active !== undefined
|
|
776
|
+
? globalDb
|
|
777
|
+
.prepare('SELECT * FROM agent_registry_agents WHERE is_active = ? ORDER BY name ASC')
|
|
778
|
+
.all(filter.active ? 1 : 0)
|
|
779
|
+
: globalDb
|
|
780
|
+
.prepare('SELECT * FROM agent_registry_agents ORDER BY name ASC')
|
|
781
|
+
.all();
|
|
782
|
+
return rows.map(rowToCredential);
|
|
698
783
|
}
|
|
699
784
|
/**
|
|
700
|
-
* Update agent identity fields in global
|
|
785
|
+
* Update agent identity fields in global cleo.db (Agent Registry).
|
|
701
786
|
* Project-specific fields (role, capabilitiesOverride) require direct
|
|
702
787
|
* conduit.db manipulation (not yet exposed by this method).
|
|
703
788
|
*
|
|
@@ -708,15 +793,17 @@ export class AgentRegistryAccessor {
|
|
|
708
793
|
* @epic T310
|
|
709
794
|
*/
|
|
710
795
|
async update(agentId, updates) {
|
|
711
|
-
this.ensureDbs();
|
|
796
|
+
await this.ensureDbs();
|
|
712
797
|
const existing = await this.get(agentId, { includeGlobal: true });
|
|
713
798
|
if (!existing)
|
|
714
799
|
throw new Error(`Agent not found: ${agentId}`);
|
|
715
|
-
|
|
716
|
-
const
|
|
717
|
-
|
|
800
|
+
// T11622 cutover: `agent_registry_agents.updated_at` is TEXT ISO-8601 (GLOB CHECK).
|
|
801
|
+
const nowIso = new Date().toISOString();
|
|
802
|
+
// SHARED global cleo.db handle — do NOT close (lifecycle owned by openDualScopeDb).
|
|
803
|
+
const globalDb = await openGlobalDb();
|
|
804
|
+
{
|
|
718
805
|
const sets = ['updated_at = ?'];
|
|
719
|
-
const params = [
|
|
806
|
+
const params = [nowIso];
|
|
720
807
|
if (updates.displayName !== undefined) {
|
|
721
808
|
sets.push('name = ?');
|
|
722
809
|
params.push(updates.displayName);
|
|
@@ -763,21 +850,19 @@ export class AgentRegistryAccessor {
|
|
|
763
850
|
}
|
|
764
851
|
params.push(agentId);
|
|
765
852
|
globalDb
|
|
766
|
-
.prepare(`UPDATE
|
|
853
|
+
.prepare(`UPDATE agent_registry_agents SET ${sets.join(', ')} WHERE agent_id = ?`)
|
|
767
854
|
.run(...params);
|
|
768
855
|
// Sync junction tables if capabilities or skills changed
|
|
769
856
|
if (updates.capabilities !== undefined || updates.skills !== undefined) {
|
|
770
857
|
const agentRow = globalDb
|
|
771
|
-
.prepare('SELECT id FROM
|
|
858
|
+
.prepare('SELECT id FROM agent_registry_agents WHERE agent_id = ?')
|
|
772
859
|
.get(agentId);
|
|
773
860
|
if (agentRow) {
|
|
774
861
|
syncJunctionTables(globalDb, agentRow.id, updates.capabilities ?? existing.capabilities, updates.skills ?? existing.skills);
|
|
775
862
|
}
|
|
776
863
|
}
|
|
777
864
|
}
|
|
778
|
-
|
|
779
|
-
globalDb.close();
|
|
780
|
-
}
|
|
865
|
+
// NOTE: globalDb is the SHARED dual-scope handle — never close it (T11562).
|
|
781
866
|
const result = await this.get(agentId, { includeGlobal: true });
|
|
782
867
|
if (!result)
|
|
783
868
|
throw new Error(`Agent not found after update: ${agentId}`);
|
|
@@ -785,24 +870,24 @@ export class AgentRegistryAccessor {
|
|
|
785
870
|
}
|
|
786
871
|
/**
|
|
787
872
|
* Remove agent from current project (sets project_agent_refs.enabled=0).
|
|
788
|
-
* Does NOT delete from global
|
|
873
|
+
* Does NOT delete from global cleo.db (Agent Registry) (per ADR-037 §6 / Q4=C).
|
|
789
874
|
*
|
|
790
875
|
* @param agentId - Agent business identifier.
|
|
791
876
|
* @task T355
|
|
792
877
|
* @epic T310
|
|
793
878
|
*/
|
|
794
879
|
async remove(agentId) {
|
|
795
|
-
this.ensureDbs();
|
|
880
|
+
await this.ensureDbs();
|
|
796
881
|
const conduitDb = openConduitDb(this.projectPath);
|
|
797
882
|
try {
|
|
798
883
|
const ref = conduitDb
|
|
799
|
-
.prepare('SELECT agent_id FROM
|
|
884
|
+
.prepare('SELECT agent_id FROM conduit_project_agent_refs WHERE agent_id = ?')
|
|
800
885
|
.get(agentId);
|
|
801
886
|
if (!ref) {
|
|
802
887
|
throw new Error(`Agent not found in current project: ${agentId}`);
|
|
803
888
|
}
|
|
804
889
|
conduitDb
|
|
805
|
-
.prepare('UPDATE
|
|
890
|
+
.prepare('UPDATE conduit_project_agent_refs SET enabled = 0 WHERE agent_id = ?')
|
|
806
891
|
.run(agentId);
|
|
807
892
|
}
|
|
808
893
|
finally {
|
|
@@ -810,7 +895,7 @@ export class AgentRegistryAccessor {
|
|
|
810
895
|
}
|
|
811
896
|
}
|
|
812
897
|
/**
|
|
813
|
-
* Remove agent from global
|
|
898
|
+
* Remove agent from global cleo.db (Agent Registry).
|
|
814
899
|
* Requires explicit opt-in. Warns if cross-project refs may exist.
|
|
815
900
|
*
|
|
816
901
|
* @param agentId - Agent business identifier.
|
|
@@ -819,38 +904,37 @@ export class AgentRegistryAccessor {
|
|
|
819
904
|
* @epic T310
|
|
820
905
|
*/
|
|
821
906
|
async removeGlobal(agentId, opts) {
|
|
822
|
-
this.ensureDbs();
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
}
|
|
840
|
-
|
|
841
|
-
finally {
|
|
842
|
-
conduitDb.close();
|
|
907
|
+
await this.ensureDbs();
|
|
908
|
+
// SHARED global cleo.db handle — do NOT close (lifecycle owned by openDualScopeDb).
|
|
909
|
+
const globalDb = await openGlobalDb();
|
|
910
|
+
const existing = globalDb
|
|
911
|
+
.prepare('SELECT id FROM agent_registry_agents WHERE agent_id = ?')
|
|
912
|
+
.get(agentId);
|
|
913
|
+
if (!existing) {
|
|
914
|
+
throw new Error(`Agent not found globally: ${agentId}`);
|
|
915
|
+
}
|
|
916
|
+
if (!opts?.force) {
|
|
917
|
+
// Best-effort cross-project scan: check the current project's conduit.db
|
|
918
|
+
const conduitDb = openConduitDb(this.projectPath);
|
|
919
|
+
try {
|
|
920
|
+
const ref = conduitDb
|
|
921
|
+
.prepare('SELECT agent_id FROM conduit_project_agent_refs WHERE agent_id = ? AND enabled = 1')
|
|
922
|
+
.get(agentId);
|
|
923
|
+
if (ref) {
|
|
924
|
+
throw new Error(`Agent "${agentId}" still has project references in the current project. ` +
|
|
925
|
+
`Use removeGlobal(id, { force: true }) to skip this check.`);
|
|
843
926
|
}
|
|
844
927
|
}
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
globalDb.close();
|
|
928
|
+
finally {
|
|
929
|
+
conduitDb.close();
|
|
930
|
+
}
|
|
849
931
|
}
|
|
932
|
+
globalDb.prepare('DELETE FROM agent_registry_agents WHERE agent_id = ?').run(agentId);
|
|
933
|
+
// NOTE: globalDb is the SHARED dual-scope handle — never close it (T11562).
|
|
850
934
|
}
|
|
851
935
|
/**
|
|
852
936
|
* Rotate API key via cloud endpoint and re-encrypt with the new T310 KDF
|
|
853
|
-
* in global
|
|
937
|
+
* in global cleo.db (Agent Registry).
|
|
854
938
|
*
|
|
855
939
|
* @param agentId - Agent business identifier.
|
|
856
940
|
* @returns Object with agentId and a redacted new API key string.
|
|
@@ -858,7 +942,7 @@ export class AgentRegistryAccessor {
|
|
|
858
942
|
* @epic T310
|
|
859
943
|
*/
|
|
860
944
|
async rotateKey(agentId) {
|
|
861
|
-
this.ensureDbs();
|
|
945
|
+
await this.ensureDbs();
|
|
862
946
|
const credential = await this.get(agentId, { includeGlobal: true });
|
|
863
947
|
if (!credential)
|
|
864
948
|
throw new Error(`Agent not found: ${agentId}`);
|
|
@@ -880,16 +964,14 @@ export class AgentRegistryAccessor {
|
|
|
880
964
|
const machineKey = readMachineKey();
|
|
881
965
|
const globalSalt = getGlobalSalt();
|
|
882
966
|
const derivedKey = deriveApiKey({ machineKey, globalSalt, agentId });
|
|
883
|
-
|
|
884
|
-
const
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
globalDb.close();
|
|
892
|
-
}
|
|
967
|
+
// T11622 cutover: `updated_at` is TEXT ISO-8601 (GLOB CHECK).
|
|
968
|
+
const nowIso = new Date().toISOString();
|
|
969
|
+
// SHARED global cleo.db handle — do NOT close (lifecycle owned by openDualScopeDb).
|
|
970
|
+
const globalDb = await openGlobalDb();
|
|
971
|
+
globalDb
|
|
972
|
+
.prepare('UPDATE agent_registry_agents SET api_key_encrypted = ?, updated_at = ?, requires_reauth = 0 WHERE agent_id = ?')
|
|
973
|
+
.run(derivedKey.toString('hex'), nowIso, agentId);
|
|
974
|
+
// NOTE: globalDb is the SHARED dual-scope handle — never close it (T11562).
|
|
893
975
|
return { agentId, newApiKey: `${newApiKey.substring(0, 8)}...rotated` };
|
|
894
976
|
}
|
|
895
977
|
/**
|
|
@@ -900,36 +982,37 @@ export class AgentRegistryAccessor {
|
|
|
900
982
|
* @epic T310
|
|
901
983
|
*/
|
|
902
984
|
async getActive() {
|
|
903
|
-
this.ensureDbs();
|
|
904
|
-
|
|
985
|
+
await this.ensureDbs();
|
|
986
|
+
// SHARED global cleo.db handle — do NOT close (lifecycle owned by openDualScopeDb).
|
|
987
|
+
const globalDb = await openGlobalDb();
|
|
905
988
|
const conduitDb = openConduitDb(this.projectPath);
|
|
906
989
|
try {
|
|
907
990
|
// Get all project-attached, enabled agent IDs ordered by project last_used_at
|
|
908
991
|
const enabledRefs = conduitDb
|
|
909
|
-
.prepare('SELECT agent_id, last_used_at FROM
|
|
992
|
+
.prepare('SELECT agent_id, last_used_at FROM conduit_project_agent_refs WHERE enabled = 1 ORDER BY last_used_at DESC')
|
|
910
993
|
.all();
|
|
911
994
|
for (const ref of enabledRefs) {
|
|
912
995
|
const agentRow = globalDb
|
|
913
|
-
.prepare('SELECT * FROM
|
|
996
|
+
.prepare('SELECT * FROM agent_registry_agents WHERE agent_id = ? AND is_active = 1')
|
|
914
997
|
.get(ref.agent_id);
|
|
915
998
|
if (agentRow)
|
|
916
999
|
return rowToCredential(agentRow);
|
|
917
1000
|
}
|
|
918
1001
|
// Fall back to global last_used_at if no project-local activity recorded
|
|
919
1002
|
const row = globalDb
|
|
920
|
-
.prepare('SELECT * FROM
|
|
1003
|
+
.prepare('SELECT * FROM agent_registry_agents WHERE is_active = 1 ORDER BY last_used_at DESC, created_at DESC LIMIT 1')
|
|
921
1004
|
.get();
|
|
922
1005
|
if (!row)
|
|
923
1006
|
return null;
|
|
924
1007
|
return rowToCredential(row);
|
|
925
1008
|
}
|
|
926
1009
|
finally {
|
|
927
|
-
globalDb
|
|
1010
|
+
// NOTE: globalDb is the SHARED dual-scope handle — never close it (T11562).
|
|
928
1011
|
conduitDb.close();
|
|
929
1012
|
}
|
|
930
1013
|
}
|
|
931
1014
|
/**
|
|
932
|
-
* Update last_used_at in both global
|
|
1015
|
+
* Update last_used_at in both global cleo.db:agent_registry_agents and
|
|
933
1016
|
* conduit.db:project_agent_refs.
|
|
934
1017
|
*
|
|
935
1018
|
* @param agentId - Agent business identifier.
|
|
@@ -937,22 +1020,20 @@ export class AgentRegistryAccessor {
|
|
|
937
1020
|
* @epic T310
|
|
938
1021
|
*/
|
|
939
1022
|
async markUsed(agentId) {
|
|
940
|
-
this.ensureDbs();
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
const
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
globalDb.close();
|
|
951
|
-
}
|
|
1023
|
+
await this.ensureDbs();
|
|
1024
|
+
// T11622 cutover: `last_used_at` / `updated_at` are TEXT ISO-8601 (GLOB CHECK)
|
|
1025
|
+
// in `agent_registry_agents`; `conduit_project_agent_refs.last_used_at` is also ISO.
|
|
1026
|
+
const nowIso = new Date().toISOString();
|
|
1027
|
+
// SHARED global cleo.db handle — do NOT close (lifecycle owned by openDualScopeDb).
|
|
1028
|
+
const globalDb = await openGlobalDb();
|
|
1029
|
+
globalDb
|
|
1030
|
+
.prepare('UPDATE agent_registry_agents SET last_used_at = ?, updated_at = ? WHERE agent_id = ?')
|
|
1031
|
+
.run(nowIso, nowIso, agentId);
|
|
1032
|
+
// NOTE: globalDb is the SHARED dual-scope handle — never close it (T11562).
|
|
952
1033
|
const conduitDb = openConduitDb(this.projectPath);
|
|
953
1034
|
try {
|
|
954
1035
|
conduitDb
|
|
955
|
-
.prepare('UPDATE
|
|
1036
|
+
.prepare('UPDATE conduit_project_agent_refs SET last_used_at = ? WHERE agent_id = ?')
|
|
956
1037
|
.run(nowIso, agentId);
|
|
957
1038
|
}
|
|
958
1039
|
finally {
|