@cleocode/core 2026.9.22 → 2026.9.24
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/dist/admin/import-tasks.d.ts.map +1 -1
- package/dist/admin/import-tasks.js +35 -6
- package/dist/admin/import-tasks.js.map +1 -1
- package/dist/admin/import.d.ts.map +1 -1
- package/dist/admin/import.js +25 -6
- package/dist/admin/import.js.map +1 -1
- package/dist/build-provenance.json +6 -0
- package/dist/cloud/http.d.ts +8 -0
- package/dist/cloud/http.d.ts.map +1 -1
- package/dist/cloud/http.js +8 -1
- package/dist/cloud/http.js.map +1 -1
- package/dist/cloud/index.d.ts +6 -1
- package/dist/cloud/index.d.ts.map +1 -1
- package/dist/cloud/index.js +6 -1
- package/dist/cloud/index.js.map +1 -1
- package/dist/cloud/nexus-auth.d.ts +169 -0
- package/dist/cloud/nexus-auth.d.ts.map +1 -0
- package/dist/cloud/nexus-auth.js +372 -0
- package/dist/cloud/nexus-auth.js.map +1 -0
- package/dist/cloud/nexus-credentials.d.ts +188 -0
- package/dist/cloud/nexus-credentials.d.ts.map +1 -0
- package/dist/cloud/nexus-credentials.js +323 -0
- package/dist/cloud/nexus-credentials.js.map +1 -0
- package/dist/cloud/nexus-link.d.ts +85 -0
- package/dist/cloud/nexus-link.d.ts.map +1 -0
- package/dist/cloud/nexus-link.js +226 -0
- package/dist/cloud/nexus-link.js.map +1 -0
- package/dist/cloud/presence.d.ts +88 -0
- package/dist/cloud/presence.d.ts.map +1 -0
- package/dist/cloud/presence.js +137 -0
- package/dist/cloud/presence.js.map +1 -0
- package/dist/cloud/projects.d.ts +3 -1
- package/dist/cloud/projects.d.ts.map +1 -1
- package/dist/cloud/projects.js +4 -2
- package/dist/cloud/projects.js.map +1 -1
- package/dist/crypto/credentials.d.ts +14 -4
- package/dist/crypto/credentials.d.ts.map +1 -1
- package/dist/crypto/credentials.js +15 -1
- package/dist/crypto/credentials.js.map +1 -1
- package/dist/decide/audit.d.ts +7 -1
- package/dist/decide/audit.d.ts.map +1 -1
- package/dist/decide/audit.js.map +1 -1
- package/dist/decide/bench/dataset.d.ts +125 -0
- package/dist/decide/bench/dataset.d.ts.map +1 -0
- package/dist/decide/bench/dataset.js +457 -0
- package/dist/decide/bench/dataset.js.map +1 -0
- package/dist/decide/bench/index.d.ts +23 -0
- package/dist/decide/bench/index.d.ts.map +1 -0
- package/dist/decide/bench/index.js +23 -0
- package/dist/decide/bench/index.js.map +1 -0
- package/dist/decide/bench/metrics.d.ts +55 -0
- package/dist/decide/bench/metrics.d.ts.map +1 -0
- package/dist/decide/bench/metrics.js +100 -0
- package/dist/decide/bench/metrics.js.map +1 -0
- package/dist/decide/bench/operation.d.ts +119 -0
- package/dist/decide/bench/operation.d.ts.map +1 -0
- package/dist/decide/bench/operation.js +171 -0
- package/dist/decide/bench/operation.js.map +1 -0
- package/dist/decide/bench/profiles.d.ts +74 -0
- package/dist/decide/bench/profiles.d.ts.map +1 -0
- package/dist/decide/bench/profiles.js +131 -0
- package/dist/decide/bench/profiles.js.map +1 -0
- package/dist/decide/bench/questions.d.ts +40 -0
- package/dist/decide/bench/questions.d.ts.map +1 -0
- package/dist/decide/bench/questions.js +107 -0
- package/dist/decide/bench/questions.js.map +1 -0
- package/dist/decide/bench/report.d.ts +21 -0
- package/dist/decide/bench/report.d.ts.map +1 -0
- package/dist/decide/bench/report.js +120 -0
- package/dist/decide/bench/report.js.map +1 -0
- package/dist/decide/bench/runner.d.ts +203 -0
- package/dist/decide/bench/runner.d.ts.map +1 -0
- package/dist/decide/bench/runner.js +335 -0
- package/dist/decide/bench/runner.js.map +1 -0
- package/dist/decide/bench/source.d.ts +21 -0
- package/dist/decide/bench/source.d.ts.map +1 -0
- package/dist/decide/bench/source.js +67 -0
- package/dist/decide/bench/source.js.map +1 -0
- package/dist/decide/bench/spot-check.d.ts +117 -0
- package/dist/decide/bench/spot-check.d.ts.map +1 -0
- package/dist/decide/bench/spot-check.js +221 -0
- package/dist/decide/bench/spot-check.js.map +1 -0
- package/dist/decide/bench/stats.d.ts +57 -0
- package/dist/decide/bench/stats.d.ts.map +1 -0
- package/dist/decide/bench/stats.js +82 -0
- package/dist/decide/bench/stats.js.map +1 -0
- package/dist/decide/bench/types.d.ts +216 -0
- package/dist/decide/bench/types.d.ts.map +1 -0
- package/dist/decide/bench/types.js +104 -0
- package/dist/decide/bench/types.js.map +1 -0
- package/dist/decide/client.d.ts +80 -4
- package/dist/decide/client.d.ts.map +1 -1
- package/dist/decide/client.js +428 -39
- package/dist/decide/client.js.map +1 -1
- package/dist/decide/credentials.d.ts +200 -16
- package/dist/decide/credentials.d.ts.map +1 -1
- package/dist/decide/credentials.js +547 -45
- package/dist/decide/credentials.js.map +1 -1
- package/dist/decide/index.d.ts +10 -4
- package/dist/decide/index.d.ts.map +1 -1
- package/dist/decide/index.js +10 -4
- package/dist/decide/index.js.map +1 -1
- package/dist/decide/jev-wire.d.ts +105 -7
- package/dist/decide/jev-wire.d.ts.map +1 -1
- package/dist/decide/jev-wire.js +426 -54
- package/dist/decide/jev-wire.js.map +1 -1
- package/dist/decide/operations.d.ts +149 -21
- package/dist/decide/operations.d.ts.map +1 -1
- package/dist/decide/operations.js +241 -31
- package/dist/decide/operations.js.map +1 -1
- package/dist/decide/provider-state.d.ts +162 -0
- package/dist/decide/provider-state.d.ts.map +1 -0
- package/dist/decide/provider-state.js +267 -0
- package/dist/decide/provider-state.js.map +1 -0
- package/dist/decide/provider.d.ts +31 -5
- package/dist/decide/provider.d.ts.map +1 -1
- package/dist/decide/provider.js.map +1 -1
- package/dist/decide/providers.d.ts +71 -0
- package/dist/decide/providers.d.ts.map +1 -0
- package/dist/decide/providers.js +85 -0
- package/dist/decide/providers.js.map +1 -0
- package/dist/decide/site.d.ts +2 -2
- package/dist/decide/site.d.ts.map +1 -1
- package/dist/decide/site.js +2 -0
- package/dist/decide/site.js.map +1 -1
- package/dist/decide/sites/list.d.ts +46 -0
- package/dist/decide/sites/list.d.ts.map +1 -0
- package/dist/decide/sites/list.js +206 -0
- package/dist/decide/sites/list.js.map +1 -0
- package/dist/decide/sites/registry.d.ts +152 -0
- package/dist/decide/sites/registry.d.ts.map +1 -0
- package/dist/decide/sites/registry.js +398 -0
- package/dist/decide/sites/registry.js.map +1 -0
- package/dist/decide/spend.d.ts +196 -0
- package/dist/decide/spend.d.ts.map +1 -0
- package/dist/decide/spend.js +387 -0
- package/dist/decide/spend.js.map +1 -0
- package/dist/decide/wizard.d.ts +61 -0
- package/dist/decide/wizard.d.ts.map +1 -0
- package/dist/decide/wizard.js +197 -0
- package/dist/decide/wizard.js.map +1 -0
- package/dist/dispatch/mvi-projection.d.ts +15 -2
- package/dist/dispatch/mvi-projection.d.ts.map +1 -1
- package/dist/dispatch/mvi-projection.js +73 -12
- package/dist/dispatch/mvi-projection.js.map +1 -1
- package/dist/docs/adr-allocator.d.ts +2 -2
- package/dist/docs/adr-allocator.d.ts.map +1 -1
- package/dist/docs/adr-allocator.js +17 -4
- package/dist/docs/adr-allocator.js.map +1 -1
- package/dist/docs/blob-consolidation.js +1 -1
- package/dist/docs/blob-consolidation.js.map +1 -1
- package/dist/docs/display-alias.d.ts +1 -1
- package/dist/docs/display-alias.d.ts.map +1 -1
- package/dist/docs/display-alias.js +7 -4
- package/dist/docs/display-alias.js.map +1 -1
- package/dist/docs/docs-audit.d.ts.map +1 -1
- package/dist/docs/docs-audit.js +1 -2
- package/dist/docs/docs-audit.js.map +1 -1
- package/dist/docs/docs-inconsistency-detector.js +1 -1
- package/dist/docs/docs-inconsistency-detector.js.map +1 -1
- package/dist/docs/docs-update.d.ts.map +1 -1
- package/dist/docs/docs-update.js +6 -1
- package/dist/docs/docs-update.js.map +1 -1
- package/dist/docs/export-document.js +3462 -1227
- package/dist/docs/export-document.js.map +3 -3
- package/dist/docs/numbering.js +1 -1
- package/dist/docs/numbering.js.map +1 -1
- package/dist/docs/supersede.d.ts.map +1 -1
- package/dist/docs/supersede.js +6 -3
- package/dist/docs/supersede.js.map +1 -1
- package/dist/docs/version-ssot.js +1 -1
- package/dist/docs/version-ssot.js.map +1 -1
- package/dist/doctor/db-substrate.d.ts.map +1 -1
- package/dist/doctor/db-substrate.js +39 -24
- package/dist/doctor/db-substrate.js.map +1 -1
- package/dist/doctor/knowledge-summary.d.ts +10 -3
- package/dist/doctor/knowledge-summary.d.ts.map +1 -1
- package/dist/doctor/knowledge-summary.js +10 -3
- package/dist/doctor/knowledge-summary.js.map +1 -1
- package/dist/doctor/project-identity.d.ts +128 -37
- package/dist/doctor/project-identity.d.ts.map +1 -1
- package/dist/doctor/project-identity.js +476 -63
- package/dist/doctor/project-identity.js.map +1 -1
- package/dist/doctor/twin-collapse.d.ts +52 -2
- package/dist/doctor/twin-collapse.d.ts.map +1 -1
- package/dist/doctor/twin-collapse.js +108 -4
- package/dist/doctor/twin-collapse.js.map +1 -1
- package/dist/error-catalog.js +2 -2
- package/dist/error-catalog.js.map +1 -1
- package/dist/error-registry.js +1 -1
- package/dist/error-registry.js.map +1 -1
- package/dist/gateway-client/generated/types.gen.d.ts +22 -2
- package/dist/gateway-client/generated/types.gen.d.ts.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/init/scaffold-workflows.d.ts.map +1 -1
- package/dist/init/scaffold-workflows.js +6 -3
- package/dist/init/scaffold-workflows.js.map +1 -1
- package/dist/init/upgrade-workflows.d.ts.map +1 -1
- package/dist/init/upgrade-workflows.js +6 -3
- package/dist/init/upgrade-workflows.js.map +1 -1
- package/dist/init.d.ts.map +1 -1
- package/dist/init.js +20 -11
- package/dist/init.js.map +1 -1
- package/dist/inject/index.d.ts.map +1 -1
- package/dist/inject/index.js +2 -3
- package/dist/inject/index.js.map +1 -1
- package/dist/internal.d.ts +6 -5
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +7 -5
- package/dist/internal.js.map +1 -1
- package/dist/llm/credential-remove-entry.d.ts +59 -0
- package/dist/llm/credential-remove-entry.d.ts.map +1 -0
- package/dist/llm/credential-remove-entry.js +101 -0
- package/dist/llm/credential-remove-entry.js.map +1 -0
- package/dist/llm/oauth/device-code.d.ts +26 -6
- package/dist/llm/oauth/device-code.d.ts.map +1 -1
- package/dist/llm/oauth/device-code.js +44 -12
- package/dist/llm/oauth/device-code.js.map +1 -1
- package/dist/llm/plugin-facade.js +3556 -1321
- package/dist/llm/plugin-facade.js.map +3 -3
- package/dist/memory/attention.d.ts.map +1 -1
- package/dist/memory/attention.js +5 -3
- package/dist/memory/attention.js.map +1 -1
- package/dist/memory/decision-contradiction.d.ts +3 -3
- package/dist/memory/decision-contradiction.d.ts.map +1 -1
- package/dist/memory/decision-contradiction.js +4 -3
- package/dist/memory/decision-contradiction.js.map +1 -1
- package/dist/memory/decisions.d.ts +48 -3
- package/dist/memory/decisions.d.ts.map +1 -1
- package/dist/memory/decisions.js +98 -14
- 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 +2 -0
- package/dist/memory/graph-memory-bridge.js.map +1 -1
- package/dist/memory/learnings.d.ts +6 -6
- package/dist/memory/observation-type-decision.d.ts +2 -2
- package/dist/memory/observation-type-decision.d.ts.map +1 -1
- package/dist/memory/observation-type-decision.js +3 -2
- package/dist/memory/observation-type-decision.js.map +1 -1
- package/dist/memory/patterns.d.ts +4 -4
- package/dist/memory/pipeline-manifest-sqlite.d.ts +111 -0
- package/dist/memory/pipeline-manifest-sqlite.d.ts.map +1 -1
- package/dist/memory/pipeline-manifest-sqlite.js +230 -2
- package/dist/memory/pipeline-manifest-sqlite.js.map +1 -1
- package/dist/migration/manual/T10165-backfill-adr-index.d.ts.map +1 -1
- package/dist/migration/manual/T10165-backfill-adr-index.js +5 -1
- package/dist/migration/manual/T10165-backfill-adr-index.js.map +1 -1
- package/dist/nexus/fleet-status.d.ts +83 -0
- package/dist/nexus/fleet-status.d.ts.map +1 -0
- package/dist/nexus/fleet-status.js +414 -0
- package/dist/nexus/fleet-status.js.map +1 -0
- package/dist/nexus/git-state.d.ts +15 -0
- package/dist/nexus/git-state.d.ts.map +1 -1
- package/dist/nexus/git-state.js +67 -2
- package/dist/nexus/git-state.js.map +1 -1
- package/dist/nexus/identity.d.ts.map +1 -1
- package/dist/nexus/identity.js +4 -0
- package/dist/nexus/identity.js.map +1 -1
- package/dist/nexus/index.d.ts +4 -1
- package/dist/nexus/index.d.ts.map +1 -1
- package/dist/nexus/index.js +7 -1
- package/dist/nexus/index.js.map +1 -1
- package/dist/nexus/migrate-json-to-sqlite.d.ts +3 -2
- package/dist/nexus/migrate-json-to-sqlite.d.ts.map +1 -1
- package/dist/nexus/migrate-json-to-sqlite.js +9 -17
- package/dist/nexus/migrate-json-to-sqlite.js.map +1 -1
- package/dist/nexus/migrations/M-split-graph.d.ts.map +1 -1
- package/dist/nexus/migrations/M-split-graph.js +4 -0
- package/dist/nexus/migrations/M-split-graph.js.map +1 -1
- package/dist/nexus/ops.d.ts +1 -0
- package/dist/nexus/ops.d.ts.map +1 -1
- package/dist/nexus/project-activity.d.ts +104 -0
- package/dist/nexus/project-activity.d.ts.map +1 -0
- package/dist/nexus/project-activity.js +150 -0
- package/dist/nexus/project-activity.js.map +1 -0
- package/dist/nexus/query.d.ts +2 -2
- package/dist/nexus/query.d.ts.map +1 -1
- package/dist/nexus/query.js +4 -19
- package/dist/nexus/query.js.map +1 -1
- package/dist/nexus/registry-errors.d.ts +61 -0
- package/dist/nexus/registry-errors.d.ts.map +1 -0
- package/dist/nexus/registry-errors.js +85 -0
- package/dist/nexus/registry-errors.js.map +1 -0
- package/dist/nexus/registry.d.ts +30 -5
- package/dist/nexus/registry.d.ts.map +1 -1
- package/dist/nexus/registry.js +115 -70
- package/dist/nexus/registry.js.map +1 -1
- package/dist/nexus/store.d.ts.map +1 -1
- package/dist/nexus/store.js +2 -0
- package/dist/nexus/store.js.map +1 -1
- package/dist/orchestrate/pivot.d.ts +4 -0
- package/dist/orchestrate/pivot.d.ts.map +1 -1
- package/dist/orchestrate/pivot.js +82 -14
- package/dist/orchestrate/pivot.js.map +1 -1
- package/dist/orchestrate/plan.d.ts.map +1 -1
- package/dist/orchestrate/plan.js +3 -0
- package/dist/orchestrate/plan.js.map +1 -1
- package/dist/orchestrate/query-ops.d.ts.map +1 -1
- package/dist/orchestrate/query-ops.js +29 -27
- package/dist/orchestrate/query-ops.js.map +1 -1
- package/dist/orchestrate/spawn-ops.d.ts.map +1 -1
- package/dist/orchestrate/spawn-ops.js +29 -3
- package/dist/orchestrate/spawn-ops.js.map +1 -1
- package/dist/orchestration/bootstrap.d.ts.map +1 -1
- package/dist/orchestration/bootstrap.js +20 -14
- package/dist/orchestration/bootstrap.js.map +1 -1
- package/dist/orchestration/index.d.ts +15 -1
- package/dist/orchestration/index.d.ts.map +1 -1
- package/dist/orchestration/index.js +25 -6
- package/dist/orchestration/index.js.map +1 -1
- package/dist/orchestration/lead-rollup.d.ts +7 -1
- package/dist/orchestration/lead-rollup.d.ts.map +1 -1
- package/dist/orchestration/lead-rollup.js +20 -5
- package/dist/orchestration/lead-rollup.js.map +1 -1
- package/dist/orchestration/owner-decision-readiness.d.ts +2 -2
- package/dist/orchestration/owner-decision-readiness.d.ts.map +1 -1
- package/dist/orchestration/owner-decision-readiness.js +3 -2
- package/dist/orchestration/owner-decision-readiness.js.map +1 -1
- package/dist/orchestration/spawn-prompt.js +1 -1
- package/dist/orchestration/spawn-prompt.js.map +1 -1
- package/dist/orchestration/validate-spawn.d.ts.map +1 -1
- package/dist/orchestration/validate-spawn.js +2 -0
- package/dist/orchestration/validate-spawn.js.map +1 -1
- package/dist/orchestration/waves.d.ts +21 -10
- package/dist/orchestration/waves.d.ts.map +1 -1
- package/dist/orchestration/waves.js +38 -35
- package/dist/orchestration/waves.js.map +1 -1
- package/dist/paths.d.ts +9 -2
- package/dist/paths.d.ts.map +1 -1
- package/dist/paths.js +30 -13
- package/dist/paths.js.map +1 -1
- package/dist/phases/index.d.ts +1 -1
- package/dist/phases/index.d.ts.map +1 -1
- package/dist/phases/index.js +3 -4
- package/dist/phases/index.js.map +1 -1
- package/dist/project-info.d.ts +40 -3
- package/dist/project-info.d.ts.map +1 -1
- package/dist/project-info.js +74 -6
- package/dist/project-info.js.map +1 -1
- package/dist/project-lifecycle.d.ts +28 -7
- package/dist/project-lifecycle.d.ts.map +1 -1
- package/dist/project-lifecycle.js +114 -47
- package/dist/project-lifecycle.js.map +1 -1
- package/dist/project-scope.d.ts +86 -3
- package/dist/project-scope.d.ts.map +1 -1
- package/dist/project-scope.js +192 -17
- package/dist/project-scope.js.map +1 -1
- package/dist/release/github-pr.d.ts.map +1 -1
- package/dist/release/github-pr.js +2 -1
- package/dist/release/github-pr.js.map +1 -1
- package/dist/release/open.d.ts +12 -2
- package/dist/release/open.d.ts.map +1 -1
- package/dist/release/open.js +32 -3
- package/dist/release/open.js.map +1 -1
- package/dist/release/preflight-skip.d.ts +73 -0
- package/dist/release/preflight-skip.d.ts.map +1 -0
- package/dist/release/preflight-skip.js +254 -0
- package/dist/release/preflight-skip.js.map +1 -0
- package/dist/render/decide/index.d.ts +51 -0
- package/dist/render/decide/index.d.ts.map +1 -0
- package/dist/render/decide/index.js +289 -0
- package/dist/render/decide/index.js.map +1 -0
- package/dist/render/index.d.ts +1 -0
- package/dist/render/index.d.ts.map +1 -1
- package/dist/render/index.js +1 -0
- package/dist/render/index.js.map +1 -1
- package/dist/render/nexus/graph/index.d.ts +5 -0
- package/dist/render/nexus/graph/index.d.ts.map +1 -1
- package/dist/render/nexus/graph/index.js +53 -0
- package/dist/render/nexus/graph/index.js.map +1 -1
- package/dist/routing/capability-matrix.d.ts.map +1 -1
- package/dist/routing/capability-matrix.js +7 -0
- package/dist/routing/capability-matrix.js.map +1 -1
- package/dist/scaffold/ensure-config.d.ts +14 -6
- package/dist/scaffold/ensure-config.d.ts.map +1 -1
- package/dist/scaffold/ensure-config.js +39 -17
- package/dist/scaffold/ensure-config.js.map +1 -1
- package/dist/scaffold/project-identity.d.ts +115 -23
- package/dist/scaffold/project-identity.d.ts.map +1 -1
- package/dist/scaffold/project-identity.js +196 -44
- package/dist/scaffold/project-identity.js.map +1 -1
- package/dist/selfimprove/fix-gen.js +3569 -1334
- package/dist/selfimprove/fix-gen.js.map +3 -3
- package/dist/sentient/cross-project-hygiene.d.ts +12 -6
- package/dist/sentient/cross-project-hygiene.d.ts.map +1 -1
- package/dist/sentient/cross-project-hygiene.js +15 -10
- package/dist/sentient/cross-project-hygiene.js.map +1 -1
- package/dist/session/engine-ops.d.ts +13 -4
- package/dist/session/engine-ops.d.ts.map +1 -1
- package/dist/session/engine-ops.js +38 -45
- package/dist/session/engine-ops.js.map +1 -1
- package/dist/sessions/briefing.d.ts +7 -3
- package/dist/sessions/briefing.d.ts.map +1 -1
- package/dist/sessions/briefing.js +32 -71
- package/dist/sessions/briefing.js.map +1 -1
- package/dist/sessions/drift-watchdog.d.ts.map +1 -1
- package/dist/sessions/drift-watchdog.js +11 -19
- package/dist/sessions/drift-watchdog.js.map +1 -1
- package/dist/sessions/focus-state-store.d.ts +109 -27
- package/dist/sessions/focus-state-store.d.ts.map +1 -1
- package/dist/sessions/focus-state-store.js +171 -39
- package/dist/sessions/focus-state-store.js.map +1 -1
- package/dist/sessions/handoff.d.ts.map +1 -1
- package/dist/sessions/handoff.js +9 -18
- package/dist/sessions/handoff.js.map +1 -1
- package/dist/sessions/index.d.ts +4 -2
- package/dist/sessions/index.d.ts.map +1 -1
- package/dist/sessions/index.js +35 -6
- package/dist/sessions/index.js.map +1 -1
- package/dist/sessions/session-drift.d.ts.map +1 -1
- package/dist/sessions/session-drift.js +4 -2
- package/dist/sessions/session-drift.js.map +1 -1
- package/dist/sessions/session-view.d.ts +8 -1
- package/dist/sessions/session-view.d.ts.map +1 -1
- package/dist/sessions/session-view.js +9 -2
- package/dist/sessions/session-view.js.map +1 -1
- package/dist/setup/config-json-merge.d.ts +28 -0
- package/dist/setup/config-json-merge.d.ts.map +1 -1
- package/dist/setup/config-json-merge.js +52 -0
- package/dist/setup/config-json-merge.js.map +1 -1
- package/dist/setup/index.d.ts +15 -10
- package/dist/setup/index.d.ts.map +1 -1
- package/dist/setup/index.js +19 -10
- package/dist/setup/index.js.map +1 -1
- package/dist/setup/sections/llm.js +1 -1
- package/dist/setup/sections/llm.js.map +1 -1
- package/dist/setup/sections/nexus-account.d.ts +32 -0
- package/dist/setup/sections/nexus-account.d.ts.map +1 -0
- package/dist/setup/sections/nexus-account.js +64 -0
- package/dist/setup/sections/nexus-account.js.map +1 -0
- package/dist/setup/sections/system-one.d.ts +28 -0
- package/dist/setup/sections/system-one.d.ts.map +1 -0
- package/dist/setup/sections/system-one.js +53 -0
- package/dist/setup/sections/system-one.js.map +1 -0
- package/dist/setup/wizard.d.ts +15 -1
- package/dist/setup/wizard.d.ts.map +1 -1
- package/dist/setup/wizard.js +15 -0
- package/dist/setup/wizard.js.map +1 -1
- package/dist/skills/orchestrator/startup.d.ts.map +1 -1
- package/dist/skills/orchestrator/startup.js +18 -31
- package/dist/skills/orchestrator/startup.js.map +1 -1
- package/dist/skills/prune-bundled.d.ts +40 -1
- package/dist/skills/prune-bundled.d.ts.map +1 -1
- package/dist/skills/prune-bundled.js +117 -1
- package/dist/skills/prune-bundled.js.map +1 -1
- package/dist/snapshot/index.d.ts.map +1 -1
- package/dist/snapshot/index.js +60 -53
- package/dist/snapshot/index.js.map +1 -1
- package/dist/spawn/agent-identity.d.ts +33 -1
- package/dist/spawn/agent-identity.d.ts.map +1 -1
- package/dist/spawn/agent-identity.js +53 -1
- package/dist/spawn/agent-identity.js.map +1 -1
- package/dist/spawn/index.d.ts +1 -1
- package/dist/spawn/index.d.ts.map +1 -1
- package/dist/spawn/index.js +1 -1
- package/dist/spawn/index.js.map +1 -1
- package/dist/stats/index.d.ts.map +1 -1
- package/dist/stats/index.js +3 -4
- package/dist/stats/index.js.map +1 -1
- package/dist/status/index.d.ts +12 -3
- package/dist/status/index.d.ts.map +1 -1
- package/dist/status/index.js +47 -5
- package/dist/status/index.js.map +1 -1
- package/dist/store/agent-registry-accessor.d.ts.map +1 -1
- package/dist/store/agent-registry-accessor.js +2 -0
- package/dist/store/agent-registry-accessor.js.map +1 -1
- package/dist/store/attachment-repair.d.ts.map +1 -1
- package/dist/store/attachment-repair.js +42 -3
- package/dist/store/attachment-repair.js.map +1 -1
- package/dist/store/attachment-store.d.ts.map +1 -1
- package/dist/store/attachment-store.js +30 -46
- package/dist/store/attachment-store.js.map +1 -1
- package/dist/store/backup-pack.js +1 -1
- package/dist/store/backup-pack.js.map +1 -1
- package/dist/store/backup-recover-brain.d.ts +4 -0
- package/dist/store/backup-recover-brain.d.ts.map +1 -1
- package/dist/store/backup-recover-brain.js +2 -0
- package/dist/store/backup-recover-brain.js.map +1 -1
- package/dist/store/backup-recover.d.ts +9 -0
- package/dist/store/backup-recover.d.ts.map +1 -1
- package/dist/store/backup-recover.js +28 -1
- package/dist/store/backup-recover.js.map +1 -1
- package/dist/store/backup-sidecar.d.ts +30 -0
- package/dist/store/backup-sidecar.d.ts.map +1 -1
- package/dist/store/backup-sidecar.js +90 -2
- package/dist/store/backup-sidecar.js.map +1 -1
- package/dist/store/backup.d.ts +15 -1
- package/dist/store/backup.d.ts.map +1 -1
- package/dist/store/backup.js +18 -2
- package/dist/store/backup.js.map +1 -1
- package/dist/store/blob-keep.d.ts +135 -0
- package/dist/store/blob-keep.d.ts.map +1 -0
- package/dist/store/blob-keep.js +283 -0
- package/dist/store/blob-keep.js.map +1 -0
- package/dist/store/conduit-sqlite.d.ts.map +1 -1
- package/dist/store/conduit-sqlite.js +3 -0
- package/dist/store/conduit-sqlite.js.map +1 -1
- package/dist/store/converters.d.ts.map +1 -1
- package/dist/store/converters.js +11 -0
- package/dist/store/converters.js.map +1 -1
- package/dist/store/credential-transfer.d.ts +37 -5
- package/dist/store/credential-transfer.d.ts.map +1 -1
- package/dist/store/credential-transfer.js +75 -18
- package/dist/store/credential-transfer.js.map +1 -1
- package/dist/store/cross-db-cleanup.d.ts.map +1 -1
- package/dist/store/cross-db-cleanup.js +2 -0
- package/dist/store/cross-db-cleanup.js.map +1 -1
- package/dist/store/data-accessor.d.ts +1 -1
- package/dist/store/data-accessor.d.ts.map +1 -1
- package/dist/store/data-accessor.js.map +1 -1
- package/dist/store/db-helpers.d.ts +18 -0
- package/dist/store/db-helpers.d.ts.map +1 -1
- package/dist/store/db-helpers.js +46 -0
- package/dist/store/db-helpers.js.map +1 -1
- package/dist/store/dual-scope-db.d.ts.map +1 -1
- package/dist/store/dual-scope-db.js +13 -2
- package/dist/store/dual-scope-db.js.map +1 -1
- package/dist/store/exodus/on-open.d.ts.map +1 -1
- package/dist/store/exodus/on-open.js +35 -0
- package/dist/store/exodus/on-open.js.map +1 -1
- package/dist/store/exodus/runtime-targets.d.ts +3 -3
- package/dist/store/exodus/runtime-targets.js +3 -3
- package/dist/store/import-remap.d.ts +12 -1
- package/dist/store/import-remap.d.ts.map +1 -1
- package/dist/store/import-remap.js +14 -0
- package/dist/store/import-remap.js.map +1 -1
- package/dist/store/legacy-tasks-lineage.d.ts +3 -1
- package/dist/store/legacy-tasks-lineage.d.ts.map +1 -1
- package/dist/store/legacy-tasks-lineage.js +3 -1
- package/dist/store/legacy-tasks-lineage.js.map +1 -1
- package/dist/store/memory-accessor.js +1 -1
- package/dist/store/memory-accessor.js.map +1 -1
- package/dist/store/migrate-signaldock-to-conduit.d.ts.map +1 -1
- package/dist/store/migrate-signaldock-to-conduit.js +3 -0
- package/dist/store/migrate-signaldock-to-conduit.js.map +1 -1
- package/dist/store/migration-manager.d.ts +61 -0
- package/dist/store/migration-manager.d.ts.map +1 -1
- package/dist/store/migration-manager.js +138 -6
- package/dist/store/migration-manager.js.map +1 -1
- package/dist/store/migration-sqlite.d.ts.map +1 -1
- package/dist/store/migration-sqlite.js +2 -0
- package/dist/store/migration-sqlite.js.map +1 -1
- package/dist/store/nexus-sqlite.d.ts.map +1 -1
- package/dist/store/nexus-sqlite.js +3 -0
- package/dist/store/nexus-sqlite.js.map +1 -1
- package/dist/store/nexus-validation-schemas.d.ts +64 -0
- package/dist/store/nexus-validation-schemas.d.ts.map +1 -1
- package/dist/store/open-cleo-db.d.ts.map +1 -1
- package/dist/store/open-cleo-db.js +3 -0
- package/dist/store/open-cleo-db.js.map +1 -1
- package/dist/store/portable-bundle-import.d.ts +8 -0
- package/dist/store/portable-bundle-import.d.ts.map +1 -1
- package/dist/store/portable-bundle-import.js +12 -0
- package/dist/store/portable-bundle-import.js.map +1 -1
- package/dist/store/portable-bundle-relocate.d.ts.map +1 -1
- package/dist/store/portable-bundle-relocate.js +2 -0
- package/dist/store/portable-bundle-relocate.js.map +1 -1
- package/dist/store/portable-bundle-scan.d.ts.map +1 -1
- package/dist/store/portable-bundle-scan.js +2 -1
- package/dist/store/portable-bundle-scan.js.map +1 -1
- package/dist/store/portable-bundle.d.ts.map +1 -1
- package/dist/store/portable-bundle.js +15 -14
- package/dist/store/portable-bundle.js.map +1 -1
- package/dist/store/ports/domain-binding.d.ts.map +1 -1
- package/dist/store/ports/domain-binding.js +5 -0
- package/dist/store/ports/domain-binding.js.map +1 -1
- package/dist/store/pre-repair-snapshot.d.ts +4 -1
- package/dist/store/pre-repair-snapshot.d.ts.map +1 -1
- package/dist/store/pre-repair-snapshot.js +5 -1
- package/dist/store/pre-repair-snapshot.js.map +1 -1
- package/dist/store/regenerators.d.ts +4 -2
- package/dist/store/regenerators.d.ts.map +1 -1
- package/dist/store/regenerators.js +7 -3
- package/dist/store/regenerators.js.map +1 -1
- package/dist/store/repair-malformed-dbs.d.ts +4 -0
- package/dist/store/repair-malformed-dbs.d.ts.map +1 -1
- package/dist/store/repair-malformed-dbs.js +3 -0
- package/dist/store/repair-malformed-dbs.js.map +1 -1
- package/dist/store/safety-data-accessor.d.ts +8 -3
- package/dist/store/safety-data-accessor.d.ts.map +1 -1
- package/dist/store/safety-data-accessor.js +11 -4
- package/dist/store/safety-data-accessor.js.map +1 -1
- package/dist/store/schema/cleo-global/nexus.d.ts +48 -0
- package/dist/store/schema/cleo-global/nexus.d.ts.map +1 -1
- package/dist/store/schema/cleo-global/nexus.js +17 -0
- package/dist/store/schema/cleo-global/nexus.js.map +1 -1
- package/dist/store/schema/cleo-project/docs.d.ts +16 -0
- package/dist/store/schema/cleo-project/docs.d.ts.map +1 -1
- package/dist/store/schema/cleo-project/docs.js +10 -0
- package/dist/store/schema/cleo-project/docs.js.map +1 -1
- package/dist/store/schema/cleo-project/tasks-core.d.ts +80 -0
- package/dist/store/schema/cleo-project/tasks-core.d.ts.map +1 -1
- package/dist/store/schema/cleo-project/tasks-core.js +25 -1
- package/dist/store/schema/cleo-project/tasks-core.js.map +1 -1
- package/dist/store/schema/cleo-shared/brain.d.ts +1 -1
- package/dist/store/schema/memory-schema.d.ts +1 -1
- package/dist/store/schema/nexus-schema.d.ts +48 -0
- package/dist/store/schema/nexus-schema.d.ts.map +1 -1
- package/dist/store/schema/nexus-schema.js +28 -7
- package/dist/store/schema/nexus-schema.js.map +1 -1
- package/dist/store/session-store.d.ts +65 -0
- package/dist/store/session-store.d.ts.map +1 -1
- package/dist/store/session-store.js +108 -7
- package/dist/store/session-store.js.map +1 -1
- package/dist/store/split-brain-import.d.ts.map +1 -1
- package/dist/store/split-brain-import.js +2 -0
- package/dist/store/split-brain-import.js.map +1 -1
- package/dist/store/sqlite-data-accessor.d.ts.map +1 -1
- package/dist/store/sqlite-data-accessor.js +252 -47
- package/dist/store/sqlite-data-accessor.js.map +1 -1
- package/dist/store/sqlite-native.d.ts.map +1 -1
- package/dist/store/sqlite-native.js +1 -0
- package/dist/store/sqlite-native.js.map +1 -1
- package/dist/store/sqlite.d.ts +15 -3
- package/dist/store/sqlite.d.ts.map +1 -1
- package/dist/store/sqlite.js +57 -20
- package/dist/store/sqlite.js.map +1 -1
- package/dist/store/store-write-guard.d.ts +9 -3
- package/dist/store/store-write-guard.d.ts.map +1 -1
- package/dist/store/store-write-guard.js +25 -4
- package/dist/store/store-write-guard.js.map +1 -1
- package/dist/store/table-classification.d.ts +1 -1
- package/dist/store/table-classification.d.ts.map +1 -1
- package/dist/store/table-classification.js +34 -8
- package/dist/store/table-classification.js.map +1 -1
- package/dist/store/task-claim.d.ts +144 -0
- package/dist/store/task-claim.d.ts.map +1 -0
- package/dist/store/task-claim.js +195 -0
- package/dist/store/task-claim.js.map +1 -0
- package/dist/store/task-version.d.ts +43 -5
- package/dist/store/task-version.d.ts.map +1 -1
- package/dist/store/task-version.js +113 -17
- package/dist/store/task-version.js.map +1 -1
- package/dist/store/tasks-schema.d.ts +2 -0
- package/dist/store/tasks-schema.d.ts.map +1 -1
- package/dist/store/tasks-schema.js +1 -0
- package/dist/store/tasks-schema.js.map +1 -1
- package/dist/store/tasks-sqlite.js +1 -1
- package/dist/store/tasks-sqlite.js.map +1 -1
- package/dist/store/twin-collapse.d.ts +339 -22
- package/dist/store/twin-collapse.d.ts.map +1 -1
- package/dist/store/twin-collapse.js +1323 -48
- package/dist/store/twin-collapse.js.map +1 -1
- package/dist/store/umbrella-data-accessor.d.ts +8 -3
- package/dist/store/umbrella-data-accessor.d.ts.map +1 -1
- package/dist/store/umbrella-data-accessor.js +10 -4
- package/dist/store/umbrella-data-accessor.js.map +1 -1
- package/dist/store/validation-schemas.d.ts +161 -1
- package/dist/store/validation-schemas.d.ts.map +1 -1
- package/dist/store/with-retry.d.ts +36 -0
- package/dist/store/with-retry.d.ts.map +1 -1
- package/dist/store/with-retry.js +51 -0
- package/dist/store/with-retry.js.map +1 -1
- package/dist/store/worktree-build-guard.d.ts +200 -0
- package/dist/store/worktree-build-guard.d.ts.map +1 -0
- package/dist/store/worktree-build-guard.js +497 -0
- package/dist/store/worktree-build-guard.js.map +1 -0
- package/dist/store/worktree-isolation-guard.d.ts +138 -0
- package/dist/store/worktree-isolation-guard.d.ts.map +1 -1
- package/dist/store/worktree-isolation-guard.js +189 -2
- package/dist/store/worktree-isolation-guard.js.map +1 -1
- package/dist/store/writer-lease.d.ts.map +1 -1
- package/dist/store/writer-lease.js +2 -0
- package/dist/store/writer-lease.js.map +1 -1
- package/dist/system/backup.d.ts +13 -2
- package/dist/system/backup.d.ts.map +1 -1
- package/dist/system/backup.js +11 -3
- package/dist/system/backup.js.map +1 -1
- package/dist/system/health.d.ts.map +1 -1
- package/dist/system/health.js +3 -1
- package/dist/system/health.js.map +1 -1
- package/dist/system/inject-generate.d.ts.map +1 -1
- package/dist/system/inject-generate.js +23 -10
- package/dist/system/inject-generate.js.map +1 -1
- package/dist/system/project-health.d.ts +8 -0
- package/dist/system/project-health.d.ts.map +1 -1
- package/dist/system/project-health.js +13 -5
- package/dist/system/project-health.js.map +1 -1
- package/dist/task-tools/index.d.ts +4 -2
- package/dist/task-tools/index.d.ts.map +1 -1
- package/dist/task-tools/index.js +3 -2
- package/dist/task-tools/index.js.map +1 -1
- package/dist/task-tools/score-task-priority.d.ts +131 -18
- package/dist/task-tools/score-task-priority.d.ts.map +1 -1
- package/dist/task-tools/score-task-priority.js +243 -80
- package/dist/task-tools/score-task-priority.js.map +1 -1
- package/dist/task-work/claims.d.ts +215 -0
- package/dist/task-work/claims.d.ts.map +1 -0
- package/dist/task-work/claims.js +272 -0
- package/dist/task-work/claims.js.map +1 -0
- package/dist/task-work/index.d.ts +47 -3
- package/dist/task-work/index.d.ts.map +1 -1
- package/dist/task-work/index.js +74 -41
- package/dist/task-work/index.js.map +1 -1
- package/dist/tasks/add.d.ts.map +1 -1
- package/dist/tasks/add.js +3 -2
- package/dist/tasks/add.js.map +1 -1
- package/dist/tasks/affected-packages.d.ts +5 -1
- package/dist/tasks/affected-packages.d.ts.map +1 -1
- package/dist/tasks/affected-packages.js +21 -3
- package/dist/tasks/affected-packages.js.map +1 -1
- package/dist/tasks/analyze.d.ts +29 -1
- package/dist/tasks/analyze.d.ts.map +1 -1
- package/dist/tasks/analyze.js +47 -37
- package/dist/tasks/analyze.js.map +1 -1
- package/dist/tasks/backfill-child-projections.d.ts.map +1 -1
- package/dist/tasks/backfill-child-projections.js +4 -1
- package/dist/tasks/backfill-child-projections.js.map +1 -1
- package/dist/tasks/change-set.d.ts +5 -0
- package/dist/tasks/change-set.d.ts.map +1 -1
- package/dist/tasks/change-set.js +75 -6
- package/dist/tasks/change-set.js.map +1 -1
- package/dist/tasks/command-line.d.ts +54 -0
- package/dist/tasks/command-line.d.ts.map +1 -0
- package/dist/tasks/command-line.js +151 -0
- package/dist/tasks/command-line.js.map +1 -0
- package/dist/tasks/complete.d.ts +16 -0
- package/dist/tasks/complete.d.ts.map +1 -1
- package/dist/tasks/complete.js +27 -7
- package/dist/tasks/complete.js.map +1 -1
- package/dist/tasks/component-pr.d.ts +162 -1
- package/dist/tasks/component-pr.d.ts.map +1 -1
- package/dist/tasks/component-pr.js +639 -53
- package/dist/tasks/component-pr.js.map +1 -1
- package/dist/tasks/delete.d.ts.map +1 -1
- package/dist/tasks/delete.js +20 -0
- package/dist/tasks/delete.js.map +1 -1
- package/dist/tasks/done-record.d.ts +14 -1
- package/dist/tasks/done-record.d.ts.map +1 -1
- package/dist/tasks/done-record.js +37 -0
- package/dist/tasks/done-record.js.map +1 -1
- package/dist/tasks/duplicate-detector.d.ts +23 -4
- package/dist/tasks/duplicate-detector.d.ts.map +1 -1
- package/dist/tasks/duplicate-detector.js +14 -5
- package/dist/tasks/duplicate-detector.js.map +1 -1
- package/dist/tasks/engine-wrap-ops.d.ts +48 -10
- package/dist/tasks/engine-wrap-ops.d.ts.map +1 -1
- package/dist/tasks/engine-wrap-ops.js +78 -10
- package/dist/tasks/engine-wrap-ops.js.map +1 -1
- package/dist/tasks/engine-wrap.d.ts +1 -1
- package/dist/tasks/engine-wrap.d.ts.map +1 -1
- package/dist/tasks/engine-wrap.js +1 -1
- package/dist/tasks/engine-wrap.js.map +1 -1
- package/dist/tasks/evidence.d.ts +2 -0
- package/dist/tasks/evidence.d.ts.map +1 -1
- package/dist/tasks/evidence.js +30 -4
- package/dist/tasks/evidence.js.map +1 -1
- package/dist/tasks/gate-runner.d.ts.map +1 -1
- package/dist/tasks/gate-runner.js +48 -12
- package/dist/tasks/gate-runner.js.map +1 -1
- package/dist/tasks/graph-ops.d.ts +9 -2
- package/dist/tasks/graph-ops.d.ts.map +1 -1
- package/dist/tasks/graph-ops.js +24 -32
- package/dist/tasks/graph-ops.js.map +1 -1
- package/dist/tasks/index.d.ts +1 -1
- package/dist/tasks/index.d.ts.map +1 -1
- package/dist/tasks/index.js +1 -1
- package/dist/tasks/index.js.map +1 -1
- package/dist/tasks/ops.d.ts +1 -0
- package/dist/tasks/ops.d.ts.map +1 -1
- package/dist/tasks/plan.d.ts.map +1 -1
- package/dist/tasks/plan.js +16 -60
- package/dist/tasks/plan.js.map +1 -1
- package/dist/tasks/ranking-audit.d.ts +122 -0
- package/dist/tasks/ranking-audit.d.ts.map +1 -0
- package/dist/tasks/ranking-audit.js +193 -0
- package/dist/tasks/ranking-audit.js.map +1 -0
- package/dist/tasks/task-analyze.d.ts.map +1 -1
- package/dist/tasks/task-analyze.js +19 -32
- package/dist/tasks/task-analyze.js.map +1 -1
- package/dist/tasks/task-context.d.ts.map +1 -1
- package/dist/tasks/task-context.js +13 -0
- package/dist/tasks/task-context.js.map +1 -1
- package/dist/tasks/task-import.d.ts.map +1 -1
- package/dist/tasks/task-import.js +21 -12
- package/dist/tasks/task-import.js.map +1 -1
- package/dist/tasks/task-next.d.ts +67 -2
- package/dist/tasks/task-next.d.ts.map +1 -1
- package/dist/tasks/task-next.js +99 -102
- package/dist/tasks/task-next.js.map +1 -1
- package/dist/tasks/task-ops.d.ts +1 -1
- package/dist/tasks/task-ops.d.ts.map +1 -1
- package/dist/tasks/task-ops.js +1 -1
- package/dist/tasks/task-ops.js.map +1 -1
- package/dist/tasks/tool-resolver.d.ts +7 -1
- package/dist/tasks/tool-resolver.d.ts.map +1 -1
- package/dist/tasks/tool-resolver.js +24 -10
- package/dist/tasks/tool-resolver.js.map +1 -1
- package/dist/tasks/update.d.ts +8 -2
- package/dist/tasks/update.d.ts.map +1 -1
- package/dist/tasks/update.js +35 -6
- package/dist/tasks/update.js.map +1 -1
- package/dist/telemetry/sqlite.d.ts.map +1 -1
- package/dist/telemetry/sqlite.js +2 -0
- package/dist/telemetry/sqlite.js.map +1 -1
- package/dist/upgrade.d.ts +1 -1
- package/dist/upgrade.d.ts.map +1 -1
- package/dist/upgrade.js +48 -9
- package/dist/upgrade.js.map +1 -1
- package/dist/validation/doctor/checks.d.ts +20 -6
- package/dist/validation/doctor/checks.d.ts.map +1 -1
- package/dist/validation/doctor/checks.js +53 -10
- package/dist/validation/doctor/checks.js.map +1 -1
- package/dist/validation/validate-ops.d.ts.map +1 -1
- package/dist/validation/validate-ops.js +2 -3
- package/dist/validation/validate-ops.js.map +1 -1
- package/migrations/drizzle-cleo-global/20260929010000_t12512-registry-probed-opened/migration.sql +35 -0
- package/migrations/drizzle-cleo-global/20260929020000_t12721-git-state-head-committed-at/migration.sql +25 -0
- package/migrations/drizzle-cleo-project/20260929000000_t12535-docs-attachments-union-shape/migration.sql +21 -0
- package/migrations/drizzle-cleo-project/20260929120000_t12502-task-claim-leases/migration.sql +77 -0
- package/migrations/drizzle-cleo-project/20260929130000_t12736-claim-lease-iso-repair/migration.sql +37 -0
- package/package.json +24 -14
- package/schemas/config.schema.json +13 -0
- package/schemas/project-info.schema.json +10 -4
- package/templates/CLEO-INJECTION.md +1 -1
- package/templates/CLEO-REFERENCE.md +7 -3
- package/templates/cleo-gitignore +11 -0
- package/templates/workflows/release-prepare.yml.tmpl +156 -10
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Decision-provider credential store — the two settings a
|
|
3
|
-
* (an API base URL and an API key)
|
|
2
|
+
* Decision-provider credential store — the provider kind, the two settings a
|
|
3
|
+
* user supplies (an API base URL and an API key) and the default model.
|
|
4
|
+
*
|
|
5
|
+
* The file stays at schema version 1. T12713 added `provider` (`layahost` |
|
|
6
|
+
* `jev`) as an OPTIONAL, additive field instead of bumping the version, so a
|
|
7
|
+
* CLEO that predates provider kinds (whose zod object is non-strict and
|
|
8
|
+
* accepts only `version: 1`) still parses the file after a downgrade. A file
|
|
9
|
+
* without `provider` infers the kind from its base URL
|
|
10
|
+
* ({@link inferDecisionProviderKind}).
|
|
4
11
|
*
|
|
5
12
|
* Stored at `<cleoHome>/decide-credentials.json` (resolved through
|
|
6
13
|
* `@cleocode/paths`, arch gate 2) with 0600 permissions:
|
|
@@ -22,28 +29,256 @@
|
|
|
22
29
|
* audit: nothing here logs, and every summary this module returns carries the
|
|
23
30
|
* masked preview only.
|
|
24
31
|
*
|
|
32
|
+
* ## Profiles (T12733)
|
|
33
|
+
*
|
|
34
|
+
* The store holds any number of profiles, several per provider (accounts,
|
|
35
|
+
* each with its own key), addressed as `<provider>/<name>` (e.g.
|
|
36
|
+
* `layahost/work`, `layahost/personal`, `jev/team`), and exactly one ACTIVE
|
|
37
|
+
* profile, which everyday decisions use. The format stays additive on
|
|
38
|
+
* version 1:
|
|
39
|
+
*
|
|
40
|
+
* ```json
|
|
41
|
+
* { "version": 1,
|
|
42
|
+
* "provider": "layahost", "baseUrl": "https://layahost.com", "apiKey": "…",
|
|
43
|
+
* "model": "laya-auto", "updatedAt": "…",
|
|
44
|
+
* "active": "layahost/work",
|
|
45
|
+
* "profiles": {
|
|
46
|
+
* "layahost/work": { "provider": "layahost", "name": "work", "baseUrl": "default", "apiKey": "…", "model": "laya-auto" },
|
|
47
|
+
* "jev/team": { "provider": "jev", "name": "team", "baseUrl": "https://jev.internal", "apiKey": "…", "model": "…" } } }
|
|
48
|
+
* ```
|
|
49
|
+
*
|
|
50
|
+
* - A profile's `baseUrl` is the literal `default` (its provider's preset
|
|
51
|
+
* URL, resolved at call time, so a changed preset flows through) or an
|
|
52
|
+
* override URL.
|
|
53
|
+
* - The top-level single-config fields ARE the active profile with its URL
|
|
54
|
+
* resolved, so a CLEO that predates profiles (9.23) reads the active profile
|
|
55
|
+
* as its one config. Every write keeps them in sync.
|
|
56
|
+
* - A file without `profiles` (written before T12733) is one active profile,
|
|
57
|
+
* `<provider>/default`.
|
|
58
|
+
* - An older CLEO that rewrites the file drops `profiles` and `active` (its
|
|
59
|
+
* zod object strips unknown keys and its save replaces the file). When the
|
|
60
|
+
* top-level settings then differ from the active profile, the TOP-LEVEL
|
|
61
|
+
* settings are authoritative: they replace the active profile (or, when the
|
|
62
|
+
* provider changed, become `<new provider>/<active name>`), and
|
|
63
|
+
* {@link listDecideProfiles} reports `reconciled: true`. Profiles dropped
|
|
64
|
+
* by such a rewrite cannot be recovered and must be added again. Empty
|
|
65
|
+
* top-level settings beside a stored active profile mean the older CLEO
|
|
66
|
+
* cleared them: no profile is active.
|
|
67
|
+
*
|
|
25
68
|
* @task T12491
|
|
69
|
+
* @task T12713
|
|
70
|
+
* @task T12733
|
|
26
71
|
* @epic T12486
|
|
27
72
|
*/
|
|
28
73
|
import { existsSync, lstatSync, mkdirSync, readdirSync, readFileSync, statSync, unlinkSync, writeFileSync, } from 'node:fs';
|
|
29
74
|
import { dirname, join } from 'node:path';
|
|
30
75
|
import { inspect } from 'node:util';
|
|
31
|
-
import { decisionProviderConfigSchema } from '@cleocode/contracts';
|
|
76
|
+
import { DECIDE_DEFAULT_PROFILE_NAME, DECIDE_PROFILE_DEFAULT_URL, DECIDE_PROFILE_NAME_PATTERN, DECISION_PROVIDER_KINDS, decisionProviderConfigSchema, decisionProviderKindSchema, } from '@cleocode/contracts';
|
|
32
77
|
import { getCleoHome } from '@cleocode/paths';
|
|
33
78
|
import { z } from 'zod';
|
|
34
79
|
import { withLock } from '../store/file-utils.js';
|
|
35
80
|
import { isValidDecisionModelName } from './jev-wire.js';
|
|
81
|
+
import { inferDecisionProviderKind, presetBaseUrl } from './providers.js';
|
|
36
82
|
/** File name of the store, directly under the CLEO home. */
|
|
37
83
|
export const DECIDE_CREDENTIALS_FILE = 'decide-credentials.json';
|
|
38
|
-
/**
|
|
84
|
+
/**
|
|
85
|
+
* On-disk schema version. Deliberately still 1: `provider` is an additive
|
|
86
|
+
* optional field, and released CLEO parses `z.literal(1)` — bumping this would
|
|
87
|
+
* silently disable System One after a downgrade.
|
|
88
|
+
*/
|
|
89
|
+
export const DECIDE_CREDENTIALS_VERSION = 1;
|
|
90
|
+
/** On-disk shape of one profile (T12733). `baseUrl` is `default` or an override URL. */
|
|
91
|
+
const profileSchema = z.object({
|
|
92
|
+
provider: decisionProviderKindSchema,
|
|
93
|
+
name: z.string(),
|
|
94
|
+
baseUrl: z.string(),
|
|
95
|
+
apiKey: z.string(),
|
|
96
|
+
model: z.string().nullable().optional(),
|
|
97
|
+
updatedAt: z.string().optional(),
|
|
98
|
+
});
|
|
99
|
+
/**
|
|
100
|
+
* On-disk shape of the store. `null` settings mean "not configured". The
|
|
101
|
+
* top-level settings are the active profile with its URL resolved (T12733);
|
|
102
|
+
* `profiles` and `active` are additive, and a malformed value for either is
|
|
103
|
+
* ignored rather than failing the whole file.
|
|
104
|
+
*/
|
|
39
105
|
const storeSchema = z.object({
|
|
40
|
-
version: z.literal(
|
|
106
|
+
version: z.literal(DECIDE_CREDENTIALS_VERSION),
|
|
107
|
+
/** T12713, optional: absent in files written before provider kinds existed. */
|
|
108
|
+
provider: decisionProviderKindSchema.nullable().optional(),
|
|
41
109
|
baseUrl: z.string().nullable(),
|
|
42
110
|
apiKey: z.string().nullable(),
|
|
43
111
|
model: z.string().nullable().optional(),
|
|
44
112
|
updatedAt: z.string().optional(),
|
|
113
|
+
/** T12733, optional: every profile, keyed by `<provider>/<name>`. Entries are validated one by one. */
|
|
114
|
+
profiles: z.record(z.string(), z.json()).optional().catch(undefined),
|
|
115
|
+
/** T12733, optional: the id of the active profile. */
|
|
116
|
+
active: z.string().nullable().optional().catch(undefined),
|
|
45
117
|
});
|
|
46
|
-
const EMPTY_STORE = {
|
|
118
|
+
const EMPTY_STORE = {
|
|
119
|
+
version: DECIDE_CREDENTIALS_VERSION,
|
|
120
|
+
baseUrl: null,
|
|
121
|
+
apiKey: null,
|
|
122
|
+
};
|
|
123
|
+
/** Parse the store; a file without `provider` infers it from its base URL. */
|
|
124
|
+
function parseStore(value) {
|
|
125
|
+
const parsed = storeSchema.safeParse(value);
|
|
126
|
+
if (!parsed.success)
|
|
127
|
+
return null;
|
|
128
|
+
const store = parsed.data;
|
|
129
|
+
if (store.provider || !store.baseUrl)
|
|
130
|
+
return store;
|
|
131
|
+
return { ...store, provider: inferDecisionProviderKind(store.baseUrl) };
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Whether `name` is a valid profile name: 1-32 characters of `a-z`, `0-9`
|
|
135
|
+
* and `-`, starting and ending with a letter or digit.
|
|
136
|
+
*
|
|
137
|
+
* @param name - Candidate name (the part after `<provider>/`).
|
|
138
|
+
* @returns True when the name may be stored.
|
|
139
|
+
*/
|
|
140
|
+
export function isValidDecideProfileName(name) {
|
|
141
|
+
return DECIDE_PROFILE_NAME_PATTERN.test(name);
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Build a profile id.
|
|
145
|
+
*
|
|
146
|
+
* @param provider - Provider kind.
|
|
147
|
+
* @param name - Profile name.
|
|
148
|
+
* @returns `<provider>/<name>`.
|
|
149
|
+
*/
|
|
150
|
+
export function decideProfileId(provider, name) {
|
|
151
|
+
return `${provider}/${name}`;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Parse a profile reference: `<provider>/<name>` (e.g. `layahost/work`), or a
|
|
155
|
+
* bare provider kind meaning `<provider>/default`.
|
|
156
|
+
*
|
|
157
|
+
* @param ref - Reference as typed by the user.
|
|
158
|
+
* @returns The parsed reference, or `null` when it names no valid profile.
|
|
159
|
+
*/
|
|
160
|
+
export function parseDecideProfileRef(ref) {
|
|
161
|
+
const parts = ref.trim().split('/');
|
|
162
|
+
const provider = DECISION_PROVIDER_KINDS.find((kind) => kind === parts[0]);
|
|
163
|
+
if (!provider || parts.length > 2)
|
|
164
|
+
return null;
|
|
165
|
+
const name = parts.length === 2 ? (parts[1] ?? '') : DECIDE_DEFAULT_PROFILE_NAME;
|
|
166
|
+
if (!isValidDecideProfileName(name))
|
|
167
|
+
return null;
|
|
168
|
+
return { provider, name, id: decideProfileId(provider, name) };
|
|
169
|
+
}
|
|
170
|
+
/** A profile's URL resolved: its override, or its provider's preset for `default`. */
|
|
171
|
+
function resolveProfileUrl(profile) {
|
|
172
|
+
return profile.baseUrl === DECIDE_PROFILE_DEFAULT_URL
|
|
173
|
+
? presetBaseUrl(profile.provider)
|
|
174
|
+
: profile.baseUrl;
|
|
175
|
+
}
|
|
176
|
+
/** Strip trailing slashes for URL comparison. */
|
|
177
|
+
function normalizeUrl(url) {
|
|
178
|
+
return url.trim().replace(/\/+$/, '');
|
|
179
|
+
}
|
|
180
|
+
/** The stored form of a URL: `default` when it is the provider's preset URL, else the URL. */
|
|
181
|
+
function urlSetting(provider, url) {
|
|
182
|
+
const preset = presetBaseUrl(provider);
|
|
183
|
+
return preset && normalizeUrl(url) === normalizeUrl(preset) ? DECIDE_PROFILE_DEFAULT_URL : url;
|
|
184
|
+
}
|
|
185
|
+
/** The top-level settings, or `null` when no URL + key is stored. */
|
|
186
|
+
function topLevelSettings(store) {
|
|
187
|
+
const baseUrl = store.baseUrl?.trim();
|
|
188
|
+
const apiKey = store.apiKey?.trim();
|
|
189
|
+
if (!baseUrl || !apiKey)
|
|
190
|
+
return null;
|
|
191
|
+
return {
|
|
192
|
+
provider: store.provider ?? inferDecisionProviderKind(baseUrl),
|
|
193
|
+
baseUrl,
|
|
194
|
+
apiKey,
|
|
195
|
+
model: store.model?.trim() || null,
|
|
196
|
+
...(store.updatedAt ? { updatedAt: store.updatedAt } : {}),
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
/** Whether a profile holds the same settings as the top level (timestamps ignored). */
|
|
200
|
+
function matchesTopLevel(profile, top) {
|
|
201
|
+
const url = resolveProfileUrl(profile);
|
|
202
|
+
return (profile.provider === top.provider &&
|
|
203
|
+
url !== undefined &&
|
|
204
|
+
normalizeUrl(url) === normalizeUrl(top.baseUrl) &&
|
|
205
|
+
profile.apiKey.trim() === top.apiKey &&
|
|
206
|
+
(profile.model?.trim() || null) === top.model);
|
|
207
|
+
}
|
|
208
|
+
/** Keep only well-formed profiles whose key matches their provider and name. */
|
|
209
|
+
function validProfiles(raw) {
|
|
210
|
+
const profiles = {};
|
|
211
|
+
for (const [id, value] of Object.entries(raw ?? {})) {
|
|
212
|
+
const parsed = profileSchema.safeParse(value);
|
|
213
|
+
if (!parsed.success)
|
|
214
|
+
continue;
|
|
215
|
+
const ref = parseDecideProfileRef(id);
|
|
216
|
+
if (ref?.id !== id || ref.provider !== parsed.data.provider || ref.name !== parsed.data.name) {
|
|
217
|
+
continue;
|
|
218
|
+
}
|
|
219
|
+
profiles[id] = parsed.data;
|
|
220
|
+
}
|
|
221
|
+
return profiles;
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* View the parsed store as profiles. The top-level settings are
|
|
225
|
+
* authoritative for the active profile (see the module doc): when they
|
|
226
|
+
* differ from it, they replace it (same provider) or become
|
|
227
|
+
* `<their provider>/<active name>` (an older CLEO switched provider).
|
|
228
|
+
*/
|
|
229
|
+
function toProfileStore(store) {
|
|
230
|
+
const profiles = validProfiles(store.profiles);
|
|
231
|
+
const hadProfiles = Object.keys(profiles).length > 0;
|
|
232
|
+
const activeRef = store.active ? parseDecideProfileRef(store.active) : null;
|
|
233
|
+
const top = topLevelSettings(store);
|
|
234
|
+
if (!top) {
|
|
235
|
+
// An older CLEO cleared the settings (or nothing was ever configured).
|
|
236
|
+
return { profiles, active: null, reconciled: activeRef !== null && activeRef.id in profiles };
|
|
237
|
+
}
|
|
238
|
+
const name = activeRef?.name ?? DECIDE_DEFAULT_PROFILE_NAME;
|
|
239
|
+
const id = activeRef?.provider === top.provider ? activeRef.id : decideProfileId(top.provider, name);
|
|
240
|
+
const existing = profiles[id];
|
|
241
|
+
const inSync = existing !== undefined && matchesTopLevel(existing, top);
|
|
242
|
+
if (!inSync) {
|
|
243
|
+
profiles[id] = {
|
|
244
|
+
provider: top.provider,
|
|
245
|
+
name: id.slice(top.provider.length + 1),
|
|
246
|
+
baseUrl: urlSetting(top.provider, top.baseUrl),
|
|
247
|
+
apiKey: top.apiKey,
|
|
248
|
+
model: top.model,
|
|
249
|
+
...(top.updatedAt ? { updatedAt: top.updatedAt } : {}),
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
const reconciled = (activeRef !== null || hadProfiles) && !(inSync && id === activeRef?.id);
|
|
253
|
+
return { profiles, active: id, reconciled };
|
|
254
|
+
}
|
|
255
|
+
/** The empty store as written. */
|
|
256
|
+
const EMPTY_WRITTEN = {
|
|
257
|
+
version: DECIDE_CREDENTIALS_VERSION,
|
|
258
|
+
baseUrl: null,
|
|
259
|
+
apiKey: null,
|
|
260
|
+
};
|
|
261
|
+
/** Render profiles back to the on-disk shape (top-level = active profile, URL resolved). */
|
|
262
|
+
function fromProfileStore(ps) {
|
|
263
|
+
const ids = Object.keys(ps.profiles).sort();
|
|
264
|
+
if (ids.length === 0)
|
|
265
|
+
return EMPTY_WRITTEN;
|
|
266
|
+
const active = ps.active ? ps.profiles[ps.active] : undefined;
|
|
267
|
+
const activeUrl = active ? resolveProfileUrl(active) : undefined;
|
|
268
|
+
return {
|
|
269
|
+
version: DECIDE_CREDENTIALS_VERSION,
|
|
270
|
+
...(active && activeUrl ? { provider: active.provider } : {}),
|
|
271
|
+
baseUrl: active && activeUrl ? activeUrl : null,
|
|
272
|
+
apiKey: active && activeUrl ? active.apiKey : null,
|
|
273
|
+
model: (active && activeUrl ? active.model : null) ?? null,
|
|
274
|
+
updatedAt: new Date().toISOString(),
|
|
275
|
+
...(ps.active && activeUrl ? { active: ps.active } : {}),
|
|
276
|
+
profiles: Object.fromEntries(ids.flatMap((id) => {
|
|
277
|
+
const profile = ps.profiles[id];
|
|
278
|
+
return profile ? [[id, profile]] : [];
|
|
279
|
+
})),
|
|
280
|
+
};
|
|
281
|
+
}
|
|
47
282
|
/**
|
|
48
283
|
* Absolute path of the decision-credential store.
|
|
49
284
|
*
|
|
@@ -67,48 +302,60 @@ export function maskApiKey(apiKey) {
|
|
|
67
302
|
* serialising or inspecting the handle yields the masked preview only.
|
|
68
303
|
*/
|
|
69
304
|
export class SealedDecideConnection {
|
|
305
|
+
/** Provider kind (not secret). */
|
|
306
|
+
provider;
|
|
70
307
|
/** Provider base URL (not secret). */
|
|
71
308
|
baseUrl;
|
|
72
309
|
/** Default model, when configured. */
|
|
73
310
|
model;
|
|
74
311
|
/** Masked key preview (`…abcd`). */
|
|
75
312
|
keyPreview;
|
|
313
|
+
/** Profile id (`<provider>/<name>`, T12733), when resolved from a profile. */
|
|
314
|
+
profile;
|
|
76
315
|
#apiKey;
|
|
77
316
|
/**
|
|
78
317
|
* @param baseUrl - Provider base URL.
|
|
79
318
|
* @param apiKey - Plaintext key; captured privately.
|
|
80
319
|
* @param model - Optional default model.
|
|
320
|
+
* @param provider - Provider kind. Default `jev`.
|
|
321
|
+
* @param profile - Profile id, when known.
|
|
81
322
|
*/
|
|
82
|
-
constructor(baseUrl, apiKey, model) {
|
|
323
|
+
constructor(baseUrl, apiKey, model, provider = 'jev', profile) {
|
|
324
|
+
this.provider = provider;
|
|
83
325
|
this.baseUrl = baseUrl;
|
|
84
326
|
this.#apiKey = apiKey;
|
|
85
327
|
this.keyPreview = maskApiKey(apiKey);
|
|
86
328
|
if (model)
|
|
87
329
|
this.model = model;
|
|
330
|
+
if (profile)
|
|
331
|
+
this.profile = profile;
|
|
88
332
|
}
|
|
89
333
|
/**
|
|
90
334
|
* Materialise the wire connection. Call only where the request is built.
|
|
91
335
|
*
|
|
92
|
-
* @returns Base URL, plaintext key and
|
|
336
|
+
* @returns Base URL, plaintext key, optional model and the profile id when known.
|
|
93
337
|
*/
|
|
94
338
|
connection() {
|
|
95
339
|
return {
|
|
96
340
|
baseUrl: this.baseUrl,
|
|
97
341
|
apiKey: this.#apiKey,
|
|
98
342
|
...(this.model ? { model: this.model } : {}),
|
|
343
|
+
...(this.profile ? { profile: this.profile } : {}),
|
|
99
344
|
};
|
|
100
345
|
}
|
|
101
346
|
/** @returns The secret-free JSON form. */
|
|
102
347
|
toJSON() {
|
|
103
348
|
return {
|
|
349
|
+
provider: this.provider,
|
|
104
350
|
baseUrl: this.baseUrl,
|
|
105
351
|
...(this.model ? { model: this.model } : {}),
|
|
106
352
|
keyPreview: this.keyPreview,
|
|
353
|
+
...(this.profile ? { profile: this.profile } : {}),
|
|
107
354
|
};
|
|
108
355
|
}
|
|
109
356
|
/** @returns A secret-free string form. */
|
|
110
357
|
toString() {
|
|
111
|
-
return `SealedDecideConnection(${this.baseUrl}, key ${this.keyPreview})`;
|
|
358
|
+
return `SealedDecideConnection(${this.provider} ${this.baseUrl}, key ${this.keyPreview})`;
|
|
112
359
|
}
|
|
113
360
|
/** Secret-free `util.inspect` / `console.log` form. */
|
|
114
361
|
[inspect.custom]() {
|
|
@@ -127,8 +374,7 @@ function readStoreSync(path = decideCredentialsPath()) {
|
|
|
127
374
|
if (!raw.trim())
|
|
128
375
|
return EMPTY_STORE;
|
|
129
376
|
try {
|
|
130
|
-
|
|
131
|
-
return parsed.success ? parsed.data : EMPTY_STORE;
|
|
377
|
+
return parseStore(JSON.parse(raw)) ?? EMPTY_STORE;
|
|
132
378
|
}
|
|
133
379
|
catch {
|
|
134
380
|
return EMPTY_STORE;
|
|
@@ -188,24 +434,142 @@ export function sameDecideHost(a, b) {
|
|
|
188
434
|
return false;
|
|
189
435
|
}
|
|
190
436
|
}
|
|
437
|
+
/** Seal settings, or `null` when the URL or key is unusable. */
|
|
438
|
+
function sealSettings(provider, baseUrl, apiKey, model, profile) {
|
|
439
|
+
const url = baseUrl?.trim();
|
|
440
|
+
const key = apiKey.trim();
|
|
441
|
+
if (!url || !key || !isAllowedDecideBaseUrl(url))
|
|
442
|
+
return null;
|
|
443
|
+
const m = model?.trim();
|
|
444
|
+
return new SealedDecideConnection(url, key, m && isValidDecisionModelName(m) ? m : undefined, provider, profile ?? undefined);
|
|
445
|
+
}
|
|
446
|
+
/** Seal a stored profile (URL resolved), or `null` when unusable. */
|
|
447
|
+
function sealProfile(profile) {
|
|
448
|
+
if (!profile)
|
|
449
|
+
return null;
|
|
450
|
+
return sealSettings(profile.provider, resolveProfileUrl(profile), profile.apiKey, profile.model, decideProfileId(profile.provider, profile.name));
|
|
451
|
+
}
|
|
452
|
+
/** Read the store as profiles. Never throws. */
|
|
453
|
+
function readProfileStoreSync(path = decideCredentialsPath()) {
|
|
454
|
+
return toProfileStore(readStoreSync(path));
|
|
455
|
+
}
|
|
456
|
+
/** Human rule for profile references, used in error messages. */
|
|
457
|
+
const PROFILE_REF_RULE = `(use <provider>/<name>: provider ${DECISION_PROVIDER_KINDS.join('|')}, name of 1-32 lowercase letters, digits or -, e.g. layahost/work)`;
|
|
458
|
+
/** ` (profiles: a, b)`, or ` (no profiles are stored)`. */
|
|
459
|
+
function knownIds(ps) {
|
|
460
|
+
const ids = Object.keys(ps.profiles).sort();
|
|
461
|
+
return ids.length ? ` (profiles: ${ids.join(', ')})` : ' (no profiles are stored)';
|
|
462
|
+
}
|
|
463
|
+
/**
|
|
464
|
+
* Parse a profile reference or throw.
|
|
465
|
+
*
|
|
466
|
+
* @throws {DecideCredentialsError} When the reference names no valid profile.
|
|
467
|
+
*/
|
|
468
|
+
function requireProfileRef(ref) {
|
|
469
|
+
const parsed = parseDecideProfileRef(ref);
|
|
470
|
+
if (!parsed)
|
|
471
|
+
throw new DecideCredentialsError(`invalid profile '${ref}' ${PROFILE_REF_RULE}`);
|
|
472
|
+
return parsed;
|
|
473
|
+
}
|
|
191
474
|
/**
|
|
192
|
-
* Load the
|
|
193
|
-
*
|
|
194
|
-
*
|
|
475
|
+
* Load the ACTIVE profile's connection: what everyday decisions use. Reads
|
|
476
|
+
* the top-level settings, which are the active profile with its URL
|
|
477
|
+
* resolved. Synchronous and total: missing, malformed or incomplete
|
|
478
|
+
* settings return `null` (the decision client then falls back to heuristics).
|
|
195
479
|
*
|
|
196
480
|
* @returns The sealed connection, or `null` when unconfigured.
|
|
197
481
|
*/
|
|
198
482
|
export function loadDecideConnection() {
|
|
199
483
|
const store = readStoreSync();
|
|
200
|
-
const
|
|
201
|
-
|
|
202
|
-
if (!baseUrl || !apiKey || !isAllowedDecideBaseUrl(baseUrl))
|
|
484
|
+
const top = topLevelSettings(store);
|
|
485
|
+
if (!top)
|
|
203
486
|
return null;
|
|
204
|
-
|
|
205
|
-
|
|
487
|
+
return sealSettings(top.provider, top.baseUrl, top.apiKey, top.model, toProfileStore(store).active);
|
|
488
|
+
}
|
|
489
|
+
/**
|
|
490
|
+
* Load a profile's connection without changing the active profile. Total:
|
|
491
|
+
* an invalid or unknown reference, or unusable settings, return `null`.
|
|
492
|
+
*
|
|
493
|
+
* @param ref - `<provider>/<name>`, or a bare provider for `<provider>/default`.
|
|
494
|
+
* @returns The sealed connection, or `null`.
|
|
495
|
+
*/
|
|
496
|
+
export function loadDecideProfile(ref) {
|
|
497
|
+
const parsed = parseDecideProfileRef(ref);
|
|
498
|
+
return parsed ? sealProfile(readProfileStoreSync().profiles[parsed.id]) : null;
|
|
499
|
+
}
|
|
500
|
+
/**
|
|
501
|
+
* Resolve a profile to its connection, for callers (the System One
|
|
502
|
+
* benchmark) that address a profile by name without switching the active
|
|
503
|
+
* one. A `default` URL is resolved to the provider's current preset. The
|
|
504
|
+
* result CONTAINS THE PLAINTEXT KEY: pass it to the wire, never log or emit
|
|
505
|
+
* it. For a secret-safe handle use {@link loadDecideProfile}.
|
|
506
|
+
*
|
|
507
|
+
* @param ref - `<provider>/<name>` (e.g. `layahost/work`), or a bare provider for `<provider>/default`.
|
|
508
|
+
* @returns `{ name, profile, provider, baseUrl, apiKey, model }`, `name` and `profile` being the id.
|
|
509
|
+
* @throws {DecideCredentialsError} When the reference is invalid or unknown,
|
|
510
|
+
* or the profile's settings are unusable. The message lists the stored ids.
|
|
511
|
+
*/
|
|
512
|
+
export function resolveDecideProfile(ref) {
|
|
513
|
+
const { id } = requireProfileRef(ref);
|
|
514
|
+
const ps = readProfileStoreSync();
|
|
515
|
+
const profile = ps.profiles[id];
|
|
516
|
+
if (!profile) {
|
|
517
|
+
throw new DecideCredentialsError(`no System One profile '${id}'${knownIds(ps)}`);
|
|
518
|
+
}
|
|
519
|
+
const sealed = sealProfile(profile);
|
|
520
|
+
if (!sealed) {
|
|
521
|
+
throw new DecideCredentialsError(`System One profile '${id}' has an unusable URL or key; store it again with: cleo decide config --profile ${id}`);
|
|
522
|
+
}
|
|
523
|
+
const wire = sealed.connection();
|
|
524
|
+
return {
|
|
525
|
+
name: id,
|
|
526
|
+
profile: id,
|
|
527
|
+
provider: sealed.provider,
|
|
528
|
+
baseUrl: wire.baseUrl,
|
|
529
|
+
apiKey: wire.apiKey,
|
|
530
|
+
...(wire.model ? { model: wire.model } : {}),
|
|
531
|
+
};
|
|
532
|
+
}
|
|
533
|
+
/** Secret-free summary of one stored profile. */
|
|
534
|
+
function summarizeProfile(id, profile, active) {
|
|
535
|
+
const model = profile.model?.trim();
|
|
536
|
+
return {
|
|
537
|
+
id,
|
|
538
|
+
name: profile.name,
|
|
539
|
+
active: id === active,
|
|
540
|
+
configured: sealProfile(profile) !== null,
|
|
541
|
+
provider: profile.provider,
|
|
542
|
+
baseUrl: withoutUserinfo(resolveProfileUrl(profile) ?? ''),
|
|
543
|
+
urlSource: profile.baseUrl === DECIDE_PROFILE_DEFAULT_URL ? 'default' : 'override',
|
|
544
|
+
...(model ? { model } : {}),
|
|
545
|
+
keyPreview: maskApiKey(profile.apiKey),
|
|
546
|
+
...(profile.updatedAt ? { updatedAt: profile.updatedAt } : {}),
|
|
547
|
+
};
|
|
548
|
+
}
|
|
549
|
+
/**
|
|
550
|
+
* List every stored profile, the active one marked, keys masked. The
|
|
551
|
+
* benchmark uses it to enumerate the profiles it can call by id.
|
|
552
|
+
*
|
|
553
|
+
* @returns The profiles sorted by id, the active id, and whether the
|
|
554
|
+
* top-level settings overrode a stale active entry (an older CLEO rewrote the file).
|
|
555
|
+
*/
|
|
556
|
+
export function listDecideProfiles() {
|
|
557
|
+
const path = decideCredentialsPath();
|
|
558
|
+
const ps = readProfileStoreSync(path);
|
|
559
|
+
return {
|
|
560
|
+
path,
|
|
561
|
+
active: ps.active,
|
|
562
|
+
profiles: Object.keys(ps.profiles)
|
|
563
|
+
.sort()
|
|
564
|
+
.flatMap((id) => {
|
|
565
|
+
const profile = ps.profiles[id];
|
|
566
|
+
return profile ? [summarizeProfile(id, profile, ps.active)] : [];
|
|
567
|
+
}),
|
|
568
|
+
reconciled: ps.reconciled,
|
|
569
|
+
};
|
|
206
570
|
}
|
|
207
571
|
/**
|
|
208
|
-
* Describe the
|
|
572
|
+
* Describe the ACTIVE profile's settings without the key.
|
|
209
573
|
*
|
|
210
574
|
* @returns A secret-free summary.
|
|
211
575
|
*/
|
|
@@ -213,13 +577,44 @@ export function describeDecideCredentials() {
|
|
|
213
577
|
const path = decideCredentialsPath();
|
|
214
578
|
const store = readStoreSync(path);
|
|
215
579
|
const sealed = loadDecideConnection();
|
|
580
|
+
const active = toProfileStore(store).active;
|
|
216
581
|
return {
|
|
217
582
|
configured: sealed !== null,
|
|
218
583
|
path,
|
|
584
|
+
...(store.provider ? { provider: store.provider } : {}),
|
|
219
585
|
...(store.baseUrl ? { baseUrl: withoutUserinfo(store.baseUrl) } : {}),
|
|
220
586
|
...(store.model ? { model: store.model } : {}),
|
|
221
587
|
...(store.apiKey ? { keyPreview: maskApiKey(store.apiKey) } : {}),
|
|
222
588
|
...(store.updatedAt ? { updatedAt: store.updatedAt } : {}),
|
|
589
|
+
...(active ? { profile: active, activeProfile: active } : {}),
|
|
590
|
+
};
|
|
591
|
+
}
|
|
592
|
+
/**
|
|
593
|
+
* Describe one profile's settings without the key.
|
|
594
|
+
*
|
|
595
|
+
* @param ref - `<provider>/<name>`, or a bare provider for `<provider>/default`.
|
|
596
|
+
* @returns A secret-free summary; `configured: false` when the profile is unknown.
|
|
597
|
+
*/
|
|
598
|
+
export function describeDecideProfile(ref) {
|
|
599
|
+
const path = decideCredentialsPath();
|
|
600
|
+
const ps = readProfileStoreSync(path);
|
|
601
|
+
const parsed = parseDecideProfileRef(ref);
|
|
602
|
+
const profile = parsed ? ps.profiles[parsed.id] : undefined;
|
|
603
|
+
const activeProfile = ps.active ? { activeProfile: ps.active } : {};
|
|
604
|
+
if (!parsed || !profile)
|
|
605
|
+
return { configured: false, path, ...activeProfile };
|
|
606
|
+
const summary = summarizeProfile(parsed.id, profile, ps.active);
|
|
607
|
+
return {
|
|
608
|
+
configured: summary.configured,
|
|
609
|
+
path,
|
|
610
|
+
provider: summary.provider,
|
|
611
|
+
baseUrl: summary.baseUrl,
|
|
612
|
+
...(summary.model ? { model: summary.model } : {}),
|
|
613
|
+
keyPreview: summary.keyPreview,
|
|
614
|
+
...(summary.updatedAt ? { updatedAt: summary.updatedAt } : {}),
|
|
615
|
+
profile: parsed.id,
|
|
616
|
+
urlSource: summary.urlSource,
|
|
617
|
+
...activeProfile,
|
|
223
618
|
};
|
|
224
619
|
}
|
|
225
620
|
/** Error thrown by {@link saveDecideCredentials} for invalid input. The message never contains the key. */
|
|
@@ -304,22 +699,72 @@ function ensureStoreFile(path) {
|
|
|
304
699
|
writeFileSync(path, `${JSON.stringify(EMPTY_STORE)}\n`, { encoding: 'utf-8', mode: 0o600 });
|
|
305
700
|
}
|
|
306
701
|
/**
|
|
307
|
-
*
|
|
702
|
+
* Apply `change` to the profiles under the store lock and write the result
|
|
703
|
+
* (0600, atomic), keeping the top-level settings equal to the active
|
|
704
|
+
* profile. `change` may throw a {@link DecideCredentialsError} to abort
|
|
705
|
+
* without writing.
|
|
706
|
+
*/
|
|
707
|
+
async function mutateProfiles(change) {
|
|
708
|
+
const path = decideCredentialsPath();
|
|
709
|
+
guardWrite(path);
|
|
710
|
+
ensureStoreFile(path);
|
|
711
|
+
await withLock(path, (current) => fromProfileStore(change(toProfileStore(parseStore(current) ?? EMPTY_STORE))), { mode: 0o600 });
|
|
712
|
+
}
|
|
713
|
+
/**
|
|
714
|
+
* The profile a save targets: `input.profile` as `<provider>/<name>` or a
|
|
715
|
+
* bare name, with the provider from `input.provider`, the reference, or the
|
|
716
|
+
* URL.
|
|
717
|
+
*/
|
|
718
|
+
function saveTarget(input, baseUrl) {
|
|
719
|
+
const raw = input.profile?.trim();
|
|
720
|
+
if (raw?.includes('/')) {
|
|
721
|
+
const ref = requireProfileRef(raw);
|
|
722
|
+
if (input.provider && input.provider !== ref.provider) {
|
|
723
|
+
throw new DecideCredentialsError(`profile '${ref.id}' belongs to ${ref.provider}, not ${input.provider}`);
|
|
724
|
+
}
|
|
725
|
+
return ref;
|
|
726
|
+
}
|
|
727
|
+
const provider = input.provider ??
|
|
728
|
+
(baseUrl === DECIDE_PROFILE_DEFAULT_URL ? 'layahost' : inferDecisionProviderKind(baseUrl));
|
|
729
|
+
const name = raw || DECIDE_DEFAULT_PROFILE_NAME;
|
|
730
|
+
if (!isValidDecideProfileName(name)) {
|
|
731
|
+
throw new DecideCredentialsError(`invalid profile name '${name}' ${PROFILE_REF_RULE}`);
|
|
732
|
+
}
|
|
733
|
+
return { provider, name, id: decideProfileId(provider, name) };
|
|
734
|
+
}
|
|
735
|
+
/**
|
|
736
|
+
* Store a profile: provider kind, base URL (`default` or an override), API
|
|
737
|
+
* key and optional model (0600, locked, atomic). Adds the profile or
|
|
738
|
+
* replaces that profile's settings; every other profile is kept. A URL equal
|
|
739
|
+
* to the provider's preset is stored as `default`, so a changed preset flows
|
|
740
|
+
* through. Writes schema version 1 with the active profile mirrored at the
|
|
741
|
+
* top level, URL resolved.
|
|
308
742
|
*
|
|
309
|
-
* @param input - Settings to store
|
|
310
|
-
* @returns Secret-free summary of
|
|
311
|
-
* @throws {DecideCredentialsError} When the URL is not https (or loopback http),
|
|
312
|
-
*
|
|
743
|
+
* @param input - Settings to store, the profile and whether to activate it.
|
|
744
|
+
* @returns Secret-free summary of the profile now stored.
|
|
745
|
+
* @throws {DecideCredentialsError} When the URL is not https (or loopback http), `default`
|
|
746
|
+
* names a provider without a preset URL, the key is blank, the model or profile is
|
|
747
|
+
* invalid, or the store or its backups are symlinks.
|
|
313
748
|
*/
|
|
314
749
|
export async function saveDecideCredentials(input) {
|
|
315
|
-
const
|
|
750
|
+
const rawUrl = input.baseUrl.trim();
|
|
316
751
|
const apiKey = input.apiKey.trim();
|
|
317
752
|
const model = input.model?.trim();
|
|
318
|
-
|
|
319
|
-
|
|
753
|
+
const target = saveTarget(input, rawUrl);
|
|
754
|
+
let baseUrl = DECIDE_PROFILE_DEFAULT_URL;
|
|
755
|
+
if (rawUrl === DECIDE_PROFILE_DEFAULT_URL) {
|
|
756
|
+
if (!presetBaseUrl(target.provider)) {
|
|
757
|
+
throw new DecideCredentialsError(`the ${target.provider} provider has no default URL; pass --url https://your-provider.example`);
|
|
758
|
+
}
|
|
320
759
|
}
|
|
321
|
-
|
|
322
|
-
|
|
760
|
+
else {
|
|
761
|
+
if (hasUserinfo(rawUrl)) {
|
|
762
|
+
throw new DecideCredentialsError('base URL must not contain a username or password (user:pass@host); supply only the URL and the API key');
|
|
763
|
+
}
|
|
764
|
+
if (!isAllowedDecideBaseUrl(rawUrl)) {
|
|
765
|
+
throw new DecideCredentialsError('base URL must be an absolute https:// URL (plain http:// is allowed only for localhost, 127.0.0.1 and ::1)');
|
|
766
|
+
}
|
|
767
|
+
baseUrl = urlSetting(target.provider, rawUrl);
|
|
323
768
|
}
|
|
324
769
|
if (model && !isValidDecisionModelName(model)) {
|
|
325
770
|
throw new DecideCredentialsError('model name may contain only letters, digits and . _ : / @ - (1-128 characters)');
|
|
@@ -328,32 +773,89 @@ export async function saveDecideCredentials(input) {
|
|
|
328
773
|
throw new DecideCredentialsError('API key must not be empty');
|
|
329
774
|
if (/\s/.test(apiKey))
|
|
330
775
|
throw new DecideCredentialsError('API key must not contain whitespace');
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
776
|
+
await mutateProfiles((ps) => {
|
|
777
|
+
const activate = input.activate ?? (ps.active === null || ps.active === target.id);
|
|
778
|
+
const profile = {
|
|
779
|
+
provider: target.provider,
|
|
780
|
+
name: target.name,
|
|
781
|
+
baseUrl,
|
|
782
|
+
apiKey,
|
|
783
|
+
model: model || null,
|
|
784
|
+
updatedAt: new Date().toISOString(),
|
|
785
|
+
};
|
|
786
|
+
return {
|
|
787
|
+
profiles: { ...ps.profiles, [target.id]: profile },
|
|
788
|
+
active: activate ? target.id : ps.active,
|
|
789
|
+
reconciled: false,
|
|
790
|
+
};
|
|
791
|
+
});
|
|
792
|
+
return describeDecideProfile(target.id);
|
|
793
|
+
}
|
|
794
|
+
/**
|
|
795
|
+
* Make a profile the active one: everyday decisions use it from now on.
|
|
796
|
+
*
|
|
797
|
+
* @param ref - `<provider>/<name>`, or a bare provider for `<provider>/default`.
|
|
798
|
+
* @returns The profile list after the switch.
|
|
799
|
+
* @throws {DecideCredentialsError} When the reference is invalid or unknown.
|
|
800
|
+
*/
|
|
801
|
+
export async function useDecideProfile(ref) {
|
|
802
|
+
const { id } = requireProfileRef(ref);
|
|
803
|
+
await mutateProfiles((ps) => {
|
|
804
|
+
if (!ps.profiles[id]) {
|
|
805
|
+
throw new DecideCredentialsError(`no System One profile '${id}'${knownIds(ps)}`);
|
|
806
|
+
}
|
|
807
|
+
return { ...ps, active: id, reconciled: false };
|
|
808
|
+
});
|
|
809
|
+
return listDecideProfiles();
|
|
810
|
+
}
|
|
811
|
+
/**
|
|
812
|
+
* Remove a profile, then delete every rotated backup of the store (a backup
|
|
813
|
+
* may hold the removed key). The active profile is removed only when `use`
|
|
814
|
+
* names another profile to activate in its place.
|
|
815
|
+
*
|
|
816
|
+
* @param ref - Profile to remove.
|
|
817
|
+
* @param use - Profile to activate instead; required when `ref` is active.
|
|
818
|
+
* @returns The profile list after the removal.
|
|
819
|
+
* @throws {DecideCredentialsError} When a reference is invalid or unknown,
|
|
820
|
+
* or `ref` is active and `use` is missing or names it.
|
|
821
|
+
*/
|
|
822
|
+
export async function removeDecideProfile(ref, use) {
|
|
823
|
+
const { id } = requireProfileRef(ref);
|
|
824
|
+
const useId = use === undefined ? undefined : requireProfileRef(use).id;
|
|
825
|
+
await mutateProfiles((ps) => {
|
|
826
|
+
if (!ps.profiles[id]) {
|
|
827
|
+
throw new DecideCredentialsError(`no System One profile '${id}'${knownIds(ps)}`);
|
|
828
|
+
}
|
|
829
|
+
let active = ps.active;
|
|
830
|
+
if (useId !== undefined) {
|
|
831
|
+
if (useId === id || !ps.profiles[useId]) {
|
|
832
|
+
throw new DecideCredentialsError(`--use must name another stored profile${knownIds(ps)}`);
|
|
833
|
+
}
|
|
834
|
+
active = useId;
|
|
835
|
+
}
|
|
836
|
+
if (active === id) {
|
|
837
|
+
throw new DecideCredentialsError(`'${id}' is the active profile: name the profile to activate instead with --use <provider>/<name>, or remove every profile with --clear`);
|
|
838
|
+
}
|
|
839
|
+
const profiles = Object.fromEntries(Object.entries(ps.profiles).filter(([profileId]) => profileId !== id));
|
|
840
|
+
return { profiles, active, reconciled: false };
|
|
841
|
+
});
|
|
842
|
+
purgeBackups(decideCredentialsPath());
|
|
843
|
+
return listDecideProfiles();
|
|
342
844
|
}
|
|
343
845
|
/**
|
|
344
|
-
* Remove
|
|
345
|
-
*
|
|
846
|
+
* Remove every profile: the store is overwritten with empty settings and
|
|
847
|
+
* every rotated backup of it (which may hold an old key) is deleted.
|
|
346
848
|
*
|
|
347
849
|
* @returns True when settings were present before the call.
|
|
348
850
|
*/
|
|
349
851
|
export async function clearDecideCredentials() {
|
|
350
852
|
const path = decideCredentialsPath();
|
|
351
853
|
const before = readStoreSync(path);
|
|
352
|
-
const hadSettings = Boolean(before.baseUrl || before.apiKey || before.model);
|
|
854
|
+
const hadSettings = Boolean(before.baseUrl || before.apiKey || before.model || Object.keys(before.profiles ?? {}).length);
|
|
353
855
|
guardWrite(path);
|
|
354
856
|
if (existsSync(path)) {
|
|
355
857
|
ensureStoreFile(path);
|
|
356
|
-
await withLock(path, () =>
|
|
858
|
+
await withLock(path, () => EMPTY_WRITTEN, { mode: 0o600 });
|
|
357
859
|
}
|
|
358
860
|
purgeBackups(path);
|
|
359
861
|
return hadSettings;
|